在卷驱动程序中引入抽象接口模型

https://blueprints.launchpad.net/cinder/+spec/abc-volume-drivers

与其使用松散的卷驱动程序接口定义,不如使用 ABC python 库构建抽象类,强制驱动程序实现所需的功能。目标是在运行时避免使用异常,并尽早发现错误,如果驱动程序没有使用正确的接口。

问题描述

cinder.volume.driver 中定义的卷接口相当宽松。驱动程序可以决定是否实现某种功能。从外部(管理器层)无法看到驱动程序实现了哪些功能。因此,发现它的唯一方法是尝试调用某个功能集的函数,并查看是否引发 NotImplementedError 异常。

用例

提议的变更

构建一个基础 VolumeDriver 类和子类,这些子类描述了功能集,例如

                         +-------------------------+
        +----------------+     BaseVolumeDriver    +---------------+
        |                |       {abstract}        |               |
        |                +-----------^-------------+               |
        |                            |                             |
        |                            |                             |
+-------+-------------+  +-----------+-------------+  +------------+---------+
| VolumeDriverBackup  |  |   VolumeDriverSnapshot  |  |  VolumeDriverImport  |
|     {abstract}      |  |      {abstract}         |  |      {abstract}      |
+---------------------+  +-------------------------+  +----------------------+

如果驱动程序实现了备份功能并支持卷导入,则应从像这样的接口类继承:

class FooDriver(VolumeDriverBackup, VolumeDriverImport):
    ...

管理层可以使用 isinstanceof() 来观察给定驱动程序的功能集。

volume_driver = FooDriver(..)
if isinstanceof(volume_driver, VolumeDriverBackup):
    pass

使用 python ABC 是首选,因为它具有多种优势(参见 [1],[2])。它将在实例化级别引发 TypeError 异常。其他 OpenStack 项目已经在使用这个库(参见 [3])。

驱动程序迁移

与其一步到位地更改所有驱动程序,不如逐步迁移。为此,VolumeDriver 类可以使用与之前相同的接口,并使用 NotImplementedError 异常。这样,所有现有驱动程序都可以逐步迁移到新的概念。

备选方案

  • 仅实现子类,不要使用 ABC

数据模型影响

无。

REST API 影响

无。

安全影响

无。

通知影响

无。

其他最终用户影响

无。

性能影响

由于 ABCMeta 及其功能仅在相关数据路径中受到非常有限的使用,因此预计不会产生严重的性能影响。以下常规对象函数可能比以前性能稍差(参见 [5])

- __new__()
- __subclasscheck__(), issubclass()
- __instancecheck__(), isinstance()

性能取决于所使用的类层次结构的深度。所提出的概念在这方面非常简单(最多 2 层)。通常,它是引发/捕获异常的周期与在 for loop 中迭代所有抽象类之间的比较。

其他部署者影响

无。

开发人员影响

此更改将略微更改所有已实现的驱动程序。功能本身不应更改,但所有驱动程序都需要采用新的类模型。

实现

负责人

主要负责人

Marc Koderer (m-koderer)

其他贡献者

Danny Al-Gaaf (danny-al-gaaf)

工作项

将在 etherpad 中跟踪。

依赖项

无。

测试

单元测试需要进行大规模调整,因为到处都在捕获 NotImplementedError 异常。

文档影响

无。

参考资料

[1]: http://legacy.python.org/dev/peps/pep-3119/ [2]: http://dbader.org/blog/abstract-base-classes-in-python [3]: http://lists.openstack.org/pipermail/openstack-dev/2013-August/014089.html [4]: https://bugs.launchpad.net/tempest/+bug/1346797 [5]: https://hg.python.org/cpython/file/2.7/Lib/abc.py