Build, inspect, verify, and install the offline air-gapped install bundle. Logic:
ragctl.airgap (packages/ragctl/src/ragctl/airgap.py).
| Command | Purpose |
|---|---|
ragctl airgap build |
Assemble the bundle: all images + Helm chart + config + installer → dist/airgap[.tar.gz] |
ragctl airgap inspect <bundle> |
Print the manifest (images + digests, versions, content hash) |
ragctl airgap verify <bundle> |
Verify the content hash (offline) + cosign signature (with --key); non-zero exit on tamper |
ragctl airgap install <bundle> |
Offline install: verify → docker load → helm upgrade --install |
| Flag | Default | Meaning |
|---|---|---|
--out, -o |
dist/airgap |
Bundle output directory (a .tar.gz is also written unless --no-tar) |
--images |
infra/airgap/images.txt |
Pinned third-party image list |
--chart |
infra/helm/rag-platform |
Helm chart directory |
--config, -f |
rag.yaml |
Example config copied into the bundle |
--version |
chart appVersion |
Bundle version + gateway image tag |
--gateway-image |
from chart values + version | Override the gateway image ref |
--sign / --cosign-key |
off | cosign sign-blob over SHA256SUMS (keyless OIDC, or key-based) |
--dry-run |
off | Skip docker save / helm package — a verifiable bundle minus image blobs |
--tar / --no-tar |
--tar |
Also pack a .tar.gz |
ragctl airgap build --version v0.1.0 --sign # full signed bundle (needs docker+helm+cosign)
ragctl airgap build --dry-run # preview / CI / test (no Docker)
ragctl airgap verify dist/airgap.tar.gz # offline integrity check
ragctl airgap verify dist/airgap.tar.gz --key cosign.pubfrom ragctl import airgap
images = airgap.parse_image_list(open("infra/airgap/images.txt").read())
manifest = airgap.assemble_bundle(
out_dir=Path("dist/airgap"), bundle_version="v0.1.0",
images=images, chart_dir=Path("infra/helm/rag-platform"),
config=Path("rag.yaml"), sign=False, dry_run=True,
)
airgap.pack_tarball(Path("dist/airgap"), Path("dist/airgap.tar.gz"))
result = airgap.verify_bundle(Path("dist/airgap")) # BundleVerification
assert result.content_ok # tamper-evident, offline- Models (frozen Pydantic):
BundleManifest,BundleImage,BundleFile,BundleVerification. - Pure:
parse_image_list,sha256_file,scan_files,render_sha256sums,content_hash,build_manifest,load_manifest,verify_bundle,chart_app_version,gateway_image_ref. - Orchestration (stubbable seam):
save_images,package_chart,load_images,install_chart,cosign_sign_blob,cosign_verify_blob,tool_available,resolve_digest,assemble_bundle,pack_tarball,extract_bundle.
A bundle is a .tar.gz of: images.tar, chart/rag-platform-<v>.tgz, rag.yaml,
install.sh / install.ps1, README.md, SHA256SUMS (+ .sig / .pem when
signed), and manifest.json. Integrity is a standard SHA256SUMS (verifiable with
sha256sum -c) whose hash is pinned as manifest.content_hash; a cosign signature
over SHA256SUMS adds authenticity. BundleVerification.reason ∈ ok / unsigned
/ keyless / cosign_unavailable / content_mismatch / signature_mismatch /
no_checksums (only content_mismatch / signature_mismatch / no_checksums fail
the gate). See architecture/airgap-bundle.md.
The bundle ships install.sh / install.ps1 that need only docker + helm on the
target host (cosign + sha256sum when present) — no Python workspace:
./install.sh --namespace agentcontextos [--release rag-platform] [--key cosign.pub]
./install.sh --verify-only # integrity check, no load/installtask airgap:build # ragctl airgap build --sign → dist/airgap.tar.gz
task airgap:build-dry # dry-run (no docker/helm/cosign)
task airgap:verify # verify dist/airgap.tar.gz (BUNDLE=… to override)CI: .github/workflows/release-airgap.yml builds + keyless-signs + attaches the
tarball to the GitHub Release on v*.*.* tags. Operator runbook:
guides/airgap-install.md.