{ lib, config, sources, ... }: let inherit (import ./constants.nix) targetMachines pathToRoot; 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 ]; # FIXME: sad times system.extraDependencies = with pkgs; [ jq jq.inputDerivation ]; 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 ' let configuration = { pkgs, config, ... }: { imports = [ ${pathToRoot}/deployment/check/common/sharedOptions.nix ${pathToRoot}/deployment/check/common/targetNode.nix ${sources.nixpkgs}/nixos/modules/profiles/qemu-guest.nix ]; enableAcme = ${lib.strings.toJSON config.enableAcme}; acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null; environment.systemPackages = with pkgs; [ hello ]; }; in import ${pathToRoot}/deployment/nixos.nix { inherit configuration; } ' ) # 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 )} ''; }