Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

.nornir/guide.md

Holger — guide (the whole workflow)

Class: guide · audience: a techie standing holger up end-to-end. The what is in design.md; the why in reasoning.md. Per-function how-tos: registry-guide · serve-guide · storage-guide · auth-guide · agent-guide · embed-guide.

f0 — one session, internet-side to airgap

The end-to-end shape of using holger crosses several functions. One pass:

  1. Pack (internet side). Run the agent to pull the packages you need and bundle them into one signed .znippy — see agent-guide.
  2. Carry. Move the .znippy across the boundary on USB/optical. No cable crosses.
  3. Serve (secure side). Point a Repository in holger.ron at the archive, run holger-server, and stock cargo/pip/docker clients fetch out of it — see serve-guide and the deploy how-to below.
  4. Lock the door. Before exposing a write path, turn on auth + RBAC — see auth-guide.
  5. Or embed it. Instead of a server, link holger-server-lib and drive a registry in-process — see embed-guide.

Deploy holger (Helm or raw k8s / Talos)

Build the image

docker build -f distribution/Dockerfile -t holger.rs/nordisk/holger:3.1.1 .

Two-stage: rust:1.96-slim builder → distroless/cc-debian12:nonroot runtime (uid 65532). Entrypoint holger-server start --config /etc/holger/holger.ron; exposes 50051 (gRPC) and 8081 (HTTP gateway).

Option 1 — Helm (recommended)

# dev: NodePort, 5Gi local-path, no auth, :latest
helm install holger deploy/helm/holger -n holger --create-namespace \
  -f deploy/helm/holger/values-dev.yaml

# prod: LoadBalancer + Ingress, 200Gi CSI, OIDC auth, pinned tag
helm install holger deploy/helm/holger -n holger --create-namespace \
  -f deploy/helm/holger/values-prod.yaml

Key values.yaml knobs:

knob default note
replicaCount 1 keep at 1 — RWO volume
image.repository / image.tag holger.rs/nordisk/holger (Holger serves its own images) / appVersion container
service.type ClusterIP NodePort (dev) / LoadBalancer (prod)
service.grpcPort / httpPort 50051 / 8081
storage.size / storageClassName 50Gi / local-path override class for prod CSI
auth.enabled / auth.mtlsCaCert false / "" mounts the CA secret
ingress.enabled / ingress.host false / holger.example.com HTTP gateway
config.ron example helm-dev repo the full RON graph

Option 2 — raw manifests

kubectl apply -f deploy/k8s/
kubectl -n holger wait --for=condition=Ready pod -l app=holger --timeout=120s

Applies: namespace, deployment (1 replica, Recreate, readonly rootfs, dropped caps, probes), service (+ service-nodeport overlay), pvc (50Gi RWO local-path), configmap (the holger.ron), secret (mTLS CA).

Talos specifics (deploy/k8s/TALOS.md)

Smoke test

kubectl -n holger port-forward svc/holger 8081:8081 &
curl http://localhost:8081/healthz                     # → ok
helm repo add dev http://localhost:8081/helm-dev
curl -X POST http://localhost:8081/helm-dev/api/charts --data-binary @mychart-0.1.0.tgz

Install / uninstall holger as a service (systemd, either scope)

holger-server install add                  # user unit (no root), state in ~/.holger
sudo holger-server install add             # system unit as the `holger` user, /home/holger/.holger
holger-server install status               # active?
holger-server install render               # dry-run: print the unit that would be written

Same lifecycle through the Skidbladnir ship: holger-server service {install,start,stop,status,health,uninstall}.

Uninstalling — it nukes the data and keeps the keys

holger-server install remove               # stop + remove the unit; data KEPT
holger-server install remove --purge       # + erase the data. SSH KEY + TOKEN KEPT.

--purge erases the scope's data tree — archives, audit log, autogen holger.ron, caches, registry state (and in system scope the staged /usr/local/bin/holger-server). It never touches:

That is the suite-wide law: uninstalling the software nukes all data but keeps the ssh keys. A reinstall reuses the same identity with nothing to re-register. The purge root follows the scope actually in use (~/.holger vs /home/holger), and every delete goes through skidbladnir::systemd::guarded_remove_dir_all, which refuses .ssh, a real user's home, a system directory, and a symlink out of the tree.

To destroy the identity too, ask for it by name:

holger-server install remove --purge --wipe-identity   # DESTROYS the deploy key + token

--wipe-identity is refused without --purge. It is irreversible: the key registered on the git remotes is gone, and a reinstall generates a new key you must register on every remote before holger can pull again.

The output says which of the two happened — KEPT : … identity item(s) — byte-intact or DESTROYED : … --wipe-identity — and a purge that found nothing to erase says so instead of claiming success.

Verify holger (the test matrix)

See testing-guide for the full grid.