From cd47d884f78fc629050264d08706f41cb16b9879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=E2=80=9CNiols=E2=80=9D=20Jeannerod?= <nicolas.jeannerod@moduscreate.com> Date: Mon, 24 Feb 2025 17:18:49 +0100 Subject: [PATCH] Cleaner grabing of options --- infra/proxmox-provision.sh | 145 ++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 59 deletions(-) diff --git a/infra/proxmox-provision.sh b/infra/proxmox-provision.sh index be433849..b92097f2 100755 --- a/infra/proxmox-provision.sh +++ b/infra/proxmox-provision.sh @@ -158,34 +158,65 @@ proxmox_sync () ( ) ################################################################################ -## Grab VM option +## Grab VM options ## -## Takes the name of the VM and an option and grabs `vmOptions.<name>.<option>` -## in the flake. +## Takes the name of the VM, grabs `.#vmOptions.<name>` and defines a bunch of +## global variables corresponding to all the options. -grab_vm_option () { - nix eval \ - --impure --raw --expr " - builtins.toJSON (builtins.getFlake (builtins.toString ./.)).vmOptions.$1 - " | jq -r ."$2" +grab_vm_options () { + local options + + vm_name=$1 + + printf 'Grabing VM options for VM %s...\n' "$vm_name" + + options=$( + nix eval \ + --impure --raw --expr " + builtins.toJSON (builtins.getFlake (builtins.toString ./.)).vmOptions.$vm_name + " \ + --log-format raw --quiet + ) + + proxmox=$(echo "$options" | jq -r .proxmox) + vm_id=$(echo "$options" | jq -r .vmId) + + if [ "$proxmox" != fediversity ]; then + die "I do not know how to provision things that are not Fediversity VMs, +but I got proxmox = '%s' for VM %s." "$proxmox" "$vm_name" + fi + + sockets=$(echo "$options" | jq -r .sockets) + cores=$(echo "$options" | jq -r .cores) + memory=$(echo "$options" | jq -r .memory) + + host_public_key=$(echo "$options" | jq -r .hostPublicKey) + host_private_key=$(echo "$options" | jq -r .unsafeHostPrivateKey) + + if [ "$host_private_key" != null ] && [ "$host_public_key" = null ]; then + die 'I do not know what to do with a private key but no public key.' + fi + + printf 'done grabing VM options for VM %s. Got:\n id: %d\n sockets: %d\n cores: %d\n memory: %d MiB\n' \ + "$vm_name" "$vm_id" "$sockets" "$cores" "$memory" } ################################################################################ ## Build ISO build_iso () { - acquire_lock build - printf 'Building ISO for VM %s...\n' "$2" + local nix_host_keys - host_public_key=$(grab_vm_option "$2" hostPublicKey) - host_private_key=$(grab_vm_option "$2" unsafeHostPrivateKey) - if [ "$host_public_key" != null ] && [ "$host_private_key" != null ]; then - echo "$host_public_key" > "$tmpdir"/"$2"_host_key.pub - echo "$host_private_key" > "$tmpdir"/"$2"_host_key + acquire_lock build + printf 'Building ISO for VM %s...\n' "$vm_name" + + if [ "$host_private_key" != null ]; then + echo "$host_public_key" > "$tmpdir"/"$vm_name"_host_key.pub + echo "$host_private_key" > "$tmpdir"/"$vm_name"_host_key nix_host_keys=" hostKeys.ed25519 = { - public = $tmpdir/$2_host_key.pub; - private = $tmpdir/$2_host_key; + public = $tmpdir/${vm_name}_host_key.pub; + private = $tmpdir/${vm_name}_host_key; }; " else @@ -196,23 +227,23 @@ build_iso () { --impure --expr " let flake = builtins.getFlake (builtins.toString ./.); in flake.lib.makeInstallerIso { - nixosConfiguration = flake.nixosConfigurations.$2; + nixosConfiguration = flake.nixosConfigurations.$vm_name; nixpkgs = flake.inputs.nixpkgs; $nix_host_keys } " \ --log-format raw --quiet \ - --out-link "$tmpdir/installer-$2" + --out-link "$tmpdir/installer-$vm_name" if [ $? -ne 0 ]; then die 'Something went wrong when building ISO for VM %s. Check the Nix logs and fix things. Possibly there just is no NixOS configuration by that name?' \ - "$2" + "$vm_name" fi - ln -sf "$tmpdir/installer-$2/iso/installer.iso" "$tmpdir/installer-$2.iso" + ln -sf "$tmpdir/installer-$vm_name/iso/installer.iso" "$tmpdir/installer-$vm_name.iso" - printf 'done building ISO for VM %s.\n' "$2" + printf 'done building ISO for VM %s.\n' "$vm_name" release_lock build } @@ -221,13 +252,13 @@ Check the Nix logs and fix things. Possibly there just is no NixOS configuration upload_iso () { acquire_lock upload - printf 'Uploading ISO for VM %s...\n' "$2" + printf 'Uploading ISO for VM %s...\n' "$vm_name" proxmox_sync POST "$api_url/nodes/$node/storage/local/upload" \ - "filename@$tmpdir/installer-$2.iso" \ + "filename@$tmpdir/installer-$vm_name.iso" \ content==iso - printf 'done uploading ISO for VM %s.\n' "$2" + printf 'done uploading ISO for VM %s.\n' "$vm_name" release_lock upload } @@ -235,26 +266,26 @@ upload_iso () { ## Remove ISO remove_iso () { - printf 'Removing ISO for VM %s...\n' "$2" + printf 'Removing ISO for VM %s...\n' "$vm_name" - proxmox_sync DELETE "$api_url/nodes/$node/storage/local/content/local:iso/installer-$2.iso" + proxmox_sync DELETE "$api_url/nodes/$node/storage/local/content/local:iso/installer-$vm_name.iso" - printf 'done removing ISO for VM %s.\n' "$2" + printf 'done removing ISO for VM %s.\n' "$vm_name" } ################################################################################ ## Create VM create_vm () { - printf 'Creating VM %s with id %d...\n' "$2" "$1" + printf 'Creating VM %s...\n' "$vm_name" proxmox_sync POST "$api_url/nodes/$node/qemu" \ \ - vmid=="$1" \ - name=="$2" \ + vmid=="$vm_id" \ + name=="$vm_name" \ pool==Fediversity \ \ - ide2=="local:iso/installer-$2.iso,media=cdrom" \ + ide2=="local:iso/installer-$vm_name.iso,media=cdrom" \ ostype==l26 \ \ bios==ovmf \ @@ -264,28 +295,28 @@ create_vm () { scsihw==virtio-scsi-single \ scsi0=='linstor_storage:32,discard=on,ssd=on,iothread=on' \ \ - sockets=="$(grab_vm_option "$2" sockets)" \ - cores=="$(grab_vm_option "$2" cores)" \ + sockets=="$sockets" \ + cores=="$cores" \ cpu==x86-64-v2-AES \ numa==1 \ \ - memory=="$(grab_vm_option "$2" memory)" \ + memory=="$memory" \ \ net0=='virtio,bridge=vnet1306' - printf 'done creating VM %s.\n' "$2" + printf 'done creating VM %s.\n' "$vm_name" } ################################################################################ ## Install VM install_vm () ( - printf 'Installing VM %s...\n' "$2" + printf 'Installing VM %s...\n' "$vm_name" - proxmox_sync POST "$api_url/nodes/$node/qemu/$1/status/start" + proxmox_sync POST "$api_url/nodes/$node/qemu/$vm_id/status/start" while :; do - response=$(proxmox GET "$api_url/nodes/$node/qemu/$1/status/current") + response=$(proxmox GET "$api_url/nodes/$node/qemu/$vm_id/status/current") status=$(echo "$response" | jq -r .data.status) case $status in running) sleep 1 ;; @@ -294,22 +325,22 @@ install_vm () ( esac done - printf 'done installing VM %s.\n' "$2" + printf 'done installing VM %s.\n' "$vm_name" ) ################################################################################ ## Start VM start_vm () { - printf 'Starting VM %s...\n' "$2" + printf 'Starting VM %s...\n' "$vm_name" - proxmox_sync POST "$api_url/nodes/$node/qemu/$1/config" \ + proxmox_sync POST "$api_url/nodes/$node/qemu/$vm_id/config" \ ide2=='none,media=cdrom' \ net0=='virtio,bridge=vnet1305' - proxmox_sync POST "$api_url/nodes/$node/qemu/$1/status/start" + proxmox_sync POST "$api_url/nodes/$node/qemu/$vm_id/status/start" - printf 'done starting VM %s.\n' "$2" + printf 'done starting VM %s.\n' "$vm_name" } ################################################################################ @@ -318,24 +349,20 @@ start_vm () { printf 'Provisioning VMs%s...\n' "$vm_names" provision_vm () ( - ## NOTE: Mind the fact that we now run in a sub-shell, allowing the following - ## functions to define global variables without clashing with concurrent VMs - ## provisioning. - - build_iso "$@" - upload_iso "$@" - create_vm "$@" - install_vm "$@" - start_vm "$@" - remove_iso "$@" + ## Grab VM options and put them in global variables. NOTE: Mind the fact that + ## we now run in a sub-shell, allowing us to define global variables without + ## clashing with concurrent executions of `provision_vm`. + grab_vm_options "$1" + build_iso + upload_iso + create_vm + install_vm + start_vm + remove_iso ) for vm_name in $vm_names; do - vm_id=$(grab_vm_option "$vm_name" vmId) - if [ "$(grab_vm_option "$vm_name" proxmox)" != fediversity ]; then - die 'This script does not know how to provision things that are not Fediversity VMs' - fi - provision_vm "$vm_id" "$vm_name" & + provision_vm "$vm_name" & done wait