diff options
Diffstat (limited to 'nixpkgs/nixos/tests')
-rw-r--r-- | nixpkgs/nixos/tests/all-terminfo.nix | 6 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/all-tests.nix | 3 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/auth-mysql.nix | 3 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/ayatana-indicators.nix | 71 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/cinnamon-wayland.nix | 71 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/guix/basic.nix | 38 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/guix/default.nix | 8 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/guix/publish.nix | 95 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/guix/scripts/add-existing-files-to-store.scm | 52 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/guix/scripts/create-file-to-store.scm | 8 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/input-remapper.nix | 5 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/installer-systemd-stage-1.nix | 4 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/installer.nix | 248 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/teleport.nix | 3 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/terminal-emulators.nix | 5 | ||||
-rw-r--r-- | nixpkgs/nixos/tests/tsm-client-gui.nix | 6 |
16 files changed, 600 insertions, 26 deletions
diff --git a/nixpkgs/nixos/tests/all-terminfo.nix b/nixpkgs/nixos/tests/all-terminfo.nix index dd47c66ee1c1..2f5e56f09f26 100644 --- a/nixpkgs/nixos/tests/all-terminfo.nix +++ b/nixpkgs/nixos/tests/all-terminfo.nix @@ -10,7 +10,11 @@ import ./make-test-python.nix ({ pkgs, ... }: rec { let o = builtins.tryEval drv; in - o.success && lib.isDerivation o.value && o.value ? outputs && builtins.elem "terminfo" o.value.outputs; + o.success && + lib.isDerivation o.value && + o.value ? outputs && + builtins.elem "terminfo" o.value.outputs && + !o.value.meta.broken; terminfos = lib.filterAttrs infoFilter pkgs; excludedTerminfos = lib.filterAttrs (_: drv: !(builtins.elem drv.terminfo config.environment.systemPackages)) terminfos; includedOuts = lib.filterAttrs (_: drv: builtins.elem drv.out config.environment.systemPackages) terminfos; diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix index 1ed0f760c9a2..e0572e3bed9c 100644 --- a/nixpkgs/nixos/tests/all-tests.nix +++ b/nixpkgs/nixos/tests/all-tests.nix @@ -135,6 +135,7 @@ in { authelia = handleTest ./authelia.nix {}; avahi = handleTest ./avahi.nix {}; avahi-with-resolved = handleTest ./avahi.nix { networkd = true; }; + ayatana-indicators = handleTest ./ayatana-indicators.nix {}; babeld = handleTest ./babeld.nix {}; bazarr = handleTest ./bazarr.nix {}; bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {}; @@ -187,6 +188,7 @@ in { chrony = handleTestOn ["aarch64-linux" "x86_64-linux"] ./chrony.nix {}; chrony-ptp = handleTestOn ["aarch64-linux" "x86_64-linux"] ./chrony-ptp.nix {}; cinnamon = handleTest ./cinnamon.nix {}; + cinnamon-wayland = handleTest ./cinnamon-wayland.nix {}; cjdns = handleTest ./cjdns.nix {}; clickhouse = handleTest ./clickhouse.nix {}; cloud-init = handleTest ./cloud-init.nix {}; @@ -357,6 +359,7 @@ in { grow-partition = runTest ./grow-partition.nix; grub = handleTest ./grub.nix {}; guacamole-server = handleTest ./guacamole-server.nix {}; + guix = handleTest ./guix {}; gvisor = handleTest ./gvisor.nix {}; hadoop = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop; }; hadoop_3_2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop_3_2; }; diff --git a/nixpkgs/nixos/tests/auth-mysql.nix b/nixpkgs/nixos/tests/auth-mysql.nix index 0ed4b050a69a..77a69eb1cd58 100644 --- a/nixpkgs/nixos/tests/auth-mysql.nix +++ b/nixpkgs/nixos/tests/auth-mysql.nix @@ -84,7 +84,7 @@ in getpwuid = '' SELECT name, 'x', uid, gid, name, CONCAT('/home/', name), "/run/current-system/sw/bin/bash" \ FROM users \ - WHERE id=%1$u \ + WHERE uid=%1$u \ LIMIT 1 ''; getspnam = '' @@ -140,6 +140,7 @@ in machine.wait_for_unit("multi-user.target") machine.wait_for_unit("mysql.service") + machine.wait_until_succeeds("cat /etc/security/pam_mysql.conf | grep users.db_passwd") machine.wait_until_succeeds("pgrep -f 'agetty.*tty1'") with subtest("Local login"): diff --git a/nixpkgs/nixos/tests/ayatana-indicators.nix b/nixpkgs/nixos/tests/ayatana-indicators.nix new file mode 100644 index 000000000000..bc7ff75f390f --- /dev/null +++ b/nixpkgs/nixos/tests/ayatana-indicators.nix @@ -0,0 +1,71 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: let + user = "alice"; +in { + name = "ayatana-indicators"; + + meta = { + maintainers = with lib.maintainers; [ OPNA2608 ]; + }; + + nodes.machine = { config, ... }: { + imports = [ + ./common/auto.nix + ./common/user-account.nix + ]; + + test-support.displayManager.auto = { + enable = true; + inherit user; + }; + + services.xserver = { + enable = true; + desktopManager.mate.enable = true; + displayManager.defaultSession = lib.mkForce "mate"; + }; + + services.ayatana-indicators = { + enable = true; + packages = with pkgs; [ + ayatana-indicator-messages + ]; + }; + + # Services needed by some indicators + services.accounts-daemon.enable = true; # messages + }; + + # TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready? + testScript = { nodes, ... }: let + runCommandPerIndicatorService = command: lib.strings.concatMapStringsSep "\n" command nodes.machine.systemd.user.targets."ayatana-indicators".wants; + in '' + start_all() + machine.wait_for_x() + + # Desktop environment should reach graphical-session.target + machine.wait_for_unit("graphical-session.target", "${user}") + + # MATE relies on XDG autostart to bring up the indicators. + # Not sure *when* XDG autostart fires them up, and awaiting pgrep success seems to misbehave? + machine.sleep(10) + + # Now check if all indicators were brought up successfully, and kill them for later + '' + (runCommandPerIndicatorService (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in '' + machine.succeed("pgrep -f ${serviceExec}") + machine.succeed("pkill -f ${serviceExec}") + '')) + '' + + # Ayatana target is the preferred way of starting up indicators on SystemD session, the graphical session is responsible for starting this if it supports them. + # Mate currently doesn't do this, so start it manually for checking (https://github.com/mate-desktop/mate-indicator-applet/issues/63) + machine.systemctl("start ayatana-indicators.target", "${user}") + machine.wait_for_unit("ayatana-indicators.target", "${user}") + + # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures + # Not sure if there's a better way of awaiting this without false-positive potential + machine.sleep(10) + + # Now check if all indicator services were brought up successfully + '' + runCommandPerIndicatorService (service: '' + machine.wait_for_unit("${service}", "${user}") + ''); +}) diff --git a/nixpkgs/nixos/tests/cinnamon-wayland.nix b/nixpkgs/nixos/tests/cinnamon-wayland.nix new file mode 100644 index 000000000000..58dddbbb0866 --- /dev/null +++ b/nixpkgs/nixos/tests/cinnamon-wayland.nix @@ -0,0 +1,71 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "cinnamon-wayland"; + + meta.maintainers = lib.teams.cinnamon.members; + + nodes.machine = { nodes, ... }: { + imports = [ ./common/user-account.nix ]; + services.xserver.enable = true; + services.xserver.desktopManager.cinnamon.enable = true; + services.xserver.displayManager = { + autoLogin.enable = true; + autoLogin.user = nodes.machine.users.users.alice.name; + defaultSession = "cinnamon-wayland"; + }; + }; + + enableOCR = true; + + testScript = { nodes, ... }: + let + user = nodes.machine.users.users.alice; + env = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${toString user.uid}/bus"; + su = command: "su - ${user.name} -c '${env} ${command}'"; + + # Call javascript in cinnamon (the shell), returns a tuple (success, output), + # where `success` is true if the dbus call was successful and `output` is what + # the javascript evaluates to. + eval = name: su "gdbus call --session -d org.Cinnamon -o /org/Cinnamon -m org.Cinnamon.Eval ${name}"; + in + '' + machine.wait_for_unit("display-manager.service") + + with subtest("Wait for wayland server"): + machine.wait_for_file("/run/user/${toString user.uid}/wayland-0") + + with subtest("Check that logging in has given the user ownership of devices"): + machine.succeed("getfacl -p /dev/snd/timer | grep -q ${user.name}") + + with subtest("Wait for the Cinnamon shell"): + # Correct output should be (true, '2') + # https://github.com/linuxmint/cinnamon/blob/5.4.0/js/ui/main.js#L183-L187 + machine.wait_until_succeeds("${eval "Main.runState"} | grep -q 'true,..2'") + + with subtest("Check if Cinnamon components actually start"): + for i in ["csd-media-keys", "xapp-sn-watcher", "nemo-desktop"]: + machine.wait_until_succeeds(f"pgrep -f {i}") + machine.wait_until_succeeds("journalctl -b --grep 'Loaded applet menu@cinnamon.org'") + machine.wait_until_succeeds("journalctl -b --grep 'calendar@cinnamon.org: Calendar events supported'") + + with subtest("Open Cinnamon Settings"): + machine.succeed("${su "cinnamon-settings themes >&2 &"}") + machine.wait_until_succeeds("${eval "global.display.focus_window.wm_class"} | grep -i 'cinnamon-settings'") + machine.wait_for_text('(Style|Appearance|Color)') + machine.sleep(2) + machine.screenshot("cinnamon_settings") + + with subtest("Check if screensaver works"): + # This is not supported at the moment. + # https://trello.com/b/HHs01Pab/cinnamon-wayland + machine.execute("${su "cinnamon-screensaver-command -l >&2 &"}") + machine.wait_until_succeeds("journalctl -b --grep 'Cinnamon Screensaver is unavailable on Wayland'") + + with subtest("Open GNOME Terminal"): + machine.succeed("${su "dbus-launch gnome-terminal"}") + machine.wait_until_succeeds("${eval "global.display.focus_window.wm_class"} | grep -i 'gnome-terminal'") + machine.sleep(2) + + with subtest("Check if Cinnamon has ever coredumped"): + machine.fail("coredumpctl --json=short | grep -E 'cinnamon|nemo'") + ''; +}) diff --git a/nixpkgs/nixos/tests/guix/basic.nix b/nixpkgs/nixos/tests/guix/basic.nix new file mode 100644 index 000000000000..7f90bdeeb1e0 --- /dev/null +++ b/nixpkgs/nixos/tests/guix/basic.nix @@ -0,0 +1,38 @@ +# Take note the Guix store directory is empty. Also, we're trying to prevent +# Guix from trying to downloading substitutes because of the restricted +# access (assuming it's in a sandboxed environment). +# +# So this test is what it is: a basic test while trying to use Guix as much as +# we possibly can (including the API) without triggering its download alarm. + +import ../make-test-python.nix ({ lib, pkgs, ... }: { + name = "guix-basic"; + meta.maintainers = with lib.maintainers; [ foo-dogsquared ]; + + nodes.machine = { config, ... }: { + environment.etc."guix/scripts".source = ./scripts; + services.guix.enable = true; + }; + + testScript = '' + import pathlib + + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("guix-daemon.service") + + # Can't do much here since the environment has restricted network access. + with subtest("Guix basic package management"): + machine.succeed("guix build --dry-run --verbosity=0 hello") + machine.succeed("guix show hello") + + # This is to see if the Guix API is usable and mostly working. + with subtest("Guix API scripting"): + scripts_dir = pathlib.Path("/etc/guix/scripts") + + text_msg = "Hello there, NixOS!" + text_store_file = machine.succeed(f"guix repl -- {scripts_dir}/create-file-to-store.scm '{text_msg}'") + assert machine.succeed(f"cat {text_store_file}") == text_msg + + machine.succeed(f"guix repl -- {scripts_dir}/add-existing-files-to-store.scm {scripts_dir}") + ''; +}) diff --git a/nixpkgs/nixos/tests/guix/default.nix b/nixpkgs/nixos/tests/guix/default.nix new file mode 100644 index 000000000000..a017668c05a7 --- /dev/null +++ b/nixpkgs/nixos/tests/guix/default.nix @@ -0,0 +1,8 @@ +{ system ? builtins.currentSystem +, pkgs ? import ../../.. { inherit system; } +}: + +{ + basic = import ./basic.nix { inherit system pkgs; }; + publish = import ./publish.nix { inherit system pkgs; }; +} diff --git a/nixpkgs/nixos/tests/guix/publish.nix b/nixpkgs/nixos/tests/guix/publish.nix new file mode 100644 index 000000000000..6dbe8f99ebd6 --- /dev/null +++ b/nixpkgs/nixos/tests/guix/publish.nix @@ -0,0 +1,95 @@ +# Testing out the substitute server with two machines in a local network. As a +# bonus, we'll also test a feature of the substitute server being able to +# advertise its service to the local network with Avahi. + +import ../make-test-python.nix ({ pkgs, lib, ... }: let + publishPort = 8181; + inherit (builtins) toString; +in { + name = "guix-publish"; + + meta.maintainers = with lib.maintainers; [ foo-dogsquared ]; + + nodes = let + commonConfig = { config, ... }: { + # We'll be using '--advertise' flag with the + # substitute server which requires Avahi. + services.avahi = { + enable = true; + nssmdns = true; + publish = { + enable = true; + userServices = true; + }; + }; + }; + in { + server = { config, lib, pkgs, ... }: { + imports = [ commonConfig ]; + + services.guix = { + enable = true; + publish = { + enable = true; + port = publishPort; + + generateKeyPair = true; + extraArgs = [ "--advertise" ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ publishPort ]; + }; + + client = { config, lib, pkgs, ... }: { + imports = [ commonConfig ]; + + services.guix = { + enable = true; + + extraArgs = [ + # Force to only get all substitutes from the local server. We don't + # have anything in the Guix store directory and we cannot get + # anything from the official substitute servers anyways. + "--substitute-urls='http://server.local:${toString publishPort}'" + + # Enable autodiscovery of the substitute servers in the local + # network. This machine shouldn't need to import the signing key from + # the substitute server since it is automatically done anyways. + "--discover=yes" + ]; + }; + }; + }; + + testScript = '' + import pathlib + + start_all() + + scripts_dir = pathlib.Path("/etc/guix/scripts") + + for machine in machines: + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("guix-daemon.service") + machine.wait_for_unit("avahi-daemon.service") + + server.wait_for_unit("guix-publish.service") + server.wait_for_open_port(${toString publishPort}) + server.succeed("curl http://localhost:${toString publishPort}/") + + # Now it's the client turn to make use of it. + substitute_server = "http://server.local:${toString publishPort}" + client.wait_for_unit("network-online.target") + response = client.succeed(f"curl {substitute_server}") + assert "Guix Substitute Server" in response + + # Authorizing the server to be used as a substitute server. + client.succeed(f"curl -O {substitute_server}/signing-key.pub") + client.succeed("guix archive --authorize < ./signing-key.pub") + + # Since we're using the substitute server with the `--advertise` flag, we + # might as well check it. + client.succeed("avahi-browse --resolve --terminate _guix_publish._tcp | grep '_guix_publish._tcp'") + ''; +}) diff --git a/nixpkgs/nixos/tests/guix/scripts/add-existing-files-to-store.scm b/nixpkgs/nixos/tests/guix/scripts/add-existing-files-to-store.scm new file mode 100644 index 000000000000..fa47320b6a51 --- /dev/null +++ b/nixpkgs/nixos/tests/guix/scripts/add-existing-files-to-store.scm @@ -0,0 +1,52 @@ +;; A simple script that adds each file given from the command-line into the +;; store and checks them if it's the same. +(use-modules (guix) + (srfi srfi-1) + (ice-9 ftw) + (rnrs io ports)) + +;; This is based from tests/derivations.scm from Guix source code. +(define* (directory-contents dir #:optional (slurp get-bytevector-all)) + "Return an alist representing the contents of DIR" + (define prefix-len (string-length dir)) + (sort (file-system-fold (const #t) + (lambda (path stat result) + (alist-cons (string-drop path prefix-len) + (call-with-input-file path slurp) + result)) + (lambda (path stat result) result) + (lambda (path stat result) result) + (lambda (path stat result) result) + (lambda (path stat errno result) result) + '() + dir) + (lambda (e1 e2) + (string<? (car e1) (car e2))))) + +(define* (check-if-same store drv path) + "Check if the given path and its store item are the same" + (let* ((filetype (stat:type (stat drv)))) + (case filetype + ((regular) + (and (valid-path? store drv) + (equal? (call-with-input-file path get-bytevector-all) + (call-with-input-file drv get-bytevector-all)))) + ((directory) + (and (valid-path? store drv) + (equal? (directory-contents path) + (directory-contents drv)))) + (else #f)))) + +(define* (add-and-check-item-to-store store path) + "Add PATH to STORE and check if the contents are the same" + (let* ((store-item (add-to-store store + (basename path) + #t "sha256" path)) + (is-same (check-if-same store store-item path))) + (if (not is-same) + (exit 1)))) + +(with-store store + (map (lambda (path) + (add-and-check-item-to-store store (readlink* path))) + (cdr (command-line)))) diff --git a/nixpkgs/nixos/tests/guix/scripts/create-file-to-store.scm b/nixpkgs/nixos/tests/guix/scripts/create-file-to-store.scm new file mode 100644 index 000000000000..467e4c4fd53f --- /dev/null +++ b/nixpkgs/nixos/tests/guix/scripts/create-file-to-store.scm @@ -0,0 +1,8 @@ +;; A script that creates a store item with the given text and prints the +;; resulting store item path. +(use-modules (guix)) + +(with-store store + (display (add-text-to-store store "guix-basic-test-text" + (string-join + (cdr (command-line)))))) diff --git a/nixpkgs/nixos/tests/input-remapper.nix b/nixpkgs/nixos/tests/input-remapper.nix index 1b0350063f7f..2ef55a01b290 100644 --- a/nixpkgs/nixos/tests/input-remapper.nix +++ b/nixpkgs/nixos/tests/input-remapper.nix @@ -46,7 +46,8 @@ import ./make-test-python.nix ({ pkgs, ... }: machine.execute("su - sybil -c input-remapper-gtk >&2 &") machine.wait_for_text("Input Remapper") - machine.wait_for_text("Preset") - machine.wait_for_text("Change Key") + machine.wait_for_text("Device") + machine.wait_for_text("Presets") + machine.wait_for_text("Editor") ''; }) diff --git a/nixpkgs/nixos/tests/installer-systemd-stage-1.nix b/nixpkgs/nixos/tests/installer-systemd-stage-1.nix index 1b4c92b584b9..d0c01a779ef1 100644 --- a/nixpkgs/nixos/tests/installer-systemd-stage-1.nix +++ b/nixpkgs/nixos/tests/installer-systemd-stage-1.nix @@ -32,6 +32,10 @@ stratisRoot swraid zfsroot + clevisLuks + clevisLuksFallback + clevisZfs + clevisZfsFallback ; } diff --git a/nixpkgs/nixos/tests/installer.nix b/nixpkgs/nixos/tests/installer.nix index e9ec28749850..f7fc168eba8c 100644 --- a/nixpkgs/nixos/tests/installer.nix +++ b/nixpkgs/nixos/tests/installer.nix @@ -12,6 +12,7 @@ let # The configuration to install. makeConfig = { bootLoader, grubDevice, grubIdentifier, grubUseEfi , extraConfig, forceGrubReinstallCount ? 0, flake ? false + , clevisTest }: pkgs.writeText "configuration.nix" '' { config, lib, pkgs, modulesPath, ... }: @@ -52,6 +53,15 @@ let boot.initrd.secrets."/etc/secret" = ./secret; + ${optionalString clevisTest '' + boot.kernelParams = [ "console=tty0" "ip=192.168.1.1:::255.255.255.0::eth1:none" ]; + boot.initrd = { + availableKernelModules = [ "tpm_tis" ]; + clevis = { enable = true; useTang = true; }; + network.enable = true; + }; + ''} + users.users.alice = { isNormalUser = true; home = "/home/alice"; @@ -71,7 +81,7 @@ let # partitions and filesystems. testScriptFun = { bootLoader, createPartitions, grubDevice, grubUseEfi, grubIdentifier , postInstallCommands, preBootCommands, postBootCommands, extraConfig - , testSpecialisationConfig, testFlakeSwitch + , testSpecialisationConfig, testFlakeSwitch, clevisTest, clevisFallbackTest }: let iface = "virtio"; isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi); @@ -79,12 +89,16 @@ let in if !isEfi && !pkgs.stdenv.hostPlatform.isx86 then '' machine.succeed("true") '' else '' + import subprocess + tpm_folder = os.environ['NIX_BUILD_TOP'] def assemble_qemu_flags(): flags = "-cpu max" ${if (system == "x86_64-linux" || system == "i686-linux") then ''flags += " -m 1024"'' else ''flags += " -m 768 -enable-kvm -machine virt,gic-version=host"'' } + ${optionalString clevisTest ''flags += f" -chardev socket,id=chrtpm,path={tpm_folder}/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0"''} + ${optionalString clevisTest ''flags += " -device virtio-net-pci,netdev=vlan1,mac=52:54:00:12:11:02 -netdev vde,id=vlan1,sock=\"$QEMU_VDE_SOCKET_1\""''} return flags @@ -110,8 +124,45 @@ let def create_machine_named(name): return create_machine({**default_flags, "name": name}) + class Tpm: + def __init__(self): + self.start() + + def start(self): + self.proc = subprocess.Popen(["${pkgs.swtpm}/bin/swtpm", + "socket", + "--tpmstate", f"dir={tpm_folder}/swtpm", + "--ctrl", f"type=unixio,path={tpm_folder}/swtpm-sock", + "--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") + + + os.mkdir(f"{tpm_folder}/swtpm") + tpm = Tpm() + tpm.check() + + start_all() + ${optionalString clevisTest '' + tang.wait_for_unit("sockets.target") + tang.wait_for_unit("network-online.target") + machine.wait_for_unit("network-online.target") + ''} + machine.wait_for_unit("multi-user.target") - machine.start() with subtest("Assert readiness of login prompt"): machine.succeed("echo hello") @@ -127,13 +178,23 @@ let machine.copy_from_host( "${ makeConfig { inherit bootLoader grubDevice grubIdentifier - grubUseEfi extraConfig; + grubUseEfi extraConfig clevisTest; } }", "/mnt/etc/nixos/configuration.nix", ) machine.copy_from_host("${pkgs.writeText "secret" "secret"}", "/mnt/etc/nixos/secret") + ${optionalString clevisTest '' + with subtest("Create the Clevis secret with Tang"): + machine.wait_for_unit("network-online.target") + machine.succeed('echo -n password | clevis encrypt sss \'{"t": 2, "pins": {"tpm2": {}, "tang": {"url": "http://192.168.1.2"}}}\' -y > /mnt/etc/nixos/clevis-secret.jwe')''} + + ${optionalString clevisFallbackTest '' + with subtest("Shutdown Tang to check fallback to interactive prompt"): + tang.shutdown() + ''} + with subtest("Perform the installation"): machine.succeed("nixos-install < /dev/null >&2") @@ -200,7 +261,7 @@ let machine.copy_from_host_via_shell( "${ makeConfig { inherit bootLoader grubDevice grubIdentifier - grubUseEfi extraConfig; + grubUseEfi extraConfig clevisTest; forceGrubReinstallCount = 1; } }", @@ -229,7 +290,7 @@ let machine.copy_from_host_via_shell( "${ makeConfig { inherit bootLoader grubDevice grubIdentifier - grubUseEfi extraConfig; + grubUseEfi extraConfig clevisTest; forceGrubReinstallCount = 2; } }", @@ -303,7 +364,7 @@ let """) machine.copy_from_host_via_shell( "${makeConfig { - inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig; + inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig clevisTest; forceGrubReinstallCount = 1; flake = true; }}", @@ -379,6 +440,8 @@ let , enableOCR ? false, meta ? {} , testSpecialisationConfig ? false , testFlakeSwitch ? false + , clevisTest ? false + , clevisFallbackTest ? false }: makeTest { inherit enableOCR; @@ -416,13 +479,13 @@ let virtualisation.rootDevice = "/dev/vdb"; virtualisation.bootLoaderDevice = "/dev/vda"; virtualisation.qemu.diskInterface = "virtio"; - - # We don't want to have any networking in the guest whatsoever. - # Also, if any vlans are enabled, the guest will reboot - # (with a different configuration for legacy reasons), - # and spend 5 minutes waiting for the vlan interface to show up - # (which will never happen). - virtualisation.vlans = []; + virtualisation.qemu.options = mkIf (clevisTest) [ + "-chardev socket,id=chrtpm,path=$NIX_BUILD_TOP/swtpm-sock" + "-tpmdev emulator,id=tpm0,chardev=chrtpm" + "-device tpm-tis,tpmdev=tpm0" + ]; + # We don't want to have any networking in the guest apart from the clevis tests. + virtualisation.vlans = mkIf (!clevisTest) []; boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true; @@ -471,7 +534,7 @@ let in [ (pkgs.grub2.override { inherit zfsSupport; }) (pkgs.grub2_efi.override { inherit zfsSupport; }) - ]); + ]) ++ optionals clevisTest [ pkgs.klibc ]; nix.settings = { substituters = mkForce []; @@ -480,12 +543,21 @@ let }; }; + } // optionalAttrs clevisTest { + tang = { + services.tang = { + enable = true; + listenStream = [ "80" ]; + ipAddressAllow = [ "192.168.1.0/24" ]; + }; + networking.firewall.allowedTCPPorts = [ 80 ]; + }; }; testScript = testScriptFun { inherit bootLoader createPartitions postInstallCommands preBootCommands postBootCommands grubDevice grubIdentifier grubUseEfi extraConfig - testSpecialisationConfig testFlakeSwitch; + testSpecialisationConfig testFlakeSwitch clevisTest clevisFallbackTest; }; }; @@ -586,6 +658,145 @@ let zfs = super.zfs.overrideAttrs(_: {meta.platforms = [];});} )]; }; + + mkClevisBcachefsTest = { fallback ? false }: makeInstallerTest "clevis-bcachefs${optionalString fallback "-fallback"}" { + clevisTest = true; + clevisFallbackTest = fallback; + enableOCR = fallback; + extraInstallerConfig = { + imports = [ no-zfs-module ]; + boot.supportedFilesystems = [ "bcachefs" ]; + environment.systemPackages = with pkgs; [ keyutils clevis ]; + }; + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" + + " mkpart primary linux-swap 100M 1024M" + + " mkpart primary 1024M -1s", + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "keyctl link @u @s", + "echo -n password | mkfs.bcachefs -L root --encrypted /dev/vda3", + "echo -n password | bcachefs unlock /dev/vda3", + "echo -n password | mount -t bcachefs /dev/vda3 /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=boot /mnt/boot", + "udevadm settle") + ''; + extraConfig = '' + boot.initrd.clevis.devices."/dev/vda3".secretFile = "/etc/nixos/clevis-secret.jwe"; + + # We override what nixos-generate-config has generated because we do + # not know the UUID in advance. + fileSystems."/" = lib.mkForce { device = "/dev/vda3"; fsType = "bcachefs"; }; + ''; + preBootCommands = '' + tpm = Tpm() + tpm.check() + '' + optionalString fallback '' + machine.start() + machine.wait_for_text("enter passphrase for") + machine.send_chars("password\n") + ''; + }; + + mkClevisLuksTest = { fallback ? false }: makeInstallerTest "clevis-luks${optionalString fallback "-fallback"}" { + clevisTest = true; + clevisFallbackTest = fallback; + enableOCR = fallback; + extraInstallerConfig = { + environment.systemPackages = with pkgs; [ clevis ]; + }; + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" + + " mkpart primary linux-swap 100M 1024M" + + " mkpart primary 1024M -1s", + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "modprobe dm_mod dm_crypt", + "echo -n password | cryptsetup luksFormat -q /dev/vda3 -", + "echo -n password | cryptsetup luksOpen --key-file - /dev/vda3 crypt-root", + "mkfs.ext3 -L nixos /dev/mapper/crypt-root", + "mount LABEL=nixos /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=boot /mnt/boot", + "udevadm settle") + ''; + extraConfig = '' + boot.initrd.clevis.devices."crypt-root".secretFile = "/etc/nixos/clevis-secret.jwe"; + ''; + preBootCommands = '' + tpm = Tpm() + tpm.check() + '' + optionalString fallback '' + machine.start() + ${if systemdStage1 then '' + machine.wait_for_text("Please enter") + '' else '' + machine.wait_for_text("Passphrase for") + ''} + machine.send_chars("password\n") + ''; + }; + + mkClevisZfsTest = { fallback ? false }: makeInstallerTest "clevis-zfs${optionalString fallback "-fallback"}" { + clevisTest = true; + clevisFallbackTest = fallback; + enableOCR = fallback; + extraInstallerConfig = { + boot.supportedFilesystems = [ "zfs" ]; + environment.systemPackages = with pkgs; [ clevis ]; + }; + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" + + " mkpart primary linux-swap 100M 1024M" + + " mkpart primary 1024M -1s", + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "zpool create -O mountpoint=legacy rpool /dev/vda3", + "echo -n password | zfs create" + + " -o encryption=aes-256-gcm -o keyformat=passphrase rpool/root", + "mount -t zfs rpool/root /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount LABEL=boot /mnt/boot", + "udevadm settle") + ''; + extraConfig = '' + boot.initrd.clevis.devices."rpool/root".secretFile = "/etc/nixos/clevis-secret.jwe"; + boot.zfs.requestEncryptionCredentials = true; + + + # Using by-uuid overrides the default of by-id, and is unique + # to the qemu disks, as they don't produce by-id paths for + # some reason. + boot.zfs.devNodes = "/dev/disk/by-uuid/"; + networking.hostId = "00000000"; + ''; + preBootCommands = '' + tpm = Tpm() + tpm.check() + '' + optionalString fallback '' + machine.start() + ${if systemdStage1 then '' + machine.wait_for_text("Enter key for rpool/root") + '' else '' + machine.wait_for_text("Key load error") + ''} + machine.send_chars("password\n") + ''; + }; + in { # !!! `parted mkpart' seems to silently create overlapping partitions. @@ -1175,6 +1386,13 @@ in { ) ''; }; +} // { + clevisBcachefs = mkClevisBcachefsTest { }; + clevisBcachefsFallback = mkClevisBcachefsTest { fallback = true; }; + clevisLuks = mkClevisLuksTest { }; + clevisLuksFallback = mkClevisLuksTest { fallback = true; }; + clevisZfs = mkClevisZfsTest { }; + clevisZfsFallback = mkClevisZfsTest { fallback = true; }; } // optionalAttrs systemdStage1 { stratisRoot = makeInstallerTest "stratisRoot" { createPartitions = '' diff --git a/nixpkgs/nixos/tests/teleport.nix b/nixpkgs/nixos/tests/teleport.nix index cdf762b12844..d68917c6c7ac 100644 --- a/nixpkgs/nixos/tests/teleport.nix +++ b/nixpkgs/nixos/tests/teleport.nix @@ -9,7 +9,8 @@ with import ../lib/testing-python.nix { inherit system pkgs; }; let packages = with pkgs; { "default" = teleport; - "11" = teleport_11; + "12" = teleport_12; + "13" = teleport_13; }; minimal = package: { diff --git a/nixpkgs/nixos/tests/terminal-emulators.nix b/nixpkgs/nixos/tests/terminal-emulators.nix index 2306c03c18e7..efaac03e1983 100644 --- a/nixpkgs/nixos/tests/terminal-emulators.nix +++ b/nixpkgs/nixos/tests/terminal-emulators.nix @@ -23,9 +23,8 @@ with pkgs.lib; let tests = { alacritty.pkg = p: p.alacritty; - # times out after spending many hours - #contour.pkg = p: p.contour; - #contour.cmd = "contour $command"; + contour.pkg = p: p.contour; + contour.cmd = "contour early-exit-threshold 0 execute $command"; cool-retro-term.pkg = p: p.cool-retro-term; cool-retro-term.colourTest = false; # broken by gloss effect diff --git a/nixpkgs/nixos/tests/tsm-client-gui.nix b/nixpkgs/nixos/tests/tsm-client-gui.nix index e11501da53d0..c9632546db6e 100644 --- a/nixpkgs/nixos/tests/tsm-client-gui.nix +++ b/nixpkgs/nixos/tests/tsm-client-gui.nix @@ -18,9 +18,9 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { defaultServername = "testserver"; servers.testserver = { # 192.0.0.8 is a "dummy address" according to RFC 7600 - server = "192.0.0.8"; - node = "SOME-NODE"; - passwdDir = "/tmp"; + tcpserveraddress = "192.0.0.8"; + nodename = "SOME-NODE"; + passworddir = "/tmp"; }; }; }; |