TT Lab
博客

한국어 English 日本語 中文

开始
博客

博客

CDI 不了解 local-path:关闭沉睡 2 年 11 个月之久的 Issue 的十二行代码

结果:已合并(2026-10-26 19:58, kubevirt/containerized-data-importer#4319),Issue #3005 已关闭。 截至 2026-10-29,尚无包含此更改的 CDI 版本(最新版本为 2026-09-06 的 v1.66.1)。实际上,这些内容来自 GitHub 上的 PR、评审、行评论、正文修改历史、时间线、检查 记录,以及 CDI 源码(PR 的基础提交 9cd4fbdb)、local-path-provisioner 源码(标签 v0.0.32)、贡献账本的实测原始数据(StorageProfile 列表、48 小时日志汇总)和 草稿。时间均为韩国时间。

目录

一句话总结

PR kubevirt/containerized-data-importer#4319 Add storage capabilities for rancher.io/local-path
更改内容 storagecapabilities.go 一个文件。 rancher.io/local-path 项,以及节点本地路径 provisioner 共用的一个助手。增加 12 行,删除 4 行
反应 两位评审人员各一条行评论(合并、去掉两个测试),维护人员重新打开并关联旧 Issue
结果 PR 发布 10-17 23:38 → /approve 10-19 16:59 → /lgtm 10-26 15:15 → 合并 19:58,约 8 天 20 小时 20 分钟。3 个提交,通过 21 个检查

1. 问题所在:空白的 StorageProfile

CDI(Containerized Data Importer)是将 KubeVirt VM 磁盘转换为 PVC 的组件。如果将 DataVolume 用作 spec.storage 则无需填写访问模式或卷模式,其默认值从每个 StorageClass 创建的 StorageProfile 中获取。StorageProfile 的默认值由 CDI 通过查看 provisioner 名称来填充。

2026-10-17 使用读取命令检查 TT Lab 集群(CDI v1.66.0)时,四个 StorageProfile 中有两个为空(账本 measure/kv).

StorageProfile Provisioner claimPropertySets Recognized
local-path rancher.io/local-path 无 UnrecognizedProvisioner
local-path-retain rancher.io/local-path 无 UnrecognizedProvisioner
两个 NFS 类 nfs.csi.k8s.io RWX, Filesystem RecognizedProvisioner

这两个 local-path 类创建于 57 天前,provisioner 镜像为 v0.0.32。在 cdi-deployment 的 48 小时日志中,每个类都有 Set metric:local-path complete:false … degraded:true 这样的相同行出现了十次。正如在 PR 正文中所写,该指标是 CDIStorageProfilesIncomplete 警报监测的值。

在此状态下,如果使用 spec.storage 创建访问模式为空的 DataVolume,它将停留在 ErrClaimNotValid: no accessMode specified in StorageProfile local-path 状态,正如我在 PR 正文中所写的那样。这是在草稿中写为“用户要运行的命令和预期结果”的内容,账本中没有实际运行记录(未实测)。 账本中没有记录表明 TT Lab 的 VM 因为此错误而停止。这不是生产事故,而是在调查过程中发现的问题。

2. 原因:源码中的哪一行

CDI 行号基于 PR 的基础提交 9cd4fbdb 。

要填入的值为 {{rwo, file}} 的依据是 provisioner 端的源码(local-path-provisioner v0.0.32 provisioner.go).

PR 正文中还提到了另一点。CDI 自己的 kind 开发环境(cluster-up/cluster/kind/manifests/local-storage-class.yaml)也使用该 provisioner。 在此更改之后,该环境的 StorageProfile 也将被填充,因此我请求告知是否有任何 e2e 测试期望它是空的。

3. 更改内容:三次 diff

第一个提交(10-17)在表中添加了一行,并在 StorageProfile 控制器测试中添加了一个针对新 provisioner 的测试以及 Recognized 表项。 这与类似的先例 #4286(Mayastor,2026-09-27 合并)形状相同。 PR 正文中的测试结果如下(Go 1.27.2, GOFLAGS=-mod=vendor,main 9cd4fbd).

测试 结果
新测试,无表项 7 个中有 2 个失败
新测试,带表项 通过
go test ./pkg/controller/ 修改后的版本 / 修改前 385 通过·3 失败 / 383 通过·3 失败

失败的三个测试在双方中都是相同的与 VDDK 相关的测试(Update PVC from POD),因此我在正文中指出这与此更改无关。

第二个提交(10-18)采纳了评审人员的建议。意见认为,通过单个目录创建卷的 provisioner 最终都是 {rwo, file} ,因此应该将它们合并。于是创建了 createLocalPathCapabilities() 助手,并让 hostpath-provisioner(CSI·遗留)、 k8s.io/minikube-hostpath, rancher.io/local-path 使用它。hostpath-provisioner 的 overlay 变体是 RWX,因此保持不变。我把直接提供整个驱动器而非目录的 DirectPV 排除在外,并回复称如果需要可以添加。此时 go test ./pkg/controller/ 的 388 个测试全部通过(回复中记录的值)。

第三个提交(10-26)按照另一位评审人员的意见,删除了第一个提交中的两个单元测试。意见指出,新 provisioner 只是复用了已有测试的助手,并没有新的逻辑。此提交 仅运行了 gofmt·go vet ,未重新运行测试(账本记录)。合并前的 CI 测试已通过。

 var CapabilitiesByProvisionerKey = map[string][]StorageCapabilities{
 	// hostpath-provisioner
-	ProvisionerHPPCSI:          {{rwo, file}},
+	ProvisionerHPPCSI:        createLocalPathCapabilities(),
 	ProvisionerHPPOverlayCSI: {{rwx, file}},
-	ProvisionerHPPLegacy:       {{rwo, file}},
-	"k8s.io/minikube-hostpath": {{rwo, file}},
+	ProvisionerHPPLegacy:     createLocalPathCapabilities(),
+	// other node-local path provisioners
+	"k8s.io/minikube-hostpath": createLocalPathCapabilities(),
+	"rancher.io/local-path":    createLocalPathCapabilities(), // local-path-provisioner, default in k3s and kind
 ...
+// createLocalPathCapabilities is shared by provisioners that back each volume
+// with a directory on a single node, so they only offer RWO filesystem volumes.
+func createLocalPathCapabilities() []StorageCapabilities {
+	return []StorageCapabilities{{rwo, file}}
+}

最终 diff 为一个文件,增加 12 行,删除 4 行。甚至比最初还要小。

所有三个提交都使用了 AI 的 Assisted-by: Claude 尾注和 DCO 签名,正文末尾附有段落说明:“在阅读 provisioner 源码以及编写更改和测试草稿时得到了 Claude 的 帮助,我已审查了每一行,StorageProfile 输出结果来自我自己的集群”。这符合 KubeVirt 组织的 AI 贡献政策的建议。SSH 签名仅附加在第一个提交上, 反映评审意见的第二个和第三个提交在 GitHub 上显示为未签名提交。

4.反应:合并、移除以及重新打开的 Issue

时间 天
10-17 23:38 发布 PR。prow 附加了 size/S 标签,提示“不受信任的作者不能直接运行测试”,指定了两位评审人员
10-18 20:25 评审人员 A 的行评论:这些本地路径 provisioner 最终都是 rwo 和 file,所以可以合并
10-18 21:03 合并为助手的第二个提交,21:05 回复。标签变更为 size/M 变为
10-19 16:57 维护人员将 2024 年 10 月自动关闭的 Issue #3005 /reopen
10-19 16:58, 17:00 同一维护人员修改了我们 PR 正文中的“Which issue(s)”栏, 填入了 Fixes #3005 (正文修改历史)
10-19 16:59 评审人员 A 提出了 /approve 和 /test all。17:13 coveralls 覆盖率为 50.288%(+0.08%)
10-25 11:33 连续六天没有 /lgtm ,因此向指定的两位评审人员请求一次:“由于已有 approve 且测试通过,现在只剩 lgtm 了”
10-25 17:53 评审人员 B 的行评论:没有新逻辑,不知道为什么需要两个单元测试
10-26 00:04 删除了两个测试的第三个提交,00:07 回复。标签再次变为 size/S
10-26 15:15 评审人员 B 提出了 /lgtm
10-26 19:58 tide 执行合并,Issue #3005 随之关闭

这次 PR 中最值得学习的场景发生在 10-19 的两行记录中。我们在编写草稿时曾写明没有处理相同问题的 Issue 或 PR(账本草稿列表中为“搜索 0”), 并且在 PR 正文的 Issue 栏中也填入了 NONE 。然而, #3005 “StorageProfile needs to be patched for the rancher local-path provisioner”早已存在。它于 2023-11-24 打开,另一位维护人员回复的大意是:“这是未识别的 provisioner 的默认行为,请在 DV 中写入访问模式或修改 profile,或者也可以发送添加默认值的 PR”(2024-01)。此后无人发送 PR,于是机器人于 2024-10-03 将其自动关闭。我们的搜索似乎只看到了打开的项目。

维护人员并未单独指出这一点。相反,他重新打开了 Issue 并将其关联到我们的 PR 正文中,随着 PR 的合并,沉睡 2 年 11 个月之久的 Issue 就此关闭。

对于两条行评论,我都一次性接受并简短回复了。第一次回复是:“感谢评审,第二个提交中已合并为助手,DirectPV 由于提供整个驱动器而非目录已被排除”;第二次回复是:“确实如此,现有的 hostpath 测试已经覆盖了该助手,只是在重复使用,因此两个都删除了”。两位评审人员的意见分别减少了我们在第一个提交中添加的内容(测试)和更改的形状(助手),结果使得 PR 变得更小了。

5. 收获:开源贡献技巧

Titi 的一句话。 我们小区的仓库管理员说没听过“泥路仓库”这个名字。于是他在存放在那里的每个箱子上都贴上了“不知如何保管”的标签。我从仓库的规则手册里找到并告知他,泥路仓库一个格子只能放一个人,且只接收箱子形状的物品。仓库管理员大叔建议把四个类似的仓库串联记下来,另一位大叔说不需要两个确认盖章。接着,有人从抽屉里翻出三年前写着同样请求的便条,和我们的便条一起放进了“已解决”的箱子里。

链接

所有资料于 2026-10-29 查阅。

登录后即可点赞

评论

还没有评论。

登录后即可发表评论