摘要

  • draft-ietf-netmod-yang-module-versioning-17 明确允许模块和 submodule 出现非线性修订历史。revision date 只标识一个不可变修订,不证明祖先、顺序或兼容关系。
  • rev:non-backwards-compatible、rev:recommended-min-date 和 YANG Library 状态布尔值都是有界声明。修订图、有效 schema、服务器行为、客户端执行、实例迁移、发布顺序与回滚必须分别验证。

控制器看见同一 YANG 模块的两个修订:一个日期是四月,一个是五月。import 建议四月为最早日期。五月版本显得更新、满足条件,似乎理应包含四月加入的 grouping。可它来自另一条分支,从未继承那项定义。日期判断全绿,依赖仍然失败。

这正是 Updated YANG Module Revision Handling 第 17 版最重要的控制变化。该稿发布于 2026 年 6 月 29 日,目前仍是 Internet-Draft,不是 RFC。它不再把日期伪装成血缘:同一 module 或 submodule 可以有两个修订直接来自同一父修订。revision date 仍须唯一,却不再隐含时间顺序、祖先关系或向后兼容。

历史是一条穿过修订图的路径

在线性想象中,日期越晚就好像自然继承了此前的一切。分支打破了这个推理。一份具体修订的 revision history 只列出它自身经过的祖先路径,不会列出所有分支的所有版本。草案明确说,比较日期或版本标签无法确定两个修订的派生关系,必须查看 revision history。

而且这份历史也未必完整。作者可以在不破坏剩余 NBC 关系的条件下移除旧条目:最老的一段连续记录可以被裁掉,部分中间记录有时也能删除,但不能因此让剩余条目错误地暗示某个非兼容变化不存在,最新条目则不能删除。这保护的是剩余叙述的相对准确,不是完整仓库图一定存在。

因此,运营所需的证据对象比模块头部更大。它应包含各修订的精确字节、来源仓库或归档、commit 祖先、被删历史的留档,以及所有 included submodule 的身份。草案建议 module 以 exact revision-date include submodule;没有它,仅凭主模块不能推出实际采用了哪个 submodule。整齐的历史表是作者视图,不是完整保管链。

NBC 标记有方向,却没有替人做比较

草案放宽了“已发布更新必须始终向后兼容”的旧规则。新修订仍然不应轻易引入 NBC,因为客户端和 importer 会因此破坏;但修复缺陷、让节点退出服务、改进不稳定模型,或以合理代价加入新能力,都可能迫使作者接受非兼容变化。

若一个修订相对其 history 中的前一修订包含违反更新规则的变化,就必须写入 rev:non-backwards-compatible。若标记不存在,则这些相邻变化必须是 BC。这个方向明确,适合工具告警和人工审查。

但标记不是自动 diff 报告。作者要判断规则是否适用;即便变化形式上可能属于 BC,若扩大 operational leaf 的取值空间会显著冲击客户端,作者也可以保守地添加标记。反过来,未标记的可信度取决于变化审查和保留历史是否准确。可靠记录必须绑定新旧字节、列出变化、指明分类条款并留下审查责任人。schema-comparison 的具体算法属于另一份规范,不在本文重复。

最早日期不是分支约束

RFC 7950 允许 import 指定 exact revision-date;不指定时,YANG 语言并未规定究竟使用哪个修订。精确绑定对松耦合模块可能过严,所以第 17 版加入 rev:recommended-min-date,用机器可读方式表达预期能满足依赖的建议最早修订。

“建议”二字是关键。工具可以在选到更早修订时报警,但该扩展不改变 import 行为,也不改变 YANG conformance。更重要的是,草案自己的例子表明:日期更晚的修订若在另一分支上,可能完全没有最早修订引入的内容。因此它最适合线性、按日期前进的历史,明确不适合分支图。

可辩护的解析回执不能只写 chosen_date >= minimum_date。它必须指出实际选择的修订,证明该修订确实从所需版本派生或以其他方式含有所需定义,并在真实 feature 与 deviation 语境中解析每个 imported symbol,最后固定有效 schema 的哈希。达到日期门槛只意味着可以继续检查,不意味着依赖已经满足。

两个布尔值缩小歧义,却不测量现实

草案还定义 ietf-yang-library-status,在 RFC 8525 的 /yang-library/schema 上增加两个只读布尔值。deprecated-nodes-implemented=true 表示 deprecated 节点像 current 一样实现,除非 deviation 明确移除;obsolete-nodes-absent=true 表示服务器没有实现任何 obsolete 节点。两者默认都是 false,而 false 时行为未规定。

两项都设为 true,客户端看到的声明 schema 会更清楚。若 deprecated 项不是 true,草案要求客户端不能只看 NBC 标记,因为某节点即使只是从 current 变为 deprecated,服务器也可能已经不再实现。这个披露规则很有价值。

但它仍由被评估的服务器自行报告。它没有对每个旧节点真正执行读、写、RPC 或 notification,也不能证明 deviation 已加载、重启后 schema 未漂移、不同管理协议行为一致。核验需要实际探测节点表面,记录 error 与 default,并把 YANG Library 声明集合和进程真正加载的 schema 对照。

客户端和实例数据各自拥有否决权

第 17 版预见了客户端失败:采用 NBC 修订的服务器可能返回对自身 schema 合法、却超出旧客户端编程约束的值。草案要求客户端防御性处理、监控 revision history,并在迁移前理解具体 NBC 变化。deprecated 节点应及时停止使用,obsolete 节点则必须停止使用。

这些动作都不会因为标签出现而自动完成。要分别测试旧客户端对新服务器、新客户端对旧服务器,覆盖解析、规范编码、default、RPC 输入、notification、错误处理和访问控制角色;还要记录精确二进制、schema set、feature 与 deviation。

持久实例数据又是另一道边界。RFC 9195 能把离线 instance data 与 content-schema 关联,但目标 schema 校验成功不证明转换保留了含义。迁移回执应统计重命名、删除、合成、补 default 和拒绝的节点,验证业务语义不变量,并证明回滚后的旧版本仍能读取新版本写过的状态。

最后,RFC 8342 把 running、intended 与 operational 分开,正因为已写配置、应用意图和实际行为可能不一致。import 成功和 schema validator 绿灯无法证明设备落实了目标状态、混合版本对端可以互通,更无法证明服务结果成立。

第 17 版把分支、非兼容步骤、宽松依赖建议和旧节点政策放到可见、可机器处理的表面,这是实质进步。保持这份精确性的办法,是让每个声明只关闭它自己的问题:日期负责标识,历史描述一条祖先路径,NBC 负责告警,最早日期负责建议,YANG Library 负责报告。客户端、迁移数据和运行网络必须提供余下证据。

主要来源

冻结的一手来源包括 Updated YANG Module Revision Handling 第 17 版、Datatracker 记录与历史、YANG 1.1(RFC 7950)、YANG Library(RFC 8525)、IETF YANG 模块指南(RFC 9907)、NMDA(RFC 8342)、NACM(RFC 8341)、YANG Instance Data(RFC 9195)和 YANG Module Versioning Requirements 第 13 版。