From 94e535688637a9dbac0463760755c2d70124cf77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=E2=80=9CNiols=E2=80=9D=20Jeannerod?= Date: Thu, 14 Nov 2024 16:24:52 +0100 Subject: [PATCH] Parallelise removal script --- deployment/proxmox/remove.sh | 92 +++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 33 deletions(-) diff --git a/deployment/proxmox/remove.sh b/deployment/proxmox/remove.sh index 259eeb1..9564fae 100755 --- a/deployment/proxmox/remove.sh +++ b/deployment/proxmox/remove.sh @@ -11,6 +11,9 @@ readonly apiurl=https://192.168.51.81:8006/api2/json ## now, let us just use `node051` everywhere. readonly node=node051 +readonly tmpdir=/tmp/proxmox-provision-$RANDOM$RANDOM +mkdir $tmpdir + ################################################################################ ## Parse arguments @@ -35,7 +38,8 @@ Others: EOF } -die () { printf "$@"; printf '\n'; help; exit 2; } +die () { printf '\033[31m'; printf "$@"; printf '\033[0m\n'; exit 2; } +die_with_help () { printf '\033[31m'; printf "$@"; printf '\033[0m\n'; help; exit 2; } while [ $# -gt 0 ]; do argument=$1 @@ -46,7 +50,7 @@ while [ $# -gt 0 ]; do -h|-\?|--help) help; exit 0 ;; - -*) die 'Unknown argument: `%s`.' "$argument" ;; + -*) die_with_help 'Unknown argument: `%s`.' "$argument" ;; *) vmids="$vmids $argument" ;; esac @@ -56,15 +60,13 @@ if [ -z "$username" ] || [ -z "$password" ]; then if [ -f .proxmox ]; then { read username; read password; } < .proxmox else - die 'Required: `--username` and `--password`.\n' + die_with_help 'Required: `--username` and `--password`.\n' fi fi ################################################################################ ## Getting started -from_response () { echo "$response" | jq -r "$1"; } - printf 'Authenticating...' response=$( http \ @@ -73,65 +75,89 @@ response=$( "username=$username" \ "password=$password" ) -readonly csrfToken=$(from_response .data.CSRFPreventionToken) -readonly ticket=$(from_response .data.ticket) +readonly ticket=$(echo "$response" | jq -r .data.ticket) +readonly csrfToken=$(echo "$response" | jq -r .data.CSRFPreventionToken) printf ' done.\n' -proxmox () { - response=$( - http \ - --verify no \ - --form \ - "$@" \ - "Cookie:PVEAuthCookie=$ticket" \ - "CSRFPreventionToken:$csrfToken" - ) +acquire_lock () { + until mkdir $tmpdir/lock-$1 2>/dev/null; do sleep 1; done +} +release_lock () { + rmdir $tmpdir/lock-$1 } -wait_ () { - upid=$1 +proxmox () { + acquire_lock proxmox + http \ + --verify no \ + --form \ + "$@" \ + "Cookie:PVEAuthCookie=$ticket" \ + "CSRFPreventionToken:$csrfToken" + release_lock proxmox +} + +## Synchronous variant for when the `proxmox` function would just respond an +## UPID in the `data` JSON field. +proxmox_sync () ( + response=$(proxmox "$@") + upid=$(echo "$response" | jq -r .data) + while :; do - proxmox GET $apiurl/nodes/$node/tasks/$upid/status - status=$(from_response .data.status) + response=$(proxmox GET $apiurl/nodes/$node/tasks/$upid/status) + status=$(echo "$response" | jq -r .data.status) + case $status in - running) printf '.'; sleep 1 ;; + running) sleep 1 ;; stopped) break ;; - *) printf ' unexpected status: `%s`\n' "$status"; exit 2 ;; + *) die 'unexpected status: `%s`' "$status" ;; esac done -} +) ################################################################################ ## Stop VM stop_vm () { - printf 'Stopping VM %d...' $1 + printf 'Stopping VM %d...\n' $1 - proxmox POST $apiurl/nodes/$node/qemu/$1/status/stop \ + proxmox_sync POST $apiurl/nodes/$node/qemu/$1/status/stop \ 'overrule-shutdown'==1 - wait_ $(from_response .data) - printf ' done.\n' + printf 'done stopping VM %d.\n' $1 } ################################################################################ ## Delete VM delete_vm () { - printf 'Deleting VM %d...' $1 + printf 'Deleting VM %d...\n' $1 - proxmox DELETE $apiurl/nodes/$node/qemu/$1 \ + proxmox_sync DELETE $apiurl/nodes/$node/qemu/$1 \ 'destroy-unreferenced-disks'==1 \ 'purge'==1 - wait_ $(from_response .data) - printf ' done.\n' + printf 'done deleting VM %d.\n' $1 } ################################################################################ ## Main loop +printf 'Removing VMs%s...\n' "$vmids" + +remove_vm () { + stop_vm $1 + delete_vm $1 +} + for vmid in $vmids; do - stop_vm $vmid - delete_vm $vmid + remove_vm $vmid & done +wait + +printf 'done removing VMs%s.\n' "$vmids" + +################################################################################ +## Cleanup + +rm -Rf $tmpdir