Skip to content

feat(llmisvc): add manager options hook for distribution-specific cache configuration#1192

Open
bartoszmajsak wants to merge 1 commit intoopendatahub-io:masterfrom
bartoszmajsak:midstream/feat/manager-options-hook
Open

feat(llmisvc): add manager options hook for distribution-specific cache configuration#1192
bartoszmajsak wants to merge 1 commit intoopendatahub-io:masterfrom
bartoszmajsak:midstream/feat/manager-options-hook

Conversation

@bartoszmajsak
Copy link

@bartoszmajsak bartoszmajsak commented Mar 12, 2026

What this PR does / why we need it:

Adds a customizeManagerOptions build-tag hook so the distro build can extend the controller manager's cache configuration without modifying main.go directly.

The distro implementation replaces the simple label-based Secret cache with a namespace-aware one that also watches the platform CA signing secret (openshift-service-ca/signing-key) needed for workload TLS certificates. Without this, cert rotation requires inline changes to main.go that conflict on every upstream sync.

Follows the established _default.go / _ocp.go companion file pattern.

Feature/Issue validation/testing:

  • go vet ./cmd/llmisvc/... passes (both default and distro tags)
  • Verified ServiceCASigningSecretName / ServiceCASigningSecretNamespace constants resolve from workload_tls_cert_ocp.go

Special notes for your reviewer:

Upstream hook landed in kserve/kserve (pending merge). This PR adds both the upstream infrastructure (main.go refactor + _default.go) and the distro implementation (_ocp.go).

Checklist:

  • Have you added unit/e2e tests that prove your fix is effective or that this feature works?
  • Has code been commented, particularly in hard-to-understand areas?
  • Have you made corresponding changes to the documentation?
NONE

Summary by CodeRabbit

  • Chores
    • Refactored internal manager initialization to support configurable options, improving system flexibility and maintainability for future enhancements.
    • Introduced extensibility points to enable distribution-specific customizations and configurations of manager behavior without requiring modifications to core implementation.
    • Enhanced cache configuration capabilities to provide more granular control and improved efficiency in system resource monitoring.

…he configuration

Extracts ctrl.Options into a variable and introduces a customizeManagerOptions
hook using the build-tag companion file pattern. The distro implementation
replaces the simple label-based Secret cache with a namespace-aware one that
also watches the platform CA signing secret needed for workload TLS certificates.

Signed-off-by: Bartosz Majsak <bartosz.majsak@gmail.com>
@openshift-ci
Copy link

openshift-ci bot commented Mar 12, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bartoszmajsak

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Walkthrough

The changes introduce a customization hook pattern for controller-runtime manager initialization. The main.go file is refactored to create manager options in a dedicated configuration object, then calls a customizeManagerOptions hook before instantiation. Two implementations are provided via build tags: a no-op default (!distro) and a distro-specific variant (distro) that configures namespace-aware caching for Secret objects to watch a platform CA signing secret alongside standard label-filtered Secrets.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Key areas requiring attention:

  • Verify the hook invocation in main.go doesn't introduce unintended side effects on mgrOpts state before Manager creation.
  • Validate build tag mutual exclusivity between manager_options_default.go (!distro) and manager_options_ocp.go (distro) to prevent duplicate symbol definitions at compile time.
  • Confirm the Secret cache configuration in manager_options_ocp.go correctly merges the namespace-specific FieldSelector (by metadata.name) with the existing AllNamespaces LabelSelector without overwriting or losing filtering logic.
  • Check that the early return in customizeManagerOptions doesn't skip other cache type configurations if Secret is absent (the log warning implies graceful degradation, but verify this matches intended behavior).
  • Ensure imports in manager_options_ocp.go (local llmisvc package reference) don't create circular dependencies given the function resides in package main.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a manager options hook for distribution-specific cache configuration, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/llmisvc/main.go`:
- Around line 176-177: Change customizeManagerOptions to return an error and
propagate failures at the callsite: update the signatures in
manager_options_ocp.go and manager_options_default.go to func
customizeManagerOptions(*ctrl.Options) error, have those implementations return
any bootstrap/cache-install errors (e.g., "Secret entry not found"), and in
cmd/llmisvc/main.go call err := customizeManagerOptions(&mgrOpts) and if err !=
nil log the error and exit before calling ctrl.NewManager so distro-specific
cache override failures stop startup instead of causing latent runtime faults.

