Edit

CLI Commands

Purpose: For platform engineers, lists every subcommand of opencenter-airgap, its flags, and behavior. Generated by reading src/opencenter_build/cli.py and confirmed with opencenter-airgap --help. To re-derive the surface, run hack/scripts/cli-help-dump.sh.

Synopsis

opencenter-airgap [--help] [--install-completion] [--show-completion]
                  COMMAND [ARGS...]

The CLI is built on Typer. There are no global options beyond completion installation; logging verbosity, paths, and colors are per-command flags.

Commands

| Command | Purpose | |---|---| | #init[init] | Initialize project directories and a default versions.env. | | #add[add] | Add a tool, repository, image, or chart to the component manifest. | | #scan[scan] | Clone or scan repositories for container images and Helm charts. | | #generate-manifest[generate-manifest] | Generate zarf.yaml from the component manifest. | | #build[build] | Run the full build pipeline. | | #validate[validate] | Validate versions.env and components.yaml schemas. | | #verify[verify] | Verify a built package’s checksum and signature. | | #status[status] | Show the state of the most recent build. | | #clean[clean] | Remove build/, dist/, and the state file. | | #serve[serve] | Deploy a Zarf package and start bastion services. | | #version[version] | Print version information for the CLI and key dependencies. | | #keygen[keygen] | Generate a Cosign signing keypair. | | #release[release] | Tag the current commit and push to trigger a CI release. |


init

Initialize project configuration.

opencenter-airgap init [--template baremetal|openstack] [--config PATH]

| Flag | Default | Purpose | |---|---|---| | --template | baremetal | Template for versions.env. openstack adds Terraform-OpenStack defaults. | | --config | config/versions.env | Where to write versions.env. |

Creates config/, config/schemas/, build/, dist/, and assets/. Writes a default versions.env. Does not create components.yamlbuild does that on first run.

If config/versions.env already exists, the command prompts before overwriting.


add

Add a component to config/components.yaml. Creates the manifest if it does not exist.

opencenter-airgap add TYPE NAME [--version V] [--url URL] [--ref REF]
                                [--repo URL] [--extract] [--binary PATH]
                                [--manifest PATH]

TYPE is one of tool, repo, image, chart.

| Flag | Required for | Purpose | |---|---|---| | --version | tools, charts | Component version (no leading v required). | | --url | tools, repos | Tool download URL or Git clone URL. May contain {{version}}. | | --ref | repos | Git ref (branch, tag, or commit SHA). | | --repo | charts | Helm or Git repo URL the chart lives in. | | --extract | tools (optional) | Extract the downloaded archive. | | --binary | tools with --extract | Path to the binary inside the archive. | | --manifest | (optional) | Manifest path. Defaults to config/components.yaml. |

Examples:

opencenter-airgap add image my-registry.example.com/payments-api:1.4.2

opencenter-airgap add chart cert-manager \
  --version v1.16.2 --repo https://charts.jetstack.io

opencenter-airgap add tool helm \
  --version 4.0.5 \
  --url 'https://get.helm.sh/helm-v{{version}}-linux-amd64.tar.gz' \
  --extract --binary linux-amd64/helm

opencenter-airgap add repo kubespray \
  --url https://github.com/kubernetes-sigs/kubespray.git --ref master

scan

Discover container images and Helm charts in Git repositories. Updates config/components.yaml and writes the discovered images, Helm repositories, and Helm releases to plain-text files under config/.

opencenter-airgap scan [--repos] [--repo PATH ...] [--discover-images]
                       [--concurrency N] [--output PATH] [--verbose]

| Flag | Default | Purpose | |---|---|---| | --repos | off | Clone the repositories listed in versions.env into build/ before scanning. | | --repo PATH | (none) | Scan a specific directory. May be repeated. | | --discover-images | off | Read repo paths from config/components.yaml. | | --concurrency N | auto | Worker processes for the scan. | | --output | config/all-images.txt | Output file for the deduplicated image list. | | --verbose | off | Print per-repo image counts and the first 5 entries of each result set. |

Outputs:

  • config/all-images.txt — every image discovered.

  • config/helm-repos.txt — every Helm repository URL discovered.

  • config/helm-charts.txt — every Helm release with its chart, source repo, and version.

  • Updated config/components.yaml — new images appended to images.additional, new charts appended to charts. Duplicates are skipped.


generate-manifest

Generate zarf.yaml from the component manifest.

opencenter-airgap generate-manifest [--output PATH] [--components PATH]
                                    [--config PATH] [--validate / --no-validate]

| Flag | Default | Purpose | |---|---|---| | --output | zarf.yaml | Output path for the generated Zarf manifest. | | --components | config/components.yaml | Component manifest to read. | | --config | config/versions.env | Configuration to read. | | --validate / --no-validate | --validate | Run a basic YAML and required-fields check after generation. |

Used internally by build. Run it directly if you want to inspect the generated zarf.yaml without running the full build.


build

Run the full build pipeline.

opencenter-airgap build [--clean] [--resume / --no-resume]
                        [--force-regenerate] [--config PATH]
                        [--state PATH] [--verbose]

| Flag | Default | Purpose | |---|---|---| | --clean | off | Delete build/state.json before running. Wipes the checkpoint. | | --resume / --no-resume | --resume | Skip steps already marked completed in build/state.json. | | --force-regenerate | off | Rebuild config/components.yaml from versions.env. Manual edits are still merged in. | | --config | config/versions.env | Configuration file. | | --state | build/state.json | Checkpoint file. | | --verbose | off | Print full tracebacks on failure. |

