LibvirtXMLConfigAPIs
在 Essex 及更早版本中,libvirt 驱动程序使用 Cheetah 模板引擎从预定义的模板生成客户机 XML 配置。这种方法存在一些问题:
- 没有进行 XML 转义。如果我们不够小心,这将导致未来的安全漏洞。
- 构建 XML 的逻辑分散在代码的多个区域、模板文件以及填充模板变量的连接驱动程序中。这不必要地使代码复杂化,并使理解用于生成 XML 的整体逻辑变得更加困难。
- 很难合理地模块化生成 XML 的代码。例如,磁盘 XML 生成在 XML 模板和 volume.py 类之间重复。
- libvirt 驱动程序代码没有可与之配合使用的对象模型。所有内容都必须发明自己的临时 XML 解析器/杂项 XPath 查询。
这些问题只会随着时间的推移而变得更糟,最终得出结论,使用模板引擎是一种注定失败的方法。
解决此问题的办法是引入一个描述 libvirt 客户机配置的正式对象模型。驱动程序代码将专门与对象模型交互,根据需要读取/写入属性/子对象。一旦对象模型完成,它就可以使用 lxml DOM API 直接序列化为 XML。这将带来以下好处:
- 保证正确转义所有 XML 元素/属性
- 驱动程序代码无需了解 XML 解析或格式化
- 将生成客户机配置的逻辑集中在一个地方
- 促进配置生成代码的模块化
- 促进配置生成代码的测试
对象模型层次结构的概要如下:
LibvirtConfigObject
|
+ LibvirtConfigGuest
+ LibvirtConfigGuestDevice
|
+- LibvirtConfigGuestDisk
+- LibvirtConfigGuestFilesys
+- LibvirtConfigGuestInterface
+- LibvirtConfigGuestInput
+- LibvirtConfigGuestGraphics
+- LibvirtConfigGuestChar
|
+- LibvirtConfigGuestSerial
+- LibvirtConfigGuestConsole
这不仅限于 libvirt 客户机 XML。与 libvirt 相关的其他 XML 文档也将同样受益,例如 CPU 配置、主机功能、域快照等。
更改的大致范围如下:
- nova/virt/libvirt.xml.template:删除文件和关联的 FLAGS.libvirt_xml_template
- nova/virt/cpuinfo.xml.template:删除文件和关联的 FLAGS.cpuinfo_xml_template
- nova/virt/connection.py:将返回模板参数字典的 _prepare_xml_info() 方法替换为返回 LibvirtConfigGuest 对象的 get_guest_config() 方法
- nova/virt/config.py:创建一组对象来表示 libvirt 客户机配置和相关的 XML 文档(参见上述类层次结构)
- nova/virt/vif.py:将 _get_configurations() 方法更改为返回 LibvirtConfigGuestInterface 对象
- nova/virt/volume.py:将 connect_volume() 方法更改为返回 LibvirtConfigGuestDisk 对象
一些背景讨论
- https://lists.launchpad.net/openstack/msg08408.html
- https://lists.launchpad.net/openstack/msg06481.html
相应的蓝图