feat(scripts): Unify behaviour and improve generation

This commit is contained in:
Tom Hubrecht 2024-11-14 22:01:58 +01:00
parent 2ffd7732ba
commit 6fbda40e5e
Signed by: thubrecht
SSH key fingerprint: SHA256:r+nK/SIcWlJ0zFZJGHtlAoRwq1Rm+WcKAm5ADYMoQPc
6 changed files with 93 additions and 96 deletions

View file

@ -114,7 +114,7 @@ in
(pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { }) (pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { })
(pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { }) (pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { })
] ++ (import ./scripts { inherit pkgs; }); ] ++ (pkgs.callPackage ./scripts { });
shellHook = '' shellHook = ''
${git-checks.shellHook} ${git-checks.shellHook}

View file

@ -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 # Build the derivation and send it to the great beyond
nix-store --query --requisites --force-realise --include-outputs "$drv" | grep -v '.*\.drv' >paths.txt nix-store --query --requisites --force-realise --include-outputs "$drv" | grep -v '.*\.drv' >paths.txt

View file

@ -1,7 +1,3 @@
#!/usr/bin/env bash
#!@bash@/bin/bash
# shellcheck shell=bash
set -o errexit set -o errexit
set -o nounset set -o nounset
set -o pipefail set -o pipefail
@ -20,7 +16,7 @@ Exemple:
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--help|-h) --help | -h)
echo "$usage" echo "$usage"
exit 0 exit 0
;; ;;
@ -51,13 +47,13 @@ GIT_TOP_LEVEL=$(git rev-parse --show-toplevel)
echo "Cloning local main..." echo "Cloning local main..."
git clone -q --branch main --single-branch "$GIT_TOP_LEVEL" "$TMP" 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 # # Evaluate configs #
#################### ####################
colmena_failed () { colmena_failed() {
>&2 echo "Colmena failed. Check your config. Logs:" >&2 echo "Colmena failed. Check your config. Logs:"
>&2 cat "$COLMENA_LOGS" >&2 cat "$COLMENA_LOGS"
exit 3 exit 3
@ -68,7 +64,7 @@ COLMENA_LOGS=$(mktemp)
echo "Evaluating configs..." echo "Evaluating configs..."
# Disable warning because of '${}' # Disable warning because of '${}'
# shellcheck disable=SC2016 # 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" rm "$COLMENA_LOGS"
echo "Evaluation finished" echo "Evaluation finished"
@ -77,49 +73,48 @@ echo "Evaluation finished"
# retrieve and check current-system # # retrieve and check current-system #
##################################### #####################################
retrieve_current_system () { retrieve_current_system() {
# TODO implement a less invasive method # TODO implement a less invasive method
ssh -n "root@$1" "readlink -f /run/current-system" ssh -n "root@$1" "readlink -f /run/current-system"
} }
return_status=0 return_status=0
echo "$RESULTS" | @jq@/bin/jq -c '.[]' | echo "$RESULTS" | jq -c '.[]' |
while IFS=$'\n' read -r c; do while IFS=$'\n' read -r c; do
machine=$(echo "$c" | @jq@/bin/jq -r '.machine') machine=$(echo "$c" | jq -r '.machine')
if [[ -n ${node-} ]] && [[ "$machine" != "$node" ]]; then if [[ -n ${node-} ]] && [[ "$machine" != "$node" ]]; then
echo "Skipping ${machine}" echo "Skipping ${machine}"
continue continue
fi fi
expected_path=$(echo "$c" | @jq@/bin/jq -r '.path') expected_path=$(echo "$c" | jq -r '.path')
domain=$(echo "$c" | @jq@/bin/jq -r '.domain') domain=$(echo "$c" | jq -r '.domain')
drv_path=$(echo "$c" | @jq@/bin/jq -r '.drv') drv_path=$(echo "$c" | jq -r '.drv')
err=0 err=0
current_path=$(retrieve_current_system "$domain") || err=1 current_path=$(retrieve_current_system "$domain") || err=1
if [[ "1" == "${err}" ]] ; then if [[ "1" == "${err}" ]]; then
echo "❌ failed to contact $domain !" echo "❌ failed to contact $domain !"
continue continue
fi fi
if [ "$expected_path" == "$current_path" ] ; then if [ "$expected_path" == "$current_path" ]; then
echo "$machine -> OK" echo "$machine -> OK"
elif [[ -n ${diff-} ]] ; then elif [[ -n ${diff-} ]]; then
nix-copy-closure --from "root@$domain" "$current_path" nix-copy-closure --from "root@$domain" "$current_path"
nix-store -r "$drv_path" nix-store -r "$drv_path"
echo "$machine -> error. nvd output:" echo "$machine -> error. nvd output:"
@nvd@/bin/nvd diff "$expected_path" "$current_path" nvd diff "$expected_path" "$current_path"
return_status=1 return_status=1
else else
echo "☠️ $machine -> error:" echo "☠️ $machine -> error:"
echo " - Expected system: $expected_path" echo " - Expected system: $expected_path"
echo " - Current system: $current_path" echo " - Current system: $current_path"
return_status=1 return_status=1
fi fi
done done
popd > /dev/null || exit 2 popd >/dev/null || exit 2
rm -r "$TMP" rm -r "$TMP"
exit $return_status exit $return_status

View file

@ -1,39 +1,34 @@
{ pkgs, ... }: {
lib,
writeShellApplication,
# Dependencies
colmena,
jq,
nvd,
...
}:
let let
substitutions = { inherit (lib) mapAttrsToList;
inherit (pkgs)
bash scripts = {
cache-node = [ colmena ];
check-deployment = [
colmena colmena
coreutils
nvd
git
jq 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 in
builtins.map mkShellScript scripts mapAttrsToList (
name: runtimeInputs:
writeShellApplication {
inherit name runtimeInputs;
text = builtins.readFile ./${name}.sh;
}
) scripts

View file

@ -1,33 +1,35 @@
#!@bash@/bin/bash
# shellcheck shell=bash
set -o errexit set -o errexit
set -o nounset set -o nounset
set -o pipefail set -o pipefail
shopt -s lastpipe
MACHINE="" MACHINE=""
HOSTFWD="" HOSTFWD=""
while getopts 'p:o:h' opt; do while getopts 'p:o:h' opt; do
case "$opt" in case "$opt" in
p) p)
HOSTFWD=",hostfwd=tcp::$OPTARG$HOSTFWD" HOSTFWD=",hostfwd=tcp::$OPTARG$HOSTFWD"
;; ;;
o) o)
MACHINE="$OPTARG" MACHINE="$OPTARG"
;; ;;
h|?) h | ?)
echo "Usage: $(basename "$0") [-p hostport-:guestport] -o MACHINE" echo "Usage: $(basename "$0") [-p hostport-:guestport] -o MACHINE"
exit 1 exit 1
;; ;;
esac esac
done 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" echo "Realising $DRV_PATH"
RESULT=$(nix-store -r "$DRV_PATH") RESULT=$(nix-store -r "$DRV_PATH")

View file

@ -1,6 +1,8 @@
#!@bash@/bin/bash set -o errexit
# shellcheck shell=bash 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 .