refactor(operator): package annotation helpers accept any client.Object (#300)#313
refactor(operator): package annotation helpers accept any client.Object (#300)#313ayuskauskas wants to merge 4 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughPackage annotation helpers now accept Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
operator/internal/controller/annotations.go (1)
93-125: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winHandle objects without a package annotation.
GetPackagereturns(nil, nil)for a missing annotation, then both helpers dereferencepkg. An unannotated Job panics instead of being treated as invalidation no-op / not-invalid.
operator/internal/controller/annotations.go#L93-L125: return early whenpkg == nil.operator/internal/controller/annotations_test.go#L73-L85: coverInvalidatePackageandIsInvalidPackageon an empty Job.Proposed fix
pkg, err := GetPackage(obj) if err != nil { return fmt.Errorf("error getting package: %w", err) } +if pkg == nil { + return nil +} pkg.Invalid = truepkg, err := GetPackage(obj) if err != nil { return false, fmt.Errorf("error getting package: %w", err) } +if pkg == nil { + return false, nil +} return pkg.Invalid, nil🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@operator/internal/controller/annotations.go` around lines 93 - 125, Handle nil packages returned by GetPackage in InvalidatePackage and IsInvalidPackage: return nil from InvalidatePackage and false, nil from IsInvalidPackage before dereferencing pkg. Add coverage in operator/internal/controller/annotations_test.go:73-85 using an empty Job to verify both helpers treat a missing package annotation without panic. Update operator/internal/controller/annotations.go:93-125 for the root fix; the test site requires corresponding cases only.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@operator/internal/controller/annotations.go`:
- Line 45: Define a named constant for the package annotation key using
v1alpha1.METADATA_PREFIX and the “/package” suffix in the nearest appropriate
file. Update the annotation read and write paths, including the code around
GetAnnotations and the locations at the other referenced ranges, to reuse this
constant instead of reconstructing the key.
- Line 41: Update GetPackage and the related annotation helpers in
operator/internal/controller/annotations.go to accept metav1.Object or a minimal
annotation-only interface instead of client.Object, so *corev1.PodTemplateSpec
is supported. In operator/internal/controller/annotations_test.go, add a
round-trip test using &job.Spec.Template that verifies annotations can be
written and read successfully.
---
Outside diff comments:
In `@operator/internal/controller/annotations.go`:
- Around line 93-125: Handle nil packages returned by GetPackage in
InvalidatePackage and IsInvalidPackage: return nil from InvalidatePackage and
false, nil from IsInvalidPackage before dereferencing pkg. Add coverage in
operator/internal/controller/annotations_test.go:73-85 using an empty Job to
verify both helpers treat a missing package annotation without panic. Update
operator/internal/controller/annotations.go:93-125 for the root fix; the test
site requires corresponding cases only.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 0a3bb469-9bef-4816-a1ff-2daf1c7893b1
📒 Files selected for processing (2)
operator/internal/controller/annotations.gooperator/internal/controller/annotations_test.go
Address review on #313: - Widen to metav1.Object instead of client.Object. The Job pod template (*corev1.PodTemplateSpec) satisfies metav1.Object but not client.Object (it has no runtime.Object methods), and the Job builder (#301) sets the package annotation on job.Spec.Template. metav1.Object is also the more precise seam, since these helpers only ever touch metadata. - Extract the repeated "<prefix>/package" key into a named constant. - Add a round-trip spec covering the Job pod template. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@operator/internal/controller/annotations_test.go`:
- Around line 50-78: Extend the round-trip assertions in the “round-trips the
package annotation identically...” test to verify fromPod.Version,
fromPod.Image, and fromPod.ContainerSHA against the expected package values,
alongside the existing Skyhook, Stage, and Name checks. Keep the cross-resource
equality and annotation assertions unchanged.
In `@operator/internal/controller/annotations.go`:
- Around line 47-50: Update the metadata helpers GetPackage, SetPackages,
InvalidatePackage, and IsInvalidPackage to use one shared nil-check helper that
detects both nil interfaces and typed-nil metav1.Object pointers before
accessing annotations or mutating objects. Replace their direct nil checks with
this helper while preserving existing behavior for non-nil objects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: b85ab0fd-a072-4392-92c7-e32dbee5e89f
📒 Files selected for processing (2)
operator/internal/controller/annotations.gooperator/internal/controller/annotations_test.go
Address the follow-up review on #313: - Guard the metadata helpers against typed-nil interface values. Widening from *corev1.Pod to metav1.Object weakened the original nil check — obj == nil misses a (*corev1.Pod)(nil) and would panic in GetAnnotations. A small isNil helper (reflect-based) catches both a nil interface and a typed-nil pointer; used by all four helpers. Adds a spec proving a typed-nil object is treated as absent. - The round-trip spec now asserts Version/Image/ContainerSHA against the source package, not just cross-resource equality, so a serialization regression is caught. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
operator/internal/controller/annotations.go (1)
106-116: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winHandle absent package annotations before dereferencing.
GetPackagereturns(nil, nil)when the annotation is missing (Lines 63-66). BothInvalidatePackageandIsInvalidPackagethen dereferencepkg, causing a panic on otherwise valid unannotated objects. Handlepkg == nilexplicitly and add a regression test for an unannotated Job or Pod.Also applies to: 134-143
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@operator/internal/controller/annotations.go` around lines 106 - 116, Handle a nil package returned by GetPackage in both InvalidatePackage and IsInvalidPackage before dereferencing pkg. Preserve the existing behavior for annotated objects, and add a regression test covering an unannotated Job or Pod to verify no panic and the expected result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@operator/internal/controller/annotations.go`:
- Around line 106-116: Handle a nil package returned by GetPackage in both
InvalidatePackage and IsInvalidPackage before dereferencing pkg. Preserve the
existing behavior for annotated objects, and add a regression test covering an
unannotated Job or Pod to verify no panic and the expected result.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: dd2f3667-a4c9-489c-8ac7-2bf5de905412
📒 Files selected for processing (2)
operator/internal/controller/annotations.gooperator/internal/controller/annotations_test.go
7ba9f6e to
9d5f6dd
Compare
Address review on #313: - Widen to metav1.Object instead of client.Object. The Job pod template (*corev1.PodTemplateSpec) satisfies metav1.Object but not client.Object (it has no runtime.Object methods), and the Job builder (#301) sets the package annotation on job.Spec.Template. metav1.Object is also the more precise seam, since these helpers only ever touch metadata. - Extract the repeated "<prefix>/package" key into a named constant. - Add a round-trip spec covering the Job pod template. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
da24d20 to
8b711e4
Compare
Address the follow-up review on #313: - Guard the metadata helpers against typed-nil interface values. Widening from *corev1.Pod to metav1.Object weakened the original nil check — obj == nil misses a (*corev1.Pod)(nil) and would panic in GetAnnotations. A small isNil helper (reflect-based) catches both a nil interface and a typed-nil pointer; used by all four helpers. Adds a spec proving a typed-nil object is treated as absent. - The round-trip spec now asserts Version/Image/ContainerSHA against the source package, not just cross-resource equality, so a serialization regression is caught. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
operator/internal/controller/annotations.go (1)
111-116: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winHandle missing package annotations before dereferencing
pkg.
GetPackagereturns(nil, nil)when the annotation is absent, so bothpkg.Invalid = trueandreturn pkg.Invalidcan panic for otherwise valid objects without package metadata. Return a no-op/falseresult whenpkg == nil, and add regression tests for unannotated objects.🛠️ Proposed fix
pkg, err := GetPackage(obj) if err != nil { return fmt.Errorf("error getting package: %w", err) } + if pkg == nil { + return nil + } pkg.Invalid = truepkg, err := GetPackage(obj) if err != nil { return false, fmt.Errorf("error getting package: %w", err) } + if pkg == nil { + return false, nil + } return pkg.Invalid, nilAlso applies to: 139-143
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@operator/internal/controller/annotations.go` around lines 111 - 116, Update the function containing GetPackage and pkg.Invalid so it handles a nil package before dereferencing it: after successful GetPackage, return the existing no-op/false result when pkg == nil, while preserving the current error path and annotated-object behavior. Apply the same guard to the corresponding return pkg.Invalid path, and add regression coverage for objects without package annotations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@operator/internal/controller/annotations.go`:
- Around line 111-116: Update the function containing GetPackage and pkg.Invalid
so it handles a nil package before dereferencing it: after successful
GetPackage, return the existing no-op/false result when pkg == nil, while
preserving the current error path and annotated-object behavior. Apply the same
guard to the corresponding return pkg.Invalid path, and add regression coverage
for objects without package annotations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 033a0bf0-8084-48a2-963b-6325453eae70
📒 Files selected for processing (1)
operator/internal/controller/annotations.go
GetPackage returns (nil, nil) when the package annotation is absent, so pkg.Invalid = true and return pkg.Invalid would panic for an object without package metadata. Now that these helpers accept any metav1.Object (and Job handling will call them on Jobs), guard nil: InvalidatePackage no-ops and IsInvalidPackage reports false. Adds a regression spec for unannotated objects. Addresses CodeRabbit review on #313. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
GetPackage/SetPackages/InvalidatePackage/IsInvalidPackage only ever touch an object's annotations, but were typed to *corev1.Pod. Widen them to client.Object (using GetAnnotations/SetAnnotations instead of the .Annotations field) so the same package metadata can ride on batch/v1 Jobs and their pod templates — the first step of the package-execution-as-Jobs migration (#223). No behavior change: every call site passes a *corev1.Pod, which already satisfies client.Object. Adds a round-trip spec proving SetPackages -> GetPackage (and the invalidate path) behaves identically on a *batchv1.Job and a *corev1.Pod. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
Address review on #313: - Widen to metav1.Object instead of client.Object. The Job pod template (*corev1.PodTemplateSpec) satisfies metav1.Object but not client.Object (it has no runtime.Object methods), and the Job builder (#301) sets the package annotation on job.Spec.Template. metav1.Object is also the more precise seam, since these helpers only ever touch metadata. - Extract the repeated "<prefix>/package" key into a named constant. - Add a round-trip spec covering the Job pod template. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
Address the follow-up review on #313: - Guard the metadata helpers against typed-nil interface values. Widening from *corev1.Pod to metav1.Object weakened the original nil check — obj == nil misses a (*corev1.Pod)(nil) and would panic in GetAnnotations. A small isNil helper (reflect-based) catches both a nil interface and a typed-nil pointer; used by all four helpers. Adds a spec proving a typed-nil object is treated as absent. - The round-trip spec now asserts Version/Image/ContainerSHA against the source package, not just cross-resource equality, so a serialization regression is caught. Part of #300. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
GetPackage returns (nil, nil) when the package annotation is absent, so pkg.Invalid = true and return pkg.Invalid would panic for an object without package metadata. Now that these helpers accept any metav1.Object (and Job handling will call them on Jobs), guard nil: InvalidatePackage no-ops and IsInvalidPackage reports false. Adds a regression spec for unannotated objects. Addresses CodeRabbit review on #313. Signed-off-by: Alex Yuskauskas <ayuskauskas@nvidia.com>
464d88e to
6717670
Compare
Coverage Report for CI Build 29611718659Warning No base build found for commit Coverage: 78.041%Details
Uncovered Changes
Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
Second PR of the #223 series (closes #300). Targets
feature/package-as-jobs, which now sits on the #311 API-rename base.What
GetPackage/SetPackages/InvalidatePackage/IsInvalidPackageinoperator/internal/controller/annotations.goonly ever touch an object's annotations, but were typed to*corev1.Pod. This widens them toclient.Object— switching from the.Annotationsfield toGetAnnotations()/SetAnnotations()— so the same package metadata can ride onbatch/v1Jobs and their pod templates.This is the first code step of the Jobs migration (design in #307): the Job builders (#301) will set the package annotation on both the Job and its pod template (the in-flight erroring path reads it off the child pod).
No behavior change
Every existing call site passes a
*corev1.Pod, which already satisfiesclient.Object, so the call sites are unchanged and compile as-is. The defensivenilguard stays as an interface-nil check; no caller passes a typed-nil pod.Tests
New
annotations_test.go(TDD — written first, watched fail to compile against the*corev1.Podsignature, then made to pass):SetPackages→GetPackageon a*batchv1.Joband asserts it is identical to the same round-trip on a*corev1.Pod(same annotation key, same decoded value);InvalidatePackage/IsInvalidPackageon a*batchv1.Job.Verification
go build ./...+go vet ./internal/controller/: clean.make lint(golangci-lint + license check): 0 issues;gofmtclean.Heads-up (unrelated to this PR): the full
make unit-tests(ginkgo ./..., shared--timeout=180s) does not complete on this base — thecmd/cli/app/packagesuite is slow (individualpackage rerunspecs take ~30s each; e.g.should accept multiple --node flagspasses in isolation but in ~33s), so the aggregate run trips the ginkgo timeout before the controller suite runs. This branch has zero CLI diff — the slowness is pre-existing on thefix/api-renamebase and worth a separate look.