]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephadm: add deploy-from command
authorJohn Mulligan <jmulligan@redhat.com>
Thu, 11 May 2023 15:05:07 +0000 (11:05 -0400)
committerAdam King <adking@redhat.com>
Thu, 31 Aug 2023 17:35:14 +0000 (13:35 -0400)
Add the `deploy-from` command. This command is like `deploy` in
functionality but instead of sourcing input from a mixture of various
CLI arguments, CLI arguments that take JSON strings, and JSON data
provided on stdin - this command aims to take configuration from a
single unified JSON object provided on the commands stdin.

This change strives to be as reasonably backwards compatible with
`deploy` as possible and this leads to some awkward hoop-jumping,
including: needing to nest CLI arguments inside the JSON, because
that is what the manager constructs; duplicate sources of the fsid
(CLI and JSON); the strange behavior of CephadmContext when setting
values; and a few others I'm probably forgetting.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/cephadm/cephadm.py

index 53fcb915565dede91670e2775b6f479d6fabc9c5..6f19620ee56f4bbaf088d04cc74c638f6b0d098a 100755 (executable)
@@ -6264,7 +6264,84 @@ def command_deploy(ctx):
 
     if ctx.tcp_ports:
         daemon_ports = list(map(int, ctx.tcp_ports.split()))
+    _common_deploy(ctx, daemon_type, daemon_id, daemon_ports, deployment_type)
 
+
+def command_deploy_from(ctx: CephadmContext) -> None:
+    """The deploy-from command is similar to deploy but sources nearly all
+    configuration parameters from an input JSON configuration file.
+    """
+    source = '-'
+    if 'source' in ctx and ctx.source:
+        source = ctx.source
+    if source == '-':
+        config_data = json.load(sys.stdin)
+    else:
+        with open(source, 'rb') as fh:
+            config_data = json.load(fh)
+    logger.debug('Loaded deploy configuration: %r', config_data)
+
+    # Bind properties taken from the json to our ctx, similar to how
+    # cli options on `deploy` are bound to the context.
+    ctx.name = config_data['name']
+    if 'image' in config_data:
+        ctx.image = config_data['image']
+    if 'fsid' in config_data:
+        ctx.fsid = config_data['fsid']
+    if 'meta' in config_data:
+        ctx.meta_properties = config_data['meta']
+    if 'config_blobs' in config_data:
+        ctx.config_blobs = config_data['config_blobs']
+    # this is quite the hack!  this is a workaround for the fact that
+    # cephadm orch module knows about "args" not what they represent
+    # and so this lets us (try to) smooth the transition. Ideally, these
+    # would be set using key-value pairs in 'params' below.
+    parser = argparse.ArgumentParser(add_help=False)
+    _add_deploy_parser_args(parser)
+    try:
+        parsed_args = parser.parse_args(
+            config_data.get('deploy_arguments', []),
+        )
+    except SystemExit:
+        # exit_on_error arg for ArgumentParser is not present on py 3.6.
+        # we need to catch the exception until we can drop this code
+        raise Error('invalid argument encountered')
+    for key, value in vars(parsed_args).items():
+        setattr(ctx, key, value)
+    # prefer to get the values directly from the params JSON object.
+    for key, value in config_data.get('params', {}).items():
+        setattr(ctx, key, value)
+    update_default_image(ctx)
+    logger.debug('Determined image: %r', ctx.image)
+
+    daemon_type, daemon_id = ctx.name.split('.', 1)
+
+    lock = FileLock(ctx, ctx.fsid)
+    lock.acquire()
+
+    if daemon_type not in get_supported_daemons():
+        raise Error('daemon type %s not recognized' % daemon_type)
+
+    deployment_type = get_deployment_type(ctx, daemon_type, daemon_id)
+
+    # Migrate sysctl conf files from /usr/lib to /etc
+    migrate_sysctl_dir(ctx, ctx.fsid)
+
+    # Get and check ports explicitly required to be opened
+    daemon_ports = []  # type: List[int]
+
+    if ctx.tcp_ports:
+        daemon_ports = list(map(int, ctx.tcp_ports.split()))
+    _common_deploy(ctx, daemon_type, daemon_id, daemon_ports, deployment_type)
+
+
+def _common_deploy(
+    ctx: CephadmContext,
+    daemon_type: str,
+    daemon_id: str,
+    daemon_ports: List[int],
+    deployment_type: DeploymentType,
+) -> None:
     if daemon_type in Ceph.daemons:
         config, keyring = get_config_and_keyring(ctx)
         uid, gid = extract_uid_gid(ctx)
@@ -10012,6 +10089,29 @@ def _get_parser():
         help='cluster FSID')
     _add_deploy_parser_args(parser_deploy)
 
+    parser_orch = subparsers.add_parser(
+        '_orch',
+    )
+    subparsers_orch = parser_orch.add_subparsers(
+        title='Orchestrator Driven Commands',
+        description='Commands that are typically only run by cephadm mgr module',
+    )
+
+    parser_deploy_from = subparsers_orch.add_parser(
+        'deploy', help='deploy a daemon')
+    parser_deploy_from.set_defaults(func=command_deploy_from)
+    # currently cephadm mgr module passes an fsid option on the CLI too
+    # TODO: remove this and always source fsid from the JSON?
+    parser_deploy_from.add_argument(
+        '--fsid',
+        help='cluster FSID')
+    parser_deploy_from.add_argument(
+        'source',
+        default='-',
+        nargs='?',
+        help='Configuration input source file',
+    )
+
     parser_check_host = subparsers.add_parser(
         'check-host', help='check host configuration')
     parser_check_host.set_defaults(func=command_check_host)