From 55541d3f866ba2a2287179ff47555ff8a2ab21c1 Mon Sep 17 00:00:00 2001 From: Thomas Bechtold Date: Thu, 7 Nov 2019 10:50:04 +0100 Subject: [PATCH] ceph-daemon: Only run in the __main__ scope That makes unit testing easier to setup because the code is not loaded when ceph-daemon gets imported. Instead it is only loaded when executed. For that, the parser also moved to a function instead of being on module level. Signed-off-by: Thomas Bechtold --- src/ceph-daemon | 553 ++++++++++++++++++++++++------------------------ 1 file changed, 279 insertions(+), 274 deletions(-) diff --git a/src/ceph-daemon b/src/ceph-daemon index bc465fcafa2..8ffad428537 100755 --- a/src/ceph-daemon +++ b/src/ceph-daemon @@ -1507,278 +1507,283 @@ def command_rm_cluster(): ################################## -parser = argparse.ArgumentParser( - description='Bootstrap Ceph daemons with systemd and containers.', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument( - '--image', - default=DEFAULT_IMAGE, - help='container image') -parser.add_argument( - '--docker', - action='store_true', - help='use docker instead of podman') -parser.add_argument( - '--data-dir', - default=DATA_DIR, - help='base directory for daemon data') -parser.add_argument( - '--log-dir', - default=LOG_DIR, - help='base directory for daemon logs') -parser.add_argument( - '--logrotate-dir', - default=LOGROTATE_DIR, - help='location of logrotate configuration files') -parser.add_argument( - '--unit-dir', - default=UNIT_DIR, - help='base directory for systemd units') -parser.add_argument( - '--debug', '-d', - action='store_true', - help='Show debug-level log messages') -subparsers = parser.add_subparsers(help='sub-command') - -parser_version = subparsers.add_parser( - 'version', help='get ceph version from container') -parser_version.set_defaults(func=command_version) - -parser_ls = subparsers.add_parser( - 'ls', help='list daemon instances on this host') -parser_ls.set_defaults(func=command_ls) - -parser_adopt = subparsers.add_parser( - 'adopt', help='adopt daemon deployed with a different tool') -parser_adopt.set_defaults(func=command_adopt) -parser_adopt.add_argument( - '--name', '-n', - required=True, - help='daemon name (type.id)') -parser_adopt.add_argument( - '--style', - required=True, - help='deployment style (legacy, ...)') -parser_adopt.add_argument( - '--cluster', - default='ceph', - help='cluster name') - -parser_rm_daemon = subparsers.add_parser( - 'rm-daemon', help='remove daemon instance') -parser_rm_daemon.set_defaults(func=command_rm_daemon) -parser_rm_daemon.add_argument( - '--name', '-n', - required=True, - help='daemon name (type.id)') -parser_rm_daemon.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_rm_daemon.add_argument( - '--force', - action='store_true', - help='proceed, even though this may destroy valuable data') - -parser_rm_cluster = subparsers.add_parser( - 'rm-cluster', help='remove all daemons for a cluster') -parser_rm_cluster.set_defaults(func=command_rm_cluster) -parser_rm_cluster.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_rm_cluster.add_argument( - '--force', - action='store_true', - help='proceed, even though this may destroy valuable data') - -parser_run = subparsers.add_parser( - 'run', help='run a ceph daemon, in a container, in the foreground') -parser_run.set_defaults(func=command_run) -parser_run.add_argument( - '--name', '-n', - required=True, - help='daemon name (type.id)') -parser_run.add_argument( - '--fsid', - required=True, - help='cluster FSID') - -parser_shell = subparsers.add_parser( - 'shell', help='run an interactive shell inside a daemon container') -parser_shell.set_defaults(func=command_shell) -parser_shell.add_argument( - '--fsid', - help='cluster FSID') -parser_shell.add_argument( - '--name', '-n', - help='daemon name (type.id)') -parser_shell.add_argument( - '--config', '-c', - help='ceph.conf to pass through to the container') -parser_shell.add_argument( - '--keyring', '-k', - help='ceph.keyring to pass through to the container') -parser_shell.add_argument( - 'command', nargs='*', - help='command (optional)') - -parser_enter = subparsers.add_parser( - 'enter', help='run an interactive shell inside a running daemon container') -parser_enter.set_defaults(func=command_enter) -parser_enter.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_enter.add_argument( - '--name', '-n', - required=True, - help='daemon name (type.id)') -parser_enter.add_argument( - 'command', nargs='*', - help='command') - -parser_ceph_volume = subparsers.add_parser( - 'ceph-volume', help='run ceph-volume inside a container') -parser_ceph_volume.set_defaults(func=command_ceph_volume) -parser_ceph_volume.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_ceph_volume.add_argument( - '--config-and-keyring', - help='JSON file with config and (client.bootrap-osd) key') -parser_ceph_volume.add_argument( - 'command', nargs='+', - help='command') - -parser_unit = subparsers.add_parser( - 'unit', help='operate on the daemon\'s systemd unit') -parser_unit.set_defaults(func=command_unit) -parser_unit.add_argument( - 'command', - help='systemd command (start, stop, restart, enable, disable, ...)') -parser_unit.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_unit.add_argument( - '--name', '-n', - required=True, - help='daemon name (type.id)') - -parser_bootstrap = subparsers.add_parser( - 'bootstrap', help='bootstrap a cluster (mon + mgr daemons)') -parser_bootstrap.set_defaults(func=command_bootstrap) -parser_bootstrap.add_argument( - '--config', '-c', - help='ceph conf file to incorporate') -parser_bootstrap.add_argument( - '--mon-id', - required=False, - help='mon id (default: local hostname)') -parser_bootstrap.add_argument( - '--mon-addrv', - help='mon IPs (e.g., [v2:localipaddr:3300,v1:localipaddr:6789])') -parser_bootstrap.add_argument( - '--mon-ip', - help='mon IP') -parser_bootstrap.add_argument( - '--mgr-id', - required=False, - help='mgr id (default: local hostname)') -parser_bootstrap.add_argument( - '--fsid', - help='cluster FSID') -parser_bootstrap.add_argument( - '--output-keyring', - help='location to write keyring file with new cluster admin and mon keys') -parser_bootstrap.add_argument( - '--output-config', - help='location to write conf file to connect to new cluster') -parser_bootstrap.add_argument( - '--output-pub-ssh-key', - help='location to write the cluster\'s public SSH key') -parser_bootstrap.add_argument( - '--skip-ssh', - action='store_true', - help='skip setup of ssh key on local host') -parser_bootstrap.add_argument( - '--no-minimize-config', - action='store_true', - help='do not assimilate and minimize the config file') -parser_bootstrap.add_argument( - '--skip-ping-check', - action='store_true', - help='do not verify that mon IP is pingable') - -parser_deploy = subparsers.add_parser( +def _get_parser(): + parser = argparse.ArgumentParser( + description='Bootstrap Ceph daemons with systemd and containers.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--image', + default=DEFAULT_IMAGE, + help='container image') + parser.add_argument( + '--docker', + action='store_true', + help='use docker instead of podman') + parser.add_argument( + '--data-dir', + default=DATA_DIR, + help='base directory for daemon data') + parser.add_argument( + '--log-dir', + default=LOG_DIR, + help='base directory for daemon logs') + parser.add_argument( + '--logrotate-dir', + default=LOGROTATE_DIR, + help='location of logrotate configuration files') + parser.add_argument( + '--unit-dir', + default=UNIT_DIR, + help='base directory for systemd units') + parser.add_argument( + '--debug', '-d', + action='store_true', + help='Show debug-level log messages') + subparsers = parser.add_subparsers(help='sub-command') + + parser_version = subparsers.add_parser( + 'version', help='get ceph version from container') + parser_version.set_defaults(func=command_version) + + parser_ls = subparsers.add_parser( + 'ls', help='list daemon instances on this host') + parser_ls.set_defaults(func=command_ls) + + parser_adopt = subparsers.add_parser( + 'adopt', help='adopt daemon deployed with a different tool') + parser_adopt.set_defaults(func=command_adopt) + parser_adopt.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + parser_adopt.add_argument( + '--style', + required=True, + help='deployment style (legacy, ...)') + parser_adopt.add_argument( + '--cluster', + default='ceph', + help='cluster name') + + parser_rm_daemon = subparsers.add_parser( + 'rm-daemon', help='remove daemon instance') + parser_rm_daemon.set_defaults(func=command_rm_daemon) + parser_rm_daemon.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + parser_rm_daemon.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_rm_daemon.add_argument( + '--force', + action='store_true', + help='proceed, even though this may destroy valuable data') + + parser_rm_cluster = subparsers.add_parser( + 'rm-cluster', help='remove all daemons for a cluster') + parser_rm_cluster.set_defaults(func=command_rm_cluster) + parser_rm_cluster.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_rm_cluster.add_argument( + '--force', + action='store_true', + help='proceed, even though this may destroy valuable data') + + parser_run = subparsers.add_parser( + 'run', help='run a ceph daemon, in a container, in the foreground') + parser_run.set_defaults(func=command_run) + parser_run.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + parser_run.add_argument( + '--fsid', + required=True, + help='cluster FSID') + + parser_shell = subparsers.add_parser( + 'shell', help='run an interactive shell inside a daemon container') + parser_shell.set_defaults(func=command_shell) + parser_shell.add_argument( + '--fsid', + help='cluster FSID') + parser_shell.add_argument( + '--name', '-n', + help='daemon name (type.id)') + parser_shell.add_argument( + '--config', '-c', + help='ceph.conf to pass through to the container') + parser_shell.add_argument( + '--keyring', '-k', + help='ceph.keyring to pass through to the container') + parser_shell.add_argument( + 'command', nargs='*', + help='command (optional)') + + parser_enter = subparsers.add_parser( + 'enter', help='run an interactive shell inside a running daemon container') + parser_enter.set_defaults(func=command_enter) + parser_enter.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_enter.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + parser_enter.add_argument( + 'command', nargs='*', + help='command') + + parser_ceph_volume = subparsers.add_parser( + 'ceph-volume', help='run ceph-volume inside a container') + parser_ceph_volume.set_defaults(func=command_ceph_volume) + parser_ceph_volume.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_ceph_volume.add_argument( + '--config-and-keyring', + help='JSON file with config and (client.bootrap-osd) key') + parser_ceph_volume.add_argument( + 'command', nargs='+', + help='command') + + parser_unit = subparsers.add_parser( + 'unit', help='operate on the daemon\'s systemd unit') + parser_unit.set_defaults(func=command_unit) + parser_unit.add_argument( + 'command', + help='systemd command (start, stop, restart, enable, disable, ...)') + parser_unit.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_unit.add_argument( + '--name', '-n', + required=True, + help='daemon name (type.id)') + + parser_bootstrap = subparsers.add_parser( + 'bootstrap', help='bootstrap a cluster (mon + mgr daemons)') + parser_bootstrap.set_defaults(func=command_bootstrap) + parser_bootstrap.add_argument( + '--config', '-c', + help='ceph conf file to incorporate') + parser_bootstrap.add_argument( + '--mon-id', + required=False, + help='mon id (default: local hostname)') + parser_bootstrap.add_argument( + '--mon-addrv', + help='mon IPs (e.g., [v2:localipaddr:3300,v1:localipaddr:6789])') + parser_bootstrap.add_argument( + '--mon-ip', + help='mon IP') + parser_bootstrap.add_argument( + '--mgr-id', + required=False, + help='mgr id (default: local hostname)') + parser_bootstrap.add_argument( + '--fsid', + help='cluster FSID') + parser_bootstrap.add_argument( + '--output-keyring', + help='location to write keyring file with new cluster admin and mon keys') + parser_bootstrap.add_argument( + '--output-config', + help='location to write conf file to connect to new cluster') + parser_bootstrap.add_argument( + '--output-pub-ssh-key', + help='location to write the cluster\'s public SSH key') + parser_bootstrap.add_argument( + '--skip-ssh', + action='store_true', + help='skip setup of ssh key on local host') + parser_bootstrap.add_argument( + '--no-minimize-config', + action='store_true', + help='do not assimilate and minimize the config file') + parser_bootstrap.add_argument( + '--skip-ping-check', + action='store_true', + help='do not verify that mon IP is pingable') + + parser_deploy = subparsers.add_parser( 'deploy', help='deploy a daemon') -parser_deploy.set_defaults(func=command_deploy) -parser_deploy.add_argument( - '--name', - required=True, - help='daemon name (type.id)') -parser_deploy.add_argument( - '--fsid', - required=True, - help='cluster FSID') -parser_deploy.add_argument( - '--config', '-c', - help='config file for new daemon') -parser_deploy.add_argument( - '--keyring', - help='keyring for new daemon') -parser_deploy.add_argument( - '--crash-keyring', - help='crash keyring for crash agent daemon') -parser_deploy.add_argument( - '--key', - help='key for new daemon') -parser_deploy.add_argument( - '--config-and-keyrings', - help='JSON file with config and keyrings for the daemon and crash agent') -parser_deploy.add_argument( - '--mon-ip', - help='mon IP') -parser_deploy.add_argument( - '--mon-network', - help='mon network (CIDR)') -parser_deploy.add_argument( - '--osd-fsid', - help='OSD uuid, if creating an OSD container') - -# allow argv to be injected -try: - av = injected_argv -except NameError: - av = sys.argv[1:] - -args = parser.parse_args(av) - -if args.debug: - logging.basicConfig(level=logging.DEBUG) -else: - logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('ceph-daemon') - -# podman or docker? -if args.docker: - podman_path = find_program('docker') -else: - for i in PODMAN_PREFERENCE: - try: - podman_path = find_program(i) - break - except Exception as e: - logger.debug('could not locate %s: %s' % (i, e)) - if not podman_path: - raise RuntimeError('unable to locate any of %s' % PODMAN_PREFERENCE) - -if 'func' not in args: - sys.stderr.write('No command specified; pass -h or --help for usage\n') - sys.exit(1) -r = args.func() -if not r: - r = 0 -sys.exit(r) + parser_deploy.set_defaults(func=command_deploy) + parser_deploy.add_argument( + '--name', + required=True, + help='daemon name (type.id)') + parser_deploy.add_argument( + '--fsid', + required=True, + help='cluster FSID') + parser_deploy.add_argument( + '--config', '-c', + help='config file for new daemon') + parser_deploy.add_argument( + '--keyring', + help='keyring for new daemon') + parser_deploy.add_argument( + '--crash-keyring', + help='crash keyring for crash agent daemon') + parser_deploy.add_argument( + '--key', + help='key for new daemon') + parser_deploy.add_argument( + '--config-and-keyrings', + help='JSON file with config and keyrings for the daemon and crash agent') + parser_deploy.add_argument( + '--mon-ip', + help='mon IP') + parser_deploy.add_argument( + '--mon-network', + help='mon network (CIDR)') + parser_deploy.add_argument( + '--osd-fsid', + help='OSD uuid, if creating an OSD container') + + return parser + + +if __name__ == "__main__": + # allow argv to be injected + try: + av = injected_argv + except NameError: + av = sys.argv[1:] + parser = _get_parser() + args = parser.parse_args(av) + + if args.debug: + logging.basicConfig(level=logging.DEBUG) + else: + logging.basicConfig(level=logging.INFO) + logger = logging.getLogger('ceph-daemon') + + # podman or docker? + if args.docker: + podman_path = find_program('docker') + else: + for i in PODMAN_PREFERENCE: + try: + podman_path = find_program(i) + break + except Exception as e: + logger.debug('could not locate %s: %s' % (i, e)) + if not podman_path: + raise RuntimeError('unable to locate any of %s' % PODMAN_PREFERENCE) + + if 'func' not in args: + sys.stderr.write('No command specified; pass -h or --help for usage\n') + sys.exit(1) + r = args.func() + if not r: + r = 0 + sys.exit(r) -- 2.39.5