From b1855d4928b9c42e1c67246690c52262482d3886 Mon Sep 17 00:00:00 2001 From: juvdiaz Date: Mon, 29 Jun 2026 17:50:24 -0600 Subject: [PATCH] Add Pimox golden image ledger --- README.md | 5 +++ README.md.tmpl | 5 +++ docs/jeannie.1.md | 3 ++ infra/pimox/golden-image-ledger.yml | 27 ++++++++++++ jeannie | 9 +++- scripts/golden-ledger | 64 +++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 infra/pimox/golden-image-ledger.yml create mode 100755 scripts/golden-ledger diff --git a/README.md b/README.md index 2eb7588..f7ffe9e 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,7 @@ Run a read-only health snapshot from the Debian server with: ./jeannie synthetic-checks ./jeannie resource-budget ./jeannie artifact-cache status +./jeannie golden-ledger check ./jeannie workers list ./jeannie change-journal list ./jeannie map @@ -338,6 +339,10 @@ it before adding heavier workloads so the HP laptop remains usable. `infra/artifact-cache` with apt-cacher-ng and a Docker Hub registry pull-through cache. Use `artifact-cache instructions` for client configuration snippets. +`golden-ledger` shows or validates `infra/pimox/golden-image-ledger.yml`, the +reviewable record of template VMID, storage, OS release, Kubernetes pins, +runtime versions, and build metadata for Pimox worker golden images. + `workers` provides named Kubernetes/Pimox worker lifecycle operations: `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. Use `recreate-plan ` before replacing one broken Pimox worker so the diff --git a/README.md.tmpl b/README.md.tmpl index 39504ae..a0de89d 100644 --- a/README.md.tmpl +++ b/README.md.tmpl @@ -279,6 +279,7 @@ Run a read-only health snapshot from the Debian server with: ./{{ main_script }} synthetic-checks ./{{ main_script }} resource-budget ./{{ main_script }} artifact-cache status +./{{ main_script }} golden-ledger check ./{{ main_script }} workers list ./{{ main_script }} change-journal list ./{{ main_script }} map @@ -338,6 +339,10 @@ it before adding heavier workloads so the HP laptop remains usable. `infra/artifact-cache` with apt-cacher-ng and a Docker Hub registry pull-through cache. Use `artifact-cache instructions` for client configuration snippets. +`golden-ledger` shows or validates `infra/pimox/golden-image-ledger.yml`, the +reviewable record of template VMID, storage, OS release, Kubernetes pins, +runtime versions, and build metadata for Pimox worker golden images. + `workers` provides named Kubernetes/Pimox worker lifecycle operations: `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. Use `recreate-plan ` before replacing one broken Pimox worker so the diff --git a/docs/jeannie.1.md b/docs/jeannie.1.md index bbff87d..0468e71 100644 --- a/docs/jeannie.1.md +++ b/docs/jeannie.1.md @@ -94,6 +94,9 @@ Kubernetes pod requests/limits and Debian disk/memory signals. : Manage the optional Debian-host artifact cache stack for apt packages and Docker Hub pull-through image caching. +`golden-ledger {show|check}` +: Show or validate the Pimox golden image version ledger. + `workers ` : Manage Kubernetes/Pimox worker lifecycle operations. Commands include `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. diff --git a/infra/pimox/golden-image-ledger.yml b/infra/pimox/golden-image-ledger.yml new file mode 100644 index 0000000..7ffc8f5 --- /dev/null +++ b/infra/pimox/golden-image-ledger.yml @@ -0,0 +1,27 @@ +# Record the intended golden image inputs for Pimox worker templates. +# Update this when rebuilding VM template 9000 or changing Kubernetes/runtime pins. +template: + vmid: 9000 + name: debian-13-arm64-worker-template + storage: local + worker_clone_storage: opi5_ssd +os: + distribution: Debian + release: "13" + architecture: arm64 + image_url: "" + image_sha256: "" +kubernetes: + kubelet: v1.36 + kubeadm: v1.36 + kubectl: v1.36 +runtime: + containerd: "" + qemu_guest_agent: "" +build: + last_built_utc: "" + built_by: "" + source_commit: "" +notes: + - Treat Pimox worker disks as rebuildable capacity. + - Rebuild workers from the template instead of hand-upgrading drifted nodes. diff --git a/jeannie b/jeannie index 30e89d4..e762d0f 100755 --- a/jeannie +++ b/jeannie @@ -6007,6 +6007,10 @@ artifact_cache() { "${REPO_ROOT}/scripts/artifact-cache" "${@:2}" } +golden_ledger() { + "${REPO_ROOT}/scripts/golden-ledger" "${@:2}" +} + workers_manage() { require_debian_server "workers" "${REPO_ROOT}/scripts/workers" "${@:2}" @@ -6078,6 +6082,9 @@ case "${1:-}" in artifact-cache) artifact_cache "$@" ;; + golden-ledger) + golden_ledger "$@" + ;; workers) workers_manage "$@" ;; @@ -6235,7 +6242,7 @@ case "${1:-}" in echo "Log: ${JEANNIE_LOG_FILE}" ;; *) - echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|workers |change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}" + echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|golden-ledger {show|check}|workers |change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}" exit 1 ;; esac diff --git a/scripts/golden-ledger b/scripts/golden-ledger new file mode 100755 index 0000000..1e78761 --- /dev/null +++ b/scripts/golden-ledger @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +LEDGER="${HOMELAB_GOLDEN_LEDGER:-${REPO_ROOT}/infra/pimox/golden-image-ledger.yml}" + +case "${1:-show}" in + show) + sed -n '1,220p' "$LEDGER" + ;; + check) + if [ ! -s "$LEDGER" ]; then + echo "missing ledger: $LEDGER" >&2 + exit 1 + fi + python3 - "$LEDGER" <<'PY' +import sys + +try: + import yaml +except ImportError: + print("yaml module unavailable; ledger file exists") + raise SystemExit(0) + +path = sys.argv[1] +with open(path, encoding="utf-8") as handle: + doc = yaml.safe_load(handle) or {} + +required = [ + "template.vmid", + "template.name", + "os.distribution", + "os.release", + "os.architecture", + "kubernetes.kubelet", + "kubernetes.kubeadm", + "kubernetes.kubectl", +] +missing = [] +for dotted in required: + value = doc + for part in dotted.split("."): + value = value.get(part) if isinstance(value, dict) else None + if value in (None, ""): + missing.append(dotted) + +if missing: + print("missing required ledger fields:") + for item in missing: + print(f" {item}") + raise SystemExit(1) + +print(f"ledger ok: {path}") +PY + ;; + update-stamp) + echo "Manual edit is preferred so image URLs/checksums stay reviewable: $LEDGER" >&2 + exit 1 + ;; + *) + echo "Usage: ./jeannie golden-ledger {show|check}" >&2 + exit 1 + ;; +esac