feat(recipe): add aicr recipe list subcommand for catalog enumeration#1208
Conversation
|
Welcome to AICR, @rsd-darshan! Thanks for your first pull request. Before review, please ensure:
A maintainer will review this soon. |
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@pkg/cli/recipe_list.go`:
- Around line 223-225: The current error wrap uses errors.ErrCodeInternal when
ctx.Err() indicates cancellation/timeouts; update the call that wraps ctx.Err()
(the errors.Wrap(...) invocation that currently passes errors.ErrCodeInternal
and the "write canceled" message) to use errors.ErrCodeTimeout instead of
ErrCodeInternal so context.Canceled / context.DeadlineExceeded are classified as
timeout/cancellation errors.
🪄 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: e4a60857-7f59-4bf1-b1d0-5fc9c4d5b4df
📒 Files selected for processing (2)
pkg/cli/recipe_list.gopkg/recipe/catalog_test.go
There was a problem hiding this comment.
The Curated field in CatalogEntry needs to be addressed before merge — see inline comment for details. Everything in main is "curated" by definition; the field conflates editorial quality with internal overlay tree structure. Either rename it to something structurally accurate (IsLeaf) or drop it entirely.
@rsd-darshan do you mind also creating an issue for this so we can align on the scope before the PR lands?
|
@mchmarny good catch — renamed On your suggestion about defaulting to leaf-only with |
mchmarny
left a comment
There was a problem hiding this comment.
Good response on IsLeaf — the rename is clean and consistent across all layers. Two small items inline.
One thing to clean up before merge: the PR description's Implementation Notes still say Curated: true / Curated: false — update that to match the renamed field.
Also: CatalogEntry.Source uses string values "embedded" / "external" that are only documented in comments, while the actual constants live unexported in pkg/recipe. Consider exporting them (e.g. CatalogSourceEmbedded, CatalogSourceExternal) so callers can compare without hardcoding magic strings.
PR mechanics before merge: squash the 5 commits to 1, add the enhancement label, and confirm CI runs the full build/lint/test gate (only label/auto-merge checks are visible on the head commit right now).
|
This seems reasonable. The |
810d5d0 to
33950bd
Compare
|
Addressed all inline items (commit 33950bd):
Also squashed the 5 commits to 1 as requested. Could a maintainer add the |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@docs/user/cli-reference.md`:
- Around line 545-609: The Markdown has fenced code blocks that lack surrounding
blank lines (MD031): add a blank line before and after each fenced block in the
"Synopsis" (the ```shell block showing "aicr recipe list [flags]"), the
"Examples" code block (the ```shell examples list), and the "Example JSON
output" block (the ```json sample); update the three blocks so there is an empty
line above the opening ``` and an empty line after the closing ``` to satisfy
markdownlint.
In `@pkg/recipe/catalog_test.go`:
- Around line 150-225: Consolidate the repetitive filter tests into a single
table-driven test (e.g., TestListCatalog_Filter) that iterates over cases with
fields: name, filter (*Criteria), wantNames ([]string) or wantLen (int) and uses
catalogStore(), calls store.ListCatalog(filter) and asserts via
entryNames/namesMatch; do the same consolidation pattern for the
matchesCatalogFilter unit tests (previously TestMatchesCatalogFilter_*),
referencing the matchesCatalogFilter function in each case; ensure cases cover
service, accelerator, service+intent, os, no-match, and all-any scenarios and
keep test helpers (catalogStore, entryNames, namesMatch) unchanged.
In `@pkg/recipe/catalog.go`:
- Around line 72-75: ListCatalog currently assigns overlay.Spec.Criteria
directly into CatalogEntry, leaking a reference to cached metadata; create and
assign a defensive deep copy of overlay.Spec.Criteria when building the
CatalogEntry (in the entries = append(...) block) so callers receive an
independent Criteria instance. Locate ListCatalog and the CatalogEntry
construction where overlay.Spec.Criteria is used and replace the direct
assignment with a deep copy operation appropriate for Criteria (e.g., struct
copy or use the project’s clone helper / proto.Clone if Criteria is a protobuf)
to prevent external mutation of the cache.
🪄 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: f567ae98-851c-430c-9564-5f0f5336b36a
📒 Files selected for processing (10)
docs/user/cli-reference.mdpkg/cli/consts.gopkg/cli/recipe.gopkg/cli/recipe_list.gopkg/client/v1/aicr.gopkg/client/v1/types.gopkg/recipe/catalog.gopkg/recipe/catalog_test.gopkg/recipe/metadata_store.gopkg/recipe/provider.go
e911a30 to
3f46c00
Compare
|
@rsd-darshan few issues from CR, otherwise it generally LGTM; |
|
@mchmarny all three CR items were addressed in commit 3f46c00 (pushed just before your comment):
|
Adds a read-only `aicr recipe list` subcommand that enumerates overlay recipes in the catalog with machine-readable output (JSON, YAML, table), solving the catalog discoverability gap in NVIDIA#1207. Problem: Tools consuming AICR as a library or CLI with external --data had no programmatic way to discover which criteria combinations resolve to a leaf overlay versus a generic intermediate recipe. Changes: - pkg/recipe/metadata_store.go: add OverlaySources map to MetadataStore. - pkg/recipe/provider.go: export CatalogSourceEmbedded/CatalogSourceExternal. - pkg/recipe/catalog.go: add CatalogEntry and MetadataStore.ListCatalog with catalog-specific equality filter. IsLeaf=true for leaf overlays. Defensive copy of Criteria on entry construction to prevent cache mutation. - pkg/recipe/catalog_test.go: table-driven tests (t.Run) for filter cases and matchesCatalogFilter semantics. - pkg/client/v1/types.go: add CatalogEntry facade type and re-export source constants. - pkg/client/v1/aicr.go: add Client.ListCatalog. - pkg/cli/consts.go: add flagService/flagAccelerator/flagIntent/flagOS/ flagPlatform/criteriaAny shared constants. - pkg/cli/recipe_list.go: implement recipeListCmd with filter flags, --format (json/yaml/table), --data support. Uses serializer.MarshalYAMLDeterministic. Exhaustive switch with explicit FormatTable case. - pkg/cli/recipe.go: register recipeListCmd; use shared flag constants. - docs/user/cli-reference.md: document aicr recipe list; blank lines around fenced code blocks per markdownlint MD031.
3f46c00 to
2417dc5
Compare
mchmarny
left a comment
There was a problem hiding this comment.
All review findings addressed. Good work on the quick turnaround — IsLeaf rename, defensive Criteria copy, table-driven tests, MarshalYAMLDeterministic, exported source constants, and the flag name constants cleanup are all clean. Also good to see the PR squashed to a single commit. LGTM.
Summary
Adds a read-only
aicr recipe listsubcommand that enumerates overlay recipes in the catalog with machine-readable output (JSON, YAML, table), solving the catalog discoverability gap in #1207.Motivation / Context
Tools consuming AICR as a library or CLI with external
--datahad no programmatic way to discover which criteria combinations resolve to a curated leaf overlay versus a generic fallback. The only workarounds were parsing--helphint text (not a complete API) or probing everyservice × accelerator × intent × oscombination and inspectingappliedOverlays— both fragile and expensive.Fixes: N/A
Related: #1207
Type of Change
Component(s) Affected
cmd/aicr,pkg/cli)cmd/aicrd,pkg/server)pkg/recipe)pkg/bundler,pkg/component/*)pkg/collector,pkg/snapshotter)pkg/validator)pkg/errors,pkg/k8s)docs/,examples/)Implementation Notes
Source tracking (
pkg/recipe/metadata_store.go): AddedOverlaySources map[string]stringtoMetadataStore, populated withprovider.Source(path)during the catalog walk alongside the existing criteria-registry staging. This avoids re-walking the provider at list time.Curated definition (
pkg/recipe/catalog.go): An overlay hasIsLeaf: truewhen no other overlay in the catalog lists it asspec.base— i.e., it is a maximal leaf. Intermediate overlays (e.g.,eks-training, which is the base ofh100-eks-training) getIsLeaf: false. This matches the issue's intent of distinguishing dedicated leaf recipes from generic shared layers.Filter semantics (
matchesCatalogFilter): Uses simple equality rather than the asymmetricCriteria.Matcheslogic used for recipe resolution.--accelerator h100returns only overlays explicitly specifyingh100; it does not match overlays whose accelerator isany. This is the correct semantic for a discovery query: "show me what targets h100", not "show me what a query for h100 would pick up via wildcard".CLI output (
pkg/cli/recipe_list.go): Default format istable(human-friendly with tabwriter);--format jsonand--format yamlare available for machine consumption. Writes tocmd.Root().Writerper project conventions. Filter flags are validated through the client's criteria registry so--dataoverlay values are accepted.Facade (
pkg/client/v1):Client.ListCatalogfollows the same inflight/lock protocol asLoadCatalogand reuses the existingtoInternalCriteria/WrapCriteriatranslation helpers to avoid parallel projection logic.Testing
All tests pass, linter clean. New unit tests in
pkg/recipe/catalog_test.gocover:anyfilter behaves identically to no filtermatchesCatalogFilternil filter, exact match, mismatched dimension, wildcard-overlay vs specific-filterRisk Assessment
Rollout notes: Purely additive. No existing commands or API endpoints are modified. The only change to
MetadataStoreis a new field populated during the existing catalog walk; no behavior changes to recipe resolution or bundling.Checklist
make testwith-race)make lint)git commit -S) — GPG signing info