From 6fbda40e5eb11b181bf3c88d9a390d2a2491fc03 Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Thu, 14 Nov 2024 22:01:58 +0100 Subject: [PATCH] feat(scripts): Unify behaviour and improve generation --- default.nix | 2 +- scripts/cache-node.sh | 7 +++- scripts/check-deployment.sh | 79 +++++++++++++++++-------------------- scripts/default.nix | 59 +++++++++++++-------------- scripts/launch-vm.sh | 32 ++++++++------- scripts/list-nodes.sh | 10 +++-- 6 files changed, 93 insertions(+), 96 deletions(-) diff --git a/default.nix b/default.nix index 5ac7bd5..4660861 100644 --- a/default.nix +++ b/default.nix @@ -114,7 +114,7 @@ in (pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { }) (pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { }) - ] ++ (import ./scripts { inherit pkgs; }); + ] ++ (pkgs.callPackage ./scripts { }); shellHook = '' ${git-checks.shellHook} diff --git a/scripts/cache-node.sh b/scripts/cache-node.sh index 9b84a29..590a605 100644 --- a/scripts/cache-node.sh +++ b/scripts/cache-node.sh @@ -1,6 +1,9 @@ -set -eu -o pipefail +set -o errexit +set -o nounset +set -o pipefail +shopt -s lastpipe -drv=$("@colmena@/bin/colmena" eval --instantiate -E "{ nodes, ... }: nodes.${BUILD_NODE}.config.system.build.toplevel") +drv=$(colmena eval --instantiate -E "{ nodes, ... }: nodes.${BUILD_NODE}.config.system.build.toplevel") # Build the derivation and send it to the great beyond nix-store --query --requisites --force-realise --include-outputs "$drv" | grep -v '.*\.drv' >paths.txt diff --git a/scripts/check-deployment.sh b/scripts/check-deployment.sh index 96371f7..48500ca 100644 --- a/scripts/check-deployment.sh +++ b/scripts/check-deployment.sh @@ -1,7 +1,3 @@ -#!/usr/bin/env bash -#!@bash@/bin/bash -# shellcheck shell=bash - set -o errexit set -o nounset set -o pipefail @@ -20,7 +16,7 @@ Exemple: while [[ $# -gt 0 ]]; do case "$1" in - --help|-h) + --help | -h) echo "$usage" exit 0 ;; @@ -51,13 +47,13 @@ GIT_TOP_LEVEL=$(git rev-parse --show-toplevel) echo "Cloning local main..." git clone -q --branch main --single-branch "$GIT_TOP_LEVEL" "$TMP" -pushd "$TMP" > /dev/null || exit 2 +pushd "$TMP" >/dev/null || exit 2 #################### # Evaluate configs # #################### -colmena_failed () { +colmena_failed() { >&2 echo "Colmena failed. Check your config. Logs:" >&2 cat "$COLMENA_LOGS" exit 3 @@ -68,7 +64,7 @@ COLMENA_LOGS=$(mktemp) echo "Evaluating configs..." # Disable warning because of '${}' # shellcheck disable=SC2016 -RESULTS=$(colmena eval -E '{ nodes, lib, ...}: lib.mapAttrsToList (k: v: { machine = k; path = v.config.system.build.toplevel; drv = v.config.system.build.toplevel.drvPath; domain = "${v.config.networking.hostName}.${v.config.networking.domain}"; }) nodes' 2> "$COLMENA_LOGS" || colmena_failed) +RESULTS=$(colmena eval -E '{ nodes, lib, ...}: lib.mapAttrsToList (k: v: { machine = k; path = v.config.system.build.toplevel; drv = v.config.system.build.toplevel.drvPath; domain = "${v.config.networking.hostName}.${v.config.networking.domain}"; }) nodes' 2>"$COLMENA_LOGS" || colmena_failed) rm "$COLMENA_LOGS" echo "Evaluation finished" @@ -77,49 +73,48 @@ echo "Evaluation finished" # retrieve and check current-system # ##################################### -retrieve_current_system () { +retrieve_current_system() { # TODO implement a less invasive method ssh -n "root@$1" "readlink -f /run/current-system" } - return_status=0 -echo "$RESULTS" | @jq@/bin/jq -c '.[]' | -while IFS=$'\n' read -r c; do +echo "$RESULTS" | jq -c '.[]' | + while IFS=$'\n' read -r c; do - machine=$(echo "$c" | @jq@/bin/jq -r '.machine') - if [[ -n ${node-} ]] && [[ "$machine" != "$node" ]]; then - echo "Skipping ${machine}" - continue - fi - expected_path=$(echo "$c" | @jq@/bin/jq -r '.path') - domain=$(echo "$c" | @jq@/bin/jq -r '.domain') - drv_path=$(echo "$c" | @jq@/bin/jq -r '.drv') + machine=$(echo "$c" | jq -r '.machine') + if [[ -n ${node-} ]] && [[ "$machine" != "$node" ]]; then + echo "Skipping ${machine}" + continue + fi + expected_path=$(echo "$c" | jq -r '.path') + domain=$(echo "$c" | jq -r '.domain') + drv_path=$(echo "$c" | jq -r '.drv') - err=0 - current_path=$(retrieve_current_system "$domain") || err=1 - if [[ "1" == "${err}" ]] ; then - echo "❌ failed to contact $domain !" - continue - fi + err=0 + current_path=$(retrieve_current_system "$domain") || err=1 + if [[ "1" == "${err}" ]]; then + echo "❌ failed to contact $domain !" + continue + fi - if [ "$expected_path" == "$current_path" ] ; then - echo "✅ $machine -> OK" - elif [[ -n ${diff-} ]] ; then - nix-copy-closure --from "root@$domain" "$current_path" - nix-store -r "$drv_path" - echo "$machine -> error. nvd output:" - @nvd@/bin/nvd diff "$expected_path" "$current_path" - return_status=1 - else - echo "☠️ $machine -> error:" - echo " - Expected system: $expected_path" - echo " - Current system: $current_path" - return_status=1 - fi -done + if [ "$expected_path" == "$current_path" ]; then + echo "✅ $machine -> OK" + elif [[ -n ${diff-} ]]; then + nix-copy-closure --from "root@$domain" "$current_path" + nix-store -r "$drv_path" + echo "$machine -> error. nvd output:" + nvd diff "$expected_path" "$current_path" + return_status=1 + else + echo "☠️ $machine -> error:" + echo " - Expected system: $expected_path" + echo " - Current system: $current_path" + return_status=1 + fi + done -popd > /dev/null || exit 2 +popd >/dev/null || exit 2 rm -r "$TMP" exit $return_status diff --git a/scripts/default.nix b/scripts/default.nix index 3503729..ae3a1b8 100644 --- a/scripts/default.nix +++ b/scripts/default.nix @@ -1,39 +1,34 @@ -{ pkgs, ... }: +{ + lib, + writeShellApplication, + + # Dependencies + colmena, + jq, + nvd, + ... +}: let - substitutions = { - inherit (pkgs) - bash + inherit (lib) mapAttrsToList; + + scripts = { + cache-node = [ colmena ]; + check-deployment = [ colmena - coreutils - nvd - git jq - ; + nvd + ]; + launch-vm = [ colmena ]; + list-nodes = [ jq ]; }; - - mkShellScript = - name: - (pkgs.substituteAll ( - { - inherit name; - src = ./. + "/${name}.sh"; - dir = "/bin/"; - isExecutable = true; - - checkPhase = '' - ${pkgs.stdenv.shellDryRun} "$target" - ''; - } - // substitutions - )); - - scripts = [ - "cache-node" - "check-deployment" - "launch-vm" - "list-nodes" - ]; in -builtins.map mkShellScript scripts +mapAttrsToList ( + name: runtimeInputs: + writeShellApplication { + inherit name runtimeInputs; + + text = builtins.readFile ./${name}.sh; + } +) scripts diff --git a/scripts/launch-vm.sh b/scripts/launch-vm.sh index 7f8c598..9956245 100755 --- a/scripts/launch-vm.sh +++ b/scripts/launch-vm.sh @@ -1,33 +1,35 @@ -#!@bash@/bin/bash -# shellcheck shell=bash set -o errexit set -o nounset set -o pipefail +shopt -s lastpipe MACHINE="" HOSTFWD="" while getopts 'p:o:h' opt; do case "$opt" in - p) - HOSTFWD=",hostfwd=tcp::$OPTARG$HOSTFWD" - ;; + p) + HOSTFWD=",hostfwd=tcp::$OPTARG$HOSTFWD" + ;; - o) - MACHINE="$OPTARG" - ;; + o) + MACHINE="$OPTARG" + ;; - h|?) - echo "Usage: $(basename "$0") [-p hostport-:guestport] -o MACHINE" - exit 1 - ;; + h | ?) + echo "Usage: $(basename "$0") [-p hostport-:guestport] -o MACHINE" + exit 1 + ;; esac done -shift "$((OPTIND -1))" +shift "$((OPTIND - 1))" -if [ -z "$MACHINE" ]; then echo "-o option needed"; exit 1; fi +if [ -z "$MACHINE" ]; then + echo "-o option needed" + exit 1 +fi -DRV_PATH=$(@colmena@/bin/colmena eval --instantiate -E "{nodes, ...}: nodes.$MACHINE.config.system.build.vm") +DRV_PATH=$(colmena eval --instantiate -E "{nodes, ...}: nodes.$MACHINE.config.system.build.vm") echo "Realising $DRV_PATH" RESULT=$(nix-store -r "$DRV_PATH") diff --git a/scripts/list-nodes.sh b/scripts/list-nodes.sh index a6c90ff..5d71169 100644 --- a/scripts/list-nodes.sh +++ b/scripts/list-nodes.sh @@ -1,6 +1,8 @@ -#!@bash@/bin/bash -# shellcheck shell=bash +set -o errexit +set -o nounset +set -o pipefail +shopt -s lastpipe -cd $(@git@/bin/git rev-parse --show-toplevel) +cd "$(git rev-parse --show-toplevel)" -nix-instantiate --strict --eval --json -A nodes | @jq@/bin/jq . +nix-instantiate --strict --eval --json -A nodes | jq .