From: Kefu Chai Date: Sun, 8 Feb 2026 12:34:15 +0000 (+0800) Subject: doc/_ext: fix ceph_commands.py for new decorator-based command system X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F67254%2Fhead;p=ceph.git doc/_ext: fix ceph_commands.py for new decorator-based command system After commit 4aa9e246f, mgr modules migrated from using a class-level COMMANDS list to decorator-based command registration using per-module CLICommand instances (e.g., @BalancerCLICommand.Read('balancer status')). This broke the ceph_commands.py Sphinx extension which was hardcoded to expect m.COMMANDS to be a list, causing documentation builds to fail. But not all modules are using this per-module CLICommand. Some modules are fully migrated (balancer, hello, etc.) and use decorators, while others are partially migrated (volumes, progress, stats, influx, k8sevents, osd_perf_query, osd_support) - they have CLICommand defined but still use the old COMMANDS list. This fix updates _collect_module_commands() to handle three scenarios: 1. Fully migrated modules: Check CLICommand.dump_cmd_list() and use it if it returns commands 2. Partially migrated modules: Fall back to the old COMMANDS list if dump_cmd_list() returns empty 3. Legacy modules: Use COMMANDS list if CLICommand doesn't exist This ensures the Sphinx extension works with modules in any migration state, maintaining backwards compatibility while supporting the new decorator pattern. Signed-off-by: Kefu Chai --- diff --git a/doc/_ext/ceph_commands.py b/doc/_ext/ceph_commands.py index d96eab08853f..1440c6e2a064 100644 --- a/doc/_ext/ceph_commands.py +++ b/doc/_ext/ceph_commands.py @@ -316,8 +316,18 @@ class CephMgrCommands(Directive): ms = [c for c in mgr_mod.__dict__.values() if subclass(c) and 'Standby' not in c.__name__] [m] = ms - assert isinstance(m.COMMANDS, list) - return m.COMMANDS + + # Modules can define commands in two ways: + # 1. New decorator pattern: Commands registered via @ModuleCLICommand decorators, + # retrieved via CLICommand.dump_cmd_list() + # 2. Old list pattern: Commands defined in a COMMANDS list + # Some modules have CLICommand defined but haven't migrated their commands yet, + # so we try the new pattern first and fall back to the old COMMANDS list. + if hasattr(m, 'CLICommand'): + commands = m.CLICommand.dump_cmd_list() + if commands: + return commands + return getattr(m, 'COMMANDS', []) def _normalize_command(self, command): if 'handler' in command: