{ lib, config, ... }: let inherit (import ./constants.nix) targetMachines pathToRoot; escapedJson = v: lib.replaceStrings [ "\"" ] [ "\\\\\"" ] (lib.strings.toJSON v); in { _class = "nixosTest"; name = "deployment-model"; sourceFileset = lib.fileset.unions [ ../../data-model.nix ../../function.nix ./constants.nix ./deployment.nix ]; nodes.deployer = { pkgs, ... }: { environment.systemPackages = with pkgs; [ jq ]; system.extraDependenciesFromModule = { pkgs, ... }: { environment.systemPackages = with pkgs; [ hello ]; }; }; extraTestScript = '' ${lib.concatStringsSep "\n" ( lib.lists.map (nodeName: '' with subtest("Check the status before deployment"): ${nodeName}.fail("${nodeName} 1>&2") with subtest("Run the deployment for ${nodeName}"): deployer.succeed(""" set -euo pipefail # INSTANTIATE command=(nix-instantiate --expr ' import ${pathToRoot}/deployment/nixos.nix { configuration = import ${pathToRoot}/deployment/check/data-model/deployment.nix { config = builtins.fromJSON "${ escapedJson { inherit (config) enableAcme; acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null; } }"; }; } ') # DEPLOY host="root@${nodeName}" sshOpts=( -o StrictHostKeyChecking=no -o "ConnectTimeout=1" -o "ServerAliveInterval=1" ) # instantiate the config in /nix/store "''${command[@]}" -A out_path # get the realized derivation to deploy outPath=$(nix-store --realize "$("''${command[@]}" --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 ${nodeName} not responding"* ]]; then echo "non-timeout error: $output" exit 1 else exit 0 fi """) ${nodeName}.wait_for_unit("multi-user.target") ${nodeName}.succeed("${nodeName} 1>&2") '') targetMachines )} ''; }