Skip to content
In this Guide

In this Guide

Deep Dives

AI: Claude and Codex patterns

ConfigHub: Deploy and manage

More in this Guide

Make a stack from Catalog entries

Pick three Catalog entries for GPU nodes, compose them into one local stack, and check them together. The entries are NVIDIA's gpu-operator, nvsentinel and cluster-readiness-engine. Each is published in the Catalog as its own flattened bundle. This Guide changes one part and checks again, then says what the check leaves out. You can also view this as a markdown file.

Every step runs on your machine with cub, with no account and no cluster. Compose reads the live Catalog index and pulls the three public bundles anonymously with oras. It writes files into a new directory and applies nothing. The check reads those files only.

You can run the steps yourself or give an assistant the task.

Set up the tools

Install the cub CLI and ORAS. Then install the Workshop plugin release this Guide was checked with (version 0.6.61).

cub plugin install confighub/cub-workshop@v0.6.61

Every command below was run with plugin v0.6.57, and the commands in steps 1 to 4 were run again with v0.6.61. The outputs below come from runs without the Flux schema plugin. Release v0.6.56 refuses these entries. It stops with receiptUrl is not a supported GitHub receipt URL.

From v0.6.58 the plugin also ships these three as a stack named gpu-node, so one command checks the same composition.

cub stack sandbox gpu-node

It reports CHECKED with the same 89 objects. Run it in a directory that holds no folder named gpu-node. The command reads a folder of that name before it looks for a shipped stack, and it then stops with an EISDIR error. This Guide writes a folder of that name in step 2, so use another directory.

The rest of this Guide composes the stack by hand, which is how you make one from entries of your own choice.

1. Find the three entries

List the entries that the Catalog files under the gpu role.

cub config list --role gpu | grep -E '^  nvidia-(cluster-readiness-engine-v0-6-0|nvsentinel-v1-25-0|gpu-operator-v26-3-3)-default '
  nvidia-cluster-readiness-engine-v0-6-0-default (v0.6.0) - operator: https://confighub.github.io/helm-expt/site/listings/nvidia-cluster-readiness-engine-v0-6-0-default.json
  nvidia-gpu-operator-v26-3-3-default (v26.3.3) - operator: https://confighub.github.io/helm-expt/site/listings/nvidia-gpu-operator-v26-3-3-default.json
  nvidia-nvsentinel-v1-25-0-default (v1.25.0) - agent: https://confighub.github.io/helm-expt/site/listings/nvidia-nvsentinel-v1-25-0-default.json

The grep keeps three lines. The full list held 44 entries on the day of the run, and it grows with the Catalog.

An entry id is the name of one base of one version. It reads <chart>-<version>-<base>, with the dots of the version written as dashes. The id nvidia-gpu-operator-v26-3-3-default names the default base of version v26.3.3 of the gpu-operator chart.

Read the ids on the Catalog's chart pages. Open the chart page for gpu-operator, nvsentinel or cluster-readiness-engine to see its versions. Open a version page to see its bases under Available Configurations. The page for each entry also holds the five steps under "Use this entry in ConfigHub", and its id appears there.

A role listing returns candidates for you to inspect. It does not choose one and says nothing about whether the three work together. Step 3 checks that.

2. Compose them into a workspace

Name each entry with --entry, name the stack, and give a new directory.

cub stack compose --entry nvidia-gpu-operator-v26-3-3-default --entry nvidia-nvsentinel-v1-25-0-default --entry nvidia-cluster-readiness-engine-v0-6-0-default --name gpu-node --out ./gpu-node
gpu-node: 3 retained catalog component(s) saved as an editable workspace. Files: <your directory>/gpu-node

The command exits 0. The path at the end is the absolute path of your own directory. List what it wrote.

find gpu-node -type f | sort
gpu-node/components/01-nvidia-cluster-readiness-engine-v0-6-0-default.yaml
gpu-node/components/02-nvidia-gpu-operator-v26-3-3-default.yaml
gpu-node/components/03-nvidia-nvsentinel-v1-25-0-default.yaml
gpu-node/evidence/01-nvidia-cluster-readiness-engine-v0-6-0-default/companions/01-crd-ordering.yaml
gpu-node/evidence/01-nvidia-cluster-readiness-engine-v0-6-0-default/metadata.json
gpu-node/evidence/01-nvidia-cluster-readiness-engine-v0-6-0-default/receipt.yaml
gpu-node/evidence/02-nvidia-gpu-operator-v26-3-3-default/companions/01-crd-ordering.yaml
gpu-node/evidence/02-nvidia-gpu-operator-v26-3-3-default/companions/02-lifecycle-actions.yaml
gpu-node/evidence/02-nvidia-gpu-operator-v26-3-3-default/metadata.json
gpu-node/evidence/02-nvidia-gpu-operator-v26-3-3-default/receipt.yaml
gpu-node/evidence/original-stack.yaml
gpu-node/provenance.json
gpu-node/rendered.yaml
gpu-node/result.json
gpu-node/stack.yaml
FileWhat it holds
stack.yamlThe stack manifest. It lists the three components, each with the path of its file. Edit this file to change the stack.
components/One file of Kubernetes objects for each entry. Those are the objects the Catalog retains for that entry: 43, 24 and 22, which add up to 89.
rendered.yamlAll 89 objects in one file, which is the input you would compare or hand to a tool.
result.jsonThe check result that compose recorded, with the hash of each file in the workspace.
provenance.jsonThe Catalog listing of each entry, as it was when you composed.
evidence/For each entry that comes with a plan, the publication receipt with its bundle digest and the plan. nvsentinel has none, so it has no folder.
evidence/original-stack.yamlA copy of the manifest as compose wrote it.

