summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam King <47704447+adk3798@users.noreply.github.com>2023-06-14 20:23:27 +0200
committerGitHub <noreply@github.com>2023-06-14 20:23:27 +0200
commit8e5a983a73202623275f70b3a42a0f3c0e425c88 (patch)
treec0579072c54c23de420468d86c94cc197d7edd0f /src
parentMerge pull request #51832 from rkachach/fix_issue_61499 (diff)
parentqa/workunits/cephadm: align test_cephadm.sh with new cephadm version (diff)
downloadceph-8e5a983a73202623275f70b3a42a0f3c0e425c88.tar.xz
ceph-8e5a983a73202623275f70b3a42a0f3c0e425c88.zip
Merge pull request #51267 from phlogistonjohn/jjm-cephadm-versioning
Support cephadm "binary" versioning Reviewed-by: Adam King <adking@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/cephadm/CMakeLists.txt8
-rwxr-xr-xsrc/cephadm/build.py41
-rwxr-xr-xsrc/cephadm/cephadm.py44
3 files changed, 82 insertions, 11 deletions
diff --git a/src/cephadm/CMakeLists.txt b/src/cephadm/CMakeLists.txt
index fdb7c9881fa..8b969bc33e7 100644
--- a/src/cephadm/CMakeLists.txt
+++ b/src/cephadm/CMakeLists.txt
@@ -11,7 +11,13 @@ add_custom_command(
${CMAKE_CURRENT_SOURCE_DIR}/cephadm.py
${CMAKE_CURRENT_SOURCE_DIR}/build.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- COMMAND ${Python3_EXECUTABLE} build.py ${bin_target_file}
+ COMMAND ${Python3_EXECUTABLE} build.py
+ --set-version-var=CEPH_GIT_VER=${CEPH_GIT_VER}
+ --set-version-var=CEPH_GIT_NICE_VER=${CEPH_GIT_NICE_VER}
+ --set-version-var=CEPH_RELEASE=${CEPH_RELEASE}
+ --set-version-var=CEPH_RELEASE_NAME=${CEPH_RELEASE_NAME}
+ --set-version-var=CEPH_RELEASE_TYPE=${CEPH_RELEASE_TYPE}
+ ${bin_target_file}
)
add_custom_target(cephadm ALL
diff --git a/src/cephadm/build.py b/src/cephadm/build.py
index 39c93ce3b30..4264b814f1e 100755
--- a/src/cephadm/build.py
+++ b/src/cephadm/build.py
@@ -27,6 +27,15 @@ except ImportError:
log = logging.getLogger(__name__)
+_VALID_VERS_VARS = [
+ "CEPH_GIT_VER",
+ "CEPH_GIT_NICE_VER",
+ "CEPH_RELEASE",
+ "CEPH_RELEASE_NAME",
+ "CEPH_RELEASE_TYPE",
+]
+
+
def _reexec(python):
"""Switch to the selected version of python by exec'ing into the desired
python path.
@@ -45,7 +54,7 @@ def _did_rexec():
return bool(os.environ.get("_BUILD_PYTHON_SET", ""))
-def _build(dest, src):
+def _build(dest, src, versioning_vars=None):
"""Build the binary."""
os.chdir(src)
tempdir = pathlib.Path(tempfile.mkdtemp(suffix=".cephadm.build"))
@@ -61,6 +70,8 @@ def _build(dest, src):
# dir to be zipped. For now we just have a simple call to copy
# (and rename) the one file we care about.
shutil.copy("cephadm.py", tempdir / "__main__.py")
+ if versioning_vars:
+ generate_version_file(versioning_vars, tempdir / "_version.py")
_compile(dest, tempdir)
finally:
shutil.rmtree(tempdir)
@@ -115,6 +126,24 @@ def _install_deps(tempdir):
)
+def generate_version_file(versioning_vars, dest):
+ log.info("Generating version file")
+ log.debug("versioning_vars=%r", versioning_vars)
+ with open(dest, "w") as fh:
+ print("# GENERATED FILE -- do not edit", file=fh)
+ for key, value in versioning_vars:
+ print(f"{key} = {value!r}", file=fh)
+
+
+def version_kv_pair(value):
+ if "=" not in value:
+ raise argparse.ArgumentTypeError(f"not a key=value pair: {value!r}")
+ key, value = value.split("=", 1)
+ if key not in _VALID_VERS_VARS:
+ raise argparse.ArgumentTypeError(f"Unexpected key: {key!r}")
+ return key, value
+
+
def main():
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter("cephadm/build.py: %(message)s"))
@@ -132,6 +161,14 @@ def main():
parser.add_argument(
"--python", help="The path to the desired version of python"
)
+ parser.add_argument(
+ "--set-version-var",
+ "-S",
+ type=version_kv_pair,
+ dest="version_vars",
+ action="append",
+ help="Set a key=value pair in the generated version info file",
+ )
args = parser.parse_args()
if not _did_rexec() and args.python:
@@ -160,7 +197,7 @@ def main():
dest = pathlib.Path(args.dest).absolute()
log.info("Source Dir: %s", source)
log.info("Destination Path: %s", dest)
- _build(dest, source)
+ _build(dest, source, versioning_vars=args.version_vars)
if __name__ == "__main__":
diff --git a/src/cephadm/cephadm.py b/src/cephadm/cephadm.py
index 3500f8b5e39..15fb31377e3 100755
--- a/src/cephadm/cephadm.py
+++ b/src/cephadm/cephadm.py
@@ -2296,6 +2296,16 @@ def default_image(func: FuncT) -> FuncT:
return cast(FuncT, _default_image)
+def executes_early(func: FuncT) -> FuncT:
+ """Decorator that indicates the command function is meant to have no
+ dependencies and no environmental requirements and can therefore be
+ executed as non-root and with no logging, etc. Commands that have this
+ decorator applied must be simple and self-contained.
+ """
+ cast(Any, func)._execute_early = True
+ return func
+
+
def get_container_info(ctx: CephadmContext, daemon_filter: str, by_name: bool) -> Optional[ContainerInfo]:
"""
:param ctx: Cephadm context
@@ -4850,15 +4860,24 @@ def command_agent(ctx: CephadmContext) -> None:
##################################
-
-@infer_image
+@executes_early
def command_version(ctx):
# type: (CephadmContext) -> int
- c = CephContainer(ctx, ctx.image, 'ceph', ['--version'])
- out, err, ret = call(ctx, c.run_cmd(), desc=c.entrypoint)
- if not ret:
- print(out.strip())
- return ret
+ import importlib
+
+ try:
+ vmod = importlib.import_module('_version')
+ except ImportError:
+ print('cephadm version UNKNOWN')
+ return 1
+ _unset = '<UNSET>'
+ print('cephadm version {0} ({1}) {2} ({3})'.format(
+ getattr(vmod, 'CEPH_GIT_NICE_VER', _unset),
+ getattr(vmod, 'CEPH_GIT_VER', _unset),
+ getattr(vmod, 'CEPH_RELEASE_NAME', _unset),
+ getattr(vmod, 'CEPH_RELEASE_TYPE', _unset),
+ ))
+ return 0
##################################
@@ -9427,7 +9446,7 @@ def _get_parser():
subparsers = parser.add_subparsers(help='sub-command')
parser_version = subparsers.add_parser(
- 'version', help='get ceph version from container')
+ 'version', help='get cephadm version')
parser_version.set_defaults(func=command_version)
parser_pull = subparsers.add_parser(
@@ -10106,6 +10125,15 @@ def main() -> None:
sys.stderr.write('No command specified; pass -h or --help for usage\n')
sys.exit(1)
+ if ctx.has_function() and getattr(ctx.func, '_execute_early', False):
+ try:
+ sys.exit(ctx.func(ctx))
+ except Error as e:
+ if ctx.verbose:
+ raise
+ logger.error('ERROR: %s' % e)
+ sys.exit(1)
+
cephadm_require_root()
cephadm_init_logging(ctx, av)
try: