Use catalog API to resolve latest version before pulling#147
Use catalog API to resolve latest version before pulling#147anisaoshafi merged 1 commit intomainfrom
Conversation
da680fd to
9b57ac2
Compare
📝 WalkthroughWalkthroughThis pull request introduces version resolution capabilities by adding a new Changes
Sequence DiagramsequenceDiagram
participant CLI as CLI
participant Catalog as Catalog API
participant Registry as Container Registry
participant Image as Image
participant License as License Service
CLI->>CLI: Pre-Pull Validation Phase
alt Pinned Version (non-"latest")
CLI->>License: Validate License
else "latest" Tag
CLI->>Catalog: GetLatestCatalogVersion()
Catalog-->>CLI: Resolved Version (e.g., 4.14.0)
CLI->>License: Validate License
end
Note over CLI,License: Catalog Resolution Success
CLI->>Registry: Pull Image
Registry->>Image: Fetch
Image-->>CLI: Image Downloaded
Note over CLI: Post-Pull Fallback (only if pre-pull unresolved)
opt Unresolved Containers Remaining
CLI->>Image: Inspect Version
Image-->>CLI: Image Version
CLI->>License: Validate License
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
internal/container/start.go (1)
298-311: Mutation of loop variablec.Tagis safe here but could be clearer.On line 305,
c.Tag = vmutates the loop variable. Sincecis a value copy (not a pointer), this doesn't affect the originalcontainersslice—which is correct behavior. However, this could be made more explicit for readability.♻️ Optional: Use explicit copy for clarity
func validateLicensesFromImages(ctx context.Context, rt runtime.Runtime, sink output.Sink, opts StartOptions, tel *telemetry.Client, containers []runtime.ContainerConfig, token string) error { - for _, c := range containers { + for i := range containers { + c := containers[i] v, err := rt.GetImageVersion(ctx, c.Image) if err != nil { return fmt.Errorf("could not resolve version from image %s: %w", c.Image, err) } c.Tag = v if err := validateLicense(ctx, sink, opts, tel, c, token); err != nil { return err } } return nil }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/container/start.go` around lines 298 - 311, In validateLicensesFromImages, avoid mutating the loop variable directly for clarity: make an explicit copy (e.g., cfg := c), set cfg.Tag = v, and pass cfg to validateLicense instead of c; this keeps behavior identical (since c is a value copy) but makes the intent explicit and improves readability when working with containers, c.Tag, and the validateLicense call.test/integration/version_resolution_test.go (1)
19-53: Consider improving robustness of path parsing in mock server.The path parsing on lines 29-30 extracts
emulatorTypeby splitting the path and takingparts[len(parts)-2]. This assumes the path always ends with/versionand the emulator type is the second-to-last segment.This works for the current endpoint format (
/v1/license/catalog/{emulator_type}/version), but could silently misbehave if the path format changes or if requests arrive malformed during test development.♻️ Optional: Use more explicit path matching
case r.Method == http.MethodGet && strings.HasPrefix(r.URL.Path, "/v1/license/catalog/"): if catalogVersion == "" { w.WriteHeader(http.StatusServiceUnavailable) return } - parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/") - emulatorType := parts[len(parts)-2] + // Expected: /v1/license/catalog/{emulator_type}/version + trimmed := strings.TrimPrefix(r.URL.Path, "/v1/license/catalog/") + trimmed = strings.TrimSuffix(trimmed, "/version") + emulatorType := trimmed w.Header().Set("Content-Type", "application/json") _, _ = fmt.Fprintf(w, `{"emulator_type":%q,"version":%q}`, emulatorType, catalogVersion)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/integration/version_resolution_test.go` around lines 19 - 53, In createVersionResolutionMockServer, avoid fragile index-based extraction of emulatorType: when handling the GET for catalog, explicitly verify the path starts with "/v1/license/catalog/" and ends with "/version", then derive emulatorType by trimming that prefix and suffix (or by splitting and validating the expected segment names) and return a 404/400 if the extracted emulatorType is empty or the path shape is unexpected; keep setting Content-Type and writing the JSON response as before but only after validating the path so malformed requests won't silently produce wrong emulatorType values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/container/start.go`:
- Around line 298-311: In validateLicensesFromImages, avoid mutating the loop
variable directly for clarity: make an explicit copy (e.g., cfg := c), set
cfg.Tag = v, and pass cfg to validateLicense instead of c; this keeps behavior
identical (since c is a value copy) but makes the intent explicit and improves
readability when working with containers, c.Tag, and the validateLicense call.
In `@test/integration/version_resolution_test.go`:
- Around line 19-53: In createVersionResolutionMockServer, avoid fragile
index-based extraction of emulatorType: when handling the GET for catalog,
explicitly verify the path starts with "/v1/license/catalog/" and ends with
"/version", then derive emulatorType by trimming that prefix and suffix (or by
splitting and validating the expected segment names) and return a 404/400 if the
extracted emulatorType is empty or the path shape is unexpected; keep setting
Content-Type and writing the JSON response as before but only after validating
the path so malformed requests won't silently produce wrong emulatorType values.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: c32ff3e3-faa2-4615-bfbb-09522b257e36
📒 Files selected for processing (4)
internal/api/catalog_version_test.gointernal/api/client.gointernal/container/start.gotest/integration/version_resolution_test.go
carole-lavillonniere
left a comment
There was a problem hiding this comment.
Great work 👏
When the image tag is "latest", the CLI previously had to pull the image first to resolve the version for license validation.
This changes the order: the catalog API (/v1/license/catalog/{emulator_type}/version) is called first to get the latest released version, so license validation happens before any image data is downloaded.
If the catalog API is unavailable, the original behavior is preserved as a fallback (pull first, inspect image for version, then validate).