ironic-python-agent 的 extensions
机制是通过 stevedore 插件系统实现的,允许 agent 以插件方式动态加载和分发各种扩展(如 clean、deploy、standby、log、rescue 等)。下面详细解释其分发原理和流程:
1. extensions 的注册(setup.cfg)
在 setup.cfg 里:
[entry_points]
ironic_python_agent.extensions =
standby = ironic_python_agent.extensions.standby:StandbyExtension
clean = ironic_python_agent.extensions.clean:CleanExtension
deploy = ironic_python_agent.extensions.deploy:DeployExtension
...
这表示:
- 名为
standby
的扩展由ironic_python_agent.extensions.standby.StandbyExtension
实现 clean
、deploy
等同理
2. 加载机制
IPA 启动时,会用 stevedore 的 ExtensionManager
加载所有注册在 ironic_python_agent.extensions
下的扩展:
from stevedore import ExtensionManager
self.extension_manager = ExtensionManager(
namespace='ironic_python_agent.extensions',
invoke_on_load=True,
)
- 这样所有扩展类都会被实例化并注册到 agent 的扩展管理器中。
3. 分发机制
3.1 接收命令
当 Ironic Conductor 通过 REST API 向 agent 下发命令(如 execute_clean_step
、download_image
等)时,agent 会根据命令类型分发到对应的 extension。
3.2 分发流程
-
命令格式
命令通常包含 extension 名称和方法名,例如:{ "name": "clean.execute_clean_step", "params": {...} }
这里
"clean"
就是 extension 名称,"execute_clean_step"
是方法名。 -
分发代码
agent 的主循环会解析命令,找到对应 extension 并调用方法:extension_name, method = command_name.split('.', 1) extension = self.extension_manager[extension_name].obj func = getattr(extension, method) result = func(**params)
-
执行方法
例如,clean.execute_clean_step
会调用CleanExtension.execute_clean_step(...)
,deploy.prepare_image
会调用DeployExtension.prepare_image(...)
。
4. 扩展性
- 你可以自定义 extension,只需实现类并注册到
ironic_python_agent.extensions
entry point,agent 启动时会自动加载。 - 新 extension 不需要修改 agent 主体代码,完全插件化。
5. 典型流程图
Ironic Conductor
|
| (REST API 下发命令: clean.execute_clean_step)
v
IPA Agent
|
| stevedore ExtensionManager 加载所有 extensions
| 解析命令,找到 clean extension
| 调用 CleanExtension.execute_clean_step(...)
v
执行结果返回
6. 代码参考
总结
ironic-python-agent 的 extensions 机制通过 stevedore 动态加载所有扩展插件,并根据命令类型自动分发到对应 extension 实例的方法,实现了高度解耦和可扩展的 agent 命令处理体系。