The plan is the Catalog's note on work a chart needs beyond its objects. For gpu-operator it names the CRD ordering and the pre-upgrade and post-delete hook Jobs. The workspace keeps its steps as files and runs none of them. Each carries the state declared-unexecuted.

3. Check them together

Check the stack manifest.

cub stack check ./gpu-node/stack.yaml
Stack: gpu-node  -  Explicit catalog retained-object composition
Resolving 3 components: nvidia-cluster-readiness-engine-v0-6-0-default, nvidia-gpu-operator-v26-3-3-default, nvidia-nvsentinel-v1-25-0-default

Check
  [PASS] no resource conflicts across components (89 objects)
  [PASS] CRD ordering: 12 CRDs are delivered before the 5 custom resources that need them
  [PASS] served API versions: 5 custom resource(s) match their bundled CRD; target availability is not checked
  [WARN] 2 custom resource(s) rely on CRDs this stack does not deliver, which must already exist: monitoring.coreos.com (2)
  [PASS] no admission webhooks need a certificate
  [WARN] namespaces: 0 created, 2 must already exist (gpu-operator, nvcre)
  [WARN] schema validation not run: the flux schema plugin is not installed; next: `flux plugin install schema` (Flux 2.9 or later)
  => CHECKED

The command exits 0. CHECKED means the check ran. It does not mean the stack is ready to apply. Read each line.

LineWhat it checkedWhat you do
PASS, no resource conflictsNo object is claimed by two components, and none appears twice in one component with different content.Nothing.
PASS, CRD orderingThe stack carries 12 CRDs, and no custom resource sits in a component ahead of the one that ships its CRD. The five custom resources are the ClusterPolicy and four LogProfile objects.Nothing. The check compares components, so it does not read the order of objects inside one file.
PASS, served API versionsEach of the 5 custom resources uses an API version and kind that its bundled CRD serves.Nothing. The line says target availability is not checked.
WARN, monitoring.coreos.comA ServiceMonitor from cluster-readiness-engine and a PodMonitor from nvsentinel need CRDs that no entry in the stack ships.Install the Prometheus Operator CRDs on the target first. Otherwise the apply fails for those two objects.
PASS, no admission webhooksNo admission webhook object in the stack lacks a CA bundle.Nothing.
WARN, namespacesThe objects write the namespaces gpu-operator and nvcre, and nothing in the stack creates them.Create both namespaces before you apply. The nvsentinel objects write no namespace, so none appears for that entry.
WARN, schema validationThe check can validate the objects against their schemas, and the Flux schema plugin is not installed here.Run the command the line prints, then check again. This Guide did not run it.

A WARN is not a failure and not a pass. It names a fact about the target that the stack cannot supply and the check cannot see.

4. Change a part and check again

Swap one --entry and compose into a new directory. Your first stack stays as it was. The first swap moves nvsentinel to its no-pod-monitor base.

cub stack compose --entry nvidia-gpu-operator-v26-3-3-default --entry nvidia-nvsentinel-v1-25-0-no-pod-monitor --entry nvidia-cluster-readiness-engine-v0-6-0-default --name gpu-node --out ./gpu-node-no-pod-monitor
cub stack check ./gpu-node-no-pod-monitor/stack.yaml
Stack: gpu-node  -  Explicit catalog retained-object composition
Resolving 3 components: nvidia-cluster-readiness-engine-v0-6-0-default, nvidia-gpu-operator-v26-3-3-default, nvidia-nvsentinel-v1-25-0-no-pod-monitor

Check
  [PASS] no resource conflicts across components (88 objects)
  [PASS] CRD ordering: 12 CRDs are delivered before the 5 custom resources that need them
  [PASS] served API versions: 5 custom resource(s) match their bundled CRD; target availability is not checked
  [WARN] 1 custom resource(s) rely on CRDs this stack does not deliver, which must already exist: monitoring.coreos.com (1)
  [PASS] no admission webhooks need a certificate
  [WARN] namespaces: 0 created, 2 must already exist (gpu-operator, nvcre)
  [WARN] schema validation not run: the flux schema plugin is not installed; next: `flux plugin install schema` (Flux 2.9 or later)
  => CHECKED