In `@cmd/llmisvc/manager_options_ocp.go`:
- Around line 35-46: The current code replaces opts.Cache.ByObject[obj]
wholesale and wipes any upstream cache knobs; instead, read the existing
cache.ByObject (bo := opts.Cache.ByObject[obj]), copy or initialize
bo.Namespaces (preserve other bo fields like Label, Field, Transform,
UnsafeDisableDeepCopy, EnableWatchBookmarks), shallow-copy the Namespaces map if
non-nil or create a new map, then set/override the two keys
llmisvc.ServiceCASigningSecretNamespace (with FieldSelector for metadata.name ==
llmisvc.ServiceCASigningSecretName) and cache.AllNamespaces (with LabelSelector
cfg.Label), assign the new Namespaces back to bo and finally store bo into
opts.Cache.ByObject[obj] so only Namespaces is modified and all other settings
remain intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 942a7f41-b039-446b-a8af-03d59d75eb0d

📥 Commits

Reviewing files that changed from the base of the PR and between c9f1a9f and 3743631.

📒 Files selected for processing (3)
  • cmd/llmisvc/main.go
  • cmd/llmisvc/manager_options_default.go
  • cmd/llmisvc/manager_options_ocp.go

Comment on lines +176 to +177
customizeManagerOptions(&mgrOpts)
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOpts)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Propagate hook failures before starting the manager.

cmd/llmisvc/manager_options_ocp.go already has a known failure path (Secret entry not found), but this call site gives it no way to stop startup. In distro builds that turns a cache-setup error into a latent runtime failure when pkg/controller/v1alpha2/llmisvc/workload_tls_cert_ocp.go:108-114 needs the CA signing secret. Make customizeManagerOptions return error and exit here if the distro-specific cache override cannot be installed. As per coding guidelines, review priorities include bug-prone patterns and error handling gaps.

Suggested change
- customizeManagerOptions(&mgrOpts)
+ if err := customizeManagerOptions(&mgrOpts); err != nil {
+ 	setupLog.Error(err, "unable to customize manager options")
+ 	os.Exit(1)
+ }
  mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOpts)

Also mirror the signature change in cmd/llmisvc/manager_options_default.go and cmd/llmisvc/manager_options_ocp.go:

