Skip to content

fix(bom): reject bare scalars without tag, digest, or registry host#776

Merged
mchmarny merged 2 commits into
mainfrom
fix/bom-bare-image-ref-filter
May 6, 2026
Merged

fix(bom): reject bare scalars without tag, digest, or registry host#776
mchmarny merged 2 commits into
mainfrom
fix/bom-bare-image-ref-filter

Conversation

@mchmarny

@mchmarny mchmarny commented May 6, 2026

Copy link
Copy Markdown
Member

Summary

Closes #765. Tightens pkg/bom.isLikelyImage so chart-default placeholders like vgpu-manager (lifted from vgpuManager: { image: vgpu-manager, enabled: false } in upstream charts) stop appearing in the published BOM.

Refs #739, #749 (unblocks digest-pinning by ensuring there are no bare placeholders to try to resolve).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Component(s) Affected

  • Core libraries (pkg/bom)
  • Docs (docs/user/container-images.md — auto-regenerated)

Implementation Notes

Before. The helm-rendered output of gpu-operator included a bare - vgpu-manager entry in docs/user/container-images.md — no registry, no tag, no digest. The CRD-style triplet collector picked up image: vgpu-manager from a section whose enabled: false made the image moot, but the extractor had no way to tell.

After. isLikelyImage now requires at least one of:

  • a registry host as the first path segment (contains ./: or is localhost),
  • a :tag after the last /,
  • an @<digest> suffix.

Bare single-segment scalars without any of those signals are rejected. Tag-only single-segment refs (busybox:1.36) still pass; their library/ canonicalization in ParseImageRef is unaffected because canonicalization runs at parse time, not extraction time.

BOM doc: image count 70 → 69 (one bare placeholder removed); auto-regenerated by make bom-docs. make bom-docs is idempotent (md5 stable across runs).

Out of scope. The issue mentioned extending the regression test to walk make bom's helm-rendered output (against a kwok cluster) so this class of drift fails in CI rather than only surfacing on manual inspection. That's a meaningful test-infrastructure addition; this PR ships the behavioral fix small enough to land cleanly on its own and unblock #749.

Testing

unset GITLAB_TOKEN && make qualify
# Codebase qualification completed
$ grep -c vgpu-manager docs/user/container-images.md
0

pkg/bom coverage held with expanded TestIsLikelyImage cases (registry host / tag-only / digest-only / bare-scalar) and updated case for vgpu-manager and driver regression scenarios.

Risk Assessment

  • Low — Tightens a single helper; all existing test cases either use real refs (already pass) or were testing the rejected-bare-scalar behavior. Auto-regenerated BOM doc loses exactly one entry: the vgpu-manager placeholder. Easy to revert.

Rollout notes: Future contributors who introduce new components with chart sections that have bare placeholder images will see those entries excluded from the BOM doc by design. If a real bare-name image is ever needed (rare in production K8s manifests), it would need a tag, digest, or registry-host first segment.

Checklist

  • Tests pass locally (make test with -race)
  • Linter passes (make lint)
  • I did not skip/disable tests to make CI green
  • I added/updated tests for new functionality
  • I updated docs if user-facing behavior changed (BOM doc auto-regenerated)
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S)

Closes #765. Tightens \`pkg/bom.isLikelyImage\` so chart-default
placeholders like \`vgpu-manager\` (lifted from
\`vgpuManager: { image: vgpu-manager, enabled: false }\` in upstream
charts) no longer dilute the published BOM.

Before: the helm-rendered output of \`gpu-operator\` produced a bare
\`- vgpu-manager\` entry in docs/user/container-images.md — no
registry, no tag, no digest. A reader can't tell what bytes that
deploys, and downstream tooling (#749 digest-pinning, #745 admission
verification) would have nothing to attest against.

After: \`isLikelyImage\` requires at least one of:
  - a registry host as the first path segment (contains \`.\`/\`:\` or
    is \`localhost\`),
  - a \`:tag\` after the last \`/\`,
  - an \`@<digest>\` suffix.

Bare single-segment scalars are rejected. Tag-only single-segment
refs (\`busybox:1.36\`) still pass; their \`library/\` canonicalization
in ParseImageRef is unaffected because canonicalization runs at parse
time, not extraction time.

BOM doc image count drops from 70 → 69 (one bare placeholder
removed). All other entries unchanged. \`make bom-docs\` is
idempotent.

The deeper fix the issue mentioned — extending the regression test to
walk \`make bom\`'s helm-rendered output (against a kwok cluster?) — is
intentionally not in this PR. That's a meaningful test-infrastructure
addition; the behavioral fix here is small enough to land cleanly on
its own and unblock #749.
@mchmarny mchmarny requested a review from a team as a code owner May 6, 2026 11:48
@mchmarny mchmarny self-assigned this May 6, 2026
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

@mchmarny mchmarny enabled auto-merge (squash) May 6, 2026 11:50
@coderabbitai

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Addresses CodeRabbit review on PR #776. Adds \`nvidia/cuda\` to the
rejected set in TestIsLikelyImage to lock in that the boundary covers
two-segment refs without tag/digest/host, not just single-segment.

The intended distinction is: ParseImageRef applies the \`library/\`
fallback only to true single-segment refs at parse time, so
\`isLikelyImage\` rejecting a \`namespace/name\` shape without further
signal is consistent with the policy — the BOM extractor should not
emit an image whose registry/tag/digest is left to downstream
inference.
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report ✅

Metric Value
Coverage 75.1%
Threshold 70%
Status Pass
Coverage Badge
![Coverage](https://img.shields.io/badge/coverage-75.1%25-green)

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/NVIDIA/aicr/pkg/bom 91.18% (+0.35%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/NVIDIA/aicr/pkg/bom/extract.go 98.26% (+0.15%) 115 (+9) 113 (+9) 2 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

@mchmarny mchmarny merged commit fb53a87 into main May 6, 2026
36 checks passed
@mchmarny mchmarny deleted the fix/bom-bare-image-ref-filter branch May 6, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(bom): gpu-operator extracts vgpu-manager as a bare image ref

2 participants