dedupe nixosTest.nix

This commit is contained in:
Kiara Grouwstra 2025-08-24 19:26:16 +02:00
parent 50e1a768e7
commit cbec8fa3fc
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
10 changed files with 48 additions and 197 deletions

View file

@ -5,4 +5,5 @@
]; ];
pathToRoot = ../../..; pathToRoot = ../../..;
pathFromRoot = ./.; pathFromRoot = ./.;
useFlake = true;
} }

View file

@ -1,4 +1,9 @@
{ inputs, lib, ... }: {
inputs,
lib,
config,
...
}:
{ {
_class = "nixosTest"; _class = "nixosTest";
@ -8,6 +13,7 @@
sourceFileset = lib.fileset.unions [ sourceFileset = lib.fileset.unions [
./constants.nix ./constants.nix
./deployment.nix ./deployment.nix
(config.pathToCwd + "/flake-under-test.nix")
]; ];
nodes.deployer = nodes.deployer =

View file

@ -8,4 +8,5 @@
pathToRoot = ../../..; pathToRoot = ../../..;
pathFromRoot = ./.; pathFromRoot = ./.;
enableAcme = true; enableAcme = true;
useFlake = true;
} }

View file

@ -1,6 +1,7 @@
{ {
inputs, inputs,
hostPkgs, hostPkgs,
config,
lib, lib,
... ...
}: }:
@ -19,6 +20,7 @@ in
sourceFileset = lib.fileset.unions [ sourceFileset = lib.fileset.unions [
./constants.nix ./constants.nix
./deployments.nix ./deployments.nix
(config.pathToCwd + "/flake-under-test.nix")
# REVIEW: I would like to be able to grab all of `/deployment` minus # REVIEW: I would like to be able to grab all of `/deployment` minus
# `/deployment/check`, but I can't because there is a bunch of other files # `/deployment/check`, but I can't because there is a bunch of other files

View file

@ -76,8 +76,6 @@ in
./sharedOptions.nix ./sharedOptions.nix
./targetNode.nix ./targetNode.nix
./targetResource.nix ./targetResource.nix
(config.pathToCwd + "/flake-under-test.nix")
]; ];
acmeNodeIP = config.nodes.acme.networking.primaryIPAddress; acmeNodeIP = config.nodes.acme.networking.primaryIPAddress;
@ -164,31 +162,38 @@ in
deployer.succeed(f"echo '{host_key}' > ${config.pathFromRoot}/${tm}_host_key.pub") deployer.succeed(f"echo '{host_key}' > ${config.pathFromRoot}/${tm}_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. if config.useFlake then
## ''
## NOTE: We use the repository as-is (cf `src` above), overriding only ## NOTE: This is super slow. It could probably be optimised in Nix, for
## `flake.nix` by our `flake-under-test.nix`. We also override the flake ## instance by allowing to grab things directly from the host's store.
## lock file to use locally available inputs, as we cannot download them. ##
## ## NOTE: We use the repository as-is (cf `src` above), overriding only
with subtest("Override the flake and its lock"): ## `flake.nix` by our `flake-under-test.nix`. We also override the flake
deployer.succeed("cp ${config.pathFromRoot}/flake-under-test.nix flake.nix") ## lock file to use locally available inputs, as we cannot download them.
deployer.succeed(""" ##
nix flake lock --extra-experimental-features 'flakes nix-command' \ with subtest("Override the flake and its lock"):
--offline -v \ deployer.succeed("cp ${config.pathFromRoot}/flake-under-test.nix flake.nix")
--override-input nixops4 ${inputs.nixops4.packages.${system}.flake-in-a-bottle} \ deployer.succeed("""
\ nix flake lock --extra-experimental-features 'flakes nix-command' \
--override-input nixops4-nixos ${inputs.nixops4-nixos} \ --offline -v \
--override-input nixops4-nixos/flake-parts ${inputs.nixops4-nixos.inputs.flake-parts} \ --override-input nixops4 ${inputs.nixops4.packages.${system}.flake-in-a-bottle} \
--override-input nixops4-nixos/flake-parts/nixpkgs-lib ${inputs.nixops4-nixos.inputs.flake-parts.inputs.nixpkgs-lib} \ \
--override-input nixops4-nixos/nixops4-nixos ${emptyFlake} \ --override-input nixops4-nixos ${inputs.nixops4-nixos} \
--override-input nixops4-nixos/nixpkgs ${inputs.nixops4-nixos.inputs.nixpkgs} \ --override-input nixops4-nixos/flake-parts ${inputs.nixops4-nixos.inputs.flake-parts} \
--override-input nixops4-nixos/nixops4 ${ --override-input nixops4-nixos/flake-parts/nixpkgs-lib ${inputs.nixops4-nixos.inputs.flake-parts.inputs.nixpkgs-lib} \
inputs.nixops4-nixos.inputs.nixops4.packages.${system}.flake-in-a-bottle --override-input nixops4-nixos/nixops4-nixos ${emptyFlake} \
} \ --override-input nixops4-nixos/nixpkgs ${inputs.nixops4-nixos.inputs.nixpkgs} \
--override-input nixops4-nixos/git-hooks-nix ${emptyFlake} \ --override-input nixops4-nixos/nixops4 ${
; inputs.nixops4-nixos.inputs.nixops4.packages.${system}.flake-in-a-bottle
""") } \
--override-input nixops4-nixos/git-hooks-nix ${emptyFlake} \
;
""")
''
else
""
}
${optionalString config.enableAcme '' ${optionalString config.enableAcme ''
with subtest("Set up handmade DNS"): with subtest("Set up handmade DNS"):

View file

@ -64,5 +64,7 @@ in
during the test to the correct value. during the test to the correct value.
''; '';
}; };
useFlake = lib.mkEnableOption "Use a flake in the test.";
}; };
} }

