diff --git a/deployment/proxmox/provision.sh b/deployment/proxmox/provision.sh index 30f5f6fc..6daadbae 100755 --- a/deployment/proxmox/provision.sh +++ b/deployment/proxmox/provision.sh @@ -46,7 +46,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 @@ -61,7 +62,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 @@ -71,7 +72,7 @@ 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 @@ -103,35 +104,48 @@ readonly ticket=$(echo "$response" | jq -r .data.ticket) readonly csrfToken=$(echo "$response" | jq -r .data.CSRFPreventionToken) printf ' done.\n' +acquire_lock () { + until mkdir $tmpdir/lock-$1 2>/dev/null; do sleep 1; done +} +release_lock () { + rmdir $tmpdir/lock-$1 +} + proxmox () { + acquire_lock proxmox http \ --form \ --verify no \ + --ignore-stdin \ "$@" \ "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 () { +proxmox_sync () ( response=$(proxmox "$@") upid=$(echo "$response" | jq -r .data) + while :; do response=$(proxmox GET $apiurl/nodes/$node/tasks/$upid/status) status=$(echo "$response" | jq -r .data.status) + case $status in running) sleep 1 ;; stopped) break ;; *) die 'unexpected status: `%s`' "$status" ;; esac done -} +) ################################################################################ ## Build ISO build_iso () { + acquire_lock build printf 'Building ISO for VM %d...\n' $1 nix build \ @@ -142,12 +156,14 @@ build_iso () { ln -sf $tmpdir/installer-fedi$1/iso/installer.iso $tmpdir/installer-fedi$1.iso printf 'done building ISO for VM %d.\n' $1 + release_lock build } ################################################################################ ## Upload ISO upload_iso () { + acquire_lock upload printf 'Uploading ISO for VM %d...\n' $1 proxmox_sync POST $apiurl/nodes/$node/storage/local/upload \ @@ -155,6 +171,7 @@ upload_iso () { content==iso printf 'done uploading ISO for VM %d.\n' $1 + release_lock upload } ################################################################################ @@ -201,7 +218,7 @@ create_vm () { ################################################################################ ## Install VM -install_vm () { +install_vm () ( printf 'Installing VM %d...\n' $1 proxmox_sync POST $apiurl/nodes/$node/qemu/$1/status/start @@ -217,7 +234,7 @@ install_vm () { done printf 'done installing VM %d.\n' $1 -} +) ################################################################################ ## Start VM @@ -252,8 +269,9 @@ provision_vm () { } for vmid in $vmids; do - provision_vm $vmid + provision_vm $vmid & done +wait printf 'done provisioning VMs%s.\n' "$vmids"