From df46fbbf9b871858a3446e077fcc370fa1e8ede3 Mon Sep 17 00:00:00 2001 From: juvdiaz Date: Mon, 29 Jun 2026 13:11:34 -0600 Subject: [PATCH] Align nuke with worker topology state --- jeannie | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/jeannie b/jeannie index f270527..16962b2 100755 --- a/jeannie +++ b/jeannie @@ -3983,8 +3983,36 @@ rebuild_cluster() { cluster_worker_targets() { local worker_ssh_targets="${WORKER_SSH_TARGETS-}" + local var_file="${REPO_ROOT}/.lab/cluster-workers.auto.tfvars.json" + local worker_key_prefix="${LAB_PIMOX_WORKER_KEY_PREFIX:-pimox}" + CLUSTER_WORKER_TARGETS=() read -r -a CLUSTER_WORKER_TARGETS <<< "${worker_ssh_targets}" + + if [[ -s "${var_file}" ]] && command -v python3 >/dev/null 2>&1; then + while IFS= read -r target; do + [[ -n "${target}" ]] || continue + if [[ ! " ${CLUSTER_WORKER_TARGETS[*]} " =~ [[:space:]]${target}[[:space:]] ]]; then + CLUSTER_WORKER_TARGETS+=("${target}") + fi + done < <(python3 - "${var_file}" "${worker_key_prefix}" <<'PY' +import json +import sys + +var_file, worker_key_prefix = sys.argv[1:3] +with open(var_file, encoding="utf-8") as handle: + document = json.load(handle) + +for key, node in sorted((document.get("worker_nodes") or {}).items()): + if key.startswith(worker_key_prefix): + continue + host = node.get("host") + user = node.get("user") + if host and user: + print(f"{user}@{host}") +PY +) + fi } stop_local_kubernetes_services() { @@ -4144,6 +4172,50 @@ fi" done } +destroy_pimox_worker_vms() { + local pimox_host="${LAB_PIMOX_HOST:-${TF_VAR_pimox_host:-192.168.100.80}}" + local pimox_user="${LAB_PIMOX_USER:-${TF_VAR_pimox_user:-jv}}" + local pimox_key="${LAB_PIMOX_SSH_KEY_PATH:-${TF_VAR_pimox_ssh_key_path:-/home/jv/.ssh/id_ed25519}}" + local qm_bin="${LAB_PIMOX_QM_BIN:-${TF_VAR_pimox_qm_bin:-/usr/sbin/qm}}" + local worker_count="${LAB_PIMOX_WORKER_COUNT:-$(pimox_worker_count_default)}" + local worker_base_vmid="${LAB_PIMOX_WORKER_BASE_VMID:-9010}" + local worker_skip_indexes="${LAB_PIMOX_SKIP_WORKER_INDEXES:-}" + local index + local vmid + + if ! truthy "${LAB_NUKE_DESTROY_PIMOX_WORKERS:-true}"; then + echo "--> Leaving Pimox worker VMs intact because LAB_NUKE_DESTROY_PIMOX_WORKERS=${LAB_NUKE_DESTROY_PIMOX_WORKERS}." + return 0 + fi + if ! [[ "${worker_count}" =~ ^[0-9]+$ ]]; then + echo "LAB_PIMOX_WORKER_COUNT must be an integer, got '${worker_count}'." >&2 + exit 1 + fi + if ((worker_count == 0)); then + return 0 + fi + + echo "--> Destroying Pimox worker VMs on ${pimox_host}..." + for ((index = 1; index <= worker_count; index++)); do + if worker_index_is_skipped "${index}" "${worker_skip_indexes}"; then + echo "Skipping Pimox worker index ${index} because LAB_PIMOX_SKIP_WORKER_INDEXES=${worker_skip_indexes}." + continue + fi + vmid=$((worker_base_vmid + index - 1)) + pimox_ssh "${pimox_host}" "${pimox_user}" "${pimox_key}" "set -eu +if ! sudo '${qm_bin}' status '${vmid}' >/dev/null 2>&1; then + echo 'Pimox worker VM ${vmid} does not exist; skipping.' + exit 0 +fi +if sudo '${qm_bin}' config '${vmid}' | grep -q '^template: 1$'; then + echo 'Pimox VM ${vmid} is a template; refusing to destroy it as a worker.' >&2 + exit 1 +fi +sudo '${qm_bin}' stop '${vmid}' >/dev/null 2>&1 || true +sudo '${qm_bin}' destroy '${vmid}' --purge 1 >/dev/null 2>&1 || sudo '${qm_bin}' destroy '${vmid}'" + done +} + start_pimox_worker_vms() { local pimox_host="${LAB_PIMOX_HOST:-${TF_VAR_pimox_host:-192.168.100.80}}" local pimox_user="${LAB_PIMOX_USER:-${TF_VAR_pimox_user:-jv}}" @@ -4778,15 +4850,13 @@ EOF } nuke() { - local worker_ssh_targets - local worker_targets local target + declare -a CLUSTER_WORKER_TARGETS=() require_debian_server "nuke" echo "Brutally nuking the homelab infrastructure..." - worker_ssh_targets="${WORKER_SSH_TARGETS-}" - read -r -a worker_targets <<< "${worker_ssh_targets}" + cluster_worker_targets echo "--> Terminating local OpenTofu tasks..." killall tofu terraform 2>/dev/null || true @@ -4795,7 +4865,7 @@ nuke() { cleanup_node sudo rm -f "${KUBECONFIG_PATH}" - for target in "${worker_targets[@]}"; do + for target in "${CLUSTER_WORKER_TARGETS[@]}"; do echo "--> Eviscerating remote Kubernetes components (${target})..." if ! ssh -o ConnectTimeout=5 "${target}" "bash -s" <<'EOF' set -euo pipefail @@ -4897,6 +4967,8 @@ EOF fi done + destroy_pimox_worker_vms + docker buildx rm lab-builder 2>/dev/null || true docker rm -f buildx_buildkit_lab-builder0 2>/dev/null || true rm -f "${BUILDX_CONFIG}" || true @@ -4914,6 +4986,7 @@ EOF rm -rf "${REPO_ROOT}"/bootstrap/edge/terraform.tfstate* rm -f "${REPO_ROOT}"/bootstrap/edge/.terraform.tfstate.lock.info rm -rf "${REPO_ROOT}"/bootstrap/edge/.terraform/ + rm -f "${REPO_ROOT}/.lab/pimox-workers.tsv" "${REPO_ROOT}/.lab/cluster-workers.auto.tfvars.json" echo "Destruction complete. Retained data under /data/openebs/local was left intact." }