diff options
Diffstat (limited to 'nixos/tests')
-rw-r--r-- | nixos/tests/all-tests.nix | 5 | ||||
-rw-r--r-- | nixos/tests/discourse.nix | 8 | ||||
-rw-r--r-- | nixos/tests/gitea.nix | 8 | ||||
-rwxr-xr-x | nixos/tests/google-oslogin/server.py | 10 | ||||
-rw-r--r-- | nixos/tests/home-assistant.nix | 107 | ||||
-rw-r--r-- | nixos/tests/isso.nix | 2 | ||||
-rw-r--r-- | nixos/tests/keepassxc.nix | 8 | ||||
-rw-r--r-- | nixos/tests/miriway.nix | 6 | ||||
-rw-r--r-- | nixos/tests/nextcloud/with-postgresql-and-redis.nix | 13 | ||||
-rw-r--r-- | nixos/tests/podman/default.nix | 117 | ||||
-rw-r--r-- | nixos/tests/soapui.nix | 2 | ||||
-rw-r--r-- | nixos/tests/systemd-credentials-tpm2.nix | 124 | ||||
-rw-r--r-- | nixos/tests/systemd-initrd-vconsole.nix | 33 | ||||
-rw-r--r-- | nixos/tests/tuxguitar.nix | 2 |
14 files changed, 328 insertions, 117 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ac15ecdad6b86..785a5621f57eb 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -228,6 +228,7 @@ in { fluentd = handleTest ./fluentd.nix {}; fluidd = handleTest ./fluidd.nix {}; fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {}; + forgejo = handleTest ./gitea.nix { giteaPackage = pkgs.forgejo; }; freenet = handleTest ./freenet.nix {}; freeswitch = handleTest ./freeswitch.nix {}; freshrss-sqlite = handleTest ./freshrss-sqlite.nix {}; @@ -241,7 +242,7 @@ in { geth = handleTest ./geth.nix {}; ghostunnel = handleTest ./ghostunnel.nix {}; gitdaemon = handleTest ./gitdaemon.nix {}; - gitea = handleTest ./gitea.nix {}; + gitea = handleTest ./gitea.nix { giteaPackage = pkgs.gitea; }; gitlab = handleTest ./gitlab.nix {}; gitolite = handleTest ./gitolite.nix {}; gitolite-fcgiwrap = handleTest ./gitolite-fcgiwrap.nix {}; @@ -647,6 +648,7 @@ in { systemd-confinement = handleTest ./systemd-confinement.nix {}; systemd-coredump = handleTest ./systemd-coredump.nix {}; systemd-cryptenroll = handleTest ./systemd-cryptenroll.nix {}; + systemd-credentials-tpm2 = handleTest ./systemd-credentials-tpm2.nix {}; systemd-escaping = handleTest ./systemd-escaping.nix {}; systemd-initrd-btrfs-raid = handleTest ./systemd-initrd-btrfs-raid.nix {}; systemd-initrd-luks-fido2 = handleTest ./systemd-initrd-luks-fido2.nix {}; @@ -657,6 +659,7 @@ in { systemd-initrd-shutdown = handleTest ./systemd-shutdown.nix { systemdStage1 = true; }; systemd-initrd-simple = handleTest ./systemd-initrd-simple.nix {}; systemd-initrd-swraid = handleTest ./systemd-initrd-swraid.nix {}; + systemd-initrd-vconsole = handleTest ./systemd-initrd-vconsole.nix {}; systemd-journal = handleTest ./systemd-journal.nix {}; systemd-machinectl = handleTest ./systemd-machinectl.nix {}; systemd-networkd = handleTest ./systemd-networkd.nix {}; diff --git a/nixos/tests/discourse.nix b/nixos/tests/discourse.nix index 35ca083c6c4e0..c79ba41c2eb9c 100644 --- a/nixos/tests/discourse.nix +++ b/nixos/tests/discourse.nix @@ -40,7 +40,7 @@ import ./make-test-python.nix ( networking.extraHosts = '' 127.0.0.1 ${discourseDomain} - ${nodes.client.config.networking.primaryIPAddress} ${clientDomain} + ${nodes.client.networking.primaryIPAddress} ${clientDomain} ''; services.postfix = { @@ -90,7 +90,7 @@ import ./make-test-python.nix ( networking.extraHosts = '' 127.0.0.1 ${clientDomain} - ${nodes.discourse.config.networking.primaryIPAddress} ${discourseDomain} + ${nodes.discourse.networking.primaryIPAddress} ${discourseDomain} ''; services.dovecot2 = { @@ -178,8 +178,8 @@ import ./make-test-python.nix ( discourse.wait_until_succeeds("curl -sS -f https://${discourseDomain}") discourse.succeed( "curl -sS -f https://${discourseDomain}/session/csrf -c cookie -b cookie -H 'Accept: application/json' | jq -r '\"X-CSRF-Token: \" + .csrf' > csrf_token", - "curl -sS -f https://${discourseDomain}/session -c cookie -b cookie -H @csrf_token -H 'Accept: application/json' -d 'login=${nodes.discourse.config.services.discourse.admin.username}' -d \"password=${adminPassword}\" | jq -e '.user.username == \"${nodes.discourse.config.services.discourse.admin.username}\"'", - "curl -sS -f https://${discourseDomain}/login -v -H 'Accept: application/json' -c cookie -b cookie 2>&1 | grep ${nodes.discourse.config.services.discourse.admin.username}", + "curl -sS -f https://${discourseDomain}/session -c cookie -b cookie -H @csrf_token -H 'Accept: application/json' -d 'login=${nodes.discourse.services.discourse.admin.username}' -d \"password=${adminPassword}\" | jq -e '.user.username == \"${nodes.discourse.services.discourse.admin.username}\"'", + "curl -sS -f https://${discourseDomain}/login -v -H 'Accept: application/json' -c cookie -b cookie 2>&1 | grep ${nodes.discourse.services.discourse.admin.username}", ) client.wait_for_unit("postfix.service") diff --git a/nixos/tests/gitea.nix b/nixos/tests/gitea.nix index 68a2566c11911..d856ecca9a132 100644 --- a/nixos/tests/gitea.nix +++ b/nixos/tests/gitea.nix @@ -1,5 +1,6 @@ { system ? builtins.currentSystem, config ? {}, + giteaPackage, pkgs ? import ../.. { inherit system config; } }: @@ -9,8 +10,8 @@ with pkgs.lib; let supportedDbTypes = [ "mysql" "postgres" "sqlite3" ]; makeGiteaTest = type: nameValuePair type (makeTest { - name = "gitea-${type}"; - meta.maintainers = with maintainers; [ aanderse kolaente ma27 ]; + name = "${giteaPackage.pname}-${type}"; + meta.maintainers = with maintainers; [ aanderse indeednotjames kolaente ma27 ]; nodes = { server = { config, pkgs, ... }: { @@ -18,9 +19,10 @@ let services.gitea = { enable = true; database = { inherit type; }; + package = giteaPackage; settings.service.DISABLE_REGISTRATION = true; }; - environment.systemPackages = [ pkgs.gitea pkgs.jq ]; + environment.systemPackages = [ giteaPackage pkgs.jq ]; services.openssh.enable = true; }; client1 = { config, pkgs, ... }: { diff --git a/nixos/tests/google-oslogin/server.py b/nixos/tests/google-oslogin/server.py index 5ea9bbd2c96ba..622cd86b26195 100755 --- a/nixos/tests/google-oslogin/server.py +++ b/nixos/tests/google-oslogin/server.py @@ -103,6 +103,16 @@ class ReqHandler(BaseHTTPRequestHandler): self._send_json_ok(gen_mockuser(username=username, uid=uid, gid=uid, home_directory=f"/home/{username}", snakeoil_pubkey=SNAKEOIL_PUBLIC_KEY)) return + # we need to provide something at the groups endpoint. + # the nss module does segfault if we don't. + elif pu.path == "/computeMetadata/v1/oslogin/groups": + self._send_json_ok({ + "posixGroups": [ + {"name" : "demo", "gid" : 4294967295} + ], + }) + return + # authorize endpoint elif pu.path == "/computeMetadata/v1/oslogin/authorize": # is user allowed to login? diff --git a/nixos/tests/home-assistant.nix b/nixos/tests/home-assistant.nix index 8d58de75eabc3..8585cb3585fef 100644 --- a/nixos/tests/home-assistant.nix +++ b/nixos/tests/home-assistant.nix @@ -22,22 +22,23 @@ in { enable = true; inherit configDir; - # tests loading components by overriding the package + # provide dependencies through package overrides package = (pkgs.home-assistant.override { extraPackages = ps: with ps; [ colorama ]; - extraComponents = [ "zha" ]; - }).overrideAttrs (oldAttrs: { - doInstallCheck = false; + extraComponents = [ + # test char-tty device allow propagation into the service + "zha" + ]; }); - # tests loading components from the module + # provide component dependencies explicitly from the module extraComponents = [ - "wake_on_lan" + "mqtt" ]; - # test extra package passing from the module + # provide package for postgresql support extraPackages = python3Packages: with python3Packages; [ psycopg2 ]; @@ -111,36 +112,38 @@ in { }; testScript = { nodes, ... }: let - system = nodes.hass.config.system.build.toplevel; + system = nodes.hass.system.build.toplevel; in '' - import re import json start_all() - # Parse the package path out of the systemd unit, as we cannot - # access the final package, that is overridden inside the module, - # by any other means. - pattern = re.compile(r"path=(?P<path>[\/a-z0-9-.]+)\/bin\/hass") - response = hass.execute("systemctl show -p ExecStart home-assistant.service")[1] - match = pattern.search(response) - assert match - package = match.group('path') - - def get_journal_cursor(host) -> str: - exit, out = host.execute("journalctl -u home-assistant.service -n1 -o json-pretty --output-fields=__CURSOR") + def get_journal_cursor() -> str: + exit, out = hass.execute("journalctl -u home-assistant.service -n1 -o json-pretty --output-fields=__CURSOR") assert exit == 0 return json.loads(out)["__CURSOR"] - def wait_for_homeassistant(host, cursor): - host.wait_until_succeeds(f"journalctl --after-cursor='{cursor}' -u home-assistant.service | grep -q 'Home Assistant initialized in'") + def get_journal_since(cursor) -> str: + exit, out = hass.execute(f"journalctl --after-cursor='{cursor}' -u home-assistant.service") + assert exit == 0 + return out + + + def get_unit_property(property) -> str: + exit, out = hass.execute(f"systemctl show --property={property} home-assistant.service") + assert exit == 0 + return out + + + def wait_for_homeassistant(cursor): + hass.wait_until_succeeds(f"journalctl --after-cursor='{cursor}' -u home-assistant.service | grep -q 'Home Assistant initialized in'") hass.wait_for_unit("home-assistant.service") - cursor = get_journal_cursor(hass) + cursor = get_journal_cursor() with subtest("Check that YAML configuration file is in place"): hass.succeed("test -L ${configDir}/configuration.yaml") @@ -148,19 +151,22 @@ in { with subtest("Check the lovelace config is copied because lovelaceConfigWritable = true"): hass.succeed("test -f ${configDir}/ui-lovelace.yaml") - with subtest("Check extraComponents and extraPackages are considered from the package"): - hass.succeed(f"grep -q 'colorama' {package}/extra_packages") - hass.succeed(f"grep -q 'zha' {package}/extra_components") - - with subtest("Check extraComponents and extraPackages are considered from the module"): - hass.succeed(f"grep -q 'psycopg2' {package}/extra_packages") - hass.succeed(f"grep -q 'wake_on_lan' {package}/extra_components") - with subtest("Check that Home Assistant's web interface and API can be reached"): - wait_for_homeassistant(hass, cursor) + wait_for_homeassistant(cursor) hass.wait_for_open_port(8123) hass.succeed("curl --fail http://localhost:8123/lovelace") + with subtest("Check that optional dependencies are in the PYTHONPATH"): + env = get_unit_property("Environment") + python_path = env.split("PYTHONPATH=")[1].split()[0] + for package in ["colorama", "paho-mqtt", "psycopg2"]: + assert package in python_path, f"{package} not in PYTHONPATH" + + with subtest("Check that declaratively configured components get setup"): + journal = get_journal_since(cursor) + for domain in ["emulated_hue", "wake_on_lan"]: + assert f"Setup of domain {domain} took" in journal, f"{domain} setup missing" + with subtest("Check that capabilities are passed for emulated_hue to bind to port 80"): hass.wait_for_open_port(80) hass.succeed("curl --fail http://localhost:80/description.xml") @@ -169,25 +175,28 @@ in { hass.succeed("systemctl show -p DeviceAllow home-assistant.service | grep -q char-ttyUSB") with subtest("Check service reloads when configuration changes"): - # store the old pid of the process - pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") - cursor = get_journal_cursor(hass) - hass.succeed("${system}/specialisation/differentName/bin/switch-to-configuration test") - new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") - assert pid == new_pid, "The PID of the process should not change between process reloads" - wait_for_homeassistant(hass, cursor) - - with subtest("check service restarts when package changes"): - pid = new_pid - cursor = get_journal_cursor(hass) - hass.succeed("${system}/specialisation/newFeature/bin/switch-to-configuration test") - new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") - assert pid != new_pid, "The PID of the process shoudl change when the HA binary changes" - wait_for_homeassistant(hass, cursor) + pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + cursor = get_journal_cursor() + hass.succeed("${system}/specialisation/differentName/bin/switch-to-configuration test") + new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + assert pid == new_pid, "The PID of the process should not change between process reloads" + wait_for_homeassistant(cursor) + + with subtest("Check service restarts when dependencies change"): + pid = new_pid + cursor = get_journal_cursor() + hass.succeed("${system}/specialisation/newFeature/bin/switch-to-configuration test") + new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + assert pid != new_pid, "The PID of the process should change when its PYTHONPATH changess" + wait_for_homeassistant(cursor) + + with subtest("Check that new components get setup after restart"): + journal = get_journal_since(cursor) + for domain in ["esphome"]: + assert f"Setup of domain {domain} took" in journal, f"{domain} setup missing" with subtest("Check that no errors were logged"): - output_log = hass.succeed("cat ${configDir}/home-assistant.log") - assert "ERROR" not in output_log + hass.fail("journalctl -u home-assistant -o cat | grep -q ERROR") with subtest("Check systemd unit hardening"): hass.log(hass.succeed("systemctl cat home-assistant.service")) diff --git a/nixos/tests/isso.nix b/nixos/tests/isso.nix index 575e1c52eccf6..4ec8b5ec3593d 100644 --- a/nixos/tests/isso.nix +++ b/nixos/tests/isso.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "isso"; meta = with pkgs.lib.maintainers; { - maintainers = [ asbachb ]; + maintainers = [ ]; }; nodes.machine = { config, pkgs, ... }: { diff --git a/nixos/tests/keepassxc.nix b/nixos/tests/keepassxc.nix index debb469032a62..a4f452412cdf8 100644 --- a/nixos/tests/keepassxc.nix +++ b/nixos/tests/keepassxc.nix @@ -4,6 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : name = "keepassxc"; meta = with pkgs.lib.maintainers; { maintainers = [ turion ]; + timeout = 1800; }; nodes.machine = { ... }: @@ -55,9 +56,12 @@ import ./make-test-python.nix ({ pkgs, ...} : machine.sleep(5) # Regression #163482: keepassxc did not crash machine.succeed("ps -e | grep keepassxc") - machine.wait_for_text("foo.kdbx") + machine.wait_for_text("Open database") machine.send_key("ret") - machine.sleep(1) + + # Wait for the enter password screen to appear. + machine.wait_for_text("/home/alice/foo.kdbx") + # Click on "Browse" button to select keyfile machine.send_key("tab") machine.send_chars("/home/alice/foo.keyfile") diff --git a/nixos/tests/miriway.nix b/nixos/tests/miriway.nix index c4c50646f0153..d0d9f16d40f95 100644 --- a/nixos/tests/miriway.nix +++ b/nixos/tests/miriway.nix @@ -3,7 +3,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { meta = { maintainers = with lib.maintainers; [ OPNA2608 ]; - # FIXME On ARM Miriway inside the VM doesn't receive keyboard inputs, why? + # Natively running Mir has problems with capturing the first registered libinput device. + # In our VM runners on ARM and on some hardware configs (my RPi4, distro-independent), this misses the keyboard. + # It can be worked around by dis- and reconnecting the affected hardware, but we can't do this in these tests. + # https://github.com/MirServer/mir/issues/2837 broken = pkgs.stdenv.hostPlatform.isAarch; }; @@ -30,6 +33,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { enable = true; config = '' add-wayland-extensions=all + enable-x11= ctrl-alt=t:foot --maximized ctrl-alt=a:env WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY=invalid alacritty --option window.startup_mode=maximized diff --git a/nixos/tests/nextcloud/with-postgresql-and-redis.nix b/nixos/tests/nextcloud/with-postgresql-and-redis.nix index 1ef848cfb1217..d28c1bdfd6e1e 100644 --- a/nixos/tests/nextcloud/with-postgresql-and-redis.nix +++ b/nixos/tests/nextcloud/with-postgresql-and-redis.nix @@ -13,7 +13,7 @@ in { # The only thing the client needs to do is download a file. client = { ... }: {}; - nextcloud = { config, pkgs, ... }: { + nextcloud = { config, pkgs, lib, ... }: { networking.firewall.allowedTCPPorts = [ 80 ]; services.nextcloud = { @@ -34,6 +34,15 @@ in { adminpassFile = toString (pkgs.writeText "admin-pass-file" '' ${adminpass} ''); + trustedProxies = [ "::1" ]; + }; + notify_push = { + enable = true; + logLevel = "debug"; + }; + extraAppsEnable = true; + extraApps = { + inherit (pkgs."nextcloud${lib.versions.major config.services.nextcloud.package.version}Packages".apps) notify_push; }; }; @@ -94,8 +103,10 @@ in { "${withRcloneEnv} ${copySharedFile}" ) client.wait_for_unit("multi-user.target") + client.execute("${pkgs.nextcloud-notify_push.passthru.test_client}/bin/test_client http://nextcloud ${adminuser} ${adminpass} >&2 &") client.succeed( "${withRcloneEnv} ${diffSharedFile}" ) + nextcloud.wait_until_succeeds("journalctl -u nextcloud-notify_push | grep -q \"Sending ping to ${adminuser}\"") ''; })) args diff --git a/nixos/tests/podman/default.nix b/nixos/tests/podman/default.nix index c9b234d2b6092..69397197775f8 100644 --- a/nixos/tests/podman/default.nix +++ b/nixos/tests/podman/default.nix @@ -6,7 +6,10 @@ import ../make-test-python.nix ( }; nodes = { - podman = { pkgs, ... }: { + rootful = { pkgs, ... }: { + virtualisation.podman.enable = true; + }; + rootless = { pkgs, ... }: { virtualisation.podman.enable = true; users.users.alice = { @@ -49,101 +52,109 @@ import ../make-test-python.nix ( return f"su {user} -l -c {cmd}" - podman.wait_for_unit("sockets.target") + rootful.wait_for_unit("sockets.target") + rootless.wait_for_unit("sockets.target") dns.wait_for_unit("sockets.target") docker.wait_for_unit("sockets.target") start_all() with subtest("Run container as root with runc"): - podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg") - podman.succeed( + rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + rootful.succeed( "podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) - podman.succeed("podman ps | grep sleeping") - podman.succeed("podman stop sleeping") - podman.succeed("podman rm sleeping") + rootful.succeed("podman ps | grep sleeping") + rootful.succeed("podman stop sleeping") + rootful.succeed("podman rm sleeping") with subtest("Run container as root with crun"): - podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg") - podman.succeed( + rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + rootful.succeed( "podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) - podman.succeed("podman ps | grep sleeping") - podman.succeed("podman stop sleeping") - podman.succeed("podman rm sleeping") + rootful.succeed("podman ps | grep sleeping") + rootful.succeed("podman stop sleeping") + rootful.succeed("podman rm sleeping") with subtest("Run container as root with the default backend"): - podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg") - podman.succeed( + rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + rootful.succeed( "podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) - podman.succeed("podman ps | grep sleeping") - podman.succeed("podman stop sleeping") - podman.succeed("podman rm sleeping") + rootful.succeed("podman ps | grep sleeping") + rootful.succeed("podman stop sleeping") + rootful.succeed("podman rm sleeping") # start systemd session for rootless - podman.succeed("loginctl enable-linger alice") - podman.succeed(su_cmd("whoami")) - podman.sleep(1) + rootless.succeed("loginctl enable-linger alice") + rootless.succeed(su_cmd("whoami")) + rootless.sleep(1) with subtest("Run container rootless with runc"): - podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) - podman.succeed( + rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) + rootless.succeed( su_cmd( "podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) ) - podman.succeed(su_cmd("podman ps | grep sleeping")) - podman.succeed(su_cmd("podman stop sleeping")) - podman.succeed(su_cmd("podman rm sleeping")) + rootless.succeed(su_cmd("podman ps | grep sleeping")) + rootless.succeed(su_cmd("podman stop sleeping")) + rootless.succeed(su_cmd("podman rm sleeping")) with subtest("Run container rootless with crun"): - podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) - podman.succeed( + rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) + rootless.succeed( su_cmd( "podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) ) - podman.succeed(su_cmd("podman ps | grep sleeping")) - podman.succeed(su_cmd("podman stop sleeping")) - podman.succeed(su_cmd("podman rm sleeping")) + rootless.succeed(su_cmd("podman ps | grep sleeping")) + rootless.succeed(su_cmd("podman stop sleeping")) + rootless.succeed(su_cmd("podman rm sleeping")) with subtest("Run container rootless with the default backend"): - podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) - podman.succeed( + rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) + rootless.succeed( su_cmd( "podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" ) ) - podman.succeed(su_cmd("podman ps | grep sleeping")) - podman.succeed(su_cmd("podman stop sleeping")) - podman.succeed(su_cmd("podman rm sleeping")) + rootless.succeed(su_cmd("podman ps | grep sleeping")) + rootless.succeed(su_cmd("podman stop sleeping")) + rootless.succeed(su_cmd("podman rm sleeping")) + + with subtest("rootlessport"): + rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg")) + rootless.succeed( + su_cmd( + "podman run -d -p 9000:8888 --name=rootlessport -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Testing</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8888" + ) + ) + rootless.succeed(su_cmd("podman ps | grep rootlessport")) + rootless.wait_until_succeeds(su_cmd("${pkgs.curl}/bin/curl localhost:9000 | grep Testing")) + rootless.succeed(su_cmd("podman stop rootlessport")) + rootless.succeed(su_cmd("podman rm rootlessport")) with subtest("Run container with init"): - podman.succeed( + rootful.succeed( "tar cv -C ${pkgs.pkgsStatic.busybox} . | podman import - busybox" ) - pid = podman.succeed("podman run --rm busybox readlink /proc/self").strip() + pid = rootful.succeed("podman run --rm busybox readlink /proc/self").strip() assert pid == "1" - pid = podman.succeed("podman run --rm --init busybox readlink /proc/self").strip() + pid = rootful.succeed("podman run --rm --init busybox readlink /proc/self").strip() assert pid == "2" with subtest("aardvark-dns"): - dns.succeed("tar cv --files-from /dev/null | podman import - scratchimg") - dns.succeed( - "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Hi</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8000" - ) - dns.succeed("podman ps | grep webserver") - dns.succeed(""" - for i in `seq 0 120`; do - podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${pkgs.curl}/bin/curl http://webserver:8000 >/dev/console \ - && exit 0 - sleep 0.5 - done - exit 1 - """) - dns.succeed("podman stop webserver") - dns.succeed("podman rm webserver") + dns.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + dns.succeed( + "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Testing</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8000" + ) + dns.succeed("podman ps | grep webserver") + dns.wait_until_succeeds( + "podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${pkgs.curl}/bin/curl http://webserver:8000 | grep Testing" + ) + dns.succeed("podman stop webserver") + dns.succeed("podman rm webserver") with subtest("A podman member can use the docker cli"): docker.succeed(su_cmd("docker version")) diff --git a/nixos/tests/soapui.nix b/nixos/tests/soapui.nix index e4ce3888fd437..3a2d11a167562 100644 --- a/nixos/tests/soapui.nix +++ b/nixos/tests/soapui.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "soapui"; meta = with pkgs.lib.maintainers; { - maintainers = [ asbachb ]; + maintainers = [ ]; }; nodes.machine = { config, pkgs, ... }: { diff --git a/nixos/tests/systemd-credentials-tpm2.nix b/nixos/tests/systemd-credentials-tpm2.nix new file mode 100644 index 0000000000000..d2dc1fd7b615b --- /dev/null +++ b/nixos/tests/systemd-credentials-tpm2.nix @@ -0,0 +1,124 @@ +import ./make-test-python.nix ({ lib, pkgs, system, ... }: + +let + tpmSocketPath = "/tmp/swtpm-sock"; + tpmDeviceModels = { + x86_64-linux = "tpm-tis"; + aarch64-linux = "tpm-tis-device"; + }; +in + +{ + name = "systemd-credentials-tpm2"; + + meta = { + maintainers = with pkgs.lib.maintainers; [ tmarkus ]; + }; + + nodes.machine = { pkgs, ... }: { + virtualisation = { + qemu.options = [ + "-chardev socket,id=chrtpm,path=${tpmSocketPath}" + "-tpmdev emulator,id=tpm_dev_0,chardev=chrtpm" + "-device ${tpmDeviceModels.${system}},tpmdev=tpm_dev_0" + ]; + }; + + boot.initrd.availableKernelModules = [ "tpm_tis" ]; + + environment.systemPackages = with pkgs; [ diffutils ]; + }; + + testScript = '' + import subprocess + from tempfile import TemporaryDirectory + + # From systemd-initrd-luks-tpm2.nix + class Tpm: + def __init__(self): + self.state_dir = TemporaryDirectory() + self.start() + + def start(self): + self.proc = subprocess.Popen(["${pkgs.swtpm}/bin/swtpm", + "socket", + "--tpmstate", f"dir={self.state_dir.name}", + "--ctrl", "type=unixio,path=${tpmSocketPath}", + "--tpm2", + ]) + + # Check whether starting swtpm failed + try: + exit_code = self.proc.wait(timeout=0.2) + if exit_code is not None and exit_code != 0: + raise Exception("failed to start swtpm") + except subprocess.TimeoutExpired: + pass + + """Check whether the swtpm process exited due to an error""" + def check(self): + exit_code = self.proc.poll() + if exit_code is not None and exit_code != 0: + raise Exception("swtpm process died") + + CRED_NAME = "testkey" + CRED_RAW_FILE = f"/root/{CRED_NAME}" + CRED_FILE = f"/root/{CRED_NAME}.cred" + + def systemd_run(machine, cmd): + machine.log(f"Executing command (via systemd-run): \"{cmd}\"") + + (status, out) = machine.execute( " ".join([ + "systemd-run", + "--service-type=exec", + "--quiet", + "--wait", + "-E PATH=\"$PATH\"", + "-p StandardOutput=journal", + "-p StandardError=journal", + f"-p LoadCredentialEncrypted={CRED_NAME}:{CRED_FILE}", + f"$SHELL -c '{cmd}'" + ]) ) + + if status != 0: + raise Exception(f"systemd_run failed (status {status})") + + machine.log("systemd-run finished successfully") + + tpm = Tpm() + + @polling_condition + def swtpm_running(): + tpm.check() + + machine.wait_for_unit("multi-user.target") + + with subtest("Check whether TPM device exists"): + machine.succeed("test -e /dev/tpm0") + machine.succeed("test -e /dev/tpmrm0") + + with subtest("Check whether systemd-creds detects TPM2 correctly"): + cmd = "systemd-creds has-tpm2" + machine.log(f"Running \"{cmd}\"") + (status, _) = machine.execute(cmd) + + # Check exit code equals 0 or 1 (1 means firmware support is missing, which is OK here) + if status != 0 and status != 1: + raise Exception("systemd-creds failed to detect TPM2") + + with subtest("Encrypt credential using systemd-creds"): + machine.succeed(f"dd if=/dev/urandom of={CRED_RAW_FILE} bs=1k count=16") + machine.succeed(f"systemd-creds --with-key=host+tpm2 encrypt --name=testkey {CRED_RAW_FILE} {CRED_FILE}") + + with subtest("Write provided credential and check for equality"): + CRED_OUT_FILE = f"/root/{CRED_NAME}.out" + systemd_run(machine, f"systemd-creds cat testkey > {CRED_OUT_FILE}") + machine.succeed(f"cmp --silent -- {CRED_RAW_FILE} {CRED_OUT_FILE}") + + with subtest("Check whether systemd service can see credential in systemd-creds list"): + systemd_run(machine, f"systemd-creds list | grep {CRED_NAME}") + + with subtest("Check whether systemd service can access credential in $CREDENTIALS_DIRECTORY"): + systemd_run(machine, f"cmp --silent -- $CREDENTIALS_DIRECTORY/{CRED_NAME} {CRED_RAW_FILE}") + ''; +}) diff --git a/nixos/tests/systemd-initrd-vconsole.nix b/nixos/tests/systemd-initrd-vconsole.nix new file mode 100644 index 0000000000000..b74df410c4224 --- /dev/null +++ b/nixos/tests/systemd-initrd-vconsole.nix @@ -0,0 +1,33 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-vconsole"; + + nodes.machine = { pkgs, ... }: { + boot.kernelParams = [ "rd.systemd.unit=rescue.target" ]; + + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + + console = { + earlySetup = true; + keyMap = "colemak"; + }; + }; + + testScript = '' + # Boot into rescue shell in initrd + machine.start() + machine.wait_for_console_text("Press Enter for maintenance") + machine.send_console("\n") + machine.wait_for_console_text("Logging in with home") + + # Check keymap + machine.send_console("(printf '%s to receive text: \\n' Ready && read text && echo \"$text\") </dev/tty1\n") + machine.wait_for_console_text("Ready to receive text:") + for key in "asdfjkl;\n": + machine.send_key(key) + machine.wait_for_console_text("arstneio") + machine.send_console("systemctl poweroff\n") + ''; +}) diff --git a/nixos/tests/tuxguitar.nix b/nixos/tests/tuxguitar.nix index 037f489e54483..00833024bfeac 100644 --- a/nixos/tests/tuxguitar.nix +++ b/nixos/tests/tuxguitar.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "tuxguitar"; meta = with pkgs.lib.maintainers; { - maintainers = [ asbachb ]; + maintainers = [ ]; }; nodes.machine = { config, pkgs, ... }: { |