switch reusable script to package, facilitating inspection and reuse

This commit is contained in:
Kiara Grouwstra 2025-08-31 18:01:32 +02:00
parent 18bcae835e
commit 1de353fada
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
2 changed files with 10 additions and 54 deletions

View file

@ -2,29 +2,23 @@
lib, lib,
config, config,
pkgs, pkgs,
inputs,
... ...
}: }:
let let
inherit (import ./constants.nix) pathToRoot pathFromRoot; inherit (import ./constants.nix) pathToRoot pathFromRoot;
inherit (pkgs) system; inherit (pkgs) system;
escapedJson = v: lib.replaceStrings [ "\"" ] [ "\\\\\"" ] (lib.strings.toJSON v);
deployment-config = { deployment-config = {
inherit pathToRoot pathFromRoot; inherit pathToRoot pathFromRoot;
inherit (config) enableAcme; inherit (config) enableAcme;
acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null; acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null;
nodeName = "ssh"; nodeName = "ssh";
}; };
inherit deploy =
((import ../common/data-model.nix { (import ../common/data-model.nix {
inherit system inputs; inherit system;
config = deployment-config; config = deployment-config;
})."ssh-deployment".ssh-host.ssh # opt not to pass `inputs`, as we could only pass serializable arguments through to its self-call
) })."ssh-deployment".ssh-host.run;
host
username
key-file
;
in in
{ {
_class = "nixosTest"; _class = "nixosTest";
@ -46,6 +40,7 @@ in
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
jq jq
deploy
]; ];
system.extraDependenciesFromModule = system.extraDependenciesFromModule =
@ -63,46 +58,7 @@ in
with subtest("Run the deployment"): with subtest("Run the deployment"):
deployer.succeed(""" deployer.succeed("""
set -euo pipefail ${lib.getExe deploy}
# INSTANTIATE
command=(nix-instantiate --show-trace --expr '
let
system = "${pkgs.system}"; # FIXME: what system are we deploying to?
in
import ${pathToRoot}/deployment/nixos.nix {
inherit system;
configuration = (
import ${pathToRoot}/deployment/check/common/data-model.nix {
inherit system;
config = builtins.fromJSON "${escapedJson deployment-config}";
}
)."ssh-deployment".ssh-host.nixos-configuration;
}
')
# DEPLOY
host="${lib.defaultTo "root" username}@${host}"
sshOpts=(
${if key-file == null then "" else "-i ${key-file}"}
-o StrictHostKeyChecking=no
-o "ConnectTimeout=1"
-o "ServerAliveInterval=1"
)
# instantiate the config in /nix/store
"''${command[@]}" --show-trace -A out_path
# get the realized derivation to deploy
outPath=$(nix-store --realize "$("''${command[@]}" --show-trace --eval --strict --json | jq -r '.drv_path')")
# deploy the config by nix-copy-closure
NIX_SSHOPTS="''${sshOpts[*]}" nix-copy-closure --to "$host" "$outPath" --gzip --use-substitutes
# switch the remote host to the config
output=$(ssh "''${sshOpts[@]}" "$host" "nix-env --profile /nix/var/nix/profiles/system --set $outPath; nohup $outPath/bin/switch-to-configuration switch &" 2>&1) || echo "status code: $?"
echo "output: $output"
if [[ $output != *"Timeout, server ssh not responding"* ]]; then
echo "non-timeout error: $output"
exit 1
else
exit 0
fi
""") """)
ssh.wait_for_unit("multi-user.target") ssh.wait_for_unit("multi-user.target")
ssh.succeed("su - operator -c hello 1>&2") ssh.succeed("su - operator -c hello 1>&2")

View file

@ -20,7 +20,7 @@ let
; ;
toBash = toBash =
v: v:
lib.replaceStrings [ "\"" ] [ "\\\\\"" ] ( lib.replaceStrings [ "\"" ] [ "\\\"" ] (
if lib.isPath v || builtins.isNull v then if lib.isPath v || builtins.isNull v then
toString v toString v
else if lib.isString v then else if lib.isString v then
@ -125,7 +125,7 @@ let
type = types.path; type = types.path;
}; };
run = mkOption { run = mkOption {
type = types.str; type = types.package;
# error: The option `tf-deployment.tf-host.run' is read-only, but it's set multiple times. # error: The option `tf-deployment.tf-host.run' is read-only, but it's set multiple times.
# readOnly = true; # readOnly = true;
default = default =
@ -160,7 +160,7 @@ let
}; };
tf-env = pkgs.callPackage ./run/tf-single-host/tf-env.nix { }; tf-env = pkgs.callPackage ./run/tf-single-host/tf-env.nix { };
in in
'' pkgs.writeShellScriptBin "deploy-ssh.sh" ''
env ${toString (lib.mapAttrsToList (k: v: "TF_VAR_${k}=\"${toBash v}\"") environment)} \ env ${toString (lib.mapAttrsToList (k: v: "TF_VAR_${k}=\"${toBash v}\"") environment)} \
tf_env=${tf-env} bash ./deployment/run/tf-single-host/run.sh tf_env=${tf-env} bash ./deployment/run/tf-single-host/run.sh
''; '';