Archived
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ba9b141fe | ||
|
|
a5308a7ee5 | ||
|
|
7b4794211d |
+43
-33
@@ -14,8 +14,8 @@
|
|||||||
# "nix-collect-garbage -d" if sudo needs a password — still collects
|
# "nix-collect-garbage -d" if sudo needs a password — still collects
|
||||||
# unreferenced store paths and old nixos-user profile generations, but leaves
|
# unreferenced store paths and old nixos-user profile generations, but leaves
|
||||||
# old system generations in place.
|
# old system generations in place.
|
||||||
# pve1: runs "nix-collect-garbage -d" as the login user (no system generations
|
# pve1: runs "bash -l -c nix-collect-garbage -d" as the login user so
|
||||||
# on a non-NixOS host).
|
# /etc/profile is sourced and the Nix daemon's PATH is set up automatically.
|
||||||
#
|
#
|
||||||
# Usage (from repo root):
|
# Usage (from repo root):
|
||||||
# bash scripts/gc-hosts.sh [--dry-run]
|
# bash scripts/gc-hosts.sh [--dry-run]
|
||||||
@@ -30,7 +30,12 @@ source scripts/lib/nix-eval.sh 2>/dev/null || true
|
|||||||
: "${MAX_JOBS:=8}"
|
: "${MAX_JOBS:=8}"
|
||||||
: "${NIXOS_USER:=nixos}"
|
: "${NIXOS_USER:=nixos}"
|
||||||
: "${PVE1_SSH_USER:=${PROXMOX_SSH_USER:-wayne}}"
|
: "${PVE1_SSH_USER:=${PROXMOX_SSH_USER:-wayne}}"
|
||||||
|
|
||||||
|
# GC connections use BatchMode — no interactive prompts, just succeed or fail.
|
||||||
SSH_OPTS=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=10)
|
SSH_OPTS=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=10)
|
||||||
|
# Discovery connections do NOT use BatchMode so that sudo can prompt if needed
|
||||||
|
# (pct/qm list require root access on Proxmox).
|
||||||
|
SSH_QUERY_OPTS=(-o StrictHostKeyChecking=no -o ConnectTimeout=10)
|
||||||
|
|
||||||
DRY_RUN=0
|
DRY_RUN=0
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
@@ -44,7 +49,7 @@ done
|
|||||||
|
|
||||||
# ORDERED_HOSTS: names in display/execution order.
|
# ORDERED_HOSTS: names in display/execution order.
|
||||||
# HOST_TARGET[name]: SSH target string (user@host).
|
# HOST_TARGET[name]: SSH target string (user@host).
|
||||||
# HOST_TYPE[name]: "nixos" (try sudo gc, fallback user) | "nix" (user gc only).
|
# HOST_TYPE[name]: "nixos" (try sudo gc, fallback user) | "nix" (login-shell gc).
|
||||||
declare -a ORDERED_HOSTS=()
|
declare -a ORDERED_HOSTS=()
|
||||||
declare -A HOST_TARGET=()
|
declare -A HOST_TARGET=()
|
||||||
declare -A HOST_TYPE=()
|
declare -A HOST_TYPE=()
|
||||||
@@ -66,42 +71,47 @@ _add_host "nixos" "${NIXOS_USER}@nixos" "nixos"
|
|||||||
_add_host "pve1" "${PVE1_SSH_USER}@${PVE1_HOST}" "nix"
|
_add_host "pve1" "${PVE1_SSH_USER}@${PVE1_HOST}" "nix"
|
||||||
|
|
||||||
# 3. Dynamically discover running NixOS guests on pve1
|
# 3. Dynamically discover running NixOS guests on pve1
|
||||||
|
#
|
||||||
|
# create-proxmox-resource.sh names every guest after its NixOS hostname:
|
||||||
|
# pct create ... --hostname <nixos-hostname> (LXC)
|
||||||
|
# qm create ... --name <nixos-hostname> (VM)
|
||||||
|
# So pct/qm list output already contains the NixOS hostname directly.
|
||||||
|
# We validate against the flake to filter out non-NixOS guests on pve1
|
||||||
|
# (e.g. FreeIPA, Proxmox Backup Server) that share the same Proxmox node.
|
||||||
echo "Discovering running guests on ${PVE1_HOST}..."
|
echo "Discovering running guests on ${PVE1_HOST}..."
|
||||||
|
|
||||||
# Evaluate the full flake hostname map in one shot.
|
# Eval the flake once to get the set of hostnames that are actually NixOS.
|
||||||
hostname_map="{}"
|
# Values are NixOS hostnames (e.g. "docker"); keys are flake targets ("lxc-docker").
|
||||||
if ! hostname_map="$(
|
nixos_hostnames=""
|
||||||
|
nixos_hostnames="$(
|
||||||
nix eval --json "${NIX_EVAL_FLAGS[@]}" .#nixosConfigurations \
|
nix eval --json "${NIX_EVAL_FLAGS[@]}" .#nixosConfigurations \
|
||||||
--apply 'cfgs: builtins.mapAttrs (_: cfg: cfg.config.networking.hostName) cfgs' \
|
--apply 'cfgs: builtins.attrValues (builtins.mapAttrs (_: cfg: cfg.config.networking.hostName) cfgs)' \
|
||||||
2>/dev/null
|
2>/dev/null | jq -r '.[]' | sort -u
|
||||||
)"; then
|
)" || { echo " warning: flake eval failed — non-NixOS guests will not be filtered" >&2; }
|
||||||
echo " warning: flake eval failed — skipping dynamic host discovery" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get names of all currently running guests from pve1.
|
# SSH_QUERY_OPTS (no BatchMode) so sudo can prompt if needed for pct/qm.
|
||||||
if ssh "${SSH_OPTS[@]}" "${PVE1_SSH_USER}@${PVE1_HOST}" "true" 2>/dev/null; then
|
if ssh "${SSH_QUERY_OPTS[@]}" "${PVE1_SSH_USER}@${PVE1_HOST}" "true" 2>/dev/null; then
|
||||||
running_guests="$(
|
running_guests="$(
|
||||||
ssh "${SSH_OPTS[@]}" "${PVE1_SSH_USER}@${PVE1_HOST}" bash <<'REMOTE'
|
ssh "${SSH_QUERY_OPTS[@]}" "${PVE1_SSH_USER}@${PVE1_HOST}" bash -s <<'DISCOVER'
|
||||||
{ sudo pct list 2>/dev/null | awk 'NR>1 && $2=="running" { print $NF }';
|
sudo pct list 2>/dev/null | awk 'NR>1 && $2=="running" { print $NF }'
|
||||||
sudo qm list 2>/dev/null | awk 'NR>1 && $3=="running" { print $2 }'; } | sort -u
|
sudo qm list 2>/dev/null | awk 'NR>1 && $3=="running" { print $2 }'
|
||||||
REMOTE
|
DISCOVER
|
||||||
)" || running_guests=""
|
)" || running_guests=""
|
||||||
|
|
||||||
while IFS= read -r guest; do
|
while IFS= read -r hostname; do
|
||||||
[[ -z "$guest" ]] && continue
|
|
||||||
|
|
||||||
# Resolve flake target name → NixOS hostname.
|
|
||||||
hostname="$(printf '%s' "$hostname_map" \
|
|
||||||
| jq -r --arg g "$guest" '.[$g] // empty' 2>/dev/null || true)"
|
|
||||||
[[ -z "$hostname" ]] && continue
|
[[ -z "$hostname" ]] && continue
|
||||||
|
# Exclude nix-cache.
|
||||||
# Exclude nix-cache and any target whose hostname is already in our list.
|
case "$hostname" in *nix-cache*) continue ;; esac
|
||||||
case "$hostname" in nix-cache) continue ;; esac
|
# Skip if not a flake-managed NixOS host (filters non-NixOS pve1 guests).
|
||||||
|
if [[ -n "$nixos_hostnames" ]] && ! grep -qxF "$hostname" <<< "$nixos_hostnames"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Skip if already in the list (e.g. a proxmox-gui guest whose hostname is nixos).
|
||||||
if [[ -n "${_SEEN_HOSTNAMES[$hostname]+_}" ]]; then continue; fi
|
if [[ -n "${_SEEN_HOSTNAMES[$hostname]+_}" ]]; then continue; fi
|
||||||
|
|
||||||
echo " + $guest → $hostname"
|
echo " + $hostname"
|
||||||
_add_host "$hostname" "${NIXOS_USER}@${hostname}" "nixos"
|
_add_host "$hostname" "${NIXOS_USER}@${hostname}" "nixos"
|
||||||
done <<< "$running_guests"
|
done <<< "$(echo "$running_guests" | sort -u)"
|
||||||
else
|
else
|
||||||
echo " warning: ${PVE1_HOST} unreachable — skipping dynamic host discovery" >&2
|
echo " warning: ${PVE1_HOST} unreachable — skipping dynamic host discovery" >&2
|
||||||
fi
|
fi
|
||||||
@@ -121,7 +131,7 @@ if [[ "$DRY_RUN" -eq 1 ]]; then
|
|||||||
echo " ssh ${SSH_OPTS[*]} $target 'sudo -n nix-collect-garbage -d'"
|
echo " ssh ${SSH_OPTS[*]} $target 'sudo -n nix-collect-garbage -d'"
|
||||||
echo " # fallback: ssh ... $target 'nix-collect-garbage -d'"
|
echo " # fallback: ssh ... $target 'nix-collect-garbage -d'"
|
||||||
else
|
else
|
||||||
echo " ssh ${SSH_OPTS[*]} $target '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix-collect-garbage -d'"
|
echo " ssh ${SSH_OPTS[*]} $target 'bash -l -c nix-collect-garbage -d'"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
exit 0
|
exit 0
|
||||||
@@ -147,10 +157,10 @@ gc_one() {
|
|||||||
echo "ok(user)"; return
|
echo "ok(user)"; return
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Non-NixOS node: BatchMode SSH doesn't source the Nix daemon profile, so
|
# Non-NixOS node: use a login shell so /etc/profile is sourced and the
|
||||||
# nix-collect-garbage won't be on PATH unless we source it explicitly.
|
# Nix daemon's bin dir is on PATH (set up by /etc/profile.d/nix-daemon.sh
|
||||||
local nix_profile='. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh 2>/dev/null || true'
|
# which the Nix installer adds to /etc/profile).
|
||||||
if ssh "${SSH_OPTS[@]}" "$target" "$nix_profile && nix-collect-garbage -d" \
|
if ssh "${SSH_OPTS[@]}" "$target" "bash -l -c 'nix-collect-garbage -d'" \
|
||||||
>>"$logfile" 2>>"$logfile"; then
|
>>"$logfile" 2>>"$logfile"; then
|
||||||
echo "ok"; return
|
echo "ok"; return
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -58,7 +58,6 @@
|
|||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZ9WKKAlP9Z7GQdgaZ1Xgw9C+vja2lqEZO5rJFpVqYN root@ha-server-1"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZ9WKKAlP9Z7GQdgaZ1Xgw9C+vja2lqEZO5rJFpVqYN root@ha-server-1"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEGNKlaaMckd8nLWNGz4B2QokXjnnIvM+rEUv+R6h0sp root@ha-server-2"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEGNKlaaMckd8nLWNGz4B2QokXjnnIvM+rEUv+R6h0sp root@ha-server-2"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+XeMco7OxUpjrjZm54HogMs9QB5xlcKmElASRvrmlW root@nixos"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+XeMco7OxUpjrjZm54HogMs9QB5xlcKmElASRvrmlW root@nixos"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMseQwPpmaa6cgV5U8KhUsiVSYARG85zGa9rho0LJWks wayne@pve1"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Admin SSH public key, authorized on the primary user of every host and
|
# Admin SSH public key, authorized on the primary user of every host and
|
||||||
|
|||||||
Reference in New Issue
Block a user