fix: Get config hash for deployer download-cache key (Cachebacked Repository refactoring)#2058
Conversation
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
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:
📝 WalkthroughWalkthroughResolver API simplified: NewResolver no longer accepts a Kubernetes client. Controllers now load a concrete *configuration.Configuration early in Reconcile and pass it into resolution/repository flows. Deployer reconcile was refactored into helper steps, finalizers are added earlier, and download/cache and matching logic were adjusted. Changes
Sequence Diagram(s)sequenceDiagram
participant Controller as Reconciler
participant ConfigSvc as configuration\nLoader
participant ResolutionSvc as resolution\nService
participant Repo as CacheBacked\nRepository
rect rgba(200,150,100,0.5)
Note over Controller: Old Flow
Controller->>ResolutionSvc: Request repository\n(OCMConfigurations, Namespace)
ResolutionSvc->>ConfigSvc: LoadConfigurations(ctx, client, ns, ocmConfigs)
ConfigSvc-->>ResolutionSvc: Configuration
ResolutionSvc->>Repo: Create with cfg
Repo-->>Controller: Repository
end
rect rgba(100,150,200,0.5)
Note over Controller: New Flow
Controller->>ConfigSvc: LoadConfigurations(ctx, client, ns, ocmConfigs)
ConfigSvc-->>Controller: Configuration
Controller->>ResolutionSvc: Request repository\n(Configuration)
ResolutionSvc->>Repo: Create with cfg
Repo-->>Controller: Repository
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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.
Actionable comments posted: 4
🧹 Nitpick comments (1)
kubernetes/controller/internal/resolution/service.go (1)
53-57: Make the preload state explicit.
Configuration: nilnow covers both “there are no OCM configs” and “the caller never materialized them”. Because repository creation still continues in both cases, a missed preload silently drops credentials/path matchers and the config hash from the cache key. A small wrapper/helper aroundLoadConfigurationswould make this much harder to misuse later.Also applies to: 71-71
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/resolution/service.go` around lines 53 - 57, RepositoryOptions currently uses Configuration *configuration.Configuration where nil ambiguously means either "no configs exist" or "caller didn't call configuration.LoadConfigurations"; add an explicit preload indicator/wrapper (e.g., a new type PreloadedConfiguration { Config *configuration.Configuration; Loaded bool } or a constructor NewPreloadedConfigurationFromLoader that calls configuration.LoadConfigurations and returns an error) and replace the raw *Configuration field with this wrapper in RepositoryOptions and callers; update CacheBackedRepository creation (and any callers that set RepositoryOptions) to require/validate Loaded == true (or return an error) so missing preload cannot be silent and the cache key includes config presence reliably.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kubernetes/controller/internal/controller/component/component_controller.go`:
- Around line 244-249: The error branch after calling LoadConfigurations
currently marks the component not ready with
v1alpha1.GetComponentVersionFailedReason; update it to use the
configuration-specific failure reason constant (e.g.,
v1alpha1.GetConfigurationsFailedReason) so configuration load errors are
reported correctly; change the call to status.MarkNotReady(r.EventRecorder,
component, v1alpha1.GetConfigurationsFailedReason, err.Error()) while keeping
the existing error return unchanged (the affected symbols: LoadConfigurations,
status.MarkNotReady, v1alpha1.GetComponentVersionFailedReason).
In `@kubernetes/controller/internal/controller/deployer/deployer_controller.go`:
- Around line 344-358: The cache key used for DownloadCache.Load (variable key)
in the no-digest branch omits repository and verification inputs so a cache hit
can return manifests that were produced from a different
resource.Status.Component.RepositorySpec or a different set of verifications
used by getEffectiveComponentDescriptor; change the key composition (or move the
DownloadCache.Load call) so it includes resource.Status.Component.RepositorySpec
and the verification inputs passed into getEffectiveComponentDescriptor (or
perform the effective descriptor resolution/verification before calling
DownloadCache.Load) so DownloadResourceWithOCM is only skipped when
repo+verification+config+component+version+resourceIdentity all match.
In
`@kubernetes/controller/internal/controller/repository/repository_controller.go`:
- Around line 172-175: The config-loading error from
configuration.LoadConfigurations (called with ctx, r.Client,
ocmRepo.GetNamespace(), configs) must be distinguished from repository failures:
detect and return a specific configure-context error (for example wrap/return
fmt.Errorf("configure context failed: %w", err) or a sentinel
ConfigureContextError) instead of the generic validate error; then update
Reconcile's error-to-reason mapping to check for that configure-specific error
(or error type) and map it to ConfigureContextFailedReason while leaving other
validate errors mapped to GetRepositoryFailedReason. Ensure references:
configuration.LoadConfigurations, validate, Reconcile,
GetRepositoryFailedReason, ConfigureContextFailedReason, ocmRepo.GetNamespace(),
configs, and r.Client.
In `@kubernetes/controller/internal/resolution/doc.go`:
- Line 10: The example call to resolution.NewResolver is using a value `logger`
but the function expects `*logr.Logger`; update the example to pass a pointer to
the logger (or ensure the declared `logger` is a `*logr.Logger`) so the call to
`resolution.NewResolver(logger, wp, pluginManager)` type-checks—locate the
example line with `resolution.NewResolver` in the doc and change the argument to
the pointer form (or adjust the logger declaration) to match the NewResolver
signature.
---
Nitpick comments:
In `@kubernetes/controller/internal/resolution/service.go`:
- Around line 53-57: RepositoryOptions currently uses Configuration
*configuration.Configuration where nil ambiguously means either "no configs
exist" or "caller didn't call configuration.LoadConfigurations"; add an explicit
preload indicator/wrapper (e.g., a new type PreloadedConfiguration { Config
*configuration.Configuration; Loaded bool } or a constructor
NewPreloadedConfigurationFromLoader that calls configuration.LoadConfigurations
and returns an error) and replace the raw *Configuration field with this wrapper
in RepositoryOptions and callers; update CacheBackedRepository creation (and any
callers that set RepositoryOptions) to require/validate Loaded == true (or
return an error) so missing preload cannot be silent and the cache key includes
config presence reliably.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5ef8c313-6085-42ec-9e27-31b94a04ec3f
📒 Files selected for processing (13)
kubernetes/controller/cmd/main.gokubernetes/controller/internal/controller/component/component_controller.gokubernetes/controller/internal/controller/component/component_controller_unit_test.gokubernetes/controller/internal/controller/component/suite_test.gokubernetes/controller/internal/controller/deployer/deployer_controller.gokubernetes/controller/internal/controller/deployer/suite_test.gokubernetes/controller/internal/controller/repository/repository_controller.gokubernetes/controller/internal/controller/repository/suite_test.gokubernetes/controller/internal/controller/resource/resource_controller.gokubernetes/controller/internal/controller/resource/suite_test.gokubernetes/controller/internal/resolution/doc.gokubernetes/controller/internal/resolution/service.gokubernetes/controller/internal/resolution/service_test.go
…omponent-model into get-config-hash
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
…omponent-model into get-config-hash
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
…omponent-model into get-config-hash
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
kubernetes/controller/internal/controller/deployer/deployer_controller_test.go (1)
820-825: Add a regression for theDigest == nilcache-key fallback.These specs still set
ResourceInfo.Digest, so they only cover the digest-key path. The bugfix in this PR is the fallbackcfg.Hash/component:version/resourceIdentitybranch; without aDigest: nilcase plus a config change, that path can regress unnoticed.Also applies to: 1060-1063, 1077-1080
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/deployer/deployer_controller_test.go` around lines 820 - 825, Add a regression test covering the Digest == nil cache-key fallback by modifying the existing specs that currently set ResourceInfo.Digest so they instead set ResourceInfo.Digest = nil (or remove it) and adjust the test config to force the fallback path (the cfg.Hash/component:version/resourceIdentity branch); specifically update the tests that reference getEffectiveComponentDescriptor behavior and the verifiedHit assertion so they exercise the non-digest branch and verify cache hits still occur (apply same change to the other two similar specs referenced near the verifiedHit assertions).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kubernetes/controller/internal/controller/deployer/deployer_controller.go`:
- Around line 350-356: The code dereferences
resource.Status.Component.RepositorySpec.Raw causing a nil-pointer panic; before
creating repoSpec or calling ocmruntime.NewScheme(...).Decode, add a guard that
checks resource.Status != nil, resource.Status.Component != nil and
resource.Status.Component.RepositorySpec != nil (and that RepositorySpec.Raw is
non-empty), and if any are missing call
status.MarkNotReady(r.GetEventRecorder(), deployer,
deliveryv1alpha1.GetRepositoryFailedReason, "repository spec missing or
incomplete") and return ctrl.Result{} (no error) so the reconciler surfaces a
NotReady state instead of panicking; update the logic around repoSpec /
ocmruntime.NewScheme.Decode to only run when the guard passes.
---
Nitpick comments:
In
`@kubernetes/controller/internal/controller/deployer/deployer_controller_test.go`:
- Around line 820-825: Add a regression test covering the Digest == nil
cache-key fallback by modifying the existing specs that currently set
ResourceInfo.Digest so they instead set ResourceInfo.Digest = nil (or remove it)
and adjust the test config to force the fallback path (the
cfg.Hash/component:version/resourceIdentity branch); specifically update the
tests that reference getEffectiveComponentDescriptor behavior and the
verifiedHit assertion so they exercise the non-digest branch and verify cache
hits still occur (apply same change to the other two similar specs referenced
near the verifiedHit assertions).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1e6fe93e-86c8-4e86-93f1-a2e2bd7724d8
📒 Files selected for processing (3)
kubernetes/controller/internal/controller/deployer/deployer_controller.gokubernetes/controller/internal/controller/deployer/deployer_controller_rgd_test.gokubernetes/controller/internal/controller/deployer/deployer_controller_test.go
…omponent-model into get-config-hash
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)
kubernetes/controller/internal/controller/deployer/deployer_controller.go (1)
335-339:⚠️ Potential issue | 🟡 MinorBug: Wrapping a nil error.
At line 338, the
errvariable is nil because the error case was already handled and returned at lines 322-333. Thefmt.Errorfwill produce confusing output like"failed to get ready resource: %!w(<nil>)".🐛 Proposed fix
if resource.Status.Resource == nil { status.MarkNotReady(r.EventRecorder, deployer, deliveryv1alpha1.ResourceIsNotAvailable, "resource is empty in status") - return ctrl.Result{}, fmt.Errorf("failed to get ready resource: %w", err) + return ctrl.Result{}, fmt.Errorf("resource is empty in status") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/deployer/deployer_controller.go` around lines 335 - 339, The check for resource.Status.Resource == nil logs the condition but then returns fmt.Errorf("failed to get ready resource: %w", err) which wraps a nil err; replace that return with a concrete error value (e.g. errors.New or fmt.Errorf without %w) that describes the missing resource so you don't wrap nil. Update the block around status.MarkNotReady, deployer, and deliveryv1alpha1.ResourceIsNotAvailable to return ctrl.Result{} and a clear non-nil error message like "failed to get ready resource: resource.Status.Resource is nil".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@kubernetes/controller/internal/controller/deployer/deployer_controller.go`:
- Around line 335-339: The check for resource.Status.Resource == nil logs the
condition but then returns fmt.Errorf("failed to get ready resource: %w", err)
which wraps a nil err; replace that return with a concrete error value (e.g.
errors.New or fmt.Errorf without %w) that describes the missing resource so you
don't wrap nil. Update the block around status.MarkNotReady, deployer, and
deliveryv1alpha1.ResourceIsNotAvailable to return ctrl.Result{} and a clear
non-nil error message like "failed to get ready resource:
resource.Status.Resource is nil".
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 65b4bfd8-6b1a-4d2c-9b71-b2c2517e5499
📒 Files selected for processing (8)
kubernetes/controller/cmd/main.gokubernetes/controller/internal/controller/component/component_controller.gokubernetes/controller/internal/controller/component/component_controller_unit_test.gokubernetes/controller/internal/controller/deployer/deployer_controller.gokubernetes/controller/internal/controller/deployer/deployer_controller_test.gokubernetes/controller/internal/controller/repository/repository_controller.gokubernetes/controller/internal/controller/resource/resource_controller.gokubernetes/controller/internal/resolution/service_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
- kubernetes/controller/internal/controller/repository/repository_controller.go
- kubernetes/controller/internal/controller/component/component_controller_unit_test.go
- kubernetes/controller/internal/controller/deployer/deployer_controller_test.go
- kubernetes/controller/internal/controller/resource/resource_controller.go
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com>
…omponent-model into get-config-hash
What this PR does / why we need it
While trying to get the config hash to use it as download-cache-key I noticed that the configuration loading in the NewCacheBackedRepository could also be done in the reconciliation loops of the controllers instead. Additionally, this make the
clientin theResolverstruct not necessary anymore. In conclusion, everything get a bit leaner.Which issue(s) this PR fixes
Subtask of open-component-model/ocm-project#963