From d8687d979ca6d375753c63d843ba0c65bc36435a Mon Sep 17 00:00:00 2001 From: beatzaplenty Date: Mon, 20 Jul 2026 16:20:45 +0000 Subject: [PATCH] Reorganize scripts/ into secrets/, proxmox/, and lib/ subfolders scripts/ had grown to 10 top-level scripts covering three distinct concerns (sops/age + SSH host-key management, Proxmox deployment, and repo-wide bootstrap/CI) with no grouping. Move the key-management scripts (backup-admin-key.sh, rotate-admin-key.sh, prepare-host-key.sh, sync-host-keys.sh) into scripts/secrets/, and the Proxmox scripts (create-proxmox-resource.sh, configure-nix-cache-client.sh) into scripts/proxmox/; leave env.sh, codex-setup.sh, codex-maintenance.sh, and bump-nixpkgs-release.sh at the top level (frequently hand-typed or pure shared config) and scripts/lib/ as-is. Updates every cross-reference: each moved script's repo_root computation (now one directory deeper), shellcheck source= directives, inter-script paths (create-proxmox-resource.sh's call into sync-host-keys.sh and its remote bootstrap of configure-nix-cache-client.sh on the Proxmox node), and every doc/module mention (CLAUDE.md's Scripts section reorganized to match, README.md, docs/auto-installer.md, docs/proxmox-images.md, modules/installer/common.nix, modules/platforms/lxc.nix). CI workflows need no change -- they only invoke codex-maintenance.sh, which didn't move. Verified via bash -n, shellcheck (no new warnings beyond the pre-existing SC1091/SC2029/SC2095 baseline), and live dry-runs of sync-host-keys.sh --all and create-proxmox-resource.sh --list from their new paths. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 118 ++++++++++++------ README.md | 4 +- docs/auto-installer.md | 12 +- docs/proxmox-images.md | 4 +- modules/installer/common.nix | 4 +- modules/platforms/lxc.nix | 4 +- scripts/env.sh | 6 +- scripts/lib/confirm.sh | 4 +- scripts/lib/sops-age.sh | 4 +- scripts/lib/ssh-host-keys.sh | 4 +- .../configure-nix-cache-client.sh | 0 .../{ => proxmox}/create-proxmox-resource.sh | 20 +-- scripts/{ => secrets}/backup-admin-key.sh | 10 +- scripts/{ => secrets}/prepare-host-key.sh | 10 +- scripts/{ => secrets}/rotate-admin-key.sh | 8 +- scripts/{ => secrets}/sync-host-keys.sh | 12 +- 16 files changed, 131 insertions(+), 93 deletions(-) rename scripts/{ => proxmox}/configure-nix-cache-client.sh (100%) rename scripts/{ => proxmox}/create-proxmox-resource.sh (98%) rename scripts/{ => secrets}/backup-admin-key.sh (94%) rename scripts/{ => secrets}/prepare-host-key.sh (91%) rename scripts/{ => secrets}/rotate-admin-key.sh (97%) rename scripts/{ => secrets}/sync-host-keys.sh (98%) diff --git a/CLAUDE.md b/CLAUDE.md index 0c613bb..52d2589 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -73,21 +73,55 @@ diff size; that's the point of it. ## Scripts -Beyond `codex-setup.sh`/`codex-maintenance.sh` above, `scripts/` also has: +Beyond `codex-setup.sh`/`codex-maintenance.sh` above, `scripts/` is +organized by purpose: `scripts/secrets/` (sops/age + SSH host-key +management), `scripts/proxmox/` (Proxmox deployment), `scripts/lib/` +(shared helpers, sourced by the scripts below — not run directly), and a +handful of repo-wide scripts left at the top level (`env.sh`, +`bump-nixpkgs-release.sh`, plus `codex-setup.sh`/`codex-maintenance.sh` +above). When adding a new script, put it in the matching subfolder rather +than the top level, and if it duplicates logic another script already has, +lift the shared part into `scripts/lib/` instead of copying it. -- `scripts/sync-host-keys.sh` — generates/registers SSH host keys and their - `.sops.yaml`/`secrets/*.yaml` recipients for flake targets, idempotently - (`--all`, ``, `--remove`, `--regenerate-all-keys`, all with - `--dry-run`). The primary tool for provisioning a new host's secrets - access — see "Creating a new machine" in `docs/auto-installer.md`. -- `scripts/prepare-host-key.sh` — narrower predecessor: generates a key by - an arbitrary name without touching `.sops.yaml`. Still useful to +### `scripts/secrets/` + +- `scripts/secrets/sync-host-keys.sh` — generates/registers SSH host keys + and their `.sops.yaml`/`secrets/*.yaml` recipients for flake targets, + idempotently (`--all`, ``, `--remove`, `--regenerate-all-keys`, + all with `--dry-run`). The primary tool for provisioning a new host's + secrets access — see "Creating a new machine" in `docs/auto-installer.md`. +- `scripts/secrets/prepare-host-key.sh` — narrower predecessor: generates a + key by an arbitrary name without touching `.sops.yaml`. Still useful to pre-generate a key before its flake target exists yet, since `sync-host-keys.sh` can only act on targets `nixosConfigurations` already has. -- `scripts/create-proxmox-resource.sh` — builds a `lxc-*`/`proxmox-*` - target's tarball/disk image and creates it on a real Proxmox node - (`pct create` against the tarball as a CT template / `qm create`+ +- `scripts/secrets/rotate-admin-key.sh [--new-key-file + ] [--dry-run]` — rotates `.sops.yaml`'s `&admin` age key: decrypts + with a backed-up copy of the key currently trusted as `&admin` (verified + by deriving its public key and comparing, not taken on faith), replaces + the `&admin` line with a new key already present in the environment + (defaults to wherever sops/age itself would look), and runs + `sops updatekeys` on every `secrets/*.yaml`. One-way: the old key can no + longer decrypt anything re-encrypted this way. This is the automation + for the manual steps `sync-host-keys.sh`/`create-proxmox-resource.sh` + print when they bootstrap a brand-new, not-yet-trusted key on a machine + with no prior admin access. +- `scripts/secrets/backup-admin-key.sh [--key-file ] + [--force] [--dry-run]` — copies the local sops age key (source + resolution matches sops/age itself: `$SOPS_AGE_KEY` inline, then + `--key-file`, then `$SOPS_AGE_KEY_FILE`, then the XDG default) to an + arbitrary destination path with `0600` permissions, validating it's a + real age identity and round-tripping the public key before and after the + write. Refuses to overwrite an existing `` without `--force`. + Purely a local filesystem copy — never touches `.sops.yaml`/ + `secrets/*.yaml` or the repo at all. The resulting file is exactly what + `rotate-admin-key.sh` expects as its backup-key argument. + +### `scripts/proxmox/` + +- `scripts/proxmox/create-proxmox-resource.sh` — builds a `lxc-*`/ + `proxmox-*` target's tarball/disk image and creates it on a real Proxmox + node (`pct create` against the tarball as a CT template / `qm create`+ `importdisk`), or reconfigures an existing resource's cores/memory/disk size (`--modify`, always requires typing the VMID back to confirm). Checks for an already-uploaded image on the node before building @@ -99,15 +133,12 @@ Beyond `codex-setup.sh`/`codex-maintenance.sh` above, `scripts/` also has: unless `--allow-duplicate-host` is passed. `--dry-run` throughout both modes. The first time it has to bootstrap build tooling on a node (i.e. `nix` wasn't already on its `PATH`), it also runs - `scripts/configure-nix-cache-client.sh` there (non-fatally — a failure - just falls back to building from source / `cache.nixos.org`) so the - node substitutes from and can offload builds to nix-cache on every + `scripts/proxmox/configure-nix-cache-client.sh` there (non-fatally — a + failure just falls back to building from source / `cache.nixos.org`) so + the node substitutes from and can offload builds to nix-cache on every subsequent run, not just this one. -- `scripts/env.sh` — shared config (`PROXMOX_HOST`, storage pool, bridge, - default cores/memory) sourced by `create-proxmox-resource.sh`. Add new - cross-script config here instead of duplicating it per-script. -- `scripts/configure-nix-cache-client.sh [--dry-run] [--no-remote-builder] - [--no-restart]` — the non-NixOS equivalent of +- `scripts/proxmox/configure-nix-cache-client.sh [--dry-run] + [--no-remote-builder] [--no-restart]` — the non-NixOS equivalent of `modules/nix-cache/client.nix`/`remote-builder-client.nix`, for a plain Debian machine with the Nix package manager (not NixOS) already installed: run as root *on that machine* to add nix-cache as a @@ -120,32 +151,39 @@ Beyond `codex-setup.sh`/`codex-maintenance.sh` above, `scripts/` also has: `/etc/ssh/ssh_known_hosts`. Idempotent (re-running replaces its own marked block rather than duplicating it); restarts `nix-daemon` by default so the change takes effect immediately. + +### `scripts/lib/` + +Sourced by the scripts above, never run directly: + +- `nix-bootstrap.sh` — `NIX_CONFIG`/`ensure_nix_profile`, shared by + `codex-setup.sh`/`codex-maintenance.sh` and the remote build commands + `create-proxmox-resource.sh` runs over SSH. +- `nix-eval.sh` — `NIX_EVAL_FLAGS` plus `list_flake_targets`/ + `flake_target_hostname` flake-introspection helpers. +- `ssh-host-keys.sh` — `generate_host_ed25519_key`/`ssh_pubkey_to_age`, + shared by `sync-host-keys.sh` and `prepare-host-key.sh`. +- `sops-age.sh` — `age_pubkey_from_identity_file`/`sops_yaml_admin_pubkey`/ + `sops_updatekeys` plus the shared sops/age default key-file resolution, + shared by `backup-admin-key.sh`, `rotate-admin-key.sh`, and + `sync-host-keys.sh`. +- `confirm.sh` — `confirm_typed`, the "type X back to confirm" destructive- + action prompt shared by `create-proxmox-resource.sh` and + `sync-host-keys.sh`. +- `sync-host-keys-edit-sops.py` — the `.sops.yaml` anchor/key_groups editor + `sync-host-keys.sh` shells out to (see that script for why: precise, + idempotent YAML edits are impractical in bash). + +### Top level + +- `scripts/env.sh` — shared config (`PROXMOX_HOST`, storage pool, bridge, + default cores/memory) sourced by `create-proxmox-resource.sh`. Add new + cross-script config here instead of duplicating it per-script. - `scripts/bump-nixpkgs-release.sh` — bumps `flake.nix`'s `nixpkgs.url`/ `home-manager.url` in place. Exists because flake input URLs can't reference `variables.nix` (confirmed empirically — `nix flake metadata` errors on it), so this is the closest equivalent to a single source of truth for the tracked release. -- `scripts/rotate-admin-key.sh [--new-key-file ] - [--dry-run]` — rotates `.sops.yaml`'s `&admin` age key: decrypts with a - backed-up copy of the key currently trusted as `&admin` (verified by - deriving its public key and comparing, not taken on faith), replaces the - `&admin` line with a new key already present in the environment - (defaults to wherever sops/age itself would look), and runs - `sops updatekeys` on every `secrets/*.yaml`. One-way: the old key can no - longer decrypt anything re-encrypted this way. This is the automation - for the manual steps `sync-host-keys.sh`/`create-proxmox-resource.sh` - print when they bootstrap a brand-new, not-yet-trusted key on a machine - with no prior admin access. -- `scripts/backup-admin-key.sh [--key-file ] [--force] - [--dry-run]` — copies the local sops age key (source resolution matches - sops/age itself: `$SOPS_AGE_KEY` inline, then `--key-file`, then - `$SOPS_AGE_KEY_FILE`, then the XDG default) to an arbitrary destination - path with `0600` permissions, validating it's a real age identity and - round-tripping the public key before and after the write. Refuses to - overwrite an existing `` without `--force`. Purely a local - filesystem copy — never touches `.sops.yaml`/`secrets/*.yaml` or the - repo at all. The resulting file is exactly what `rotate-admin-key.sh` - expects as its backup-key argument. `sync-host-keys.sh`, `create-proxmox-resource.sh`, and `rotate-admin-key.sh` genuinely mutate real state when run for real (not diff --git a/README.md b/README.md index c9dabd1..b47631f 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ anywhere in this repo — that's live infrastructure state, not something a committed file can keep accurate, and it changes independently of the code. Check the Proxmox node itself, or `/etc/flake-target` on a running host (see below), if you need to know what's really out there right now. -`scripts/create-proxmox-resource.sh`'s duplicate-host guard works the same +`scripts/proxmox/create-proxmox-resource.sh`'s duplicate-host guard works the same way: it checks the Proxmox node directly rather than any file here. Each buildtype's `hosts//host.nix` carries the per-machine identity @@ -114,7 +114,7 @@ Three different paths depending on target, none of them involving a manual disk image and attached to a new VM with no install step — see `docs/proxmox-images.md`. -`scripts/create-proxmox-resource.sh --type lxc|vm --host ` automates +`scripts/proxmox/create-proxmox-resource.sh --type lxc|vm --host ` automates either of the last two end to end (host-key registration, building the image directly on the Proxmox node itself, `pct create`/`qm create`), with `--dry-run` and a guard against duplicating an already-deployed host's diff --git a/docs/auto-installer.md b/docs/auto-installer.md index b014f46..8e92f03 100644 --- a/docs/auto-installer.md +++ b/docs/auto-installer.md @@ -73,7 +73,7 @@ booting one: First boot runs `boot.postBootCommands` (registers the Nix store DB and system profile) — there's no separate activation step to run yourself. -`scripts/create-proxmox-resource.sh --type lxc --host ` automates all +`scripts/proxmox/create-proxmox-resource.sh --type lxc --host ` automates all of this (host-key handling, building the tarball directly on the Proxmox node itself, `pct create` with the flags above) — see its `--help`. @@ -102,7 +102,7 @@ groups required, got 0`, and *every* secret (including this host's own login) permanently fails to decrypt, silently — no error in the boot log at all, since the activation step that would install secrets only runs on a from-scratch first activation and skips silently once `/run/current-system` -already exists. `scripts/create-proxmox-resource.sh` always builds with +already exists. `scripts/proxmox/create-proxmox-resource.sh` always builds with `NIXOS_HOST_KEYS_DIR` set for this reason. ## Layout @@ -116,10 +116,10 @@ already exists. `scripts/create-proxmox-resource.sh` always builds with `docs/pxe-boot.md`). - `modules/installer/host-keys.nix` — optionally bakes pre-generated SSH host keys into the image; see "Host keys" below. -- `scripts/sync-host-keys.sh` — admin-workstation tool that generates, +- `scripts/secrets/sync-host-keys.sh` — admin-workstation tool that generates, registers, and (via `--remove`/`--regenerate-all-keys`) retires host keys; see "Creating a New Machine" below. -- `scripts/prepare-host-key.sh` — narrower predecessor: generates a single +- `scripts/secrets/prepare-host-key.sh` — narrower predecessor: generates a single key by an arbitrary name without touching `.sops.yaml`. Still useful for pre-generating a key *before* its flake target exists (`sync-host-keys.sh` can only act on targets `nixosConfigurations` already has); otherwise @@ -238,7 +238,7 @@ GitHub token behind sops-nix for all of them). 2. **On your admin workstation, generate and register its host key:** ```sh - ./scripts/sync-host-keys.sh + ./scripts/secrets/sync-host-keys.sh ``` This generates `host-keys/_ssh_host_ed25519_key(.pub)`, @@ -250,7 +250,7 @@ GitHub token behind sops-nix for all of them). Doing this for every host that needs one at once — after adding several new targets, or just to catch up any that were missed — is - `./scripts/sync-host-keys.sh --all`. See `scripts/sync-host-keys.sh --help` + `./scripts/secrets/sync-host-keys.sh --all`. See `scripts/secrets/sync-host-keys.sh --help` for its other modes (`--remove`, `--regenerate-all-keys`). 3. **Commit and push.** The flake build the installer uses has to see the diff --git a/docs/proxmox-images.md b/docs/proxmox-images.md index 5ce94f3..0c5c8e2 100644 --- a/docs/proxmox-images.md +++ b/docs/proxmox-images.md @@ -7,7 +7,7 @@ config (`modules/disko/proxmox.nix`) already used to format a real disk on install, so there's nothing host-specific to write; it's available for every `proxmox-*` target automatically. -`scripts/create-proxmox-resource.sh --type vm --host ` automates the +`scripts/proxmox/create-proxmox-resource.sh --type vm --host ` automates the whole walkthrough below (and the equivalent LXC one) end to end, including host-key handling and building the image directly on the Proxmox node itself (no local build, no image transfer) — see its `--help`. The steps @@ -51,7 +51,7 @@ sudo ./result \ --build-memory 2048 ``` -Generate the key first with `scripts/sync-host-keys.sh `, same +Generate the key first with `scripts/secrets/sync-host-keys.sh `, same as any other host — see `docs/auto-installer.md` for the full walkthrough (it registers the new key in `.sops.yaml` and re-encrypts the affected `secrets/*.yaml` files too, no manual editing needed). diff --git a/modules/installer/common.nix b/modules/installer/common.nix index 2951068..26a7d7e 100644 --- a/modules/installer/common.nix +++ b/modules/installer/common.nix @@ -130,7 +130,7 @@ # at *activation* time, which runs before systemd would otherwise # generate one on first boot. Without pre-seeding it here, secrets # (including the login password) fail to decrypt on first boot. - # Generate the key with scripts/prepare-host-key.sh first. + # Generate the key with scripts/secrets/prepare-host-key.sh first. # # Two places a key can come from, checked in order: # /etc/host-keys — baked into this image at build time (see @@ -150,7 +150,7 @@ else echo "WARNING: no SSH host key found for ''${choice} (checked /etc/host-keys and /root/host-keys)" echo "sops-nix secrets (including the login password) will NOT decrypt on first boot." - echo "Run scripts/prepare-host-key.sh for host ''${choice} on your admin workstation first," + echo "Run scripts/secrets/prepare-host-key.sh for host ''${choice} on your admin workstation first," echo "then either rebuild this image with NIXOS_HOST_KEYS_DIR set, or scp the result to" echo "/root/host-keys/ on this machine." read -rp "Continue without a pre-seeded key anyway? (y/N): " skip_key diff --git a/modules/platforms/lxc.nix b/modules/platforms/lxc.nix index 0c14bd2..ab3d10f 100644 --- a/modules/platforms/lxc.nix +++ b/modules/platforms/lxc.nix @@ -14,7 +14,7 @@ let # Without this, config.system.build.tarball's built-in system just # generates a fresh host key at first boot like any other host would -- # but sops-nix derives its decryption key from *this* file, and - # .sops.yaml only trusts whatever key scripts/sync-host-keys.sh already + # .sops.yaml only trusts whatever key scripts/secrets/sync-host-keys.sh already # registered for this exact target name. A freshly-generated key can # never match that, so every secret (including this host's own login) # permanently fails to decrypt. Confirmed live: sops-install-secrets @@ -26,7 +26,7 @@ let hostKeysDir = /. + hostKeysDirStr; # flakeTarget ("${platform}-${buildType}") comes in via specialArgs from - # flake.nix's mkTarget -- exactly the name scripts/sync-host-keys.sh + # flake.nix's mkTarget -- exactly the name scripts/secrets/sync-host-keys.sh # registers keys under. Deliberately not read back from # config.environment.etc."flake-target" (which is set to the same value) # -- this module also *contributes* to environment.etc below, and a diff --git a/scripts/env.sh b/scripts/env.sh index 7f6000d..dc864d6 100755 --- a/scripts/env.sh +++ b/scripts/env.sh @@ -3,10 +3,10 @@ # second copy of these values in every script: # source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/env.sh" # Every variable can still be overridden per-invocation via the -# environment (e.g. PROXMOX_STORAGE=tank-nvme ./scripts/create-proxmox-resource.sh ...) +# environment (e.g. PROXMOX_STORAGE=tank-nvme ./scripts/proxmox/create-proxmox-resource.sh ...) # since each one only sets a default if unset. -# SSH-reachable Proxmox node that scripts/create-proxmox-resource.sh runs +# SSH-reachable Proxmox node that scripts/proxmox/create-proxmox-resource.sh runs # pct/qm on. Matches the Proxmox web UI hostname already used in # hosts/nixos/home.nix's desktop shortcuts (pve. from # variables.nix) -- change this if that's not actually reachable over SSH, @@ -15,7 +15,7 @@ : "${PROXMOX_SSH_USER:=root}" # Where this flake repo lives on the Proxmox node itself. -# scripts/create-proxmox-resource.sh builds images directly on the node +# scripts/proxmox/create-proxmox-resource.sh builds images directly on the node # instead of transferring them over the network -- it clones the repo here # (from this checkout's own `origin` remote) the first time it doesn't # find it, installing build tooling via scripts/codex-setup.sh, then diff --git a/scripts/lib/confirm.sh b/scripts/lib/confirm.sh index ebb3f7b..e46b421 100644 --- a/scripts/lib/confirm.sh +++ b/scripts/lib/confirm.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# Shared "type X to confirm" prompt for scripts/create-proxmox-resource.sh +# Shared "type X to confirm" prompt for scripts/proxmox/create-proxmox-resource.sh # (--modify, and replacing an existing --allow-duplicate-host resource) and -# scripts/sync-host-keys.sh (--regenerate-all-keys) -- three destructive +# scripts/secrets/sync-host-keys.sh (--regenerate-all-keys) -- three destructive # confirmations that all work the same way (echo the expected value back # exactly), kept in one place so the prompt/comparison logic can't drift. # Source alongside env.sh: diff --git a/scripts/lib/sops-age.sh b/scripts/lib/sops-age.sh index e0afa4f..cde7624 100644 --- a/scripts/lib/sops-age.sh +++ b/scripts/lib/sops-age.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Shared sops/age helpers for scripts/backup-admin-key.sh, -# scripts/rotate-admin-key.sh, and scripts/sync-host-keys.sh -- all three +# Shared sops/age helpers for scripts/secrets/backup-admin-key.sh, +# scripts/secrets/rotate-admin-key.sh, and scripts/secrets/sync-host-keys.sh -- all three # derive an age public key from a private identity file the same way, two # of them resolve the same sops/age default key-file path, and two of them # run `sops updatekeys` the same way. Kept in one place so they can't drift diff --git a/scripts/lib/ssh-host-keys.sh b/scripts/lib/ssh-host-keys.sh index cd0b658..8605b15 100644 --- a/scripts/lib/ssh-host-keys.sh +++ b/scripts/lib/ssh-host-keys.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Shared SSH-host-key / age-conversion helpers for scripts/sync-host-keys.sh -# and scripts/prepare-host-key.sh -- both generate the same kind of key +# Shared SSH-host-key / age-conversion helpers for scripts/secrets/sync-host-keys.sh +# and scripts/secrets/prepare-host-key.sh -- both generate the same kind of key # (ed25519, no passphrase, the sops-nix age-derivation input) and convert it # to an age recipient the same way; kept in one place so the two can't # drift apart. diff --git a/scripts/configure-nix-cache-client.sh b/scripts/proxmox/configure-nix-cache-client.sh similarity index 100% rename from scripts/configure-nix-cache-client.sh rename to scripts/proxmox/configure-nix-cache-client.sh diff --git a/scripts/create-proxmox-resource.sh b/scripts/proxmox/create-proxmox-resource.sh similarity index 98% rename from scripts/create-proxmox-resource.sh rename to scripts/proxmox/create-proxmox-resource.sh index 33c2a4a..891c7d0 100755 --- a/scripts/create-proxmox-resource.sh +++ b/scripts/proxmox/create-proxmox-resource.sh @@ -13,9 +13,9 @@ # alone wouldn't carry it) before building. # # Usage: -# scripts/create-proxmox-resource.sh --type lxc|vm --host [options] -# scripts/create-proxmox-resource.sh --type lxc|vm --list -# scripts/create-proxmox-resource.sh --modify --vmid [--cores N] [--memory MB] [--grow-disk GB] +# scripts/proxmox/create-proxmox-resource.sh --type lxc|vm --host [options] +# scripts/proxmox/create-proxmox-resource.sh --type lxc|vm --list +# scripts/proxmox/create-proxmox-resource.sh --modify --vmid [--cores N] [--memory MB] [--grow-disk GB] # # SAFETY: # - The default (create) mode only ever creates a NEW resource -- it @@ -41,15 +41,15 @@ # See --help for the full option list. set -euo pipefail -repo_root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=env.sh +repo_root="$(cd "$(dirname "$0")/../.." && pwd)" +# shellcheck source=../env.sh source "${repo_root}/scripts/env.sh" -# shellcheck source=lib/nix-eval.sh +# shellcheck source=../lib/nix-eval.sh source "${repo_root}/scripts/lib/nix-eval.sh" -# shellcheck source=lib/confirm.sh +# shellcheck source=../lib/confirm.sh source "${repo_root}/scripts/lib/confirm.sh" -sync_keys="${repo_root}/scripts/sync-host-keys.sh" +sync_keys="${repo_root}/scripts/secrets/sync-host-keys.sh" usage() { cat < Ensuring ${remote_repo_dir} exists and is current on ${node}..." if [[ "$dry_run" -eq 1 ]]; then - echo "[dry-run] would ensure ${remote_repo_dir} exists on ${node} (clone if missing, git pull if present), and would verify/bootstrap build tooling there (scripts/codex-setup.sh) if \`nix\` isn't already on PATH -- and if that bootstrap actually ran, would also configure ${node} as a nix-cache client (scripts/configure-nix-cache-client.sh)" + echo "[dry-run] would ensure ${remote_repo_dir} exists on ${node} (clone if missing, git pull if present), and would verify/bootstrap build tooling there (scripts/codex-setup.sh) if \`nix\` isn't already on PATH -- and if that bootstrap actually ran, would also configure ${node} as a nix-cache client (scripts/proxmox/configure-nix-cache-client.sh)" return fi @@ -583,7 +583,7 @@ ensure_remote_repo() { # above -- ssh's non-interactive command execution won't have picked # up a freshly single-user-installed `nix` otherwise. echo "==> Configuring ${node} as a nix-cache substituter/remote-builder client..." - if ! ssh "$ssh_target" "cd '${remote_repo_dir}' && . scripts/lib/nix-bootstrap.sh && ensure_nix_profile && bash scripts/configure-nix-cache-client.sh"; then + if ! ssh "$ssh_target" "cd '${remote_repo_dir}' && . scripts/lib/nix-bootstrap.sh && ensure_nix_profile && bash scripts/proxmox/configure-nix-cache-client.sh"; then echo "WARNING: configure-nix-cache-client.sh failed on ${node} -- continuing without it (${node} will build from source / against cache.nixos.org only)." >&2 fi fi diff --git a/scripts/backup-admin-key.sh b/scripts/secrets/backup-admin-key.sh similarity index 94% rename from scripts/backup-admin-key.sh rename to scripts/secrets/backup-admin-key.sh index 007643f..5178f48 100755 --- a/scripts/backup-admin-key.sh +++ b/scripts/secrets/backup-admin-key.sh @@ -6,7 +6,7 @@ # copy is ever lost, or to run either script from a different machine. # # Usage: -# scripts/backup-admin-key.sh [--key-file ] [--force] [--dry-run] +# scripts/secrets/backup-admin-key.sh [--key-file ] [--force] [--dry-run] # # Source key resolution matches sops/age's own default order: # $SOPS_AGE_KEY (inline identity text) if set, else @@ -15,12 +15,12 @@ # ${XDG_CONFIG_HOME:-$HOME/.config}/sops/age/keys.txt set -euo pipefail -repo_root="$(cd "$(dirname "$0")/.." && pwd)" +repo_root="$(cd "$(dirname "$0")/../.." && pwd)" sops_yaml="${repo_root}/.sops.yaml" -# shellcheck source=env.sh +# shellcheck source=../env.sh source "${repo_root}/scripts/env.sh" -# shellcheck source=lib/sops-age.sh +# shellcheck source=../lib/sops-age.sh source "${repo_root}/scripts/lib/sops-age.sh" # Pin cwd for the same reason rotate-admin-key.sh does: age/sops calls @@ -146,5 +146,5 @@ Done. Backed up to: ${dest} This is a private key -- store it somewhere offline/secure, not in this repo or anywhere it'd get committed. Restore it with: - scripts/rotate-admin-key.sh ${dest} + scripts/secrets/rotate-admin-key.sh ${dest} EOF diff --git a/scripts/prepare-host-key.sh b/scripts/secrets/prepare-host-key.sh similarity index 91% rename from scripts/prepare-host-key.sh rename to scripts/secrets/prepare-host-key.sh index fb311ca..a148cf0 100755 --- a/scripts/prepare-host-key.sh +++ b/scripts/secrets/prepare-host-key.sh @@ -2,7 +2,7 @@ # Generates a new machine's SSH host key by an arbitrary name, before it # necessarily has a flake target yet -- prints the .sops.yaml snippet to # add by hand. For any host that already has a flake target, -# scripts/sync-host-keys.sh does this same job plus the +# scripts/secrets/sync-host-keys.sh does this same job plus the # .sops.yaml/key_groups registration and re-encryption automatically; use # this script only to pre-generate a key ahead of adding the flake target # itself. @@ -22,13 +22,13 @@ # new machine. set -euo pipefail -repo_root="$(cd "$(dirname "$0")/.." && pwd)" -# shellcheck source=env.sh +repo_root="$(cd "$(dirname "$0")/../.." && pwd)" +# shellcheck source=../env.sh source "${repo_root}/scripts/env.sh" -# shellcheck source=lib/ssh-host-keys.sh +# shellcheck source=../lib/ssh-host-keys.sh source "${repo_root}/scripts/lib/ssh-host-keys.sh" -hostname="${1:?usage: scripts/prepare-host-key.sh }" +hostname="${1:?usage: scripts/secrets/prepare-host-key.sh }" sops_yaml="${repo_root}/.sops.yaml" if [[ ! -f "$sops_yaml" ]]; then diff --git a/scripts/rotate-admin-key.sh b/scripts/secrets/rotate-admin-key.sh similarity index 97% rename from scripts/rotate-admin-key.sh rename to scripts/secrets/rotate-admin-key.sh index bfcda23..cd5358b 100755 --- a/scripts/rotate-admin-key.sh +++ b/scripts/secrets/rotate-admin-key.sh @@ -10,7 +10,7 @@ # sync-host-keys.sh print when they bootstrap a brand-new, not-yet-trusted # age key on a machine that's never had admin access before: # -# scripts/rotate-admin-key.sh /path/to/backed-up/admin/keys.txt +# scripts/secrets/rotate-admin-key.sh /path/to/backed-up/admin/keys.txt # # The backup key's *public* key must match .sops.yaml's current &admin # entry -- this script verifies that by deriving it, it doesn't just trust @@ -19,12 +19,12 @@ # the common case is just pointing this at the restored backup. set -euo pipefail -repo_root="$(cd "$(dirname "$0")/.." && pwd)" +repo_root="$(cd "$(dirname "$0")/../.." && pwd)" sops_yaml="${repo_root}/.sops.yaml" -# shellcheck source=env.sh +# shellcheck source=../env.sh source "${repo_root}/scripts/env.sh" -# shellcheck source=lib/sops-age.sh +# shellcheck source=../lib/sops-age.sh source "${repo_root}/scripts/lib/sops-age.sh" # sops resolves .sops.yaml by walking up from the process's cwd, not from diff --git a/scripts/sync-host-keys.sh b/scripts/secrets/sync-host-keys.sh similarity index 98% rename from scripts/sync-host-keys.sh rename to scripts/secrets/sync-host-keys.sh index 9834706..eda2915 100755 --- a/scripts/sync-host-keys.sh +++ b/scripts/secrets/sync-host-keys.sh @@ -24,20 +24,20 @@ # ever touches keys it itself manages. set -euo pipefail -repo_root="$(cd "$(dirname "$0")/.." && pwd)" +repo_root="$(cd "$(dirname "$0")/../.." && pwd)" sops_yaml="${repo_root}/.sops.yaml" keydir="${repo_root}/host-keys" editor="${repo_root}/scripts/lib/sync-host-keys-edit-sops.py" -# shellcheck source=env.sh +# shellcheck source=../env.sh source "${repo_root}/scripts/env.sh" -# shellcheck source=lib/nix-eval.sh +# shellcheck source=../lib/nix-eval.sh source "${repo_root}/scripts/lib/nix-eval.sh" -# shellcheck source=lib/ssh-host-keys.sh +# shellcheck source=../lib/ssh-host-keys.sh source "${repo_root}/scripts/lib/ssh-host-keys.sh" -# shellcheck source=lib/sops-age.sh +# shellcheck source=../lib/sops-age.sh source "${repo_root}/scripts/lib/sops-age.sh" -# shellcheck source=lib/confirm.sh +# shellcheck source=../lib/confirm.sh source "${repo_root}/scripts/lib/confirm.sh" mkdir -p "$keydir"