Two numbers moved. The stack holds 88 objects, and one custom resource relies on the monitoring CRDs. The remaining ServiceMonitor comes from cluster-readiness-engine, so that WARN stays. Compare the two stacks to see the whole change.

cub config diff gpu-node/rendered.yaml gpu-node-no-pod-monitor/rendered.yaml | head -2
Configuration diff: 0 added, 1 removed, 0 changed, 88 unchanged
  removed: monitoring.coreos.com/v1 PodMonitor (namespace unspecified)/nvsentinel

The only difference is the PodMonitor. The second swap moves gpu-operator back to v25.10.1, with the other two entries as they were.

cub stack compose --entry nvidia-gpu-operator-v25-10-1-default --entry nvidia-nvsentinel-v1-25-0-default --entry nvidia-cluster-readiness-engine-v0-6-0-default --name gpu-node --out ./gpu-node-v25
cub stack check ./gpu-node-v25/stack.yaml
cub config diff gpu-node/rendered.yaml gpu-node-v25/rendered.yaml | grep -E 'Configuration diff|driver/version|toolkit/version'

The check printed the same seven lines as step 3, with 89 objects. The diff printed three lines.

With the Flux schema plugin installed, the schema line of this check passes and counts one null.

  [PASS] schema validation: 85 object(s) valid against the default and ecosystem catalogs (flux-schema/0.16.0); 4 without a catalog schema skipped; 1 null in a custom resource field, which the API server drops before defaulting

The null is /spec/migManager/config/name in the ClusterPolicy. The API server drops it and fills in the field's default, so the entry is accepted as it is. Releases before v0.6.61 refused this compose on that null.

Configuration diff: 0 added, 0 removed, 21 changed, 68 unchanged
    /spec/driver/version replace: "580.126.20" -> "580.105.08"
    /spec/toolkit/version replace: "v1.19.1" -> "v1.18.1"

The check gave no sign that 21 objects changed. It reads one stack at a time and does not compare versions. Use cub config diff for that, as in the gpu-operator upgrade Guide. The check also does not say that one version suits your nodes better than the other.

5. Know what the check does not prove

Nothing was applied

Compose wrote files and the check read them. No object reached a cluster, and no cluster was contacted. The check line says target availability is not checked, and result.json records application health as not-checked.

A passing composition is not runtime compatibility

The check looks at names, kinds, ordering and references inside the files. It does not show that the three run next to each other. It does not show that the driver matches your hardware. Each entry carries its own publication proof, and the Catalog does not inherit runtime proof from it.

The plan is recorded and not executed

The workspace holds the CRD ordering steps and the gpu-operator hook steps as files. It runs no hook. Whoever delivers the stack must decide who applies the pre-upgrade Job, as the hooks and CRDs Guide explains.

The stack is not in ConfigHub

The workspace is a local directory. Nothing was uploaded to ConfigHub, no Space or Unit exists for it, and nobody has approved it.

One entry was delivered, and the stack was not

On 2026-10-08 the default base of gpu-operator v26.3.3 alone was deployed through ConfigHub and Argo CD v3.5.4 to a kind cluster that had no GPUs. The walk log holds every command and its output. Argo CD accepted all 25 objects in one sync, and the Application ended Synced and Healthy. The ClusterPolicy reported ready with the reason NoGPUNodes.

That run covers one entry. It did not include nvsentinel or cluster-readiness-engine, and it did not run on a node with a GPU. The stack of three has not been deployed.

A task for an assistant

Start a fresh session in an empty directory with normal approvals.

Install the Workshop plugin with cub plugin install confighub/cub-workshop@v0.6.61.
Run cub config list --role gpu and find the ids of the default bases of
NVIDIA gpu-operator v26.3.3, nvsentinel v1.25.0 and cluster-readiness-engine
v0.6.0. Compose them with cub stack compose, one --entry for each, --name
gpu-node and --out ./gpu-node. List the files it wrote. Run cub stack check
./gpu-node/stack.yaml and explain every PASS and WARN line in one sentence,
including what I must do about each warning. Then compose a second stack in a
new directory that swaps nvsentinel to its no-pod-monitor base, check it, and
compare the two rendered.yaml files with cub config diff. Report the exit codes
and counts you saw. Do not say the stack is compatible, ready or safe from a
passing check. Do not log in, upload, publish or apply anything, and do not
contact a cluster or ConfigHub.

Where the next step belongs

You now hold a local stack, a check result and a comparison of two variants. Nothing has left your machine.

To run a stack that ships with the plugin, follow Compose and check a stack. To open a shipped stack as an editable workspace and review a change to it, follow the local stack Guide.

To bring a single entry into ConfigHub, open its page and follow the five steps under "Use this entry in ConfigHub", for example gpu-operator v26.3.3. Those steps take one entry from its exact objects to a promoted change. This Guide does not take a stack of three that far.