View file

@ -1,168 +0,0 @@
{
inputs,
lib,
config,
hostPkgs,
sources,
...
}:
let
inherit (builtins)
concatStringsSep
toJSON
;
inherit (lib)
types
fileset
mkOption
genAttrs
attrNames
optionalString
;
inherit (hostPkgs)
writeText
;
forConcat = xs: f: concatStringsSep "\n" (map f xs);
in
{
_class = "nixosTest";
imports = [
../common/sharedOptions.nix
];
options = {
## FIXME: I wish I could just use `testScript` but with something like
## `mkOrder` to put this module's string before something else.
extraTestScript = mkOption { };
sourceFileset = mkOption {
## REVIEW: Upstream to nixpkgs?
type = types.mkOptionType {
name = "fileset";
description = "fileset";
descriptionClass = "noun";
check = (x: (builtins.tryEval (fileset.unions [ x ])).success);
merge = (_: defs: fileset.unions (map (x: x.value) defs));
};
description = ''
A fileset that will be copied to the deployer node in the current
working directory. This should contain all the files that are
necessary to run that particular test, such as the NixOS
modules necessary to evaluate a deployment.
'';
};
};
config = {
sourceFileset = fileset.unions [
../../../mkFlake.nix
../../../flake.lock
../../../npins
../../data-model.nix
../../function.nix
../common/sharedOptions.nix
../common/targetNode.nix
../common/targetResource.nix
];
acmeNodeIP = config.nodes.acme.networking.primaryIPAddress;
nodes =
{
deployer = {
imports = [ ../common/deployerNode.nix ];
_module.args = { inherit inputs sources; };
enableAcme = config.enableAcme;
acmeNodeIP = config.nodes.acme.networking.primaryIPAddress;
};
}
//
(
if config.enableAcme then
{
acme = {
## FIXME: This makes `nodes.acme` into a local resolver. Maybe this will
## break things once we play with DNS?
imports = [ "${inputs.nixpkgs}/nixos/tests/common/acme/server" ];
## We aren't testing ACME - we just want certificates.
systemd.services.pebble.environment.PEBBLE_VA_ALWAYS_VALID = "1";
};
}
else
{ }
)
//
genAttrs config.targetMachines (_: {
imports = [ ../common/targetNode.nix ];
_module.args = { inherit inputs sources; };
enableAcme = config.enableAcme;
acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null;
});
testScript = ''
${forConcat (attrNames config.nodes) (n: ''
${n}.start()
'')}
${forConcat (attrNames config.nodes) (n: ''
${n}.wait_for_unit("multi-user.target")
'')}
## A subset of the repository that is necessary for this test. It will be
## copied inside the test. The smaller this set, the faster our CI, because we
## won't need to re-run when things change outside of it.
with subtest("Unpacking"):
deployer.succeed("cp -r --no-preserve=mode ${
fileset.toSource {
root = ../../..;
fileset = config.sourceFileset;
}
}/* .")
with subtest("Configure the network"):
${forConcat config.targetMachines (
tm:
let
targetNetworkJSON = writeText "target-network.json" (
toJSON config.nodes.${tm}.system.build.networkConfig
);
in
''
deployer.copy_from_host("${targetNetworkJSON}", "${config.pathFromRoot}/${tm}-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()
${forConcat config.targetMachines (tm: ''
${tm}.succeed(f"mkdir -p /root/.ssh && echo '{deployer_key}' >> /root/.ssh/authorized_keys")
'')}
with subtest("Configure the target host key"):
${forConcat config.targetMachines (tm: ''
host_key = ${tm}.succeed("ssh-keyscan ${tm} | grep -v '^#' | cut -f 2- -d ' ' | head -n 1")
deployer.succeed(f"echo '{host_key}' > ${config.pathFromRoot}/${tm}_host_key.pub")
'')}
# with subtest("Override the flake and its lock"):
# deployer.succeed("cp ${config.pathFromRoot}/flake-under-test.nix flake.nix")
${optionalString config.enableAcme ''
with subtest("Set up handmade DNS"):
deployer.succeed("echo '${config.nodes.acme.networking.primaryIPAddress}' > ${config.pathFromRoot}/acme_server_ip")
''}
${config.extraTestScript}
'';
};
}

View file

@ -8,7 +8,7 @@ runNixOSTest {
imports = [ imports = [
../../data-model.nix ../../data-model.nix
../../function.nix ../../function.nix
./common-nixosTest.nix ../common/nixosTest.nix
./nixosTest.nix ./nixosTest.nix
]; ];
_module.args = { inherit inputs sources; }; _module.args = { inherit inputs sources; };

View file

@ -8,4 +8,5 @@
pathToRoot = ../../..; pathToRoot = ../../..;
pathFromRoot = ./.; pathFromRoot = ./.;
enableAcme = true; enableAcme = true;
useFlake = true;
} }

View file

@ -128,6 +128,7 @@ in
sourceFileset = lib.fileset.unions [ sourceFileset = lib.fileset.unions [
./constants.nix ./constants.nix
./deployment.nix ./deployment.nix
(config.pathToCwd + "/flake-under-test.nix")
# REVIEW: I would like to be able to grab all of `/deployment` minus # REVIEW: I would like to be able to grab all of `/deployment` minus
# `/deployment/check`, but I can't because there is a bunch of other files # `/deployment/check`, but I can't because there is a bunch of other files