Fediversity/deployment/check/basic/nixosTest.nix

133 lines
4.2 KiB
Nix

{
testers,
inputs,
sources ? import ../npins,
...
}:
testers.runNixOSTest (
{
lib,
config,
hostPkgs,
...
}:
let
pathToRoot = ../../..;
pathFromRoot = "deployment/check/basic";
## TODO: sanity check the existence of (pathToRoot + "/flake.nix")
## TODO: sanity check that (pathToRoot + "/${pathFromRoot}" == ./.)
## The whole repository, with the flake at its root.
src = lib.fileset.toSource {
fileset = pathToRoot;
root = pathToRoot;
};
targetNetworkJSON = hostPkgs.writeText "target-network.json" (
builtins.toJSON config.nodes.target.system.build.networkConfig
);
in
{
name = "deployment-basic";
# imports = [
# ];
nodes = {
deployer =
{ pkgs, nodes, ... }:
{
# environment.systemPackages = [
# ];
virtualisation = {
## Memory use is expected to be dominated by the NixOS evaluation,
## which happens on the deployer.
memorySize = 4096;
diskSize = 10 * 1024;
cores = 2;
};
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
connect-timeout = 1;
};
system.extraDependencies =
[
sources.nixpkgs
pkgs.stdenv
pkgs.stdenvNoCC
pkgs.cowsay
pkgs.cowsay.inputDerivation # NOTE: Crucial!!!
## Some derivations will be different compared to target's initial
## state, so we'll need to be able to build something similar.
## Generally the derivation inputs aren't that different, so we
## use the initial state of the target as a base.
nodes.target.system.build.toplevel.inputDerivation
nodes.target.system.build.etc.inputDerivation
nodes.target.system.path.inputDerivation
nodes.target.system.build.bootStage1.inputDerivation
nodes.target.system.build.bootStage2.inputDerivation
]
++ lib.concatLists (
lib.mapAttrsToList (
_k: v: if v ? source.inputDerivation then [ v.source.inputDerivation ] else [ ]
) nodes.target.environment.etc
);
};
target.imports = [ ./minimalTarget.nix ];
};
testScript = ''
start_all()
target.wait_for_unit("multi-user.target")
deployer.wait_for_unit("multi-user.target")
with subtest("Unpacking"):
deployer.succeed("cp -r --no-preserve=mode ${src} work")
with subtest("Configure the network"):
deployer.copy_from_host("${targetNetworkJSON}", "/root/target-network.json")
deployer.succeed("mv /root/target-network.json work/${pathFromRoot}/target-network.json")
with subtest("Configure the deployer key"):
deployer.succeed("""mkdir -p ~/.ssh && ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa""")
deployer_key = deployer.succeed("cat ~/.ssh/id_rsa.pub").strip()
deployer.succeed(f"echo '{deployer_key}' > work/${pathFromRoot}/deployer.pub")
target.succeed(f"mkdir -p /root/.ssh && echo '{deployer_key}' >> /root/.ssh/authorized_keys")
with subtest("Configure the target host key"):
target_host_key = target.succeed("ssh-keyscan target | grep -v '^#' | cut -f 2- -d ' ' | head -n 1")
deployer.succeed(f"echo '{target_host_key}' > work/${pathFromRoot}/target_host_key.pub")
## NOTE: This is super slow. It could probably be optimised in Nix, for
## instance by allowing to grab things directly from the host's store.
with subtest("Override the lock"):
deployer.succeed("""
cd work
nix flake lock --extra-experimental-features 'flakes nix-command' \
--offline -v \
--override-input nixpkgs ${inputs.nixpkgs} \
;
""")
with subtest("Check the status before deployment"):
target.fail("cowsay hi 1>&2")
with subtest("Run the deployment"):
deployer.succeed("cd work && tofu apply --show-trace --no-interactive")
with subtest("Check the deployment"):
target.succeed("cowsay hi 1>&2")
'';
}
)