Add emergency Hetzner shutdown script
This commit is contained in:
parent
5462b0adab
commit
e26c3ecc1e
2 changed files with 119 additions and 0 deletions
|
|
@ -118,6 +118,16 @@ flowchart TB
|
|||
<li>Session auth: signed JWT cookie <code>session_token</code>; roles: USER, ADMIN, USER_MODERATOR, LISTING_MODERATOR.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Emergency shutdown</h2>
|
||||
<ul>
|
||||
<li>Script: <code>scripts/emergency-shutdown.sh</code> issues Hetzner poweroff/shutdown commands for tracked nodes (currently <code>node1.lomavuokraus.fi</code> and <code>db1.lomavuokraus.fi</code>).</li>
|
||||
<li>List tracked nodes: <code>./scripts/emergency-shutdown.sh --list</code>.</li>
|
||||
<li>Hard stop everything: <code>./scripts/emergency-shutdown.sh --yes --confirm "SHUTDOWN ALL LOMAVUOKRAUS NODES NOW"</code> (default action is <code>poweroff</code>; use <code>--action shutdown</code> for ACPI).</li>
|
||||
<li>Requires <code>hcloud</code> CLI with <code>HCLOUD_TOKEN</code> or configured at <code>~/.config/hcloud/cli.toml</code>; keep the node list updated when adding servers.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
|
|
|
|||
109
scripts/emergency-shutdown.sh
Executable file
109
scripts/emergency-shutdown.sh
Executable file
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Emergency hard power-off for all lomavuokraus Hetzner nodes.
|
||||
# Keep the NODES list up to date when adding/removing servers so this script
|
||||
# always covers every host.
|
||||
|
||||
NODES=(
|
||||
"node1.lomavuokraus.fi|k3s + ingress + app workloads"
|
||||
"db1.lomavuokraus.fi|PostgreSQL"
|
||||
)
|
||||
|
||||
CONFIRM_PHRASE="SHUTDOWN ALL LOMAVUOKRAUS NODES NOW"
|
||||
HCLOUD_BIN="${HCLOUD_BIN:-hcloud}"
|
||||
ACTION="poweroff" # poweroff = immediate; shutdown = ACPI (softer)
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [--yes] [--confirm "${CONFIRM_PHRASE}"] [--action poweroff|shutdown] [--list]
|
||||
|
||||
Options:
|
||||
--list List tracked nodes and exit.
|
||||
--action <mode> Either "poweroff" (default, immediate) or "shutdown" (soft ACPI).
|
||||
--yes Actually issue the command (otherwise dry-run).
|
||||
--confirm <phrase> Required confirmation phrase: "${CONFIRM_PHRASE}"
|
||||
|
||||
Env:
|
||||
HCLOUD_BIN Override hcloud binary path (default: hcloud)
|
||||
HCLOUD_TOKEN Hetzner API token (or ~/.config/hcloud/cli.toml)
|
||||
|
||||
Examples:
|
||||
$0 --list
|
||||
$0 --yes --confirm "${CONFIRM_PHRASE}"
|
||||
EOF
|
||||
}
|
||||
|
||||
log() {
|
||||
echo "[$(date +"%H:%M:%S")] $*"
|
||||
}
|
||||
|
||||
list_nodes() {
|
||||
log "Tracked nodes:"
|
||||
for entry in "${NODES[@]}"; do
|
||||
IFS="|" read -r name desc <<<"$entry"
|
||||
echo "- ${name}: ${desc}"
|
||||
done
|
||||
}
|
||||
|
||||
require_hcloud() {
|
||||
if ! command -v "$HCLOUD_BIN" >/dev/null 2>&1; then
|
||||
echo "hcloud CLI not found (HCLOUD_BIN=${HCLOUD_BIN}). Install it before running." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${HCLOUD_TOKEN:-}" && ! -f "${HOME}/.config/hcloud/cli.toml" ]]; then
|
||||
echo "HCLOUD_TOKEN not set and no CLI config found at ~/.config/hcloud/cli.toml." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
CONFIRM_INPUT=""
|
||||
DO_IT=0
|
||||
LIST_ONLY=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--yes) DO_IT=1 ;;
|
||||
--confirm) shift; CONFIRM_INPUT="${1:-}";;
|
||||
--action) shift; ACTION="${1:-poweroff}";;
|
||||
--list) LIST_ONLY=1 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Unknown argument: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ "$ACTION" != "poweroff" && "$ACTION" != "shutdown" ]]; then
|
||||
echo "Invalid action: ${ACTION}. Use poweroff or shutdown." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $LIST_ONLY -eq 1 ]]; then
|
||||
list_nodes
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Requested action: ${ACTION}"
|
||||
list_nodes
|
||||
|
||||
if [[ $DO_IT -ne 1 ]]; then
|
||||
log "Dry run only. Add --yes --confirm \"${CONFIRM_PHRASE}\" to execute."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${CONFIRM_INPUT}" != "${CONFIRM_PHRASE}" ]]; then
|
||||
echo "Confirmation phrase mismatch. Expected: \"${CONFIRM_PHRASE}\"." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_hcloud
|
||||
|
||||
for entry in "${NODES[@]}"; do
|
||||
IFS="|" read -r name desc <<<"$entry"
|
||||
log "Issuing ${ACTION} to ${name} (${desc})..."
|
||||
# poweroff is an immediate hard stop; shutdown attempts a graceful halt.
|
||||
"$HCLOUD_BIN" server "${ACTION}" "$name"
|
||||
done
|
||||
|
||||
log "All shutdown requests sent."
|
||||
Loading…
Add table
Reference in a new issue