diff --git a/scripts/proxmox/create-proxmox-resource.sh b/scripts/proxmox/create-proxmox-resource.sh index 84903f4..35d6aa1 100755 --- a/scripts/proxmox/create-proxmox-resource.sh +++ b/scripts/proxmox/create-proxmox-resource.sh @@ -502,6 +502,29 @@ sync_args=("$flake_target") [[ "$dry_run" -eq 1 ]] && sync_args+=(--dry-run) bash "$sync_keys" "${sync_args[@]}" +# If sync-host-keys.sh changed .sops.yaml or secrets/, those changes must be +# committed and pushed before the remote `git pull` below picks them up -- +# the PVE node builds from whatever HEAD is checked out there, not the local +# working tree. Detect uncommitted changes and block until the operator +# confirms they've pushed, so the build never runs against a stale flake. +if [[ "$dry_run" -eq 0 ]]; then + _sops_dirty="$(git -C "$repo_root" status --porcelain -- .sops.yaml secrets/ 2>/dev/null || true)" + if [[ -n "$_sops_dirty" ]]; then + echo + echo "==> COMMIT + PUSH REQUIRED before the remote build can succeed:" + echo " sync-host-keys.sh modified .sops.yaml / secrets/ to register the" + echo " new host's sops recipient. The PVE node builds from the git-tracked" + echo " flake, so these changes must be committed and pushed first -- otherwise" + echo " the image build will succeed but the host cannot decrypt secrets on" + echo " first boot (its age key isn't in the encrypted secrets files yet)." + echo + git -C "$repo_root" status --short -- .sops.yaml secrets/ || true + echo + read -rp " Commit and push those changes, then press Enter to continue (Ctrl-C to abort): " + fi + unset _sops_dirty +fi + # --- VMID: pick one, and refuse to touch anything that already exists --- echo if [[ -z "$vmid" ]]; then @@ -707,6 +730,12 @@ cd "$repo_dir" # right after a successful install. . scripts/lib/nix-bootstrap.sh ensure_nix_profile +if [[ ! -f "host-keys/${target}_ssh_host_ed25519_key" ]]; then + echo "ERROR: host-keys/${target}_ssh_host_ed25519_key not found in ${repo_dir}." >&2 + echo "Generate the key locally (scripts/secrets/sync-host-keys.sh ${target})" >&2 + echo "and ensure it was synced here before starting the build." >&2 + exit 1 +fi NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build --impure \ --no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \ ".#nixosConfigurations.${target}.config.system.build.tarball" \ @@ -747,6 +776,12 @@ declare -a NIX_OPTS=() cd "$repo_dir" . scripts/lib/nix-bootstrap.sh ensure_nix_profile +if [[ ! -f "host-keys/${target}_ssh_host_ed25519_key" ]]; then + echo "ERROR: host-keys/${target}_ssh_host_ed25519_key not found in ${repo_dir}." >&2 + echo "Generate the key locally (scripts/secrets/sync-host-keys.sh ${target})" >&2 + echo "and ensure it was synced here before starting the build." >&2 + exit 1 +fi nix build --no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \ ".#nixosConfigurations.${target}.config.system.build.diskoImagesScript" \ --out-link "result-${target}" diff --git a/scripts/secrets/prepare-host-key.sh b/scripts/secrets/prepare-host-key.sh index a148cf0..a72e192 100755 --- a/scripts/secrets/prepare-host-key.sh +++ b/scripts/secrets/prepare-host-key.sh @@ -41,8 +41,9 @@ mkdir -p "$keydir" keyfile="${keydir}/${hostname}_ssh_host_ed25519_key" if [[ -f "$keyfile" ]]; then - echo "ERROR: $keyfile already exists. Remove it first if you want to regenerate." >&2 - exit 1 + echo "Key already exists: ${keyfile}" + echo "Reusing the existing key. Remove it first if you want to regenerate." + exit 0 fi nix_extra_opts