aboutsummaryrefslogtreecommitdiffstats
path: root/tests/by-name
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/by-name/at/atuin-sync/test.nix189
-rw-r--r--tests/by-name/ba/back/test.nix38
-rw-r--r--tests/by-name/dn/dns/test.nix2
-rw-r--r--tests/by-name/em/email-dns/nodes/mail_server.nix14
-rw-r--r--tests/by-name/em/email-dns/nodes/name_server.nix236
-rw-r--r--tests/by-name/em/email-dns/nodes/user.nix8
-rw-r--r--tests/by-name/em/email-dns/secrets/dkim/alice.com/private.age11
-rw-r--r--tests/by-name/em/email-dns/secrets/dkim/bob.com/private.age13
-rw-r--r--tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/private.age10
-rw-r--r--tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/private.age13
-rw-r--r--tests/by-name/em/email-dns/test.nix54
-rw-r--r--tests/by-name/em/email-http/nodes/mail_server.nix57
-rw-r--r--tests/by-name/em/email-http/nodes/user.nix26
-rw-r--r--tests/by-name/em/email-http/test.nix100
-rw-r--r--tests/by-name/em/email-ip/test.nix4
-rw-r--r--tests/by-name/gi/git-server/test.nix11
-rw-r--r--tests/by-name/ro/rocie/secrets/login.age16
-rw-r--r--tests/by-name/ro/rocie/test.nix106
-rw-r--r--tests/by-name/ru/rust-motd/test.nix63
-rw-r--r--tests/by-name/sh/sharkey-cpu/test.nix81
-rw-r--r--tests/by-name/sh/sharkey/test.nix102
-rw-r--r--tests/by-name/ta/taskchampion-sync/test.nix150
-rwxr-xr-xtests/common/acme/certs/generate (renamed from tests/by-name/em/email-dns/nodes/acme/certs/generate)0
-rwxr-xr-xtests/common/acme/certs/generate.ca (renamed from tests/by-name/em/email-dns/nodes/acme/certs/generate.ca)0
-rwxr-xr-xtests/common/acme/certs/generate.client (renamed from tests/by-name/em/email-dns/nodes/acme/certs/generate.client)0
-rw-r--r--tests/common/acme/certs/output/acme.test.cert.pem (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.cert.pem)0
-rw-r--r--tests/common/acme/certs/output/acme.test.key.pem (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.key.pem)0
-rw-r--r--tests/common/acme/certs/output/acme.test.template (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.template)0
-rw-r--r--tests/common/acme/certs/output/ca.cert.pem (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/ca.cert.pem)0
-rw-r--r--tests/common/acme/certs/output/ca.key.pem (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/ca.key.pem)0
-rw-r--r--tests/common/acme/certs/output/ca.template (renamed from tests/by-name/em/email-dns/nodes/acme/certs/output/ca.template)0
-rw-r--r--tests/common/acme/certs/snakeoil-certs.nix (renamed from tests/by-name/em/email-dns/nodes/acme/certs/snakeoil-certs.nix)0
-rw-r--r--tests/common/acme/client.nix (renamed from tests/by-name/em/email-dns/nodes/acme/client.nix)0
-rw-r--r--tests/common/acme/server.nix (renamed from tests/by-name/em/email-dns/nodes/acme/default.nix)27
-rw-r--r--tests/common/email/dkim/alice.com/public (renamed from tests/by-name/em/email-dns/secrets/dkim/alice.com/public)0
-rw-r--r--tests/common/email/dkim/bob.com/public (renamed from tests/by-name/em/email-dns/secrets/dkim/bob.com/public)0
-rwxr-xr-xtests/common/email/dkim/gen_key.sh (renamed from tests/by-name/em/email-dns/secrets/dkim/gen_key.sh)2
-rw-r--r--tests/common/email/dkim/mail1.server.com/public (renamed from tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/public)0
-rw-r--r--tests/common/email/dkim/mail2.server.com/public (renamed from tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/public)0
-rw-r--r--tests/common/email/hostKey (renamed from tests/by-name/em/email-dns/secrets/hostKey)0
40 files changed, 1042 insertions, 291 deletions
diff --git a/tests/by-name/at/atuin-sync/test.nix b/tests/by-name/at/atuin-sync/test.nix
new file mode 100644
index 0000000..d65c216
--- /dev/null
+++ b/tests/by-name/at/atuin-sync/test.nix
@@ -0,0 +1,189 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs;
+ name = "atuin-sync";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = let
+ atuinSession = "01969ec6b8d07e30a9d2df0911fbfe2a";
+ in {
+ acme = {
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ name_server = {nodes, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../common/acme/client.nix
+ ../../../common/dns/server.nix
+ ];
+
+ vhack.dns.zones = {
+ "atuin-sync.server" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.server.networking.primaryIPv6Address
+ ];
+ };
+ };
+ };
+
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ vhack = {
+ persist.enable = true;
+ nginx.enable = true;
+ atuin-sync = {
+ enable = true;
+ fqdn = "atuin-sync.server";
+ };
+ };
+ };
+
+ client1 = {config, ...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ environment.sessionVariables.ATUIN_SESSION = atuinSession;
+
+ environment.systemPackages = [
+ pkgs.atuin
+ pkgs.sqlite-interactive
+ ];
+ };
+ client2 = {config, ...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ environment.sessionVariables.ATUIN_SESSION = atuinSession;
+
+ environment.systemPackages = [
+ pkgs.atuin
+ pkgs.sqlite-interactive
+ ];
+ };
+ };
+
+ testScript = {nodes, ...}: let
+ syncLogin = pkgs.writeShellScript "login-atuin-sync-account" ''
+ atuin login --username syncy --password password1234 --key "$1"
+ '';
+
+ syncRegister = pkgs.writeShellScript "register-atuin-sync-account" ''
+ atuin register --username syncy --email syncy@email.com --password password1234
+ '';
+
+ mkSyncConfig = pkgs.writeShellScript "register-atuin-sync-account" ''
+ mkdir --parents ~/.config/atuin/
+ cat << EOF > ~/.config/atuin/config.toml
+ sync_address = "https://atuin-sync.server"
+
+ # Use the v2 sync
+ [sync]
+ records = true
+ EOF
+ '';
+
+ runCommandAndRecordInAtuin = pkgs.writeShellScript "run-command-and-record-in-atuin" ''
+ # SPDX-SnippetBegin
+ # SPDX-SnippetCopyrightText: 2023 mentalisttraceur (https://github.com/mentalisttraceur)
+ # Source: https://github.com/atuinsh/atuin/issues/1188#issuecomment-1698354107
+ run_and_record_in_atuin()
+ {
+ local id
+ local status
+ local escaped_command="$(printf '%q ' "$@")"
+ id="$(atuin history start -- "$escaped_command")"
+ "$@"
+ status=$?
+ atuin history end --exit $status "$id"
+ return $status
+ }
+ # SPDX-SnippetEnd
+
+ run_and_record_in_atuin "$@"
+ '';
+
+ acme = import ../../../common/acme {inherit pkgs;};
+ in
+ acme.prepare ["server" "client1" "client2"]
+ # Python
+ ''
+ server.wait_for_unit("atuin.service")
+ server.wait_for_open_port(443)
+
+ # Wait for the server to acquire the acme certificate
+ client1.wait_until_succeeds("curl https://atuin-sync.server")
+
+ with subtest("Setup client syncing"):
+ # See https://docs.atuin.sh/guide/sync/
+ for client in [client1, client2]:
+ client.succeed("${mkSyncConfig}")
+
+ client1.succeed("${syncRegister}")
+ client2.succeed(f"${syncLogin} '{client1.succeed("atuin key")}'")
+
+ with subtest("Can import shell history"):
+ client1.succeed("${runCommandAndRecordInAtuin} echo hi - client 1")
+ client2.succeed("${runCommandAndRecordInAtuin} echo hi - client 2")
+
+ with subtest("Can sync tasks"):
+ for client in [client1, client2]:
+ client.succeed("atuin sync --force")
+ client1.succeed("atuin sync --force")
+
+
+ with subtest("Have correct tasks"):
+ hist1 = client1.succeed("atuin history list --session --format '{command}'").strip().split('\n')
+ hist2 = client2.succeed("atuin history list --session --format '{command}'").strip().split('\n')
+
+ hist1.sort()
+ hist2.sort()
+
+ canonicalHistory = [
+ "echo hi - client 1",
+ "echo hi - client 2"
+ ]
+
+ assert hist1 == hist2, f"The clients don't have the same amount of history items, client1: '{hist1}', client2: '{hist2}'"
+ assert hist1 == canonicalHistory, f"The history is not correct: '{hist1}' vs. '{canonicalHistory}'"
+ '';
+}
diff --git a/tests/by-name/ba/back/test.nix b/tests/by-name/ba/back/test.nix
index 85cb611..41d6c8e 100644
--- a/tests/by-name/ba/back/test.nix
+++ b/tests/by-name/ba/back/test.nix
@@ -56,14 +56,9 @@ in
domain = "git.${domain}";
gitolite.adminPubkey = sshKeys.admin.pub;
};
- back = {
+ git-back = {
enable = true;
domain = "issues.${domain}";
-
- settings = {
- scan_path = "${config.services.gitolite.dataDir}/repositories";
- project_list = "${config.services.gitolite.dataDir}/projects.list";
- };
};
};
};
@@ -114,6 +109,12 @@ in
with subtest("admin can clone and configure gitolite-admin.git"):
+ server.succeed("sudo -u git ${pkgs.writeShellScript "delete_main_branch_on_server" ''
+ set -xe
+
+ cd ~git/repositories/gitolite-admin.git
+ git branch --move --force main master
+ ''}")
client.succeed("${pkgs.writeShellScript "setup-gitolite-admin.git" ''
set -xe
@@ -123,12 +124,9 @@ in
cp ${sshKeys.alice.pub} gitolite-admin/keydir/alice.pub
- (cd gitolite-admin && git switch -c master && git branch -D main)
-
(cd gitolite-admin && git add . && git commit -m 'Add keys for alice' && git push -u origin master)
cat ${gitoliteAdminConfSnippet} >> gitolite-admin/conf/gitolite.conf
(cd gitolite-admin && git add . && git commit -m 'Add support for wild repos' && git push)
- (cd gitolite-admin && git push -d origin main)
''}")
with subtest("alice can create a repo"):
@@ -152,35 +150,35 @@ in
cd alice/repo1
- git bug user create --avatar "" --email "alice@server.org" --name "alice" --non-interactive
+ git bug user new --avatar "" --email "alice@server.org" --name "alice" --non-interactive
- git bug add \
+ git bug bug new \
--title "Some bug title" \
--message "A long description of the bug. Probably has some code segments, maybe even *markdown* mark_up_ or other things" \
--non-interactive
- git bug add \
+ git bug bug new \
--title "Second bug title" \
--message "" \
--non-interactive
- git bug add \
+ git bug bug new \
--title "Third bug title" \
--message "" \
--non-interactive
- git bug select "$(git bug ls --format plain | awk '{print $1}' | head -n 1)"
+ git bug bug select "$(git bug bug --format plain | awk '{print $1}' | head -n 1)"
- git bug comment add --message "Some comment message" --non-interactive
- git bug comment add --message "Second comment message" --non-interactive
+ git bug bug comment new --message "Some comment message" --non-interactive
+ git bug bug comment new --message "Second comment message" --non-interactive
# TODO: This should use `git bug push`, but their ssh implementation is just
# too special to work in a VM test <2025-03-08>
git push origin +refs/bugs/*
git push origin +refs/identities/*
- ssh git@${domain} -- config alice/repo1 --add cgit.owner Alice
- ssh git@${domain} -- perms alice/repo1 + READERS @all
+ ssh git@git.${domain} -- config alice/repo1 --add cgit.owner Alice
+ ssh git@git.${domain} -- perms alice/repo1 + READERS @all
''}")
with subtest("back server starts"):
@@ -190,12 +188,12 @@ in
client.succeed("${pkgs.writeShellScript "curl-back" ''
set -xe
- curl --insecure --fail --show-error "https://issues.${domain}/alice/repo1.git/issues/open" --output /root/issues.html
+ curl --insecure --fail --show-error "https://issues.${domain}/alice/repo1/issues/?query=status:open" --output /root/issues.html
grep -- 'Second bug title' /root/issues.html
curl --insecure --fail --show-error "https://issues.${domain}/" --output /root/repos.html
grep -- 'repo' /root/repos.html
- grep -- "&#60;No description&#62;" /root/repos.html
+ grep -- "&lt;No description&gt;" /root/repos.html
grep -- '<span class="user-name">Alice</span>' /root/repos.html
''} >&2")
diff --git a/tests/by-name/dn/dns/test.nix b/tests/by-name/dn/dns/test.nix
index 07a6e8c..01d8833 100644
--- a/tests/by-name/dn/dns/test.nix
+++ b/tests/by-name/dn/dns/test.nix
@@ -55,7 +55,7 @@ in
vhack = {
dns = {
enable = true;
- interfaces = lib.debug.traceValSeqN 2 [
+ interfaces = [
(lib.head config.networking.interfaces.eth1.ipv4.addresses).address
(lib.head config.networking.interfaces.eth1.ipv6.addresses).address
];
diff --git a/tests/by-name/em/email-dns/nodes/mail_server.nix b/tests/by-name/em/email-dns/nodes/mail_server.nix
index a8c528a..279d289 100644
--- a/tests/by-name/em/email-dns/nodes/mail_server.nix
+++ b/tests/by-name/em/email-dns/nodes/mail_server.nix
@@ -13,7 +13,8 @@
extraModules
++ [
../../../../../modules
- ./acme/client.nix
+ ../../../../common/acme/client.nix
+ ../../../../common/dns/client.nix
];
environment.systemPackages = [
@@ -21,12 +22,7 @@
pkgs.openssl
];
- networking.nameservers = lib.mkForce [
- nodes.name_server.networking.primaryIPAddress
- nodes.name_server.networking.primaryIPv6Address
- ];
-
- age.identityPaths = ["${../secrets/hostKey}"];
+ age.identityPaths = ["${../../../../common/email/hostKey}"];
vhack = {
stalwart-mail = {
@@ -36,8 +32,8 @@
security = {
dkimKeys = let
loadKey = name: {
- dkimPublicKey = builtins.readFile (../secrets/dkim + "/${name}/public");
- dkimPrivateKeyPath = ../secrets/dkim + "/${name}/private.age";
+ dkimPublicKey = builtins.readFile (../../../../common/email/dkim + "/${name}/public");
+ dkimPrivateKeyPath = ../../../../common/email/dkim + "/${name}/private.age";
keyAlgorithm = "ed25519-sha256";
};
in {
diff --git a/tests/by-name/em/email-dns/nodes/name_server.nix b/tests/by-name/em/email-dns/nodes/name_server.nix
index ef657f4..bde1a16 100644
--- a/tests/by-name/em/email-dns/nodes/name_server.nix
+++ b/tests/by-name/em/email-dns/nodes/name_server.nix
@@ -63,7 +63,7 @@
adkim = "strict";
aspf = "strict";
fo = ["0" "1" "d" "s"];
- p = "quarantine";
+ p = "reject";
rua = cfg.admin;
ruf = [cfg.admin];
}
@@ -139,14 +139,10 @@ in {
extraModules
++ [
../../../../../modules
- ./acme/client.nix
+ ../../../../common/acme/client.nix
+ ../../../../common/dns/server.nix
];
- networking.nameservers = lib.mkForce [
- nodes.name_server.networking.primaryIPAddress
- nodes.name_server.networking.primaryIPv6Address
- ];
-
services.nginx = {
logError = "stderr debug";
virtualHosts = let
@@ -175,145 +171,121 @@ in {
nginx = {
enable = true;
};
- dns = {
- enable = true;
- openFirewall = true;
- interfaces = [
- nodes.name_server.networking.primaryIPAddress
- nodes.name_server.networking.primaryIPv6Address
- ];
-
- zones = let
- stsZone = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
+ dns.zones = let
+ stsZone = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
- useOrigin = false;
+ useOrigin = false;
- A = [
- nodes.name_server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.name_server.networking.primaryIPv6Address
- ];
+ A = [
+ nodes.name_server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+ };
+ in {
+ "arpa" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
};
- in {
- "arpa" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
-
- PTR = [
- {
- name = "acme.test";
- ip.v4 = nodes.acme.networking.primaryIPAddress;
- }
- {
- name = "acme.test";
- ip.v6 = nodes.acme.networking.primaryIPv6Address;
- }
+ useOrigin = false;
- {
- name = "alice.com";
- ip.v4 = nodes.alice.networking.primaryIPAddress;
- }
- {
- name = "alice.com";
- ip.v6 = nodes.alice.networking.primaryIPv6Address;
- }
+ PTR = [
+ {
+ name = "acme.test";
+ ip.v4 = nodes.acme.networking.primaryIPAddress;
+ }
+ {
+ name = "acme.test";
+ ip.v6 = nodes.acme.networking.primaryIPv6Address;
+ }
- {
- name = "bob";
- ip.v4 = nodes.bob.networking.primaryIPAddress;
- }
- {
- name = "bob";
- ip.v6 = nodes.bob.networking.primaryIPv6Address;
- }
+ {
+ name = "alice.com";
+ ip.v4 = nodes.alice.networking.primaryIPAddress;
+ }
+ {
+ name = "alice.com";
+ ip.v6 = nodes.alice.networking.primaryIPv6Address;
+ }
- {
- name = "mail1.server.com";
- ip.v4 = nodes.mail1_server.networking.primaryIPAddress;
- }
- {
- name = "mail1.server.com";
- ip.v6 = nodes.mail1_server.networking.primaryIPv6Address;
- }
+ {
+ name = "bob";
+ ip.v4 = nodes.bob.networking.primaryIPAddress;
+ }
+ {
+ name = "bob";
+ ip.v6 = nodes.bob.networking.primaryIPv6Address;
+ }
- {
- name = "mail2.server.com";
- ip.v4 = nodes.mail2_server.networking.primaryIPAddress;
- }
- {
- name = "mail2.server.com";
- ip.v6 = nodes.mail2_server.networking.primaryIPv6Address;
- }
+ {
+ name = "mail1.server.com";
+ ip.v4 = nodes.mail1_server.networking.primaryIPAddress;
+ }
+ {
+ name = "mail1.server.com";
+ ip.v6 = nodes.mail1_server.networking.primaryIPv6Address;
+ }
- {
- name = "ns.server.com";
- ip.v4 = nodes.name_server.networking.primaryIPAddress;
- }
- {
- name = "ns.server.com";
- ip.v6 = nodes.name_server.networking.primaryIPv6Address;
- }
- ];
- };
+ {
+ name = "mail2.server.com";
+ ip.v4 = nodes.mail2_server.networking.primaryIPAddress;
+ }
+ {
+ name = "mail2.server.com";
+ ip.v6 = nodes.mail2_server.networking.primaryIPv6Address;
+ }
- "alice.com" = mkZone "alice" nodes lib nodes.mail2_server.vhack.stalwart-mail;
- "mta-sts.alice.com" = stsZone;
- "bob.com" = mkZone "bob" nodes lib nodes.mail1_server.vhack.stalwart-mail;
- "mta-sts.bob.com" = stsZone;
- "mail1.server.com" = mkServerZone "mail1" nodes lib;
- "mail2.server.com" = mkServerZone "mail2" nodes lib;
- "ns.server.com" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
+ {
+ name = "ns.server.com";
+ ip.v4 = nodes.name_server.networking.primaryIPAddress;
+ }
+ {
+ name = "ns.server.com";
+ ip.v6 = nodes.name_server.networking.primaryIPv6Address;
+ }
+ ];
+ };
- A = [
- nodes.name_server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.name_server.networking.primaryIPv6Address
- ];
+ "alice.com" = mkZone "alice" nodes lib nodes.mail2_server.vhack.stalwart-mail;
+ "mta-sts.alice.com" = stsZone;
+ "bob.com" = mkZone "bob" nodes lib nodes.mail1_server.vhack.stalwart-mail;
+ "mta-sts.bob.com" = stsZone;
+ "mail1.server.com" = mkServerZone "mail1" nodes lib;
+ "mail2.server.com" = mkServerZone "mail2" nodes lib;
+ "ns.server.com" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
};
- "acme.test" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
+ useOrigin = false;
- A = [
- nodes.acme.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.acme.networking.primaryIPv6Address
- ];
+ A = [
+ nodes.name_server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+ };
+ "server.com" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
};
- "server.com" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
- NS = [
- "ns.server.com."
- ];
- };
+ useOrigin = false;
+ NS = [
+ "ns.server.com."
+ ];
};
};
};
diff --git a/tests/by-name/em/email-dns/nodes/user.nix b/tests/by-name/em/email-dns/nodes/user.nix
index e4db347..fba02ce 100644
--- a/tests/by-name/em/email-dns/nodes/user.nix
+++ b/tests/by-name/em/email-dns/nodes/user.nix
@@ -8,7 +8,8 @@
...
}: {
imports = [
- ./acme/client.nix
+ ../../../../common/acme/client.nix
+ ../../../../common/dns/client.nix
];
environment.systemPackages = [
@@ -20,11 +21,6 @@
pkgs.openssl
];
- networking.nameservers = lib.mkForce [
- nodes.name_server.networking.primaryIPAddress
- nodes.name_server.networking.primaryIPv6Address
- ];
-
users.users."${user}" = {isNormalUser = true;};
systemd.tmpfiles.rules = [
diff --git a/tests/by-name/em/email-dns/secrets/dkim/alice.com/private.age b/tests/by-name/em/email-dns/secrets/dkim/alice.com/private.age
deleted file mode 100644
index 97b9be7..0000000
--- a/tests/by-name/em/email-dns/secrets/dkim/alice.com/private.age
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFJzZ1dwUSAxanpG
-VWxCYjF3aWFUUEM0b2Q2bGJUNEJZMGFlVkJpTFg3eUc1UGdyblF3CnlJVXY2Ti9z
-SmltMmIzM25jajl3WE5kMkVsY05NUkpDdzlJVHdJYXByZjQKLT4gU0t5SSxMLWdy
-ZWFzZSB6Tgova0Juc0x3RlFrR1NSVzBIMllYRmZiRXlzN2hSdHZQaFVDS3FPUFNr
-NzBiM0Q5dExOREgydFpKWm1MaGQ5QkxBCgotLS0gNC81ZHQ5eFBrUGJxWXF6dWF4
-Mlg0WHBXS2RqeW1uY1hGUVJXbHpUaDhlWQpih0QTGjejnwIQ2lvDFS1wbNiiOJ+c
-awJ2tX8chzWm+wOECaIZAqwW2NwVZj5Sj+Vzv6LQ1BVaQAiEN41GRvjyP/u3X+d+
-LKI3bPa8DWxQNd7/zAhFjSB1KEIBrqGb2GtW/Yv8Mu07V8IV/MaGUwpDOXgvFQVH
-UQ1qpM0R1r190IuV2Y7M558J42crH9/5mIvMH5rW++Ru
------END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/em/email-dns/secrets/dkim/bob.com/private.age b/tests/by-name/em/email-dns/secrets/dkim/bob.com/private.age
deleted file mode 100644
index 6bd9e28..0000000
--- a/tests/by-name/em/email-dns/secrets/dkim/bob.com/private.age
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFJzZ1dwUSBtQ1lC
-bmtXZWlqeE1SWmR2d1JTcEZMZFRKZW1jVnRGSHpUMEM1cnpvTkdFCkRVbmlNV0ZS
-SDdobTFFQUcyU3dMVXlTditvZXN0L0pPN1ZHaWtxOFZSL1EKLT4gfSM6JGpjOlot
-Z3JlYXNlICdRYiBLKlV6CmZmczdSa2U5cWl6OG5QL0VaUGsyNUlCVFJ1UjJxVnpV
-ZE1sN2lSRTgzVjI1S3pJVzdqN05WUVZmaTRYMXptb0kKczJEOG9EM2xtMFRHd3Vt
-TUpiK2RzZkRwZTZqb3lEOGpKNy80Vk9BVDlSNjhYSkROYlVGQ1ZESGhIV3ZJWVEK
-LS0tIEk0MXVEci9ITERYRzZFbTJJQWxSQzhFV3NqV2o3M0NvVlNhLzhhVkJYcTQK
-GJtIH4AxSSwZhnLn5IUhOihz9Ai2lLnf00uhvF6+i29TtyEgxgWhisBJtzShB/Aq
-Bct5em093jryJPNQBNDJpImEViP9WS/kTqQG0bnu2i/Nr5+vZyRcK8qv75guMxki
-p7sUirbzCNtA+5JGGJb30PqOAWpflBPL0fkC5L7JyAjhNRCOgIL+QQS3mosU1AYJ
-izFOdod2DA==
------END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/private.age b/tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/private.age
deleted file mode 100644
index 03bb0b1..0000000
--- a/tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/private.age
+++ /dev/null
@@ -1,10 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFJzZ1dwUSBiZmcz
-OVlacDhjS3pCWlZCYlpyVVFoQWxFN1Z0eTJIY2ovNVg2MjQ1SXpVClRZUnhkblFI
-c0VyelMxYzBsZ2NMUEVzWmtTSzJuVTdoVHFiZEc5cEd3aHMKLT4gJyctZ3JlYXNl
-IG1tIFt2YSAwCkQvY2VnMlBTSHhPbXJ2NE55ck0KLS0tIGkxWHdQb0NIVmZyaTdW
-bmorU2NLMjByakpTMlo1NUtFQ0NFd1YvOC9EaFEKtDNLHVtnsFiyhsREJOPq1xlk
-74MURNlYnlF1IMrUaA3oUQSR5M34Crg7rHtjF54OsRhm79Y1dGHWeeC3evVNVpY3
-1dn/q/12aWIzT/TgGcSi3bK5fPkv+nMs/WPKTREHJ1HcWLGDeH6e8uTV7lAwiSuP
-PjYhDbnNUCMMyaBsgbtCnMe8HuHdTwXQWuh0dApS5iL3z8qoSQ==
------END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/private.age b/tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/private.age
deleted file mode 100644
index 6768973..0000000
--- a/tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/private.age
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFJzZ1dwUSBBZ3Ex
-ZWNUU01JK0ZGOEhEWUpEM3JLdXpjc3doMVA2RUI5TVVpblQxS0JJCnlHRmdVVk05
-MW56cEt4M00raE1nU3JZaTMvTXdUQXdzbTYvVElqVjdvNWcKLT4gRnJFLWdyZWFz
-ZSA5bEhvWn4Kb01McHBBekVTalcwM0tob3VUd3NuVFlvZUpnSFQxbXVBaEJNMVlQ
-K1BiSjRCL1YrZDZoSnFBNU9aQkQyNjRoSwpqcnBnd2NJQlMxaHdoa0pPWGR0SEZO
-SU5DNjFxb3JQTTZITVZNRGF1VUR4Zm9laWhYd3lHZityRTNJVVF1bXdwCnhGYzMK
-LS0tIFFsN0Q3V1pxWUduSU9xd21uVEF2R0tJcURYa1FOTS9kMDh6RGkwNS9SMUEK
-Ni+1WbmAiavBCwLg8r1nvVipXQJ2/cItN1MgWlYe0+UrgLxRU5VLhoWi9BEulGEV
-KHkNWyMCK4Tl/NJt1PAQVJ6QBVHYYxIYQWY1QkNCqXe1YdaJ5jDcWGSZdhbCrzMN
-3tx3EPhigU2DiQZB6l4OOaHLjAw2a+POVwwsCavnRp7vEhs/5O2t5Lo2vCoDGCot
-6o+Sdr86mw==
------END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/em/email-dns/test.nix b/tests/by-name/em/email-dns/test.nix
index 32447ae..c7ba3b3 100644
--- a/tests/by-name/em/email-dns/test.nix
+++ b/tests/by-name/em/email-dns/test.nix
@@ -31,9 +31,9 @@ in
lib,
...
}: {
- imports = [./nodes/acme];
- networking.nameservers = lib.mkForce [
- nodes.name_server.networking.primaryIPAddress
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
];
};
@@ -44,7 +44,7 @@ in
{
class = "individual";
name = "bob";
- secret = "bob-password";
+ secret = "{PLAIN}bob-password";
email = ["bob@bob.com"];
};
@@ -53,7 +53,7 @@ in
{
class = "individual";
name = "alice";
- secret = "alice-password";
+ secret = "{PLAIN}alice-password";
email = ["alice@alice.com"];
};
@@ -89,23 +89,14 @@ in
exit 1
}
'';
- inherit (pkgs) lib;
+
+ acme = import ../../../common/acme {inherit pkgs;};
in
- /*
- python
- */
+ acme.prepare ["mail1_server" "mail2_server" "alice" "bob"]
+ # Python
''
from time import sleep
- # Start dependencies for the other services
- acme.start()
- acme.wait_for_unit("pebble.service")
- name_server.start()
- name_server.wait_for_unit("nsd.service")
-
- # Start the actual testing machines
- start_all()
-
mail1_server.wait_for_unit("stalwart-mail.service")
mail1_server.wait_for_open_port(993) # imap
mail1_server.wait_for_open_port(465) # smtp
@@ -119,33 +110,6 @@ in
name_server.wait_until_succeeds("stat /var/lib/acme/mta-sts.alice.com/cert.pem")
name_server.wait_until_succeeds("stat /var/lib/acme/mta-sts.bob.com/cert.pem")
- with subtest("Add pebble ca key to all services"):
- for node in [name_server, mail1_server, mail2_server, alice, bob]:
- node.succeed("${pkgs.writeShellScript "fetch-and-set-ca" ''
- set -xe
-
- # Fetch the randomly generated ca certificate
- curl https://acme.test:15000/roots/0 > /tmp/ca.crt
- curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt
-
- # Append it to the various system stores
- # The file paths are from <nixpgks>/modules/security/ca.nix
- for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do
- cert_path="/etc/$cert_path"
-
- mv "$cert_path" "$cert_path.old"
- cat "$cert_path.old" > "$cert_path"
- cat /tmp/ca.crt >> "$cert_path"
- done
-
- export NIX_SSL_CERT_FILE=/tmp/ca.crt
- export SSL_CERT_FILE=/tmp/ca.crt
-
- # TODO
- # # P11-Kit trust source.
- # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source";
- ''}")
-
with subtest("Both mailserver successfully started all services"):
import json
def all_services_running(host):
diff --git a/tests/by-name/em/email-http/nodes/mail_server.nix b/tests/by-name/em/email-http/nodes/mail_server.nix
new file mode 100644
index 0000000..e94c4e9
--- /dev/null
+++ b/tests/by-name/em/email-http/nodes/mail_server.nix
@@ -0,0 +1,57 @@
+{
+ extraModules,
+ pkgs,
+ vhackPackages,
+}: {
+ mkMailServer = serverName: principal: {
+ config,
+ lib,
+ nodes,
+ ...
+ }: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../../modules
+ ../../../../common/acme/client.nix
+ ];
+
+ environment.systemPackages = [
+ pkgs.bind
+ pkgs.openssl
+ ];
+
+ networking.nameservers = lib.mkForce [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ age.identityPaths = ["${../../../../common/email/hostKey}"];
+
+ vhack = {
+ stalwart-mail = {
+ enable = true;
+ fqdn = "${serverName}.server.com";
+ admin = "admin@${serverName}.server.com";
+ security = {
+ dkimKeys = let
+ loadKey = name: {
+ dkimPublicKey = builtins.readFile (../../../../common/email/dkim + "/${name}/public");
+ dkimPrivateKeyPath = ../../../../common/email/dkim + "/${name}/private.age";
+ keyAlgorithm = "ed25519-sha256";
+ };
+ in {
+ "mail.server.com" = loadKey "mail1.server.com";
+ "bob.com" = loadKey "bob.com";
+ };
+ verificationMode = "strict";
+ };
+ openFirewall = true;
+ principals =
+ if principal == null
+ then null
+ else [principal];
+ };
+ };
+ };
+}
diff --git a/tests/by-name/em/email-http/nodes/user.nix b/tests/by-name/em/email-http/nodes/user.nix
new file mode 100644
index 0000000..73b9ff7
--- /dev/null
+++ b/tests/by-name/em/email-http/nodes/user.nix
@@ -0,0 +1,26 @@
+{
+ pkgs,
+ vhackPackages,
+}: {
+ mkUser = user: serverName: {
+ nodes,
+ lib,
+ ...
+ }: {
+ imports = [
+ ../../../../common/acme/client.nix
+ ];
+
+ environment.systemPackages = [
+ pkgs.bind
+ pkgs.openssl
+ ];
+
+ networking.nameservers = lib.mkForce [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ users.users."${user}" = {isNormalUser = true;};
+ };
+}
diff --git a/tests/by-name/em/email-http/test.nix b/tests/by-name/em/email-http/test.nix
new file mode 100644
index 0000000..82b4c45
--- /dev/null
+++ b/tests/by-name/em/email-http/test.nix
@@ -0,0 +1,100 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}: let
+ mail_server = import ./nodes/mail_server.nix {inherit extraModules pkgs vhackPackages;};
+ inherit (mail_server) mkMailServer;
+ user = import ./nodes/user.nix {inherit pkgs vhackPackages;};
+ inherit (user) mkUser;
+in
+ nixos-lib.runTest {
+ hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+ name = "email-http";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ acme = {
+ nodes,
+ lib,
+ ...
+ }: {
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+
+ name_server = {nodes, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../common/acme/client.nix
+ ../../../common/dns/server.nix
+ ];
+
+ vhack.dns.zones = {
+ "mail.server.com" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.mail_server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.mail_server.networking.primaryIPv6Address
+ ];
+ };
+ };
+ };
+
+ mail_server = mkMailServer "mail" null;
+
+ bob = mkUser "bob" "mail";
+ };
+
+ # TODO(@bpeetz): This test should also test the http JMAP features of stalwart-mail. <2025-04-12>
+ testScript = _: let
+ acme = import ../../../common/acme {inherit pkgs;};
+ in
+ acme.prepare ["mail_server" "bob"]
+ # Python
+ ''
+ mail_server.wait_for_unit("stalwart-mail.service")
+ mail_server.wait_for_open_port(993) # imap
+ mail_server.wait_for_open_port(465) # smtp
+
+ bob.wait_for_unit("multi-user.target")
+
+ with subtest("The mailserver successfully started all services"):
+ import json
+ def all_services_running(host):
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+ all_services_running(mail_server)
+
+ with subtest("Bob can use the self-service interface"):
+ bob.succeed("${pkgs.writeShellScript "check-self-service" ''
+ curl mail.server.com --location --output /home/bob/output.html;
+ ''}")
+
+ bob.copy_from_vm("/home/bob", "")
+ '';
+ }
diff --git a/tests/by-name/em/email-ip/test.nix b/tests/by-name/em/email-ip/test.nix
index 688cd8f..dabc404 100644
--- a/tests/by-name/em/email-ip/test.nix
+++ b/tests/by-name/em/email-ip/test.nix
@@ -113,13 +113,13 @@ in
{
class = "individual";
name = "alice";
- secret = "alice-password";
+ secret = "{PLAIN}alice-password";
email = ["alice@${domain}"];
}
{
class = "individual";
name = "bob";
- secret = "bob-password";
+ secret = "{PLAIN}bob-password";
email = ["bob@${domain}"];
}
];
diff --git a/tests/by-name/gi/git-server/test.nix b/tests/by-name/gi/git-server/test.nix
index 5cd8c33..4e503b6 100644
--- a/tests/by-name/gi/git-server/test.nix
+++ b/tests/by-name/gi/git-server/test.nix
@@ -122,6 +122,12 @@ in
with subtest("admin can clone and configure gitolite-admin.git"):
+ server.succeed("sudo -u git ${pkgs.writeShellScript "delete_main_branch_on_server" ''
+ set -xe
+
+ cd ~git/repositories/gitolite-admin.git
+ git branch --move --force main master
+ ''}")
client.succeed("${pkgs.writeShellScript "setup-gitolite-admin.git" ''
set -xe
@@ -132,12 +138,9 @@ in
cp ${sshKeys.alice.pub} gitolite-admin/keydir/alice.pub
cp ${sshKeys.bob.pub} gitolite-admin/keydir/bob.pub
- (cd gitolite-admin && git switch -c master && git branch -D main)
-
(cd gitolite-admin && git add . && git commit -m 'Add keys for alice, bob' && git push -u origin master)
cat ${gitoliteAdminConfSnippet} >> gitolite-admin/conf/gitolite.conf
(cd gitolite-admin && git add . && git commit -m 'Add support for wild repos' && git push)
- (cd gitolite-admin && git push -d origin main)
''}")
server.succeed("${pkgs.writeShellScript "verify gitolite-admin.conf" ''
@@ -202,7 +205,7 @@ in
cd ~bob
# Disable ssl verification, as the certs are self-signed
- git -c http.sslVerify=false clone https://server/alice/alice-project.git
+ git -c http.sslVerify=false clone https://server/alice/alice-project
''}")
with subtest("Alice can change settings in her repo"):
diff --git a/tests/by-name/ro/rocie/secrets/login.age b/tests/by-name/ro/rocie/secrets/login.age
new file mode 100644
index 0000000..33d63be
--- /dev/null
+++ b/tests/by-name/ro/rocie/secrets/login.age
@@ -0,0 +1,16 @@
+-----BEGIN AGE ENCRYPTED FILE-----
+YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzMWE5dTBiU0hDUC9jUi93
+Y1phYllHRk9YSHBzUGQ2YmF5ZC9ydXNGV0JrClRpTjZZUHZ5MEFFa0VrYVVhTkE2
+eCtSaEU1YVlhNjFNYlRRYzNCdjhYRWMKLT4gWDI1NTE5IDUrZWdDUmpQcFBOcE0x
+UE5QRDR5NXVXUHdQOVk3UGV1S3lCc0pUQmZIZ00KUldVSVF3TzB0cHFVaDZuNlZR
+b2FoT0lVSTZydHFTNHhnQ3U0NGdSR1k1MAotPiBzc2gtZWQyNTUxOSBSc2dXcFEg
+dldGZU15UXgrRTMxRkp2MEVKUllWQ3VFdnJDMnM4OS8wc202WW9lNW5BYwpPWjV0
+cmNuaDlPZndtUVVScm5TaGlvVUhHa0JiN1MvbDhCTTUxYzNhM3RRCi0+IDxXeEhv
+cC1ncmVhc2UKM3N5OHRLNTJEY1NIeGlWYm9yR096Y1NpSlVOM1lYQk9jOHkxU3N2
+K2c3QitDYnR6QTJOOWczV0xBa2dEUE1PTQpYU2Z1elZwRzU0Tm1RVDE2VWVqekUw
+bFROLzU0c2NNTXYwL2N5QkxTaGtXUWxKVVF6SE0KLS0tIGlYMHIvUkJpZUR0SHo4
+cldLSTdnbU90SGJTcGZGaHkyOTZON0hka3BLdlEKeP4nHmKWvJfqgEXuiLBMzldi
+n1qIsnlF3IU1EA0abJg/RK1BFwWlx4wBlLmViw6UTL+VEw8lv23PuZl2t7UtXVzQ
+smXDapW8nInNmTaElBPdwJ072/dD0Ly+KF95Qr0FDDv+jlKG/D/Mw+xD4jvuJHSo
+2HQnPF6MLTjCxpyPPggleWgKrBQggHBjm/pHtOKmPC5qfp+LAjmQoJXny/0X6cA=
+-----END AGE ENCRYPTED FILE-----
diff --git a/tests/by-name/ro/rocie/test.nix b/tests/by-name/ro/rocie/test.nix
new file mode 100644
index 0000000..c2ba97a
--- /dev/null
+++ b/tests/by-name/ro/rocie/test.nix
@@ -0,0 +1,106 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+ name = "rocie";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ acme = {...}: {
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ name_server = {nodes, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../common/acme/client.nix
+ ../../../common/dns/server.nix
+ ];
+
+ vhack.dns.zones = {
+ "rocie.server" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.server.networking.primaryIPv6Address
+ ];
+ };
+ };
+ };
+
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ age.identityPaths = ["${../../../common/email/hostKey}"];
+
+ vhack = {
+ persist.enable = true;
+ nginx.enable = true;
+ rocie = {
+ enable = true;
+ domain = "rocie.server";
+ loginSecret = ./secrets/login.age;
+ };
+ };
+ };
+
+ client = {...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ };
+
+ testScript = {nodes, ...}: let
+ acme = import ../../../common/acme {inherit pkgs;};
+ in
+ acme.prepare ["server" "client"]
+ # Python
+ ''
+ server.wait_for_unit("rocie.service")
+
+ with subtest("All services running"):
+ import json
+ def all_services_running(host):
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+ all_services_running(server)
+
+ client.wait_until_succeeds("curl --verbose https://rocie.server/api/can-be-provisioned > out.file")
+ client.copy_from_vm("out.file")
+ '';
+}
diff --git a/tests/by-name/ru/rust-motd/test.nix b/tests/by-name/ru/rust-motd/test.nix
new file mode 100644
index 0000000..6623c0c
--- /dev/null
+++ b/tests/by-name/ru/rust-motd/test.nix
@@ -0,0 +1,63 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs;
+
+ name = "rust-motd";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ vhack = {
+ rust-motd.enable = true;
+ };
+ };
+ };
+
+ testScript = {nodes, ...}:
+ /*
+ python
+ */
+ ''
+ from time import sleep
+
+ start_all()
+
+ # Give the service time to run.
+ sleep(3)
+
+ with subtest("All services running"):
+ import json
+ def all_services_running(host):
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+ all_services_running(server)
+
+ with subtest("Motd generated"):
+ sleep(1)
+ server.succeed("cat /var/lib/rust-motd/motd | tee /dev/stderr | grep --invert-match Error")
+
+ server.copy_from_vm("/var/lib/rust-motd/motd")
+ '';
+}
diff --git a/tests/by-name/sh/sharkey-cpu/test.nix b/tests/by-name/sh/sharkey-cpu/test.nix
new file mode 100644
index 0000000..47c16ff
--- /dev/null
+++ b/tests/by-name/sh/sharkey-cpu/test.nix
@@ -0,0 +1,81 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+ name = "sharkey-cpu";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ vhack = {
+ persist.enable = true;
+ nginx.enable = true;
+ sharkey = {
+ enable = true;
+ fqdn = "sharkey.server";
+ };
+ };
+ systemd.services = {
+ # Avoid an error from this service.
+ "acme-sharkey.server".enable = false;
+
+ # Test that sharkey's hardening still allows access to the CPUs.
+ sharkey.serviceConfig.ExecStart = let
+ nodejs = pkgs.lib.getExe pkgs.nodejs;
+ script = pkgs.writeTextFile {
+ name = "script.js";
+ text = ''
+ import * as os from 'node:os';
+
+ console.log(os.cpus()[0].model)
+ console.log(os.cpus().length)
+ '';
+ };
+ in
+ pkgs.lib.mkForce "${nodejs} ${script}";
+ };
+ };
+ };
+
+ testScript = {nodes, ...}:
+ /*
+ python
+ */
+ ''
+ from time import sleep
+
+ start_all()
+
+ # Give the service time to run.
+ sleep(3)
+
+ with subtest("All services running"):
+ import json
+ def all_services_running(host):
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+ all_services_running(server)
+ '';
+}
diff --git a/tests/by-name/sh/sharkey/test.nix b/tests/by-name/sh/sharkey/test.nix
new file mode 100644
index 0000000..0d79cd2
--- /dev/null
+++ b/tests/by-name/sh/sharkey/test.nix
@@ -0,0 +1,102 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+ name = "sharkey";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ acme = {...}: {
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ name_server = {nodes, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../common/acme/client.nix
+ ../../../common/dns/server.nix
+ ];
+
+ vhack.dns.zones = {
+ "sharkey.server" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.server.networking.primaryIPv6Address
+ ];
+ };
+ };
+ };
+
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ vhack = {
+ persist.enable = true;
+ nginx.enable = true;
+ sharkey = {
+ enable = true;
+ fqdn = "sharkey.server";
+ };
+ };
+ };
+
+ client = {...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ };
+
+ testScript = {nodes, ...}: let
+ acme = import ../../../common/acme {inherit pkgs;};
+ in
+ acme.prepare ["server" "client"]
+ # Python
+ ''
+ server.wait_for_unit("sharkey.service")
+
+ with subtest("All services running"):
+ import json
+ def all_services_running(host):
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+ all_services_running(server)
+
+ client.wait_until_succeeds("curl --silent https://sharkey.server | grep 'Thank you for using Sharkey!'")
+ '';
+}
diff --git a/tests/by-name/ta/taskchampion-sync/test.nix b/tests/by-name/ta/taskchampion-sync/test.nix
new file mode 100644
index 0000000..4bca4e0
--- /dev/null
+++ b/tests/by-name/ta/taskchampion-sync/test.nix
@@ -0,0 +1,150 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}:
+nixos-lib.runTest {
+ hostPkgs = pkgs;
+ name = "taskchampion-sync";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = let
+ taskwarriorPackage = pkgs.taskwarrior3.overrideAttrs (final: prev: {
+ cmakeFlags = (prev.cmakeFlags or []) ++ ["-DENABLE_TLS_NATIVE_ROOTS=true"];
+ });
+ in {
+ acme = {
+ imports = [
+ ../../../common/acme/server.nix
+ ../../../common/dns/client.nix
+ ];
+ };
+ name_server = {nodes, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../common/acme/client.nix
+ ../../../common/dns/server.nix
+ ];
+
+ vhack.dns.zones = {
+ "taskchampion.server" = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.server.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.server.networking.primaryIPv6Address
+ ];
+ };
+ };
+ };
+
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ vhack = {
+ persist.enable = true;
+ nginx.enable = true;
+ taskchampion-sync = {
+ enable = true;
+ fqdn = "taskchampion.server";
+ };
+ };
+ };
+
+ task_client1 = {config, ...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ environment.systemPackages = [
+ taskwarriorPackage
+ ];
+ };
+ task_client2 = {config, ...}: {
+ imports = [
+ ../../../common/acme/client.nix
+ ../../../common/dns/client.nix
+ ];
+
+ environment.systemPackages = [
+ taskwarriorPackage
+ ];
+ };
+ };
+
+ testScript = {nodes, ...}: let
+ # Generated with uuidgen
+ uuid = "bf01376e-04a4-435a-9263-608567531af3";
+ password = "nixos-test";
+
+ mkSyncConfig = path:
+ pkgs.writeShellScript "setup-config-file" ''
+ set -xe
+
+ mkdir --parents "$(dirname "${path}")"
+ echo 'sync.server.url=https://taskchampion.server' >> "${path}"
+ echo 'sync.server.client_id=${uuid}' >> "${path}"
+ echo 'sync.encryption_secret=${password}' >> "${path}"
+ '';
+
+ acme = import ../../../common/acme {inherit pkgs;};
+ in
+ acme.prepare ["server" "task_client1" "task_client2"]
+ # Python
+ ''
+ server.wait_for_unit("taskchampion-sync-server.service")
+ server.wait_for_open_port(443)
+
+ with subtest("Setup task syncing"):
+ for task in [task_client1, task_client2]:
+ # See man task-sync(5)
+ task.succeed("mkdir ~/.task")
+ task.succeed("${mkSyncConfig "$HOME/.taskrc"}")
+
+ with subtest("Can create tasks"):
+ task_client1.succeed("task add 'First task -- task_client1'")
+ task_client2.succeed("task add 'First task -- task_client2'")
+
+ # Wait for the server to acquire the acme certificate
+ task_client1.wait_until_succeeds("curl https://taskchampion.server")
+
+ with subtest("Can sync tasks"):
+ for task in [task_client1, task_client2]:
+ task.succeed("task sync")
+ task_client1.succeed("task sync")
+
+
+ with subtest("Have correct tasks"):
+ count1 = task_client1.succeed("task count")
+ count2 = task_client2.succeed("task count")
+
+ assert int(count1) == 2, f"We don't have exactly 2 tasks, but {count1}"
+ assert count1 == count2, f"The clients don't have the same amount of tasks, client1: {count1}, client2: {count2}"
+ '';
+}
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/generate b/tests/common/acme/certs/generate
index 0d6258e..0d6258e 100755
--- a/tests/by-name/em/email-dns/nodes/acme/certs/generate
+++ b/tests/common/acme/certs/generate
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/generate.ca b/tests/common/acme/certs/generate.ca
index 92832c5..92832c5 100755
--- a/tests/by-name/em/email-dns/nodes/acme/certs/generate.ca
+++ b/tests/common/acme/certs/generate.ca
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/generate.client b/tests/common/acme/certs/generate.client
index 5930298..5930298 100755
--- a/tests/by-name/em/email-dns/nodes/acme/certs/generate.client
+++ b/tests/common/acme/certs/generate.client
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.cert.pem b/tests/common/acme/certs/output/acme.test.cert.pem
index 687101d..687101d 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.cert.pem
+++ b/tests/common/acme/certs/output/acme.test.cert.pem
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.key.pem b/tests/common/acme/certs/output/acme.test.key.pem
index 06195b8..06195b8 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.key.pem
+++ b/tests/common/acme/certs/output/acme.test.key.pem
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.template b/tests/common/acme/certs/output/acme.test.template
index 320a170..320a170 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/acme.test.template
+++ b/tests/common/acme/certs/output/acme.test.template
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.cert.pem b/tests/common/acme/certs/output/ca.cert.pem
index 0fa9d14..0fa9d14 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.cert.pem
+++ b/tests/common/acme/certs/output/ca.cert.pem
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.key.pem b/tests/common/acme/certs/output/ca.key.pem
index 64263bc..64263bc 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.key.pem
+++ b/tests/common/acme/certs/output/ca.key.pem
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.template b/tests/common/acme/certs/output/ca.template
index a2295d8..a2295d8 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/output/ca.template
+++ b/tests/common/acme/certs/output/ca.template
diff --git a/tests/by-name/em/email-dns/nodes/acme/certs/snakeoil-certs.nix b/tests/common/acme/certs/snakeoil-certs.nix
index aeb6dfc..aeb6dfc 100644
--- a/tests/by-name/em/email-dns/nodes/acme/certs/snakeoil-certs.nix
+++ b/tests/common/acme/certs/snakeoil-certs.nix
diff --git a/tests/by-name/em/email-dns/nodes/acme/client.nix b/tests/common/acme/client.nix
index 2b870e8..2b870e8 100644
--- a/tests/by-name/em/email-dns/nodes/acme/client.nix
+++ b/tests/common/acme/client.nix
diff --git a/tests/by-name/em/email-dns/nodes/acme/default.nix b/tests/common/acme/server.nix
index 236ba6a..997c944 100644
--- a/tests/by-name/em/email-dns/nodes/acme/default.nix
+++ b/tests/common/acme/server.nix
@@ -1,28 +1,5 @@
-# The certificate for the ACME service is exported as:
-#
-# config.test-support.acme.caCert
-#
-# This value can be used inside the configuration of other test nodes to inject
-# the test certificate into security.pki.certificateFiles or into package
-# overlays.
-#
-# {
-# acme = { nodes, lib, ... }: {
-# imports = [ ./common/acme/server ];
-# networking.nameservers = lib.mkForce [
-# nodes.mydnsresolver.networking.primaryIPAddress
-# ];
-# };
-#
-# dnsmyresolver = ...;
-# }
-#
-# Keep in mind, that currently only _one_ resolver is supported, if you have
-# more than one resolver in networking.nameservers only the first one will be
-# used.
-#
-# Also make sure that whenever you use a resolver from a different test node
-# that it has to be started _before_ the ACME service.
+# Add this node as acme server.
+# This also needs a DNS server.
{
config,
pkgs,
diff --git a/tests/by-name/em/email-dns/secrets/dkim/alice.com/public b/tests/common/email/dkim/alice.com/public
index 0f3c3b2..0f3c3b2 100644
--- a/tests/by-name/em/email-dns/secrets/dkim/alice.com/public
+++ b/tests/common/email/dkim/alice.com/public
diff --git a/tests/by-name/em/email-dns/secrets/dkim/bob.com/public b/tests/common/email/dkim/bob.com/public
index ddea670..ddea670 100644
--- a/tests/by-name/em/email-dns/secrets/dkim/bob.com/public
+++ b/tests/common/email/dkim/bob.com/public
diff --git a/tests/by-name/em/email-dns/secrets/dkim/gen_key.sh b/tests/common/email/dkim/gen_key.sh
index 1e090f4..48b4434 100755
--- a/tests/by-name/em/email-dns/secrets/dkim/gen_key.sh
+++ b/tests/common/email/dkim/gen_key.sh
@@ -1,6 +1,8 @@
#! /usr/bin/env nix-shell
#! nix-shell -p rage -p openssl -p dash -i dash --impure
+# shellcheck shell=dash
+
cd "$(dirname "$0")" || {
echo "No basedir?!"
exit 1
diff --git a/tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/public b/tests/common/email/dkim/mail1.server.com/public
index 4941b85..4941b85 100644
--- a/tests/by-name/em/email-dns/secrets/dkim/mail1.server.com/public
+++ b/tests/common/email/dkim/mail1.server.com/public
diff --git a/tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/public b/tests/common/email/dkim/mail2.server.com/public
index 5c4406d..5c4406d 100644
--- a/tests/by-name/em/email-dns/secrets/dkim/mail2.server.com/public
+++ b/tests/common/email/dkim/mail2.server.com/public
diff --git a/tests/by-name/em/email-dns/secrets/hostKey b/tests/common/email/hostKey
index 79c9d6c..79c9d6c 100644
--- a/tests/by-name/em/email-dns/secrets/hostKey
+++ b/tests/common/email/hostKey