Ironic 插件机制(stevedore)

108 阅读2分钟

Ironic 的插件机制是基于 stevedore 这个 Python 插件管理库实现的。stevedore 是 OpenStack 生态广泛使用的插件发现与加载框架,支持动态扩展、热插拔和解耦开发。下面详细解释其原理和在 Ironic 中的应用:


1. stevedore 的基本原理

  • Entry Point:stevedore 利用 Python setuptools 的 entry_points 机制,在 setup.cfgsetup.py 中注册插件。例如:

    [ironic.hardware.types]
    mydriver = mypackage.mydriver:MyDriver
    

    这表示 mydriver 插件的实现类是 mypackage.mydriver.MyDriver

  • 插件发现:stevedore 可以根据 entry point 名称(如 ironic.hardware.types)自动发现所有已安装包中注册的插件。

  • 插件加载:stevedore 支持按需加载插件,可以选择只加载指定名称的插件,也可以全部加载。

  • 插件实例化:可以选择加载时是否自动实例化插件对象(invoke_on_load=True)。


2. stevedore 在 Ironic 中的应用

2.1 注册插件

  • Ironic 的各类驱动(硬件类型、接口类型等)都通过 entry_points 注册在 setup.cfg 里。例如:
    [ironic.hardware.types]
    ipmi = ironic.drivers.ipmi:IPMIHardware
    redfish = ironic.drivers.redfish:RedfishHardware
    

2.2 插件加载

  • Ironic 通过 stevedore 的 NamedExtensionManagerExtensionManager 加载插件。例如:
    stevedore.NamedExtensionManager(
        'ironic.hardware.types',
        enabled_driver_list,  # 只加载配置启用的驱动
        invoke_on_load=True,
        ...
    )
    
  • 这样,Ironic 可以根据配置文件动态加载、实例化所需的驱动或接口插件。

2.3 插件管理

  • 加载后的插件实例被统一管理在 _extension_manager 属性中,可以通过名称查找、遍历、调用插件对象。
  • 例如:self._extension_manager['ipmi'].obj 就是 IPMI 驱动实例。

2.4 插件扩展点

  • Ironic 支持多种扩展点(entry point),如:

    • ironic.hardware.types(硬件类型)
    • ironic.hardware.interfaces.power(电源接口)
    • ironic.hardware.interfaces.deploy(部署接口)
    • 等等
  • 每种扩展点都可以有多个插件实现,用户可根据需求选择、组合和扩展。


3. stevedore 的优势

  • 解耦:插件开发和主程序解耦,便于社区和第三方扩展。
  • 动态发现:无需修改主程序代码即可添加新插件。
  • 灵活配置:可通过配置文件启用/禁用插件。
  • 易于维护:插件可独立开发、测试和发布。

4. Ironic 插件机制的典型流程

  1. 开发插件:实现自定义驱动类。
  2. 注册 entry point:在 setup.cfg 里注册插件。
  3. 安装插件包:通过 pip 安装到 Ironic 环境。
  4. 配置启用:在 Ironic 配置文件中启用插件名称。
  5. Ironic 启动时加载:stevedore 自动发现并加载所有已注册、已启用的插件。
  6. 运行时调用:Ironic 通过统一接口调用插件,实现功能扩展。

5. stevedore 相关 API 简介

  • ExtensionManager:加载所有 entry point 下的插件。
  • NamedExtensionManager:只加载指定名称的插件。
  • Extension:每个插件的封装对象,.obj 属性为插件实例。

总结

Ironic 的插件机制基于 stevedore,利用 entry point 实现插件的自动发现、加载和管理,极大提升了系统的可扩展性和灵活性。
开发者可以方便地自定义和集成新驱动或接口,无需修改 Ironic 主体代码。