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 <k.chai@proxmox.com>
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: