Skip to content

feat(bundler): support dynamic toleration injection for pre-built OCI bundles#1471

Draft
mohityadav8 wants to merge 14 commits into
NVIDIA:mainfrom
mohityadav8:fix-1371-dynamic-toleration-injection
Draft

feat(bundler): support dynamic toleration injection for pre-built OCI bundles#1471
mohityadav8 wants to merge 14 commits into
NVIDIA:mainfrom
mohityadav8:fix-1371-dynamic-toleration-injection

Conversation

@mohityadav8

Copy link
Copy Markdown
Contributor

Summary

Closes #1371

When AICR generates an OCI bundle, GPU node tolerations are baked in at
build time via --accelerated-node-toleration. Once built, there was no
way to inject additional tolerations at install time without rebuilding
the entire bundle — a blocker when customers add arbitrary taints to GPU
nodes (e.g. reserved-by:NoSchedule during application upgrades).

What changed

pkg/bundler/bundler.go

  • Added dynamicPathSetFor(componentName, provider) — resolves
    --dynamic override keys to component names via the registry and
    returns the declared path set for that component.

  • In extractComponentValues(), dynamic paths are merged into
    policy.optOut before applyNodeSchedulingOverrides runs. The
    existing filterPaths() machinery already skips injection for opt-out
    paths — so no changes to applyNodeSchedulingOverrides itself were
    needed. The result: cluster-values.yaml gets an empty placeholder
    instead of a baked-in toleration value.

pkg/bundler/bundler_test.go

  • TestDynamicPathSetFor — verifies the helper correctly resolves
    override keys to component names and scopes paths per component.

  • TestDynamicTolerationPathExcludedFromBakeIn — verifies that when
    --dynamic gpuoperator:daemonsets.tolerations is set alongside
    --accelerated-node-toleration, the toleration is NOT written into
    component values.

How to use

aicr bundle \
  --accelerated-node-toleration reserved-by:NoSchedule \
  --dynamic gpuoperator:daemonsets.tolerations \
  --output ./bundle

daemonsets.tolerations will be an empty placeholder in
cluster-values.yaml. At install time, inject the taint:

helm upgrade --install gpu-operator ./bundle/gpu-operator \
  --set daemonsets.tolerations[0].key=reserved-by \
  --set daemonsets.tolerations[0].effect=NoSchedule

Testing

go test ./pkg/bundler/... -run "TestDynamic"

mohityadav8 and others added 9 commits June 17, 2026 17:19
- Add NO_COLOR-aware color helpers (_ok, _fail, _warn_line)
- Add _step_header/ok/fail/retry for per-component section framing
- Show [N/M] progress counter and manual copy-paste command per step
- Color-code pre-flight pass/fail and final deployment summary

Closes NVIDIA#1362
Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
Signed-off-by: Mohit Yadav <ymohit799057@gmail.com>
- Re-indent attempt/while/done block inside for-loop body
- Add env var caveat to Manual: step hint with printf -v quoting
- Regenerate all 6 testdata goldens
When a toleration path is declared via --dynamic, skip baking in the
CLI-supplied value during applyNodeSchedulingOverrides. Merging dynamic
paths into policy.optOut causes the injection to be skipped, so
cluster-values.yaml carries an empty placeholder instead of a baked-in
toleration. Operators can then inject additional taints at install time
without rebuilding the OCI bundle.

Add dynamicPathSetFor() helper that resolves --dynamic override keys to
component names via the registry and returns the declared path set.

Closes NVIDIA#1371
@mohityadav8 mohityadav8 requested a review from a team as a code owner June 25, 2026 10:07
@copy-pr-bot

copy-pr-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

Welcome to AICR, @mohityadav8! Thanks for your first pull request.

Before review, please ensure:

  • All commits are signed off per the DCO
  • CI checks pass (tests, lint, security scan)
  • The PR description explains the why behind your changes

A maintainer will review this soon.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The bundler now filters enabled components inline, rejects bundles when none remain enabled, and removes the old filtering helper. It also resolves dynamic value paths from the component registry, adds them to scheduling opt-out, and keeps those paths unset during node scheduling overrides. Agentgateway handling now emits warnings instead of rewriting source ranges. Tests cover alias-based dynamic path resolution and toleration opt-out behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/aicr#1465: Both changes adjust component enablement and deployment-order handling in bundler generation.

Suggested reviewers

  • atif1996
  • lockwobr
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also changes argocd dynamic-value rejection and agentgateway exposure handling, which are unrelated to #1371. Move the argocd validation and agentgateway exposure changes to a separate PR unless they are required for this issue.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: enabling dynamic toleration injection for OCI bundles.
Description check ✅ Passed The description is directly related to the bundler and dynamic toleration changes in the PR.
Linked Issues check ✅ Passed The changes implement dynamic toleration placeholders and match the requested bundle-time behavior for pre-built OCI bundles.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 `@pkg/bundler/bundler_test.go`:
- Around line 2477-2544: The new tests in TestDynamicPathSetFor and
TestDynamicTolerationPathExcludedFromBakeIn use spaces instead of the file’s
tab-based Go formatting, which will fail fmt-check. Reformat the added test
blocks with gofmt (or make tidy) so the indentation matches the surrounding
code, and keep the test logic in place around dynamicPathSetFor,
computeSchedulingPathPolicy, and applyNodeSchedulingOverrides.

In `@pkg/bundler/bundler.go`:
- Around line 1143-1146: The registry-load failure in
applyNodeSchedulingOverrides is being swallowed when
GetComponentRegistryFor(provider) returns an error, which can silently disable
dynamic opt-out behavior. Update the applyNodeSchedulingOverrides path in
bundler.go to keep returning nil on error but also add a slog.Debug log,
matching the existing GetComponentRegistryFor failure handling, so the failure
is visible without changing behavior.
- Around line 1109-1132: Remove the duplicated storage-class injection block in
bundler.go within the component handling logic: the second copy of the
sc/comp.GetStorageClassPaths()/component.ApplyMapOverrides sequence is redundant
and should be deleted, leaving only the original implementation. While editing,
ensure the remaining code in that area uses the existing tab-based Go formatting
so the bundler logic around getValueOverridesForComponent and ApplyMapOverrides
still passes fmt checks.
🪄 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: 229b45ed-3222-4948-adcd-3c26498a11b7

📥 Commits

Reviewing files that changed from the base of the PR and between 596ba97 and c8b69c2.

📒 Files selected for processing (9)
  • pkg/bundler/bundler.go
  • pkg/bundler/bundler_test.go
  • pkg/bundler/deployer/helm/templates/deploy.sh.tmpl
  • pkg/bundler/deployer/helm/testdata/kai_scheduler_present/deploy.sh
  • pkg/bundler/deployer/helm/testdata/manifest_only/deploy.sh
  • pkg/bundler/deployer/helm/testdata/mixed_gpu_operator/deploy.sh
  • pkg/bundler/deployer/helm/testdata/mixed_with_pre/deploy.sh
  • pkg/bundler/deployer/helm/testdata/nodewright_present/deploy.sh
  • pkg/bundler/deployer/helm/testdata/upstream_helm_only/deploy.sh

Comment thread pkg/bundler/bundler_test.go
Comment thread pkg/bundler/bundler.go Outdated
Comment thread pkg/bundler/bundler.go

@mchmarny mchmarny left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this — the core approach is clean: merging dynamic paths into policy.optOut and letting the existing filterPaths machinery skip injection is exactly the right seam, no churn to applyNodeSchedulingOverrides, and optOut is always initialized so the merge is panic-safe.

Blockers before this can merge:

gofmt failure (inline) pkg/bundler/bundler_test.go is space-indented; gofmt -l flags it, so make qualify fails.

One medium concern inline on dynamicPathSetFor (silent fail-open on bad --dynamic keys), plus two nits:

  • "empty placeholder" (PR description + the comment at the optOut merge): the path ends up absent from values, not set to an empty placeholder — the test correctly asserts absence, but the wording overstates it.
  • Worth a one-line note in docs/user/bundling.md that --dynamic paths are excluded from scheduling bake-in, since that's the user-visible behavior this enables.

None of the substance is in question — once the rebase shrinks the diff and gofmt passes, this should be quick to re-review.

Comment thread pkg/bundler/bundler_test.go
Comment thread pkg/bundler/bundler.go
@github-actions github-actions Bot added size/M and removed size/XL labels Jun 25, 2026
- Add slog.Warn when GetByOverrideKey returns nil in dynamicPathSetFor
  so gaps in upstream validation surface immediately rather than
  silently baking in a toleration the user expected to leave dynamic
- Fix gofmt tab indentation in new test functions
@mohityadav8

Copy link
Copy Markdown
Contributor Author

@mchmarny buildDynamicValuesMap already validates all --dynamic keys upstream and returns ErrCodeInvalidRequest if GetByOverrideKey returns nil ---- so a typo like gpuoperatr fails loudly before extractComponentValues is ever reached. The silent return in dynamicPathSetFor is defence-in-depth only.
That said, added slog.Warn on both the registry-load-failure path and the unresolved-key path so any future gap in upstream validation surfaces immediately rather than silently baking in a toleration. Fixed in latest commit.

@mohityadav8 mohityadav8 requested a review from mchmarny June 25, 2026 11:20
@mchmarny

Copy link
Copy Markdown
Member

pkg/bundler/bundler.go:1171:1: File is not properly formatted (gofmt)

- Delete duplicate space-indented storage-class block causing gofmt failure
- Fix optOut merge comment: path is absent from values, not an empty placeholder
- Add note to docs/user/bundling.md on --dynamic scheduling exclusion
@github-actions github-actions Bot added size/L and removed size/M labels Jun 25, 2026
@mohityadav8 mohityadav8 marked this pull request as draft June 25, 2026 16:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 `@pkg/bundler/bundler.go`:
- Around line 228-252: The new filtering loops in bundler.go ignore cancellation
while iterating over recipeResult.ComponentRefs and DeploymentOrder, so add
ctx.Err() checks inside these loops and return early when the context is
canceled, consistent with extractComponentValues. Update the filtering logic in
the bundle-building path to stop processing once Make’s ctx is done, using the
existing ctx passed through the bundling flow and the same cancellation pattern
used elsewhere in the bundle work.
- Around line 238-244: The re-enable path in bundler logic still carries the
recipe-level enabled override into value generation, so a component restored by
`--set <component>:enabled=true` can still render with stale disabled state.
Update the enabled-ref handling in `bundler.go` where refs are added to
`enabledRefs`/`enabledSet` so that `enabled` is stripped from any ref that was
re-enabled before later value extraction, matching the existing cleanup done for
scalar `--set` values.
- Around line 1265-1270: The source-range check in the bundler helper that
iterates over items and calls netutil.IsAnySourceCIDR is treating malformed
CIDRs as scoped, so invalid values like not-a-cidr bypass the warning. Update
that logic to validate each entry first using net.ParseCIDR (or equivalent)
before calling IsAnySourceCIDR, and return false on parse failure; add the net
import if it is not already used. Keep the behavior in the same helper so the
warning is only suppressed for valid non-any source CIDRs.
🪄 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: 29502f5a-8943-4072-9963-1667ef3cf757

📥 Commits

Reviewing files that changed from the base of the PR and between a0002d9 and 6f95c5f.

📒 Files selected for processing (1)
  • pkg/bundler/bundler.go

Comment thread pkg/bundler/bundler.go
Comment on lines +228 to +252
for _, ref := range recipeResult.ComponentRefs {
setEnabled, ok, overrideErr := b.getSetEnabledOverride(ref.Name, recipeResult.DataProvider())
if overrideErr != nil {
return nil, overrideErr
}
if ok {
if !setEnabled {
slog.Info("skipping component disabled via --set", "component", ref.Name)
continue
}
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}
}

// Filter DeploymentOrder to match enabled components
filteredOrder := make([]string, 0, len(recipeResult.DeploymentOrder))
for _, name := range recipeResult.DeploymentOrder {
if _, ok := enabledSet[name]; ok {
filteredOrder = append(filteredOrder, name)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Honor cancellation in the new filtering loops.

These loops run under Make's ctx but continue after cancellation; add ctx.Err() checks like extractComponentValues does before later bundle work proceeds.

As per coding guidelines, Always check ctx.Done() in loops and long operations to respect context cancellation.

Proposed fix
 	for _, ref := range recipeResult.ComponentRefs {
+		if err := ctx.Err(); err != nil {
+			return nil, errors.Wrap(errors.ErrCodeTimeout, "context cancelled during component filtering", err)
+		}
 		setEnabled, ok, overrideErr := b.getSetEnabledOverride(ref.Name, recipeResult.DataProvider())
 		if overrideErr != nil {
 			return nil, overrideErr
@@
 	// Filter DeploymentOrder to match enabled components
 	filteredOrder := make([]string, 0, len(recipeResult.DeploymentOrder))
 	for _, name := range recipeResult.DeploymentOrder {
+		if err := ctx.Err(); err != nil {
+			return nil, errors.Wrap(errors.ErrCodeTimeout, "context cancelled during deployment order filtering", err)
+		}
 		if _, ok := enabledSet[name]; ok {
 			filteredOrder = append(filteredOrder, name)
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, ref := range recipeResult.ComponentRefs {
setEnabled, ok, overrideErr := b.getSetEnabledOverride(ref.Name, recipeResult.DataProvider())
if overrideErr != nil {
return nil, overrideErr
}
if ok {
if !setEnabled {
slog.Info("skipping component disabled via --set", "component", ref.Name)
continue
}
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}
}
// Filter DeploymentOrder to match enabled components
filteredOrder := make([]string, 0, len(recipeResult.DeploymentOrder))
for _, name := range recipeResult.DeploymentOrder {
if _, ok := enabledSet[name]; ok {
filteredOrder = append(filteredOrder, name)
}
for _, ref := range recipeResult.ComponentRefs {
if err := ctx.Err(); err != nil {
return nil, errors.Wrap(errors.ErrCodeTimeout, "context cancelled during component filtering", err)
}
setEnabled, ok, overrideErr := b.getSetEnabledOverride(ref.Name, recipeResult.DataProvider())
if overrideErr != nil {
return nil, overrideErr
}
if ok {
if !setEnabled {
slog.Info("skipping component disabled via --set", "component", ref.Name)
continue
}
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}
}
// Filter DeploymentOrder to match enabled components
filteredOrder := make([]string, 0, len(recipeResult.DeploymentOrder))
for _, name := range recipeResult.DeploymentOrder {
if err := ctx.Err(); err != nil {
return nil, errors.Wrap(errors.ErrCodeTimeout, "context cancelled during deployment order filtering", err)
}
if _, ok := enabledSet[name]; ok {
filteredOrder = append(filteredOrder, name)
}
🤖 Prompt for 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.

In `@pkg/bundler/bundler.go` around lines 228 - 252, The new filtering loops in
bundler.go ignore cancellation while iterating over recipeResult.ComponentRefs
and DeploymentOrder, so add ctx.Err() checks inside these loops and return early
when the context is canceled, consistent with extractComponentValues. Update the
filtering logic in the bundle-building path to stop processing once Make’s ctx
is done, using the existing ctx passed through the bundling flow and the same
cancellation pattern used elsewhere in the bundle work.

Source: Coding guidelines

Comment thread pkg/bundler/bundler.go
Comment on lines +238 to +244
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Strip enabled from re-enabled refs before value extraction.

Line 238 allows --set <component>:enabled=true to include a recipe-disabled component, but Line 243 appends the original ref with Overrides["enabled"]=false. Since only scalar --set strips enabled later, that stale recipe toggle can be rendered into chart values for the component the user re-enabled.

Proposed fix
 		} else if !ref.IsEnabled() {
 			slog.Info("skipping disabled component", "component", ref.Name)
 			continue
 		}
+		if len(ref.Overrides) > 0 {
+			if _, hasEnabled := ref.Overrides[config.ComponentEnabledKey]; hasEnabled {
+				cleaned := make(map[string]any, len(ref.Overrides)-1)
+				for k, v := range ref.Overrides {
+					if k == config.ComponentEnabledKey {
+						continue
+					}
+					cleaned[k] = v
+				}
+				ref.Overrides = cleaned
+			}
+		}
 		enabledRefs = append(enabledRefs, ref)
 		enabledSet[ref.Name] = struct{}{}
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}
// --set enabled=true overrides recipe-level disabled
} else if !ref.IsEnabled() {
slog.Info("skipping disabled component", "component", ref.Name)
continue
}
if len(ref.Overrides) > 0 {
if _, hasEnabled := ref.Overrides[config.ComponentEnabledKey]; hasEnabled {
cleaned := make(map[string]any, len(ref.Overrides)-1)
for k, v := range ref.Overrides {
if k == config.ComponentEnabledKey {
continue
}
cleaned[k] = v
}
ref.Overrides = cleaned
}
}
enabledRefs = append(enabledRefs, ref)
enabledSet[ref.Name] = struct{}{}
🤖 Prompt for 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.

In `@pkg/bundler/bundler.go` around lines 238 - 244, The re-enable path in bundler
logic still carries the recipe-level enabled override into value generation, so
a component restored by `--set <component>:enabled=true` can still render with
stale disabled state. Update the enabled-ref handling in `bundler.go` where refs
are added to `enabledRefs`/`enabledSet` so that `enabled` is stripped from any
ref that was re-enabled before later value extraction, matching the existing
cleanup done for scalar `--set` values.

Comment thread pkg/bundler/bundler.go
Comment on lines 1265 to +1270
for _, r := range items {
if !netutil.IsValidCIDR(r) {
return exposureInvalid, fmt.Sprintf("%q is not a valid CIDR", r)
}
if netutil.IsAnySourceCIDR(r) {
hasAnySource = true
return false
}
}
if hasAnySource {
return exposureOpen, ""
}
return exposureScoped, ""
return true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject malformed CIDRs before treating source ranges as scoped.

netutil.IsAnySourceCIDR returns false for parse errors, so allowedSourceRanges: ["not-a-cidr"] reaches Line 1270 and suppresses the warning even though the value is invalid.

Proposed fix
 	for _, r := range items {
+		if _, _, err := net.ParseCIDR(strings.TrimSpace(r)); err != nil {
+			return false
+		}
 		if netutil.IsAnySourceCIDR(r) {
 			return false
 		}
 	}

Add net to the imports if it is not already present.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, r := range items {
if !netutil.IsValidCIDR(r) {
return exposureInvalid, fmt.Sprintf("%q is not a valid CIDR", r)
}
if netutil.IsAnySourceCIDR(r) {
hasAnySource = true
return false
}
}
if hasAnySource {
return exposureOpen, ""
}
return exposureScoped, ""
return true
for _, r := range items {
if _, _, err := net.ParseCIDR(strings.TrimSpace(r)); err != nil {
return false
}
if netutil.IsAnySourceCIDR(r) {
return false
}
}
return true
🤖 Prompt for 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.

In `@pkg/bundler/bundler.go` around lines 1265 - 1270, The source-range check in
the bundler helper that iterates over items and calls netutil.IsAnySourceCIDR is
treating malformed CIDRs as scoped, so invalid values like not-a-cidr bypass the
warning. Update that logic to validate each entry first using net.ParseCIDR (or
equivalent) before calling IsAnySourceCIDR, and return false on parse failure;
add the net import if it is not already used. Keep the behavior in the same
helper so the warning is only suppressed for valid non-any source CIDRs.

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.

Support dynamic toleration injection for pre-built OCI bundles

2 participants