diff options
Diffstat (limited to 'nixos/tests')
-rw-r--r-- | nixos/tests/acme.nix | 8 | ||||
-rw-r--r-- | nixos/tests/activation/etc-overlay-immutable.nix | 4 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 5 | ||||
-rw-r--r-- | nixos/tests/alloy.nix | 32 | ||||
-rw-r--r-- | nixos/tests/aria2.nix | 43 | ||||
-rw-r--r-- | nixos/tests/clatd.nix | 95 | ||||
-rw-r--r-- | nixos/tests/firefly-iii.nix | 4 | ||||
-rw-r--r-- | nixos/tests/greetd-no-shadow.nix | 49 | ||||
-rw-r--r-- | nixos/tests/kerberos/heimdal.nix | 2 | ||||
-rw-r--r-- | nixos/tests/kerberos/mit.nix | 2 | ||||
-rw-r--r-- | nixos/tests/kubo/default.nix | 4 | ||||
-rw-r--r-- | nixos/tests/kubo/kubo-fuse.nix | 2 | ||||
-rw-r--r-- | nixos/tests/ladybird.nix | 4 | ||||
-rw-r--r-- | nixos/tests/mpv.nix | 2 | ||||
-rw-r--r-- | nixos/tests/mycelium/default.nix | 3 | ||||
-rw-r--r-- | nixos/tests/openssh.nix | 14 | ||||
-rw-r--r-- | nixos/tests/pghero.nix | 63 | ||||
-rw-r--r-- | nixos/tests/renovate.nix | 69 | ||||
-rw-r--r-- | nixos/tests/systemd-machinectl.nix | 24 |
19 files changed, 386 insertions, 43 deletions
diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index 511d3c589faef..379496583d25d 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -392,8 +392,6 @@ in { testScript = { nodes, ... }: let caDomain = nodes.acme.test-support.acme.caDomain; - newServerSystem = nodes.webserver.config.system.build.toplevel; - switchToNewServer = "${newServerSystem}/bin/switch-to-configuration test"; in # Note, wait_for_unit does not work for oneshot services that do not have RemainAfterExit=true, # this is because a oneshot goes from inactive => activating => inactive, and never @@ -545,6 +543,12 @@ in { check_fullchain(webserver, "http.example.test") check_issuer(webserver, "http.example.test", "pebble") + # Perform account hash test + with subtest("Assert that account hash didn't unexpected change"): + hash = webserver.succeed("ls /var/lib/acme/.lego/accounts/") + print("Account hash: " + hash) + assert hash.strip() == "d590213ed52603e9128d" + # Perform renewal test with subtest("Can renew certificates when they expire"): hash = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem") diff --git a/nixos/tests/activation/etc-overlay-immutable.nix b/nixos/tests/activation/etc-overlay-immutable.nix index f347f9cf8efe2..f0abf70d350ff 100644 --- a/nixos/tests/activation/etc-overlay-immutable.nix +++ b/nixos/tests/activation/etc-overlay-immutable.nix @@ -13,6 +13,7 @@ users.mutableUsers = false; boot.initrd.systemd.enable = true; boot.kernelPackages = pkgs.linuxPackages_latest; + time.timeZone = "Utc"; specialisation.new-generation.configuration = { environment.etc."newgen".text = "newgen"; @@ -23,6 +24,9 @@ with subtest("/etc is mounted as an overlay"): machine.succeed("findmnt --kernel --type overlay /etc") + with subtest("direct symlinks point to the target without indirection"): + assert machine.succeed("readlink -n /etc/localtime") == "/etc/zoneinfo/Utc" + with subtest("switching to the same generation"): machine.succeed("/run/current-system/bin/switch-to-configuration test") diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ddeeeb298c356..a9b6881aab0f8 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -115,6 +115,7 @@ in { akkoma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix {}; akkoma-confined = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix { confined = true; }; alice-lg = handleTest ./alice-lg.nix {}; + alloy = handleTest ./alloy.nix {}; allTerminfo = handleTest ./all-terminfo.nix {}; alps = handleTest ./alps.nix {}; amazon-init-shell = handleTest ./amazon-init-shell.nix {}; @@ -129,6 +130,7 @@ in { appliance-repart-image = runTest ./appliance-repart-image.nix; apparmor = handleTest ./apparmor.nix {}; archi = handleTest ./archi.nix {}; + aria2 = handleTest ./aria2.nix {}; armagetronad = handleTest ./armagetronad.nix {}; artalk = handleTest ./artalk.nix {}; atd = handleTest ./atd.nix {}; @@ -379,6 +381,7 @@ in { grafana-agent = handleTest ./grafana-agent.nix {}; graphite = handleTest ./graphite.nix {}; graylog = handleTest ./graylog.nix {}; + greetd-no-shadow = handleTest ./greetd-no-shadow.nix {}; grocy = handleTest ./grocy.nix {}; grow-partition = runTest ./grow-partition.nix; grub = handleTest ./grub.nix {}; @@ -720,6 +723,7 @@ in { pg_anonymizer = handleTest ./pg_anonymizer.nix {}; pgadmin4 = handleTest ./pgadmin4.nix {}; pgbouncer = handleTest ./pgbouncer.nix {}; + pghero = runTest ./pghero.nix; pgjwt = handleTest ./pgjwt.nix {}; pgmanage = handleTest ./pgmanage.nix {}; pgvecto-rs = handleTest ./pgvecto-rs.nix {}; @@ -800,6 +804,7 @@ in { redis = handleTest ./redis.nix {}; redlib = handleTest ./redlib.nix {}; redmine = handleTest ./redmine.nix {}; + renovate = handleTest ./renovate.nix {}; restartByActivationScript = handleTest ./restart-by-activation-script.nix {}; restic-rest-server = handleTest ./restic-rest-server.nix {}; restic = handleTest ./restic.nix {}; diff --git a/nixos/tests/alloy.nix b/nixos/tests/alloy.nix new file mode 100644 index 0000000000000..d87492127d5bb --- /dev/null +++ b/nixos/tests/alloy.nix @@ -0,0 +1,32 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: + + let + nodes = { + machine = { + services.alloy = { + enable = true; + }; + environment.etc."alloy/config.alloy".text = ""; + }; + }; + in + { + name = "alloy"; + + meta = with lib.maintainers; { + maintainers = [ flokli hbjydev ]; + }; + + inherit nodes; + + testScript = '' + start_all() + + machine.wait_for_unit("alloy.service") + machine.wait_for_open_port(12345) + machine.succeed( + "curl -sSfN http://127.0.0.1:12345/-/healthy" + ) + machine.shutdown() + ''; + }) diff --git a/nixos/tests/aria2.nix b/nixos/tests/aria2.nix new file mode 100644 index 0000000000000..48fe2094b5dcf --- /dev/null +++ b/nixos/tests/aria2.nix @@ -0,0 +1,43 @@ +import ./make-test-python.nix ({ pkgs, ... }: +let + rpcSecret = "supersecret"; + rpc-listen-port = 6800; + curlBody = { + jsonrpc = 2.0; + id = 1; + method = "aria2.getVersion"; + params = [ "token:${rpcSecret}" ]; + }; +in +rec { + name = "aria2"; + + nodes.machine = { + environment.etc."aria2Rpc".text = rpcSecret; + services.aria2 = { + enable = true; + rpcSecretFile = "/etc/aria2Rpc"; + settings = { + inherit rpc-listen-port; + allow-overwrite = false; + check-integrity = true; + console-log-level = "warn"; + listen-port = [{ from = 20000; to = 20010; } { from = 22222; to = 22222; }]; + max-concurrent-downloads = 50; + seed-ratio = 1.2; + summary-interval = 0; + }; + }; + }; + + testScript = '' + machine.start() + machine.wait_for_unit("aria2.service") + curl_cmd = 'curl --fail-with-body -X POST -H "Content-Type: application/json" \ + -d \'${builtins.toJSON curlBody}\' http://localhost:${toString rpc-listen-port}/jsonrpc' + print(machine.wait_until_succeeds(curl_cmd, timeout=10)) + machine.shutdown() + ''; + + meta.maintainers = [ pkgs.lib.maintainers.timhae ]; +}) diff --git a/nixos/tests/clatd.nix b/nixos/tests/clatd.nix index f4d2242ce54f4..d0d504851ce4e 100644 --- a/nixos/tests/clatd.nix +++ b/nixos/tests/clatd.nix @@ -6,8 +6,8 @@ # Client | clat Address: 192.0.0.1/32 (configured via clatd) # | Route: default # | -# | eth1 Address: 2001:db8::2/64 -# | | Route: default via 2001:db8::1 +# | eth1 Address: Assigned via SLAAC within 2001:db8::/64 +# | | Route: default via IPv6LL address # +--|--- # | VLAN 3 # +--|--- @@ -31,7 +31,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "clatd"; meta = with pkgs.lib.maintainers; { - maintainers = [ hax404 ]; + maintainers = [ hax404 jmbaur ]; }; nodes = { @@ -66,18 +66,19 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: }; # The router is configured with static IPv4 addresses towards the server - # and IPv6 addresses towards the client. For NAT64, the Well-Known prefix - # 64:ff9b::/96 is used. NAT64 is done with TAYGA which provides the - # tun-interface nat64 and does the translation over it. The IPv6 packets - # are sent to this interfaces and received as IPv4 packets and vice versa. - # As TAYGA only translates IPv6 addresses to dedicated IPv4 addresses, it - # needs a pool of IPv4 addresses which must be at least as big as the - # expected amount of clients. In this test, the packets from the pool are - # directly routed towards the client. In normal cases, there would be a - # second source NAT44 to map all clients behind one IPv4 address. + # and IPv6 addresses towards the client. DNS64 is exposed towards the + # client so clatd is able to auto-discover the PLAT prefix. For NAT64, the + # Well-Known prefix 64:ff9b::/96 is used. NAT64 is done with TAYGA which + # provides the tun-interface nat64 and does the translation over it. The + # IPv6 packets are sent to this interfaces and received as IPv4 packets and + # vice versa. As TAYGA only translates IPv6 addresses to dedicated IPv4 + # addresses, it needs a pool of IPv4 addresses which must be at least as + # big as the expected amount of clients. In this test, the packets from the + # pool are directly routed towards the client. In normal cases, there would + # be a second source NAT44 to map all clients behind one IPv4 address. router = { boot.kernel.sysctl = { - "net.ipv4.ip_forward" = 1; + "net.ipv4.conf.all.forwarding" = 1; "net.ipv6.conf.all.forwarding" = 1; }; @@ -102,6 +103,36 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: }; }; + systemd.network.networks."40-eth2" = { + networkConfig.IPv6SendRA = true; + ipv6Prefixes = [ { Prefix = "2001:db8::/64"; } ]; + ipv6PREF64Prefixes = [ { Prefix = "64:ff9b::/96"; } ]; + ipv6SendRAConfig = { + EmitDNS = true; + DNS = "_link_local"; + }; + }; + + services.resolved.extraConfig = '' + DNSStubListener=no + ''; + + networking.extraHosts = '' + 192.0.0.171 ipv4only.arpa + 192.0.0.170 ipv4only.arpa + ''; + + services.coredns = { + enable = true; + config = '' + .:53 { + bind :: + hosts /etc/hosts + dns64 64:ff9b::/96 + } + ''; + }; + services.tayga = { enable = true; ipv4 = { @@ -127,10 +158,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: }; }; - # The client is configured with static IPv6 addresses. It has also a static - # default route towards the router. To reach the IPv4-only server, the - # client starts the clat daemon which starts and configures the local - # IPv4 -> IPv6 translation via Tayga. + # The client uses SLAAC to assign IPv6 addresses. To reach the IPv4-only + # server, the client starts the clat daemon which starts and configures the + # local IPv4 -> IPv6 translation via Tayga after discovering the PLAT + # prefix via DNS64. client = { virtualisation.vlans = [ 3 # towards router @@ -145,25 +176,36 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: enable = true; networks."vlan1" = { matchConfig.Name = "eth1"; - address = [ - "2001:db8::2/64" - ]; - routes = [ - { Destination = "::/0"; Gateway = "2001:db8::1"; } - ]; + + # NOTE: clatd does not actually use the PREF64 prefix discovered by + # systemd-networkd (nor does systemd-networkd do anything with it, + # yet), but we set this to confirm it works. See the test script + # below. + ipv6AcceptRAConfig.UsePREF64 = true; }; }; services.clatd = { enable = true; - settings.plat-prefix = "64:ff9b::/96"; + # NOTE: Perl's Net::DNS resolver does not seem to work well querying + # for AAAA records to systemd-resolved's default IPv4 bind address + # (127.0.0.53), so we add an IPv6 listener address to systemd-resolved + # and tell clatd to use that instead. + settings.dns64-servers = "::1"; }; + # Allow clatd to find dns server. See comment above. + services.resolved.extraConfig = '' + DNSStubListenerExtra=::1 + ''; + environment.systemPackages = [ pkgs.mtr ]; }; }; testScript = '' + import json + start_all() # wait for all machines to start up @@ -178,6 +220,11 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: 'journalctl -u clatd -e | grep -q "Starting up TAYGA, using config file"' ) + with subtest("networkd exports PREF64 prefix"): + assert json.loads(client.succeed("networkctl status eth1 --json=short"))[ + "NDisc" + ]["PREF64"][0]["Prefix"] == [0x0, 0x64, 0xFF, 0x9B] + ([0] * 12) + with subtest("Test ICMP"): client.wait_until_succeeds("ping -c 3 100.64.0.2 >&2") diff --git a/nixos/tests/firefly-iii.nix b/nixos/tests/firefly-iii.nix index 2373ba8360264..f8e4ca4bfe2b4 100644 --- a/nixos/tests/firefly-iii.nix +++ b/nixos/tests/firefly-iii.nix @@ -39,12 +39,13 @@ in DB_DATABASE = "firefly"; DB_USERNAME = "firefly"; DB_PASSWORD_FILE = "/etc/postgres-pass"; + PGSQL_SCHEMA = "firefly"; }; }; services.postgresql = { enable = true; - package = pkgs.postgresql_15; + package = pkgs.postgresql_16; authentication = '' local all postgres peer local firefly firefly password @@ -52,6 +53,7 @@ in initialScript = pkgs.writeText "firefly-init.sql" '' CREATE USER "firefly" WITH LOGIN PASSWORD '${db-pass}'; CREATE DATABASE "firefly" WITH OWNER "firefly"; + \c firefly CREATE SCHEMA AUTHORIZATION firefly; ''; }; diff --git a/nixos/tests/greetd-no-shadow.nix b/nixos/tests/greetd-no-shadow.nix new file mode 100644 index 0000000000000..382218ffa948f --- /dev/null +++ b/nixos/tests/greetd-no-shadow.nix @@ -0,0 +1,49 @@ +import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... }: +{ + name = "greetd-no-shadow"; + meta = with pkgs.lib.maintainers; { + maintainers = [ ]; + }; + + nodes.machine = + { pkgs, lib, ... }: { + + users.users.alice = { + isNormalUser = true; + group = "alice"; + password = "foobar"; + }; + users.groups.alice = {}; + + # This means login(1) breaks, so we must use greetd/agreety instead. + security.shadow.enable = false; + + services.greetd = { + enable = true; + settings = { + default_session = { + command = "${pkgs.greetd.greetd}/bin/agreety --cmd bash"; + }; + }; + }; + }; + + testScript = '' + machine.start() + + machine.wait_for_unit("multi-user.target") + machine.wait_until_succeeds("pgrep -f 'agretty.*tty1'") + machine.screenshot("postboot") + + with subtest("Log in as alice on a virtual console"): + machine.wait_until_tty_matches("1", "login: ") + machine.send_chars("alice\n") + machine.wait_until_tty_matches("1", "login: alice") + machine.wait_until_succeeds("pgrep login") + machine.wait_until_tty_matches("1", "Password: ") + machine.send_chars("foobar\n") + machine.wait_until_succeeds("pgrep -u alice bash") + machine.send_chars("touch done\n") + machine.wait_for_file("/home/alice/done") + ''; +}) diff --git a/nixos/tests/kerberos/heimdal.nix b/nixos/tests/kerberos/heimdal.nix index 393289f7a92ca..098080a84592e 100644 --- a/nixos/tests/kerberos/heimdal.nix +++ b/nixos/tests/kerberos/heimdal.nix @@ -4,7 +4,7 @@ import ../make-test-python.nix ({pkgs, ...}: { nodes.machine = { config, libs, pkgs, ...}: { services.kerberos_server = { enable = true; - realms = { + settings.realms = { "FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}]; }; }; diff --git a/nixos/tests/kerberos/mit.nix b/nixos/tests/kerberos/mit.nix index 1191d047abbf0..172261f95fe6b 100644 --- a/nixos/tests/kerberos/mit.nix +++ b/nixos/tests/kerberos/mit.nix @@ -4,7 +4,7 @@ import ../make-test-python.nix ({pkgs, ...}: { nodes.machine = { config, libs, pkgs, ...}: { services.kerberos_server = { enable = true; - realms = { + settings.realms = { "FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}]; }; }; diff --git a/nixos/tests/kubo/default.nix b/nixos/tests/kubo/default.nix index d8c0c69dc1fbd..629922fc366db 100644 --- a/nixos/tests/kubo/default.nix +++ b/nixos/tests/kubo/default.nix @@ -1,7 +1,5 @@ { recurseIntoAttrs, runTest }: recurseIntoAttrs { kubo = runTest ./kubo.nix; - # The FUSE functionality is completely broken since Kubo v0.24.0 - # See https://github.com/ipfs/kubo/issues/10242 - # kubo-fuse = runTest ./kubo-fuse.nix; + kubo-fuse = runTest ./kubo-fuse.nix; } diff --git a/nixos/tests/kubo/kubo-fuse.nix b/nixos/tests/kubo/kubo-fuse.nix index 71a5bf61649f6..c8c273fc0dfc7 100644 --- a/nixos/tests/kubo/kubo-fuse.nix +++ b/nixos/tests/kubo/kubo-fuse.nix @@ -23,7 +23,7 @@ with subtest("FUSE mountpoint"): machine.fail("echo a | su bob -l -c 'ipfs add --quieter'") - # The FUSE mount functionality is broken as of v0.13.0 and v0.17.0. + # The FUSE mount functionality is broken as of v0.13.0. This is still the case with v0.29.0. # See https://github.com/ipfs/kubo/issues/9044. # Workaround: using CID Version 1 avoids that. ipfs_hash = machine.succeed( diff --git a/nixos/tests/ladybird.nix b/nixos/tests/ladybird.nix index 8ed0f47887c7d..85c23353a668a 100644 --- a/nixos/tests/ladybird.nix +++ b/nixos/tests/ladybird.nix @@ -10,9 +10,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { ]; services.xserver.enable = true; - environment.systemPackages = [ - pkgs.ladybird - ]; + programs.ladybird.enable = true; }; enableOCR = true; diff --git a/nixos/tests/mpv.nix b/nixos/tests/mpv.nix index 32a81cbe2495e..c2e151c224760 100644 --- a/nixos/tests/mpv.nix +++ b/nixos/tests/mpv.nix @@ -12,7 +12,7 @@ in { environment.systemPackages = [ pkgs.curl - (pkgs.wrapMpv pkgs.mpv-unwrapped { + (pkgs.mpv.override { scripts = [ pkgs.mpvScripts.simple-mpv-webui ]; }) ]; diff --git a/nixos/tests/mycelium/default.nix b/nixos/tests/mycelium/default.nix index 9174c49d70869..956a822a21860 100644 --- a/nixos/tests/mycelium/default.nix +++ b/nixos/tests/mycelium/default.nix @@ -51,6 +51,9 @@ in peer1.wait_for_unit("mycelium.service") peer2.wait_for_unit("mycelium.service") + peer1.succeed("mycelium peers list | grep 192.168.1.12") + peer2.succeed("mycelium peers list | grep 192.168.1.11") + peer1.succeed("ping -c5 ${peer2-ip}") peer2.succeed("ping -c5 ${peer1-ip}") ''; diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix index 3929522a39e73..d420c482ca7f2 100644 --- a/nixos/tests/openssh.nix +++ b/nixos/tests/openssh.nix @@ -120,12 +120,14 @@ in { { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } ]; settings = { - # Must not specify the OpenSSL provided algorithms. - Ciphers = [ "chacha20-poly1305@openssh.com" ]; - KexAlgorithms = [ - "curve25519-sha256" - "curve25519-sha256@libssh.org" - ]; + # Since this test is against an OpenSSH-without-OpenSSL, + # we have to override NixOS's defaults ciphers (which require OpenSSL) + # and instead set these to null, which will mean OpenSSH uses its defaults. + # Expectedly, OpenSSH's defaults don't require OpenSSL when it's compiled + # without OpenSSL. + Ciphers = null; + KexAlgorithms = null; + Macs = null; }; }; users.users.root.openssh.authorizedKeys.keys = [ diff --git a/nixos/tests/pghero.nix b/nixos/tests/pghero.nix new file mode 100644 index 0000000000000..bce32da008862 --- /dev/null +++ b/nixos/tests/pghero.nix @@ -0,0 +1,63 @@ +let + pgheroPort = 1337; + pgheroUser = "pghero"; + pgheroPass = "pghero"; +in +{ lib, ... }: { + name = "pghero"; + meta.maintainers = [ lib.maintainers.tie ]; + + nodes.machine = { config, ... }: { + services.postgresql = { + enable = true; + # This test uses default peer authentication (socket and its directory is + # world-readably by default), so we essentially test that we can connect + # with DynamicUser= set. + ensureUsers = [{ + name = "pghero"; + ensureClauses.superuser = true; + }]; + }; + services.pghero = { + enable = true; + listenAddress = "[::]:${toString pgheroPort}"; + settings = { + databases = { + postgres.url = "<%= ENV['POSTGRES_DATABASE_URL'] %>"; + nulldb.url = "nulldb:///"; + }; + }; + environment = { + PGHERO_USERNAME = pgheroUser; + PGHERO_PASSWORD = pgheroPass; + POSTGRES_DATABASE_URL = "postgresql:///postgres?host=/run/postgresql"; + }; + }; + }; + + testScript = '' + pgheroPort = ${toString pgheroPort} + pgheroUser = "${pgheroUser}" + pgheroPass = "${pgheroPass}" + + pgheroUnauthorizedURL = f"http://localhost:{pgheroPort}" + pgheroBaseURL = f"http://{pgheroUser}:{pgheroPass}@localhost:{pgheroPort}" + + def expect_http_code(node, code, url): + http_code = node.succeed(f"curl -s -o /dev/null -w '%{{http_code}}' '{url}'") + assert http_code.split("\n")[-1].strip() == code, \ + f"expected HTTP status code {code} but got {http_code}" + + machine.wait_for_unit("postgresql.service") + machine.wait_for_unit("pghero.service") + + with subtest("requires HTTP Basic Auth credentials"): + expect_http_code(machine, "401", pgheroUnauthorizedURL) + + with subtest("works with some databases being unavailable"): + expect_http_code(machine, "500", pgheroBaseURL + "/nulldb") + + with subtest("connects to the PostgreSQL database"): + expect_http_code(machine, "200", pgheroBaseURL + "/postgres") + ''; +} diff --git a/nixos/tests/renovate.nix b/nixos/tests/renovate.nix new file mode 100644 index 0000000000000..a30b5b3d60b9c --- /dev/null +++ b/nixos/tests/renovate.nix @@ -0,0 +1,69 @@ +import ./make-test-python.nix ( + { pkgs, ... }: + { + name = "renovate"; + meta.maintainers = with pkgs.lib.maintainers; [ marie natsukium ]; + + nodes.machine = + { config, ... }: + { + services.renovate = { + enable = true; + settings = { + platform = "gitea"; + endpoint = "http://localhost:3000"; + autodiscover = true; + gitAuthor = "Renovate <renovate@example.com>"; + }; + credentials = { + RENOVATE_TOKEN = "/etc/renovate-token"; + }; + }; + environment.systemPackages = [ + config.services.forgejo.package + pkgs.tea + pkgs.git + ]; + services.forgejo = { + enable = true; + settings.server.HTTP_PORT = 3000; + }; + }; + + testScript = '' + def gitea(command): + return machine.succeed(f"cd /var/lib/forgejo && sudo --user=forgejo GITEA_WORK_DIR=/var/lib/forgejo GITEA_CUSTOM=/var/lib/forgejo/custom gitea {command}") + + machine.wait_for_unit("forgejo.service") + machine.wait_for_open_port(3000) + + machine.systemctl("stop forgejo.service") + + gitea("admin user create --username meow --email meow@example.com --password meow") + + machine.systemctl("start forgejo.service") + machine.wait_for_unit("forgejo.service") + machine.wait_for_open_port(3000) + + accessToken = gitea("admin user generate-access-token --raw --username meow --scopes all | tr -d '\n'") + + machine.succeed(f"tea login add --name default --user meow --token '{accessToken}' --password meow --url http://localhost:3000") + machine.succeed("tea repo create --name kitty --init") + machine.succeed("git config --global user.name Meow") + machine.succeed("git config --global user.email meow@example.com") + machine.succeed(f"git clone http://meow:{accessToken}@localhost:3000/meow/kitty.git /tmp/kitty") + machine.succeed("echo '{ \"name\": \"meow\", \"version\": \"0.1.0\" }' > /tmp/kitty/package.json") + machine.succeed("git -C /tmp/kitty add /tmp/kitty/package.json") + machine.succeed("git -C /tmp/kitty commit -m 'add package.json'") + machine.succeed("git -C /tmp/kitty push origin") + + machine.succeed(f"echo '{accessToken}' > /etc/renovate-token") + machine.systemctl("start renovate.service") + + machine.succeed("tea pulls list --repo meow/kitty | grep 'Configure Renovate'") + machine.succeed("tea pulls merge --repo meow/kitty 1") + + machine.systemctl("start renovate.service") + ''; + } +) diff --git a/nixos/tests/systemd-machinectl.nix b/nixos/tests/systemd-machinectl.nix index 9d761c6d4d8b8..555a8bb43b30e 100644 --- a/nixos/tests/systemd-machinectl.nix +++ b/nixos/tests/systemd-machinectl.nix @@ -76,10 +76,23 @@ in }; }; + systemd.nspawn.${containerName} = { + filesConfig = { + # workaround to fix kernel namespaces; needed for Nix sandbox + # https://github.com/systemd/systemd/issues/27994#issuecomment-1704005670 + Bind = "/proc:/run/proc"; + }; + }; + systemd.services."systemd-nspawn@${containerName}" = { serviceConfig.Environment = [ # Disable tmpfs for /tmp "SYSTEMD_NSPAWN_TMPFS_TMP=0" + + # force unified cgroup delegation, which would be the default + # if systemd could check the capabilities of the installed systemd. + # see also: https://github.com/NixOS/nixpkgs/pull/198526 + "SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1" ]; overrideStrategy = "asDropin"; }; @@ -121,6 +134,17 @@ in machine.succeed("machinectl start ${containerName}"); machine.wait_until_succeeds("systemctl -M ${containerName} is-active default.target"); + # Test systemd-nspawn configured unified cgroup delegation + # see also: + # https://github.com/systemd/systemd/blob/main/docs/CGROUP_DELEGATION.md#three-different-tree-setups- + machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/stat --format="%T" --file-system /sys/fs/cgroup > fstype') + machine.succeed('test $(tr -d "\\r" < fstype) = cgroup2fs') + + # Test if systemd-nspawn provides a working environment for nix to build derivations + # https://nixos.org/guides/nix-pills/07-working-derivation + machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-instantiate --expr \'derivation { name = "myname"; builder = "/bin/sh"; args = [ "-c" "echo foo > $out" ]; system = "${pkgs.system}"; }\' --add-root /tmp/drv') + machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-store --option substitute false --realize /tmp/drv') + # Test nss_mymachines without nscd machine.succeed('LD_LIBRARY_PATH="/run/current-system/sw/lib" getent -s hosts:mymachines hosts ${containerName}'); |