Behavior:

  1. Loads config/versions.env into a BuildConfig.

  2. If versions.env is newer than config/components.yaml, regenerates the manifest from versions.env and merges in any manual edits. With --force-regenerate, regeneration runs unconditionally but still merges custom additions.

  3. Runs the orchestrator pipeline: scan repositories → collect Helm charts → generate Kubespray asset lists → mirror Terraform providers → organize assets → create Zarf package → write artifact manifest.

  4. Writes outputs to dist/. The .tar.zst package is only produced if the Zarf CLI is installed.


validate

Run schema validation on versions.env and components.yaml.

opencenter-airgap validate [--strict] [--check-upstream] [--config PATH]
                           [--components PATH]

| Flag | Default | Purpose | |---|---|---| | --strict | off | Treat warnings as errors. | | --check-upstream | off | Reserved — not implemented yet. Prints a warning. | | --config | config/versions.env | Configuration file. | | --components | config/components.yaml | Component manifest. |

Returns non-zero on any error (or any warning when --strict). The validator is src/opencenter_build/validation.py:ComprehensiveConfigValidator.


verify

Verify a built package.

opencenter-airgap verify PACKAGE [--manifest PATH]

| Argument / Flag | Purpose | |---|---| | PACKAGE | Path to the .tar.zst package. | | --manifest | Optional artifact manifest (dist/artifact-manifest.json) to cross-check against. |

Prints a table of: signature valid, checksums valid, manifest matches (if provided), artifact count. Exit code is non-zero on any failure.

The CLI does not check SBOM policy. Use hack/scripts/verify-package.sh for that. See ../operations/verify-package.md[Verify a Built Package].


status

Show build state.

opencenter-airgap status [--state PATH]

| Flag | Default | Purpose | |---|---|---| | --state | build/state.json | State file location. |

Prints build ID, start time, config hash, and a per-step table with status (Completed / Failed / Running / Pending), duration, and truncated error message. Also lists known build artifacts (zarf.yaml, dist/artifact-manifest.json, dist/zarf-package-*.tar.zst) when the build is complete.


clean

Remove build artifacts.

opencenter-airgap clean [--state PATH] [--build-dir PATH] [--dist-dir PATH]
                        [--yes]

| Flag | Default | Purpose | |---|---|---| | --state | build/state.json | State file to remove. | | --build-dir | build | Build directory to remove. | | --dist-dir | dist | Distribution directory to remove. | | --yes, -y | off | Skip the confirmation prompt. |

Lists each item with a file count and prompts before deletion unless --yes is passed.


serve

Deploy a Zarf package on the bastion and start the bastion services.

opencenter-airgap serve PACKAGE [--verify / --no-verify]
                                [--nginx-port PORT] [--registry-port PORT]
                                [--git-port PORT] [--install-path PATH]
                                [--verbose]

| Flag | Default | Purpose | |---|---|---| | --verify / --no-verify | --verify | Run verify on the package before deploying. | | --nginx-port | 80 | Port for the nginx file server. | | --registry-port | 31999 | Port for the container registry. | | --git-port | 3000 | Port for the Gitea server. | | --install-path | /opt/opencenter | Bastion install directory. | | --verbose | off | Print Zarf and Docker stdout/stderr. |

After zarf package deploy, starts an nginx:1.29.2 container with mounts for /files, /debs, and /pypi, then runs HTTP health checks on every service. Cleans up the nginx container on failure.

Requires the Zarf CLI and Docker on the bastion’s $PATH.


version

Print versions.

opencenter-airgap version

Prints the package version and a table of Python plus key dependency versions (typer, rich, pyyaml, hypothesis, jsonschema).


keygen

Generate a Cosign signing keypair.

opencenter-airgap keygen [--output DIR] [--name NAME] [--force]

| Flag | Default | Purpose | |---|---|---| | --output, -o | .secrets | Directory for the keys. | | --name, -n | signing-key | Filename stem. The output is <name>.key (private) and <name>.pub (public). | | --force, -f | off | Overwrite existing keys. |

Prompts for a password (minimum 8 characters), shells out to cosign generate-key-pair, sets 0600 on the private key, and adds the output directory to .gitignore if a git repo is detected.

Requires cosign on $PATH.


release

Tag the current commit and push to trigger a CI/CD release.

opencenter-airgap release [VERSION] [--dry-run] [--force]

| Argument / Flag | Default | Purpose | |---|---|---| | VERSION | (read from pyproject.toml) | Version to tag, with or without leading v. | | --dry-run | off | Print the commands that would run, but do not tag or push. | | --force | off | Skip the confirmation prompt. |

Refuses to run with a dirty working tree, missing origin remote, or an existing tag. Creates an annotated tag with message Release vX.Y.Z and pushes it to origin.

Exit codes

The CLI uses Typer’s default convention:

  • 0 — success.

  • 1 — most non-success paths (configuration errors, validation errors, subprocess failures, file-not-found, etc.). Specific per-command codes are documented inline in src/opencenter_build/cli.py.

For finer-grained policy gating in CI, prefer wrapper scripts (e.g. hack/scripts/verify-package.sh exits 2/3/4 for different failure classes).

Logging

Rich is used for human-readable terminal output. There is no global --log-level today; verbosity is per-command via --verbose. Tracebacks are suppressed by default and printed when --verbose is set.