TT Lab
博客

한국어 English 日本語 中文

开始
博客

博客

日志中打印的指针地址:CDI 的两行日志修改在 2 天 19 小时内被合并的全过程

结果:已合并(2026-10-22 20:19, kubevirt/containerized-data-importer#4320). 事实上,这些内容取自 GitHub 的 PR、评审、评论、时间线、检查记录,以及 CDI 源码(PR 的基准提交 9cd4fbdb)、Go 标准库文档和贡献记录的初稿。 时间均为韩国时间。

目录

一句话总结

PR kubevirt/containerized-data-importer#4320 Log the storage class name, not its pointer, in filesystem overhead
修改内容 pkg/controller/common/util.go 的两行日志。新增 2 行,删除 2 行
反应 维护者在 16 小时后 /approve·/lgtm。在说明了一个无关的 e2e 失败后,维护者进行了 override
结果 PR 公开 10-20 00:49 → 批准 17:05 → override 10-22 16:42 → 合并 20:19,历时约 2 天 19 小时 30 分钟

1. 问题所在:读代码时发现的两行

这次的问题并非在生产环境中发现的。这是在撰写本博客的 “阅读 KubeVirt 源代码”系列时,追踪 CDI 大小计算逻辑的过程中,被记录在贡献记录的“代码阅读发现的贡献候选”列表中的第五条。该日志位于 第 8 篇中讨论的、为每个存储类选择文件系统预留空间值的函数内部。

GetFilesystemOverheadForStorageClass 如果找不到存储类,会查找默认类,如果还没有则使用全局预留空间。在这两个分支中会记录详情级别为 3(-v=3)的日志。PR 正文中记录的输出如下:

Storage class0x7035abda0020not found, trying default storage class

存储类名称的位置显示的是内存地址,并且前后没有空格。修改后打印出的效果如下:

Storage class "local-path" not found, trying default storage class

虽然 PR 正文中提到已经复现了此输出,但贡献记录中并未保留该复现的原始输出。上面两行摘自 PR 正文中的示例。并且未确认 TT Lab 集群中的 CDI 是否正在以详情级别 3 运行(未确认)。

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

行号基于 PR 的基准提交 9cd4fbdb 。

storageClassName 是 *string 。这似乎是因为在 Kubernetes API 中经常使用指针来表示“可以为空的字符串”而导致的失误。两点叠加导致了上述输出。

  1. klog.Info 使用 fmt.Sprint 的方式连接参数。Go 的 fmt.Sprint 文档写道:“仅当两个操作数都不是字符串时,它们之间才会插入空格。”在 "Storage class" 与指针之间、指针与 "not found…" 之间,由于其中一方是字符串,因此不会插入空格。
  2. %v 如果用指针打印,输出的将是其指向的地址而不是值。因此诸如 0x7035abda0020 这样的值会出现在名称的位置上。

Info 将 Infof 替换为 k8s.io/utils/ptr 并提供格式化字符串,空格问题就会消失。指针需要解引用,但由于它可能为 nil,因此使用了该文件已经引入的 ptr.Deref(storageClassName, "") 的

。

 	targetStorageClass, err := GetStorageClassByNameWithK8sFallback(ctx, client, storageClassName)
 	if err != nil || targetStorageClass == nil {
-		klog.V(3).Info("Storage class", storageClassName, "not found, trying default storage class")
+		klog.V(3).Infof("Storage class %q not found, trying default storage class", ptr.Deref(storageClassName, ""))
 ...
 	if targetStorageClass == nil {
-		klog.V(3).Info("Storage class", storageClassName, "not found, continuing with global overhead")
+		klog.V(3).Infof("Storage class %q not found, continuing with global overhead", ptr.Deref(storageClassName, ""))

%q 3. 修改内容:diff 要点 "" 选择 go vet ./pkg/controller/common/ 是为了确保即使名称为空字符串时,也能显示为 go test ./pkg/controller/common/ 。同一函数中“没有默认存储类”的日志由于只有一个字符串参数,没有问题,因此保留了原样。PR 正文中说明了这只是一个修改日志的变更,并且已经过验证。 -mod=vendor干净无误,

的 43 个测试全部通过(golang:1.27.2 容器, Assisted-by: Claude )。未单独开启 Issue,仅说明是“读代码时发现的”。人工智能的使用体现在提交尾注

和 DCO 签名中,以及正文末尾的段落中:“在 Claude 的协助下发现并修复,并经过了审查和上述日志输出的复现”。此提交在 GitHub 上也显示为未签名提交。似乎漏掉了原则 3 的 SSH 签名。

4. 反应:16 小时获批,随后遇到一个 e2e 测试失败 时间
10-20 00:49 日 release-note-none·size/XS PR 公开。prow 添加了
10-20 17:05 标签,指定了两名评审员 /approve·/lgtm 维护者在评审中给出 lgtm·approved 和一句感谢。
10-21 22:23 标签 /retest-required 我们输入了
10-22 01:05 ,但机器人回复“不受信任的作者无法直接运行测试”
10-22 16:42 记录失败测试的内容并请求重新测试的评论 /override pull-containerized-data-importer-e2e-ceph-wffc
10-22 20:19 维护者

tide 进行合并 批准很迅速。因为只有两行,且将修改前后的日志并排展示,所以似乎没有什么需要额外询问的。这位维护者与第 7 篇 和第 6 篇

的评审员是同一个人。 e2e-ceph-wffc 批准后阻碍合并的是 e2e 测试集 DataImportCron … with snapshot sources [test_id:10033] 。从名字来看,这似乎是围绕 ceph 存储和延迟绑定(WaitForFirstConsumer)运行的测试集。失败的只有一个,是名为

的测试。546 个测试中有 545 个通过。仅修改了两行日志的变更,看起来不可能破坏快照源的 DataImportCron 测试。 /retest-required 因此我先输入了重新测试命令 /ok-to-test ,但 prow 称这是外部作者的命令而拒绝执行。在此仓库中,不受信任的作者无法使用

来启动或重新运行测试。几个小时后,我写下了失败测试的名称和 545/546 的数字,用一句话解释了该变更与该测试无关,然后请求某人帮忙触发重新测试。维护者没有重新测试,而是直接 override 了该检查,四小时后便合并了。

输入 虽然是白跑一趟,但机器人的回复准确指出了外部作者在此仓库中无法进行的操作。这与第 6 篇中看到的 KubeVirt 本体遵循相同的规则。

小 T 的碎碎念。

本应用本该写着“找不到某某仓库”,却写成了仓库名称而不是“7035号抽屉”,而且连空格都没有。把写着名字的纸条放进抽屉里,结果只抄了抽屉编号。拿出来把名字读出来写上之后,很快就得到了“赞”。不过隔壁班的一张试卷批错了只能等待,我也没法要求重新批改。于是我写道“错的是这道题,跟我的笔记没关系”,老师就把那张试卷递过来了。

登录后即可点赞

评论

还没有评论。

登录后即可发表评论