func customizeManagerOptions(*ctrl.Options) error
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/llmisvc/main.go` around lines 176 - 177, Change customizeManagerOptions
to return an error and propagate failures at the callsite: update the signatures
in manager_options_ocp.go and manager_options_default.go to func
customizeManagerOptions(*ctrl.Options) error, have those implementations return
any bootstrap/cache-install errors (e.g., "Secret entry not found"), and in
cmd/llmisvc/main.go call err := customizeManagerOptions(&mgrOpts) and if err !=
nil log the error and exit before calling ctrl.NewManager so distro-specific
cache override failures stop startup instead of causing latent runtime faults.

Comment on lines +35 to +46
opts.Cache.ByObject[obj] = cache.ByObject{
Namespaces: map[string]cache.Config{
llmisvc.ServiceCASigningSecretNamespace: {
FieldSelector: fields.SelectorFromSet(map[string]string{
"metadata.name": llmisvc.ServiceCASigningSecretName,
}),
},
cache.AllNamespaces: {
LabelSelector: cfg.Label,
},
},
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In sigs.k8s.io/controller-runtime v0.21.0, what fields exist on cache.ByObject and cache.Config, and what is the correct way to preserve an existing ByObject cache configuration when adding per-namespace settings?

💡 Result:

Fields in sigs.k8s.io/controller-runtime/pkg/cache v0.21.0

cache.ByObject fields: Namespaces map[string]cache.Config, Label labels.Selector, Field fields.Selector, Transform toolscache.TransformFunc, UnsafeDisableDeepCopy *bool, EnableWatchBookmarks *bool. [1]

cache.Config fields: LabelSelector labels.Selector, FieldSelector fields.Selector, Transform toolscache.TransformFunc, UnsafeDisableDeepCopy *bool, EnableWatchBookmarks *bool. [1]


Preserving existing ByObject config when adding per-namespace settings

Don’t overwrite the whole ByObject entry (or its Namespaces map). Instead, read the existing ByObject, copy/initialize its Namespaces map, modify it, then write it back—so you keep the existing selectors/transform/deep-copy/bookmark settings. Also note the semantics: ByObject.Namespaces == nil means “default to cache.Options.DefaultNamespaces”; an empty map means “cache all namespaces”. [1]

obj := &corev1.Secret{} // example key; must be the same type you configured earlier

bo := opts.ByObject[obj] // existing ByObject (zero value if absent)

// IMPORTANT: setting Namespaces from nil -> non-nil changes semantics,
// but that's required if you want explicit per-namespace settings.
ns := bo.Namespaces
if ns == nil {
    ns = map[string]cache.Config{}
} else {
    // shallow copy so we don't mutate a shared map
    cp := make(map[string]cache.Config, len(ns)+1)
    for k, v := range ns { cp[k] = v }
    ns = cp
}

ns["my-namespace"] = cache.Config{
    // set only what you want to override for that namespace
    // (unset fields will be defaulted per the precedence described in ByObject.Namespaces docs)
}

bo.Namespaces = ns
opts.ByObject[obj] = bo

If you instead do opts.ByObject[obj] = cache.ByObject{Namespaces: ...}, you’ll drop any previously-set Label/Field/Transform/... on that object’s cache configuration. [1]

Sources: [1] (pkg.go.dev)

Citations:


Preserve the existing Secret cache configuration when adding per-namespace settings.

This code rebuilds the entire cache.ByObject entry from scratch, discarding any upstream-configured Label, Field, Transform, UnsafeDisableDeepCopy, or EnableWatchBookmarks settings. If cmd/llmisvc/main.go later adds any of these cache knobs, distro builds will silently drop them—reintroducing the upstream-drift problem this hook prevents.

Instead, read the existing cache.ByObject for the Secret, preserve all its fields, and only modify or extend the Namespaces map:

Correct pattern
bo := opts.Cache.ByObject[obj] // existing ByObject (zero value if absent)
ns := bo.Namespaces
if ns == nil {
    ns = map[string]cache.Config{}
} else {
    cp := make(map[string]cache.Config, len(ns)+1)
    for k, v := range ns { cp[k] = v }
    ns = cp
}
ns["llmisvc.ServiceCASigningSecretNamespace"] = cache.Config{
    FieldSelector: fields.SelectorFromSet(map[string]string{
        "metadata.name": llmisvc.ServiceCASigningSecretName,
    }),
}
ns[cache.AllNamespaces] = cache.Config{
    LabelSelector: cfg.Label,
}
bo.Namespaces = ns
opts.Cache.ByObject[obj] = bo
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/llmisvc/manager_options_ocp.go` around lines 35 - 46, The current code
replaces opts.Cache.ByObject[obj] wholesale and wipes any upstream cache knobs;
instead, read the existing cache.ByObject (bo := opts.Cache.ByObject[obj]), copy
or initialize bo.Namespaces (preserve other bo fields like Label, Field,
Transform, UnsafeDisableDeepCopy, EnableWatchBookmarks), shallow-copy the
Namespaces map if non-nil or create a new map, then set/override the two keys
llmisvc.ServiceCASigningSecretNamespace (with FieldSelector for metadata.name ==
llmisvc.ServiceCASigningSecretName) and cache.AllNamespaces (with LabelSelector
cfg.Label), assign the new Namespaces back to bo and finally store bo into
opts.Cache.ByObject[obj] so only Namespaces is modified and all other settings
remain intact.

@bartoszmajsak
Copy link
Author

/retest-required

1 similar comment
@bartoszmajsak
Copy link
Author

/retest-required

@KillianGolds
Copy link

/retest

@openshift-ci
Copy link

openshift-ci bot commented Mar 13, 2026

@bartoszmajsak: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-raw 3743631 link true /test e2e-raw
ci/prow/e2e-predictor 3743631 link true /test e2e-predictor
ci/prow/e2e-graph 3743631 link true /test e2e-graph

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: New/Backlog

Development

Successfully merging this pull request may close these issues.

2 participants