向后兼容性和 TripleO¶
https://blueprints.launchpad.net/tripleo/+spec/tripleo-juno-backwards-compat
TripleO 自创建以来一直具有良好但并非完美向后兼容性。现在是时候将其正式化,以便记录和测试。
TripleO 将对所有发布版本使用语义化版本控制(又称 semver)。我们将努力避免破坏向后兼容性,如果必须破坏,那将是由于特殊情况,例如没有其他修复方法的安全修复。
问题描述¶
TripleO 历史上一直具有未明确的向后兼容性策略,但现在有太多人进行更改 - 我们需要建立一个明确的策略,否则我们的贡献者将在一位评审者要求向后兼容性时重新工作(他们认为不需要),或者反之,做向后兼容性工作,而实际上不需要。
其次,由于我们尚未将任何项目标记为 1.0.0,用户或开发人员无法确定何时何地需要/适合向后兼容性。
提议的变更¶
采用以下高级启发式方法来识别向后不兼容的更改
进行破坏用户代码的更改,这些代码脚本或使用公共接口。
无法安装我们以前可以安装的东西。
无法安装某些东西,因为其他人更改了某些东西 - 例如,如果它不再在互联网上存在,则无法安装 F20 不是不兼容的更改 - 如果它返回到网络,我们将能够再次安装它。如果我们删除支持此内容的的代码,那么我们将进行不兼容的更改。这里有一个例外,那就是不受支持的项目 - 例如,不受支持的 OpenStack 版本、Fedora 或 Ubuntu。由于不受支持的版本存在安全问题,并且我们期望大多数依赖项都发布版本并停止支持某些内容,因此我们将清理仅用于支持此类不受支持版本的代码,不视为向后兼容。例如,破坏部署先前仍然受支持的 OpenStack 版本的可能性,而我们之前能够部署它,是不兼容的更改,但破坏部署不受支持的 OpenStack 版本的可能性则不是。
这些原则的推论
破坏公共 API(网络或 Python)。项目的公共 API 是任何已发布的 API(例如,未明确标记为 alpha/beta/rc)的版本,该版本 >= 1.0.0。对于 Python 项目,下划线 _ 前缀标记一个命名空间为非公共,例如在
foo.\_bar.quuxquux中,由于它位于非公共命名空间中,因此不是公共的。对于接受环境变量的项目,如果变量已记录在 README.md/用户文档中,则该变量是公共接口的一部分。否则,它不是。增加 Heat 模板所需的参数数量。这将破坏使用 TripleO 进行部署的脚本。请注意,添加需要在部署新内容时设置的新参数是可以的,因为用户不仅仅是在拉取更新的代码。
减少 Heat 模板接受的参数数量。同样,这将破坏使用 Heat 模板进行部署的脚本。如果不再接受这些参数,因为它们是针对不再受支持的 OpenStack 版本,则涵盖了上述例外情况。
增加使用元素所需的元数据,除非 Tuskar 和 tripleo-heat-templates 都已更新以使用它。t-i-e 和 t-h-t 之间存在双向依赖关系 - 当我们在模板中更改信号时,我们必须首先更新 t-i-e,当我们更改元素参数时,我们必须首先更改 t-h-t。我们可以选择使 t-h-t 和 t-i-e 完全独立,但我们认为这并不是明智的时间利用 - 它们紧密相连,即使是松散耦合的。相反,我们将它们视为一个单元:在任何给定时间点,t-h-t 只能保证部署从 t-i-e 的某个最低版本构建的镜像,并且 t-i-e 只能保证使用 t-h-t 的某个最低版本进行部署。这里的公共 API 是 t-h-t 的参数,以及与 t-i-e 的链接等同于 Python 库/程序的辅助库的依赖关系:通常认为不需要新的辅助库版本不会被视为调用代码的 API 破坏。升级仍然可以正常工作,机器将在同一时间获得新的镜像和新的元数据,中间进行重建。降级/回滚可能需要同时切换到旧模板,但这已经是这种情况了。
如果这将导致错误或错误行为,则减少元素接受的元数据。
其他类型的更改也可能向后不兼容,如果识别出来,将据此处理 - 也就是说,此列表并非详尽无遗。
我们不认为 Heat 模板的内部结构是 API,也不认为 TripleO 代码库中的任何测试代码(无论其可能看起来是公共的还是不是)是 API。
TripleO 的孵化器未发布,没有向后兼容性保证 - 但某个时间点的孵化器快照与正在进行的其他组件的发布进行交互 - 并且它们将遵循 semver,这意味着想要稳定性的用户可以获得稳定性,只要他们不更改孵化器。
TripleO 将在创建后一个 OpenStack 发布周期内将所有组件项目提升到 1.0。项目在成为版本为 1.0 或更高的项目的依赖项之前,不得成为依赖项。此限制旨在防止依赖版本锁定(使升级不可能)或破坏(破坏用户),如果预 1.0 项目破坏兼容性。添加新项目将涉及创建测试作业,以测试所需的交互,然后再添加依赖项,以便在项目达到 1.0 之前验证 API。
采用以下规则,规定何时我们愿意[故意]破坏向后兼容性
当已知代码的所有用途都是针对不再受支持的 OpenStack 版本时。
- 如果 PTL 签署了破坏。
例如,对于我们无法找到向后兼容的交付方式的高影响安全修复。
我们还需要
为新代码库设定成熟时间表(一个周期)。现有代码库的计时器将在批准此规范时启动。
设定允许任何人依赖新代码库的规则(代码库必须为 1.0.0)。
记录在 Heat 模板和元素上下文中向后兼容意味着什么。
添加一个显式测试作业,以从 trunk 部署 Icehouse,因为这将告诉我们我们部署当前受支持的 OpenStack 版本的能力,而我们之前可以部署这些版本 - 如果失败,将表明拟议的补丁向后不兼容。
如果需要,修复 Icehouse,或达成共识,从此策略中排除 Icehouse 支持。
承诺维护向后兼容性。
当我们需要替代代码路径来支持向后兼容性时,我们将明确标记它们,以便于未来的清理。
# Backwards compatibility: <....> if .. # Trunk ... elif # Icehouse ... else # Havana ...
替代方案¶
我们可以说我们不进行向后兼容性,并像 OpenStack API 服务一样发布,但这会使与我们合作变得非常困难,并且还会迫使那些具有稳定支持需求的人从单独的分支工作,而不是能够在一个代码库上进行协作。
我们可以将 tripleo-heat-templates 和 tripleo-image-elements 与各个组件分开,并使用不同的规则来运行它们 - 例如,使用稳定的分支而不是 semver。但向后兼容性很难以至于这样做似乎不值得。
安全影响¶
保留代码更长时间可能会带来安全问题,但这是一个众所周知的交互。
其他最终用户影响¶
最终用户会喜欢我们。
性能影响¶
没有预料到的。由于携带向后兼容代码,镜像会略大一些。
其他部署者影响¶
部署者会感谢我们不必重新工作。虽然他们还没有遇到过,但仍然如此。
开发人员影响¶
开发人员将对向后兼容性设定明确的期望,这将有助于他们避免被要求重新工作。他们和评审者需要注意向后不兼容的更改以及对它们进行特殊处理,以实现我们所期望的兼容性。
实现¶
负责人¶
- 主要负责人
无生命
其他贡献者
工作项¶
起草此规范。
获得共识。
将我们所有非孵化器项目发布为 1.0.0。
添加 Icehouse 部署测试作业。(因为我们可以在 Juno 开始时安装 Icehouse,如果我们行动迅速,我们可以继续这样做)。
依赖项¶
没有。可以认为进行快速清理,但现实是这并不是一个负担,我们还没有清理它。
测试¶
为了确保我们不会意外破坏向后兼容性,我们最终应该查看 oslo 跨项目矩阵 - 例如,对 os-apply-config 的旧版本运行 os-refresh-config,以确保我们不会破坏兼容性。我们构建版本并使用这些版本的通用策略在很大程度上使我们对没有单步回归充满信心(但仍然需要注意 N 步回归,除非实施某种机制)。
文档影响¶
用户手册和开发人员指南应反映这一点。