Files
server-config/tests/server-n0/integration.nix
T
flowey bea6496491
diff-pr / dix (pull_request) Successful in 38m21s
flake-check / flake-check (pull_request) Successful in 9m14s
lint / lint (pull_request) Successful in 1m48s
meow
2026-09-22 15:53:42 -05:00

184 lines
5.4 KiB
Nix

{
lib,
host,
dsl,
commonModule,
}:
pkgs:
let
inherit (host.specialArgs.hostInfo) paths;
serverDataDir = paths.data;
serverSecretsDir = paths.secrets;
testContainers = dsl.filterDeployments (c: c.includedInTests) host.containers;
it = dsl.mkIntegrationTest { inherit host testContainers pkgs; };
nginxAcmeDomains =
if testContainers ? nginx && testContainers.nginx.miscProperties ? acmeDomains then
testContainers.nginx.miscProperties.acmeDomains
else
[ ];
nginxAcmeDir = domain: "${serverDataDir}/core/nginx/acme/${domain}";
fakeCert =
domain:
pkgs.runCommand "fake-cert-${domain}"
{
nativeBuildInputs = [ pkgs.openssl ];
}
''
mkdir -p "$out"
openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
-subj "/CN=${domain}" \
-keyout "$out/key.pem" -out "$out/fullchain.pem" 2>/dev/null
'';
mkdirAcmeDirs = lib.concatMapStrings (
domain: ''mkdir -p "${nginxAcmeDir domain}"'' + "\n"
) nginxAcmeDomains;
installFakeCerts = lib.concatMapStrings (
domain:
let
dir = nginxAcmeDir domain;
cert = fakeCert domain;
in
''
if [[ ! -f "${dir}/fullchain.pem" ]]; then
install -m 644 ${cert}/fullchain.pem "${dir}/fullchain.pem"
install -m 600 ${cert}/key.pem "${dir}/key.pem"
fi
''
) nginxAcmeDomains;
# used in ssh-admin
testSshKey =
pkgs.runCommand "test-ssh-key"
{
nativeBuildInputs = [ pkgs.openssh ];
}
''
mkdir -p "$out"
ssh-keygen -q -t ed25519 -N "" -f "$out/key" -C test
'';
sshpiperTestUser = "admin";
hostSshdPort = 5952;
# derive data directories from container bind mounts
allDataDirs = lib.unique (
lib.concatMap (c: lib.filter (p: lib.hasPrefix serverDataDir p) c.bindMountHostPaths) (
lib.attrValues testContainers
)
);
mkdirAllDataDirs = lib.concatMapStrings (p: ''mkdir -p "${p}"'' + "\n") allDataDirs;
# writable data dirs need ownership set to 1000:1000 (the standard
# container user uid). services that run as a different user (loki,
# prometheus, grafana) fix ownership via StateDirectory on startup.
writableDataDirs = lib.unique (
lib.concatMap (
c:
if c.kind == "nspawn" then
lib.filter (p: lib.hasPrefix serverDataDir p) (
map (bm: bm.hostPath) (lib.attrValues (lib.filterAttrs (_: bm: !bm.isReadOnly) c.bindMounts))
)
else
[ ]
) (lib.attrValues testContainers)
);
chownWritableDataDirs = lib.concatMapStrings (
p: ''chown -R 1000:1000 "${p}"'' + "\n"
) writableDataDirs;
# secret paths needed by test containers
secretPaths = lib.unique (
lib.concatMap (c: lib.filter (p: lib.hasPrefix serverSecretsDir p) c.bindMountHostPaths) (
lib.attrValues testContainers
)
);
mkdirSecretParents = lib.concatMapStrings (p: ''mkdir -p "$(dirname '${p}')"'' + "\n") secretPaths;
in
{
name = "integration-${host.hostName}";
nodes = {
internet = it.internetNode;
server =
{ pkgs, lib, ... }:
{
imports = [
commonModule
host.specialArgs.inputs.microvm.nixosModules.host
(dsl.mkHostFromContainers {
containers = testContainers;
inherit (host) ctx;
})
it.serverModule
];
system.activationScripts.test-secrets =
# bash
''
mkdir -p /nix/var/nix/db /nix/var/nix/daemon-socket
mkdir -p /var/log/journal
mkdir -p "${serverSecretsDir}"
${mkdirAllDataDirs}
${mkdirAcmeDirs}
${mkdirSecretParents}
${chownWritableDataDirs}
for keytype in ed25519 rsa ecdsa; do
keyfile="${serverSecretsDir}/ssh_host_''${keytype}_key"
if [[ ! -f "$keyfile" ]]; then
${lib.getExe' pkgs.openssh "ssh-keygen"} -q -t "$keytype" -f "$keyfile" -N ""
fi
done
${installFakeCerts}
''
+ lib.optionalString (testContainers ? sshpiper) ''
mkdir -p "${serverDataDir}/core/sshpiper/user_${sshpiperTestUser}"
install -m 644 ${testSshKey}/key.pub \
"${serverDataDir}/core/sshpiper/user_${sshpiperTestUser}/authorized_keys"
''
+ lib.optionalString (testContainers ? mail) ''
for f in mail-admin-password mail-account-password; do
target="${serverSecretsDir}/$f"
if [[ ! -f "$target" ]]; then
head -c 32 /dev/urandom | base64 | tr -d '\n' > "$target"
chmod 600 "$target"
fi
done
'';
}
// lib.optionalAttrs (testContainers ? nginx && nginxAcmeDomains != [ ]) {
containers.nginx.config = {
systemd.services = lib.genAttrs (map (d: "acme-order-renew-${d}") nginxAcmeDomains) (_: {
enable = lib.mkForce false;
});
};
};
};
testScript =
it.testScriptPreamble
+ ''
# store paths are world-readable; ssh refuses a key with those permissions
SSH_KEY = "/root/test-ssh-key"
SSH_OPTS = f"-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -i {SSH_KEY}"
TEST_SSH_KEY_STORE = "${testSshKey}/key"
SSHPIPER_TEST_USER = "${sshpiperTestUser}"
HOST_SSHD_PORT = ${toString hostSshdPort}
''
+ builtins.readFile ./integration.py;
}