From e05ba723be5c83543d9075ac8e64dcd799bbdc4a Mon Sep 17 00:00:00 2001 From: Shweta Bhosale Date: Mon, 18 May 2026 16:17:47 +0530 Subject: [PATCH] cephadm: moved check-online,sysctl-dir subcommands under _orch Moved above mentioned commands under the existing cephadm _orch namespace Fixes: https://tracker.ceph.com/issues/74045 Signed-off-by: Shweta Bhosale --- doc/cephadm/host-management.rst | 3 +- doc/man/8/cephadm.rst | 39 ++++------------ src/cephadm/cephadm.py | 54 ++++++++++++----------- src/cephadm/tests/test_cephadm.py | 8 ++-- src/pybind/mgr/cephadm/module.py | 9 ++-- src/pybind/mgr/cephadm/offline_watcher.py | 14 ++++-- src/pybind/mgr/cephadm/tests/test_ssh.py | 2 +- src/pybind/mgr/cephadm/tuned_profiles.py | 6 +-- 8 files changed, 62 insertions(+), 73 deletions(-) diff --git a/doc/cephadm/host-management.rst b/doc/cephadm/host-management.rst index 7167ae31570..0fd4f1284e0 100644 --- a/doc/cephadm/host-management.rst +++ b/doc/cephadm/host-management.rst @@ -552,8 +552,7 @@ cephadm operations. Run a command of the following form: ceph cephadm set-user The ``set-user`` command automatically configures the specified user on all cluster -hosts by calling ``cephadm setup-ssh-user`` on each host. This command is available starting -with the Umbrella release and includes the following: +hosts by calling ``cephadm setup-ssh-user`` on each host. This command includes the following: - Setting up passwordless sudo access for non-root users - Authorizing the cluster's SSH public key for the user diff --git a/doc/man/8/cephadm.rst b/doc/man/8/cephadm.rst index c8f2ba98d29..5843448d19d 100644 --- a/doc/man/8/cephadm.rst +++ b/doc/man/8/cephadm.rst @@ -13,7 +13,7 @@ Synopsis | [--log-dir LOG_DIR] [--logrotate-dir LOGROTATE_DIR] | [--unit-dir UNIT_DIR] [--verbose] [--timeout TIMEOUT] | [--retry RETRY] [--no-container-init] -| {version,pull,inspect-image,ls,list-networks,list-rdma,adopt,rm-daemon,rm-cluster,remove-file,deploy-file,sysctl-dir,run,shell,enter,ceph-volume,unit,logs,bootstrap,deploy,check-host,check-online,prepare-host,prepare-host-sudo-hardening,setup-ssh-user,add-repo,rm-repo,install,list-images,update-osd-service} +| {version,pull,inspect-image,ls,list-networks,list-rdma,adopt,rm-daemon,rm-cluster,remove-file,deploy-file,run,shell,enter,ceph-volume,unit,logs,bootstrap,deploy,check-host,prepare-host,prepare-host-sudo-hardening,setup-ssh-user,add-repo,rm-repo,install,list-images,update-osd-service} | ... @@ -90,17 +90,19 @@ Synopsis | **cephadm** **check-host** [-h] [--expect-hostname EXPECT_HOSTNAME] -| **cephadm** **check-online** - | **cephadm** **remove-file** [-h] [--fsid FSID] --path PATH | **cephadm** **deploy-file** [-h] [--fsid FSID] --path PATH [--mode MODE] | [--uid UID] [--gid GID] -| **cephadm** **sysctl-dir** [-h] [--fsid FSID] (--list | --apply-system) - | **cephadm** **prepare-host** +| **cephadm** **prepare-host-sudo-hardening** [-h] [--ssh-user SSH_USER] +| [--ssh-pub-key SSH_PUB_KEY] +| [--cephadm-version VERSION] + +| **cephadm** **setup-ssh-user** [-h] --ssh-user SSH_USER --ssh-pub-key SSH_PUB_KEY + | **cephadm** **add-repo** [-h] [--release RELEASE] [--version VERSION] | [--dev DEV] [--dev-commit DEV_COMMIT] | [--gpg-url GPG_URL] [--repo-url REPO_URL] @@ -298,25 +300,14 @@ Arguments: * [--expect-hostname EXPECT_HOSTNAME] Check that hostname matches an expected value -check-online ------------- - -check that the host is online by running ``true`` locally. - -This command is primarily intended for cephadm internals (for example, the -offline host watcher), rather than direct operator workflows. - - remove-file ----------- Remove a regular file on the local host. Missing paths are ignored. -Refuses directories and symbolic links, only plain files are -removed. Arguments: -* [--fsid FSID] cluster FSID (passed automatically when invoked by the orchestrator) +* [--fsid FSID] cluster FSID * --path PATH absolute path of the file to remove (required) @@ -328,25 +319,13 @@ Write or replace a file on the local host. The **entire file body** is read from Arguments: -* [--fsid FSID] cluster FSID (passed automatically when invoked by the orchestrator) +* [--fsid FSID] cluster FSID * --path PATH absolute destination path for the file (required) * [--mode MODE] octal file mode (for example ``644`` or ``0644``) * [--uid UID] numeric owner user id (**must** be given together with ``--gid``) * [--gid GID] numeric owner group id (**must** be given together with ``--uid``) -sysctl-dir ----------- - -List basenames under ``/etc/sysctl.d`` or run ``sysctl --system`` on the local host. - -Arguments: - -* [--fsid FSID] cluster FSID (passed automatically when invoked by the orchestrator) -* --list print one directory entry per line (sorted) -* --apply-system reload sysctl settings from all configuration paths - - deploy ------ diff --git a/src/cephadm/cephadm.py b/src/cephadm/cephadm.py index 11de13858b5..1e788ceadf2 100755 --- a/src/cephadm/cephadm.py +++ b/src/cephadm/cephadm.py @@ -5663,6 +5663,32 @@ def _get_parser(): help='Configuration input source file', ) + parser_check_online = subparsers_orch.add_parser( + 'check-online', help='return true to indicate host is running') + parser_check_online.set_defaults(func=command_check_online) + + parser_sysctl_dir = subparsers_orch.add_parser( + 'sysctl-dir', + help='list entries in sysctl.d or run sysctl --system') + parser_sysctl_dir.set_defaults(func=command_sysctl_dir) + parser_sysctl_dir.add_argument( + '--fsid', + help='cluster FSID') + _sysctl_dir_action = parser_sysctl_dir.add_mutually_exclusive_group( + required=True) + _sysctl_dir_action.add_argument( + '--list', + dest='sysctl_dir_action', + action='store_const', + const='list', + help=f'print one basename per line from {SYSCTL_DIR}') + _sysctl_dir_action.add_argument( + '--apply-system', + dest='sysctl_dir_action', + action='store_const', + const='apply_system', + help='reload sysctl settings from all config paths (sysctl --system)') + parser_check_host = subparsers.add_parser( 'check-host', help='check host configuration') parser_check_host.set_defaults(func=command_check_host) @@ -5670,10 +5696,6 @@ def _get_parser(): '--expect-hostname', help='Check that hostname matches an expected value') - parser_check_online = subparsers.add_parser( - 'check-online', help='return true to indicate host is running') - parser_check_online.set_defaults(func=command_check_online) - parser_prepare_host = subparsers.add_parser( 'prepare-host', help='prepare a host for cephadm use') parser_prepare_host.set_defaults(func=command_prepare_host) @@ -5808,28 +5830,6 @@ def _get_parser(): default=None, help='numeric owner gid (requires --uid)') - parser_sysctl_dir = subparsers.add_parser( - 'sysctl-dir', - help='list entries in sysctl.d or run sysctl --system') - parser_sysctl_dir.set_defaults(func=command_sysctl_dir) - parser_sysctl_dir.add_argument( - '--fsid', - help='cluster FSID') - _sysctl_dir_action = parser_sysctl_dir.add_mutually_exclusive_group( - required=True) - _sysctl_dir_action.add_argument( - '--list', - dest='sysctl_dir_action', - action='store_const', - const='list', - help=f'print one basename per line from {SYSCTL_DIR}') - _sysctl_dir_action.add_argument( - '--apply-system', - dest='sysctl_dir_action', - action='store_const', - const='apply_system', - help='reload sysctl settings from all config paths (sysctl --system)') - parser_maintenance = subparsers.add_parser( 'host-maintenance', help='Manage the maintenance state of a host') parser_maintenance.add_argument( @@ -5975,6 +5975,8 @@ def main() -> None: command_check_host, command_check_online, command_prepare_host, + command_setup_ssh_user, + command_prepare_host_sudo_hardening, command_add_repo, command_rm_repo, command_install, diff --git a/src/cephadm/tests/test_cephadm.py b/src/cephadm/tests/test_cephadm.py index f57b224468c..3b9a70424a9 100644 --- a/src/cephadm/tests/test_cephadm.py +++ b/src/cephadm/tests/test_cephadm.py @@ -191,7 +191,7 @@ class TestCephAdm(object): cephadm_fs.create_file(os.path.join(SYSCTL_DIR, 'c.conf')) cephadm_fs.create_file(os.path.join(SYSCTL_DIR, 'a.conf')) with with_cephadm_ctx( - ['sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--list'] + ['_orch', 'sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--list'] ) as ctx: assert _cephadm.command_sysctl_dir(ctx) == 0 assert capsys.readouterr().out.splitlines() == ['a.conf', 'c.conf'] @@ -204,14 +204,14 @@ class TestCephAdm(object): shutil.rmtree(SYSCTL_DIR) assert not cephadm_fs.exists(SYSCTL_DIR) with with_cephadm_ctx( - ['sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--list'] + ['_orch', 'sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--list'] ) as ctx: with pytest.raises(_cephadm.Error, match='Not a directory'): _cephadm.command_sysctl_dir(ctx) def test_command_sysctl_dir_apply_system(self, cephadm_fs): with with_cephadm_ctx( - ['sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--apply-system'] + ['_orch', 'sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--apply-system'] ) as ctx: assert _cephadm.command_sysctl_dir(ctx) == 0 @@ -219,7 +219,7 @@ class TestCephAdm(object): # Do not let with_cephadm_ctx re-patch cephadm.call back to success (exit 0). with mock.patch('cephadm.call', return_value=('out', 'sysctl failed', 1)): with with_cephadm_ctx( - ['sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--apply-system'], + ['_orch', 'sysctl-dir', '--fsid', '00000000-0000-0000-0000-0000deadbeef', '--apply-system'], mock_cephadm_call_fn=False, ) as ctx: with pytest.raises(_cephadm.Error, match='sysctl --system failed'): diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index c81ee9b9c3f..d201da57a0a 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -1197,7 +1197,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule): def _setup_user_on_host(self, host: str, user: str, ssh_pub_key: str, addr: Optional[str] = None) -> None: """ - Setup sudoers and copy SSH key by calling cephadm setup-ssh-user command. + Setup sudoers and copy SSH key by calling cephadm setup-ssh-user. User must already exist on the host. For root user, only SSH key is copied (sudoers setup is skipped). """ @@ -1582,7 +1582,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule): addr: Optional[str] = None ) -> Tuple[str, bool, str]: """ - Prepare a host for sudo hardening by executing 'cephadm prepare-host-sudo-hardening' command. + Prepare a host for sudo hardening by executing cephadm prepare-host-sudo-hardening. """ try: self.log.debug('Preparing host %s for sudo hardening...', host) @@ -1591,7 +1591,10 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule): with self.async_timeout_handler(host, 'cephadm prepare-host-sudo-hardening'): out, err, code = self.wait_async( CephadmServe(self)._run_cephadm( - host, cephadmNoImage, 'prepare-host-sudo-hardening', cephadm_args, + host, + cephadmNoImage, + 'prepare-host-sudo-hardening', + cephadm_args, addr=addr, error_ok=True, no_fsid=True)) if code: error_msg = '\n'.join(err) if err else 'Unknown error' diff --git a/src/pybind/mgr/cephadm/offline_watcher.py b/src/pybind/mgr/cephadm/offline_watcher.py index c8bfa4cb3d1..b96475f9a98 100644 --- a/src/pybind/mgr/cephadm/offline_watcher.py +++ b/src/pybind/mgr/cephadm/offline_watcher.py @@ -41,10 +41,16 @@ class OfflineHostWatcher(threading.Thread): def check_host(self, host: str) -> None: if host not in self.mgr.offline_hosts: try: - with self.mgr.async_timeout_handler(host, 'cephadm check-online'): - self.mgr.wait_async(CephadmServe(self.mgr)._run_cephadm( - host, cephadmNoImage, 'check-online', [], - no_fsid=True, log_output=self.mgr.log_refresh_metadata)) + with self.mgr.async_timeout_handler( + host, 'cephadm _orch check-online'): + self.mgr.wait_async( + CephadmServe(self.mgr)._run_cephadm( + host, + cephadmNoImage, + ['_orch', 'check-online'], + [], + no_fsid=True, + log_output=self.mgr.log_refresh_metadata)) except Exception: logger.debug(f'OfflineHostDetector: detected {host} to be offline') # kick serve loop in case corrective action must be taken for offline host diff --git a/src/pybind/mgr/cephadm/tests/test_ssh.py b/src/pybind/mgr/cephadm/tests/test_ssh.py index ebb80b18b94..5a8b380a4b6 100644 --- a/src/pybind/mgr/cephadm/tests/test_ssh.py +++ b/src/pybind/mgr/cephadm/tests/test_ssh.py @@ -123,6 +123,6 @@ def test_offline_watcher_uses_cephadm_check_online(run_cephadm, cephadm_module): cephadm_module.offline_watcher.check_host('test') run_cephadm.assert_called_once_with( - 'test', cephadmNoImage, 'check-online', [], + 'test', cephadmNoImage, ['_orch', 'check-online'], [], no_fsid=True, log_output=cephadm_module.log_refresh_metadata ) diff --git a/src/pybind/mgr/cephadm/tuned_profiles.py b/src/pybind/mgr/cephadm/tuned_profiles.py index 9223b1e0842..941494d299f 100644 --- a/src/pybind/mgr/cephadm/tuned_profiles.py +++ b/src/pybind/mgr/cephadm/tuned_profiles.py @@ -13,7 +13,7 @@ logger = logging.getLogger(__name__) SYSCTL_DIR = '/etc/sysctl.d' -SYSCTL_DIR_CEPHADM_CMD = 'sysctl-dir' +SYSCTL_DIR_CEPHADM_CMD = ['_orch', 'sysctl-dir'] class TunedProfileUtils(): @@ -21,7 +21,7 @@ class TunedProfileUtils(): self.mgr = mgr def _sysctl_dir_list(self, host: str) -> str: - with self.mgr.async_timeout_handler(host, 'cephadm sysctl-dir --list'): + with self.mgr.async_timeout_handler(host, 'cephadm _orch sysctl-dir --list'): out, _err, _code = self.mgr.wait_async(CephadmServe(self.mgr)._run_cephadm( host, cephadmNoImage, @@ -32,7 +32,7 @@ class TunedProfileUtils(): return ''.join(out) def _sysctl_dir_apply_system(self, host: str) -> None: - with self.mgr.async_timeout_handler(host, 'cephadm sysctl-dir --apply-system'): + with self.mgr.async_timeout_handler(host, 'cephadm _orch sysctl-dir --apply-system'): self.mgr.wait_async(CephadmServe(self.mgr)._run_cephadm( host, cephadmNoImage, -- 2.47.3