Bundler CLI
bundler.sh ships in the install kit. It builds an offline bundle on a connected host and loads it
into your registry on a host that has no internet access.
Its only input is the release-manifest.yaml inside the kit. No access to our source is needed, so you
can build your own bundle from any published release.
For the procedure rather than the reference, see Prepare the artifacts.
Which commands need internet access
This is the table an isolated site actually needs. The pipeline is split on internet access, not on environment.
| Command | Internet | Talks to |
|---|---|---|
validate | Required | Parses the manifest, resolves tooling, then fetches one image manifest to confirm registry access |
assemble | Required | Source registry: images and charts |
assemble-charts | Required | Source registry: charts only |
assemble-images | Required | Source registry: images only |
verify-assembly | Required | Source registry for signature artifacts, plus Sigstore trust material |
create-package | Required | Inherits assemble and verify-assembly |
package | None | Local tar |
verify-package | None | Local extract and checksum comparison |
mirror | None | Destination registry, over your local network |
retarget | None | Local files |
apply | None | Destination registry. This is mirror plus retarget |
cleanup, version, help | None | Local |
Split the pipeline at the tarball, not earlier. create-package cannot run on an isolated host: it
fails in preflight with no route to the source registry.
Commands
| Command | What it does |
|---|---|
validate | Preflight. The manifest exists and its schema is sane, every image and chart is digest-pinned, the tooling resolves, and the source registry is readable. Fetches one image manifest, so a bad host, missing login, TLS mismatch or unpublished digest fails here rather than partway through a multi-gigabyte download |
assemble | Creates the bundle directory, pulls every image and chart, extracts each chart's production values file, copies in the manifest and itself. Fails if the directory exists |
assemble-charts | The charts half. What the registry install method uses, since the cluster pulls its own images |
assemble-images | The images half. Separable so a failed multi-hour pull can be retried without re-fetching charts |
verify-assembly | Keyless signature verification of every pinned image and chart, then writes SHA256SUMS and prints the bundle fingerprint. Reports every failure and refuses to continue on any |
package | Tars the bundle directory into a tarball beside it, never inside |
verify-package | Unpacks to a temporary directory and re-checks SHA256SUMS |
create-package | assemble, verify-assembly, package, verify-package, in order |
mirror | Verifies the bundle against SHA256SUMS, then pushes every image to your registry |
retarget | Rewrites the registry host in the bundle's own values files, in place, and updates the affected SHA256SUMS entries so the bundle stays self-consistent |
apply | mirror then retarget. The usual customer step |
cleanup | Removes every directory and archive the bundler created |
version | The bundler's version, stamped at release |
help | Usage |
Every command runs validate first, so any of them is safe to invoke on its own.
Options
| Option | Effect |
|---|---|
--arch amd64 or --arch arm64 | Single-architecture bundle, roughly half the size. Loses SBOM attestations. See below |
-o <file> | A different tarball name |
-r <registry> | Destination registry for mirror, retarget and apply |
--dangerously-skip-cosign-verify | Drops signature verification and its tooling requirement. The bundle is annotated as unverified |
The --arch trade-off
A single-architecture bundle extracts one manifest out of each multi-architecture index, which changes every image digest by definition.
| Default | With --arch | |
|---|---|---|
| Image signatures | Verify | Verify. Each per-architecture manifest is signed individually |
| SBOM attestations | Verify | Lost. They hang off the index, which is what is left behind |
| Digests match the manifest | Yes | No |
| Tarball and directory name | multiarch | Named after the architecture, so substitute it everywhere |
If your acceptance process checks attestations, or your nodes are mixed, or you are not certain what they run: take the default. A missing architecture fails when the kubelet tries to pull, on an isolated cluster, after the transfer.
Environment variables
| Variable | Purpose |
|---|---|
MIKEFARAH_YQ_PATH | Path to the Go yq, when the one on PATH is the Python one |
BUNDLE_TLS_VERIFY=false | Disables TLS verification on the pull side |
MIRROR_TLS_VERIFY=false | Disables TLS verification on the push side, for a plain-HTTP registry |
The two TLS variables are the only places in the whole install where verification can be disabled. Prefer a certificate from your internal CA. See Hardening.
Credentials, and the three stores
Three tools, three credential stores. You log in to two of them.
| Tool | Store | Login needed |
|---|---|---|
skopeo | The containers store | Yes, both source and destination |
helm | HELM_REGISTRY_CONFIG | Yes, source only |
cosign | The Docker config | No. The bundler lends it the one skopeo holds |
If you see the bundler say it is reusing skopeo's credential for cosign, that is the expected path and not a warning.
Behavior worth knowing
assemble refuses to write into an existing directory | So a stale bundle cannot be silently mixed with a new one |
retarget takes no file arguments | Rewriting arbitrary paths handed in on a command line is not something an isolated install should be able to ask for |
retarget verifies integrity before editing, never after | That order is what stops a checksum update from re-blessing a bundle that arrived altered |
retarget is idempotent | Running apply twice is safe |
mirror runs before retarget inside apply | So a registry failure leaves your values files untouched |
| Mirroring is additive | New tags land beside old ones, so a running install keeps working and a rollback still has its images |
| An egress proxy is fine for the bundler | Provided the host can reach the registry and Sigstore. Unlike the relay, these are ordinary CLI tools that honour proxy variables |
Bundle contents
gen0sec-cerebellum-<arch>-<version>/
├── oci/ every image, as an OCI layout
├── charts/ installable chart archives
├── values/ each chart's production values, retargeted by `apply`
├── release-manifest.yaml the digests this bundle was built from
├── bundler.sh a copy
└── SHA256SUMS over every file above
assemble extracts each chart's values file as values/<chart>-values-onprem.yaml. There is no bare
values-onprem.yaml in the bundle root, which is why the install commands name the file in full.
The bundle does not carry the install kit's scripts/ or examples/. Those cross the air gap
inside the kit directory. See Install kit contents.