Skip to content

feat(cli): add --config support to snapshot command#918

Merged
mchmarny merged 3 commits into
mainfrom
feat/913-snapshot-config
May 15, 2026
Merged

feat(cli): add --config support to snapshot command#918
mchmarny merged 3 commits into
mainfrom
feat/913-snapshot-config

Conversation

@mchmarny

Copy link
Copy Markdown
Member

Summary

Extends AICRConfig with spec.snapshot.* so aicr snapshot --config aicr-config.yaml works without bare CLI flags, mirroring the existing config support on recipe, bundle, and validate.

Motivation / Context

pkg/cli/snapshot.go did not read --config, so config-driven CUJ demos (e.g. demos/cuj1-gke-config.md) still had to pass --namespace, --node-selector, and --toleration as bare CLI flags for the snapshot step while the rest of the pipeline was config-driven. This broke the "one file drives the whole flow" property.

Fixes: #913
Related: N/A

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Documentation update

Component(s) Affected

  • CLI (cmd/aicr, pkg/cli)
  • Core libraries (pkg/errors, pkg/k8s) — pkg/config
  • Docs/examples (docs/, examples/)

Implementation Notes

  • New SnapshotSpec in pkg/config/config.go with output, agent, execution sub-sections, mirroring the shape of ValidateSpec. The agent block reuses the same nil-vs-explicitly-empty semantics for nodeSelector and tolerations (omit → inherit; [] → clear the tolerate-all default).
  • (*SnapshotSpec).Resolve() converts wire-string form to a typed SnapshotResolved once at the boundary; CLI overrides layer on top via the existing stringFlagOrConfig / boolFlagOrConfig / stringSliceFlagOrConfig / durationFlagOrConfig / intFlagOrConfig helpers — same pattern as recipe, bundle, and validate.
  • Snapshot CLI action refactored to extract parseSnapshotCmdOptions(cmd, cfg) (mirroring parseBundleCmdOptions) so tests can capture the merged result without touching the deploy path.
  • Behavior preserved: when neither CLI nor config sets tolerations, the resolver falls back to snapshotter.DefaultTolerations() (tolerate all) — matching the legacy aicr snapshot default. This is verified by TestSnapshotCmd_FlagsAloneDefaultsTolerateAll.
  • Privileged is a *bool in SnapshotExecutionSpec so an operator running in PSS-restricted namespaces can set privileged: false without the CLI flag's default-true silently re-enabling it.
  • Demo demos/cuj1-gke-config.md updated to use aicr snapshot --config aicr-config.yaml (no more bare flags); removed the implicit issue-tracking note.

Testing

make qualify

Coverage delta on affected packages:

  • pkg/cli: 63.7% → 66.5% (+2.8%)
  • pkg/config: 93.7% → 93.8% (+0.1%)

New tests:

  • pkg/config/resolve_test.goSnapshotResolve_*: nil receiver, empty spec, all fields, zero/invalid/negative timeout, invalid tolerations, defensive map/slice clone, nil-vs-explicitly-empty, Privileged pointer semantics, negative maxNodesPerEntry.
  • pkg/config/config_test.goValidate_SnapshotOnly, Validate_InvalidSnapshot{Timeout,Format,Tolerations}, Validate_NegativeSnapshotMaxNodesPerEntry, plus the updated none of test now covers spec.snapshot.
  • pkg/config/loader_test.goTestLoad_RejectsUnknownSnapshotField guards the strict-decode path.
  • pkg/cli/snapshot_config_test.go (new) — --config flag wiring, FlagsAloneStillWork, FlagsAloneDefaultsTolerateAll, AllConfigSectionsResolve, ConfigOnly_NoCLIFlags, FlagOverridesEverySection, ConfigEmptyTolerationsOptOut, InvalidConfig_* (bad timeout/format/unknown field/bad resources), RequireGPURuntimeClass_StillMutuallyExclusive, ConfigPrivilegedFalseHonored, NoConfigPrivilegedDefaultsTrue, ToAgentConfig translation pin.

Risk Assessment

  • Low — Additive: new optional spec.snapshot section. No existing CLI flags removed or renamed. Strict-decode rejection unaffected since the new fields are added to the schema in the same change.

Rollout notes: Backwards-compatible. Existing aicr snapshot invocations without --config continue to work unchanged.

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
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S)

Extends AICRConfig with `spec.snapshot.*` so `aicr snapshot --config
aicr-config.yaml` works without bare CLI flags. CLI flags continue to
win over the matching config field; selectors and tolerations preserve
the nil-vs-explicit-empty semantics already used by spec.validate.agent
(omit to inherit defaults; `[]` to opt out of tolerate-all).

The CUJ demo (demos/cuj1-gke-config.md) now drives snapshot, recipe,
bundle, and validate from a single AICRConfig.

Fixes #913
@github-actions

Copy link
Copy Markdown
Contributor

@mchmarny mchmarny self-assigned this May 15, 2026
The hardcoded `aicr-<run-id>` cluster name and `eidosx` project leak
internal-environment specifics that do not generalize.
@github-actions

github-actions Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

Coverage Report ✅

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

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/NVIDIA/aicr/pkg/cli 66.51% (+2.79%) 👍
github.com/NVIDIA/aicr/pkg/config 93.84% (+0.14%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/NVIDIA/aicr/pkg/cli/snapshot.go 56.67% (+53.10%) 90 (+34) 51 (+49) 39 (-15) 🌟
github.com/NVIDIA/aicr/pkg/config/accessors.go 87.50% (-12.50%) 24 (+3) 21 3 (+3) 💀
github.com/NVIDIA/aicr/pkg/config/config.go 0.00% (ø) 0 0 0
github.com/NVIDIA/aicr/pkg/config/resolve.go 96.28% (+1.07%) 188 (+42) 181 (+42) 7 👍
github.com/NVIDIA/aicr/pkg/config/validate.go 100.00% (ø) 54 (+10) 54 (+10) 0

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.

@coderabbitai

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

lalitadithya
lalitadithya previously approved these changes May 15, 2026
Per CodeRabbit review on #918. Five Validate_*Snapshot* tests merge into
TestValidate_Snapshot; the ten single-case TestSnapshotResolve_* tests
fold into ShapeEdges, InvalidInput, DefensiveCloneOfCollections, and
TolerationsNilVsExplicitlyEmpty tables. AllFieldsPopulated,
ZeroTimeoutPreserved, and PrivilegedPointer stay as-is — bespoke
assertions or already table-driven.
@mchmarny mchmarny merged commit 30e99c2 into main May 15, 2026
34 checks passed
@mchmarny mchmarny deleted the feat/913-snapshot-config branch May 15, 2026 13:25
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.

[Feature]: --config support for aicr snapshot

2 participants