diff options
Diffstat (limited to 'nixos')
114 files changed, 1408 insertions, 1302 deletions
diff --git a/nixos/doc/manual/installation/installing-virtualbox-guest.xml b/nixos/doc/manual/installation/installing-virtualbox-guest.xml index 5c86eacfbf45..0ba909fa953f 100644 --- a/nixos/doc/manual/installation/installing-virtualbox-guest.xml +++ b/nixos/doc/manual/installation/installing-virtualbox-guest.xml @@ -49,6 +49,11 @@ </listitem> <listitem> <para> + Click on Settings / Display / Screen and select VBoxVGA as Graphics Controller + </para> + </listitem> + <listitem> + <para> Save the settings, start the virtual machine, and continue installation like normal </para> diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml index c697b7ee0472..495dbc8859b1 100644 --- a/nixos/doc/manual/man-nixos-rebuild.xml +++ b/nixos/doc/manual/man-nixos-rebuild.xml @@ -494,6 +494,20 @@ </para> </listitem> </varlistentry> + + <varlistentry> + <term> + <option>--use-remote-sudo</option> + </term> + <listitem> + <para> + When set, nixos-rebuild prefixes remote commands that run on + the <option>--build-host</option> and <option>--target-host</option> + systems with <command>sudo</command>. Setting this option allows + deploying as a non-root user. + </para> + </listitem> + </varlistentry> </variablelist> <para> diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py index 45b7e229a5c6..c8d4936ac52a 100644 --- a/nixos/lib/test-driver/test-driver.py +++ b/nixos/lib/test-driver/test-driver.py @@ -4,7 +4,9 @@ from contextlib import contextmanager from xml.sax.saxutils import XMLGenerator import _thread import atexit +import json import os +import ptpython.repl import pty import queue import re @@ -15,7 +17,6 @@ import sys import tempfile import time import unicodedata -import ptpython.repl CHAR_TO_KEY = { "A": "shift-a", @@ -305,7 +306,7 @@ class Machine: if state == "inactive": status, jobs = self.systemctl("list-jobs --full 2>&1", user) if "No jobs" in jobs: - info = self.get_unit_info(unit) + info = self.get_unit_info(unit, user) if info["ActiveState"] == state: raise Exception( ( @@ -318,7 +319,11 @@ class Machine: def get_unit_info(self, unit, user=None): status, lines = self.systemctl('--no-pager show "{}"'.format(unit), user) if status != 0: - return None + raise Exception( + 'retrieving systemctl info for unit "{}" {} failed with exit code {}'.format( + unit, "" if user is None else 'under user "{}"'.format(user), status + ) + ) line_pattern = re.compile(r"^([^=]+)=(.*)$") @@ -344,6 +349,18 @@ class Machine: ) return self.execute("systemctl {}".format(q)) + def require_unit_state(self, unit, require_state="active"): + with self.nested( + "checking if unit ‘{}’ has reached state '{}'".format(unit, require_state) + ): + info = self.get_unit_info(unit) + state = info["ActiveState"] + if state != require_state: + raise Exception( + "Expected unit ‘{}’ to to be in state ".format(unit) + + "'active' but it is in state ‘{}’".format(state) + ) + def execute(self, command): self.connect() @@ -364,15 +381,17 @@ class Machine: def succeed(self, *commands): """Execute each command and check that it succeeds.""" + output = "" for command in commands: with self.nested("must succeed: {}".format(command)): - status, output = self.execute(command) + (status, out) = self.execute(command) if status != 0: - self.log("output: {}".format(output)) + self.log("output: {}".format(out)) raise Exception( "command `{}` failed (exit code {})".format(command, status) ) - return output + output += out + return output def fail(self, *commands): """Execute each command and check that it fails.""" @@ -494,6 +513,11 @@ class Machine: if ret.returncode != 0: raise Exception("Cannot convert screenshot") + def dump_tty_contents(self, tty): + """Debugging: Dump the contents of the TTY<n> + """ + self.execute("fold -w 80 /dev/vcs{} | systemd-cat".format(tty)) + def get_screen_text(self): if shutil.which("tesseract") is None: raise Exception("get_screen_text used but enableOCR is false") @@ -588,7 +612,7 @@ class Machine: stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - shell=False, + shell=True, cwd=self.state_dir, env=environment, ) @@ -597,7 +621,7 @@ class Machine: def process_serial_output(): for line in self.process.stdout: - line = line.decode().replace("\r", "").rstrip() + line = line.decode("unicode_escape").replace("\r", "").rstrip() eprint("{} # {}".format(self.name, line)) self.logger.enqueue({"msg": line, "machine": self.name}) @@ -611,14 +635,14 @@ class Machine: self.log("QEMU running (pid {})".format(self.pid)) def shutdown(self): - if self.booted: + if not self.booted: return self.shell.send("poweroff\n".encode()) self.wait_for_shutdown() def crash(self): - if self.booted: + if not self.booted: return self.log("forced crash") @@ -642,9 +666,38 @@ class Machine: if status == 0: return + def get_window_names(self): + return self.succeed( + r"xwininfo -root -tree | sed 's/.*0x[0-9a-f]* \"\([^\"]*\)\".*/\1/; t; d'" + ).splitlines() + + def wait_for_window(self, regexp): + pattern = re.compile(regexp) + + def window_is_visible(last_try): + names = self.get_window_names() + if last_try: + self.log( + "Last chance to match {} on the window list,".format(regexp) + + " which currently contains: " + + ", ".join(names) + ) + return any(pattern.search(name) for name in names) + + with self.nested("Waiting for a window to appear"): + retry(window_is_visible) + def sleep(self, secs): time.sleep(secs) + def forward_port(self, host_port=8080, guest_port=80): + """Forward a TCP port on the host to a TCP port on the guest. + Useful during interactive testing. + """ + self.send_monitor_command( + "hostfwd_add tcp::{}-:{}".format(host_port, guest_port) + ) + def block(self): """Make the machine unreachable by shutting down eth1 (the multicast interface used to talk to the other VMs). We keep eth0 up so that diff --git a/nixos/modules/config/fonts/corefonts.nix b/nixos/modules/config/fonts/corefonts.nix deleted file mode 100644 index b9f69879a103..000000000000 --- a/nixos/modules/config/fonts/corefonts.nix +++ /dev/null @@ -1,36 +0,0 @@ -# This module is deprecated, since you can just say ‘fonts.fonts = [ -# pkgs.corefonts ];’ instead. - -{ config, lib, pkgs, ... }: - -with lib; - -{ - - options = { - - fonts = { - - enableCoreFonts = mkOption { - visible = false; - default = false; - description = '' - Whether to include Microsoft's proprietary Core Fonts. These fonts - are redistributable, but only verbatim, among other restrictions. - See <link xlink:href="http://corefonts.sourceforge.net/eula.htm"/> - for details. - ''; - }; - - }; - - }; - - - config = mkIf config.fonts.enableCoreFonts { - - fonts.fonts = [ pkgs.corefonts ]; - - }; - -} diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix deleted file mode 100644 index 84d90899dfff..000000000000 --- a/nixos/modules/config/fonts/fontconfig-ultimate.nix +++ /dev/null @@ -1,86 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let cfg = config.fonts.fontconfig.ultimate; - - latestVersion = pkgs.fontconfig.configVersion; - - # The configuration to be included in /etc/font/ - confPkg = pkgs.runCommand "font-ultimate-conf" { preferLocalBuild = true; } '' - support_folder=$out/etc/fonts/conf.d - latest_folder=$out/etc/fonts/${latestVersion}/conf.d - - mkdir -p $support_folder - mkdir -p $latest_folder - - # fontconfig ultimate substitutions - ${optionalString (cfg.substitutions != "none") '' - ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \ - $support_folder - ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \ - $latest_folder - ''} - - # fontconfig ultimate various configuration files - ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/conf.d/*.conf \ - $support_folder - ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/conf.d/*.conf \ - $latest_folder - ''; - -in -{ - - options = { - - fonts = { - - fontconfig = { - - ultimate = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Enable fontconfig-ultimate settings (formerly known as - Infinality). Besides the customizable settings in this NixOS - module, fontconfig-ultimate also provides many font-specific - rendering tweaks. - ''; - }; - - substitutions = mkOption { - type = types.enum ["free" "combi" "ms" "none"]; - default = "free"; - description = '' - Font substitutions to replace common Type 1 fonts with nicer - TrueType fonts. <literal>free</literal> uses free fonts, - <literal>ms</literal> uses Microsoft fonts, - <literal>combi</literal> uses a combination, and - <literal>none</literal> disables the substitutions. - ''; - }; - - preset = mkOption { - type = types.enum ["ultimate1" "ultimate2" "ultimate3" "ultimate4" "ultimate5" "osx" "windowsxp"]; - default = "ultimate3"; - description = '' - FreeType rendering settings preset. Any of the presets may be - customized by setting environment variables. - ''; - }; - }; - }; - }; - - }; - - config = mkIf (config.fonts.fontconfig.enable && cfg.enable) { - - fonts.fontconfig.confPackages = [ confPkg ]; - environment.variables.INFINALITY_FT = cfg.preset; - - }; - -} diff --git a/nixos/modules/config/xdg/sounds.nix b/nixos/modules/config/xdg/sounds.nix index 148240d631cf..14d6340fc33b 100644 --- a/nixos/modules/config/xdg/sounds.nix +++ b/nixos/modules/config/xdg/sounds.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: with lib; { @@ -14,6 +14,10 @@ with lib; }; config = mkIf config.xdg.sounds.enable { + environment.systemPackages = [ + pkgs.sound-theme-freedesktop + ]; + environment.pathsToLink = [ "/share/sounds" ]; diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix index 719ba5ffb127..e0b558dcb0d8 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix @@ -22,17 +22,7 @@ with lib; }); ''; - services.xserver = { - enable = true; - - # Automatically login as nixos. - displayManager.slim = { - enable = true; - defaultUser = "nixos"; - autoLogin = true; - }; - - }; + services.xserver.enable = true; # Provide networkmanager for easy wireless configuration. networking.networkmanager.enable = true; diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix index 0b813bbf37b4..23c3426bff08 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix @@ -10,8 +10,6 @@ with lib; services.xserver.desktopManager.gnome3.enable = true; - services.xserver.displayManager.slim.enable = mkForce false; - # Auto-login as root. services.xserver.displayManager.gdm.autoLogin = { enable = true; diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix index 1dc7920ff640..6a10a6404e67 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-kde.nix @@ -13,6 +13,15 @@ with lib; enable = true; enableQt4Support = false; }; + + # Automatically login as nixos. + displayManager.sddm = { + enable = true; + autoLogin = { + enable = true; + user = "nixos"; + }; + }; }; environment.systemPackages = with pkgs; [ diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix index d510f3b2daf2..7865b767f0b7 100644 --- a/nixos/modules/installer/cd-dvd/sd-image.nix +++ b/nixos/modules/installer/cd-dvd/sd-image.nix @@ -140,7 +140,11 @@ in export img=$out/sd-image/${config.sdImage.imageName} echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system - echo "file sd-image $img" >> $out/nix-support/hydra-build-products + if test -n "$compressImage"; then + echo "file sd-image $img.bz2" >> $out/nix-support/hydra-build-products + else + echo "file sd-image $img" >> $out/nix-support/hydra-build-products + fi # Gap in front of the first partition, in MiB gap=8 diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 891f374df536..c53dc1000c4a 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -90,6 +90,11 @@ while [ "$#" -gt 0 ]; do targetHost="$1" shift 1 ;; + --use-remote-sudo) + # note the trailing space + maybeSudo="sudo " + shift 1 + ;; *) echo "$0: unknown option \`$i'" exit 1 @@ -97,10 +102,6 @@ while [ "$#" -gt 0 ]; do esac done -if [ -n "$SUDO_USER" ]; then - maybeSudo="sudo " -fi - if [ -z "$buildHost" -a -n "$targetHost" ]; then buildHost="$targetHost" fi diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 3e8a5b07a5ed..a4db2c9d1d87 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -128,7 +128,7 @@ tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice. firebird = 95; #keys = 96; # unused - haproxy = 97; + #haproxy = 97; # DynamicUser as of 2019-11-08 mongodb = 98; openldap = 99; #users = 100; # unused @@ -443,7 +443,7 @@ #tcpcryptd = 93; # unused firebird = 95; keys = 96; - haproxy = 97; + #haproxy = 97; # DynamicUser as of 2019-11-08 #mongodb = 98; # unused openldap = 99; munin = 102; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 24912c27245c..f7c66166c5c5 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1,9 +1,7 @@ [ ./config/debug-info.nix - ./config/fonts/corefonts.nix ./config/fonts/fontconfig.nix ./config/fonts/fontconfig-penultimate.nix - ./config/fonts/fontconfig-ultimate.nix ./config/fonts/fontdir.nix ./config/fonts/fonts.nix ./config/fonts/ghostscript.nix diff --git a/nixos/modules/profiles/graphical.nix b/nixos/modules/profiles/graphical.nix index 649f5564ac61..ac3c228b3c65 100644 --- a/nixos/modules/profiles/graphical.nix +++ b/nixos/modules/profiles/graphical.nix @@ -16,7 +16,6 @@ # Enable sound in virtualbox appliances. hardware.pulseaudio.enable = true; - hardware.pulseaudio.systemWide = true; # Needed since we run plasma as root. environment.systemPackages = [ pkgs.glxinfo pkgs.firefox ]; } diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index 703975fd06c9..80198990ed11 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -251,7 +251,7 @@ in ExecStart = "${cfg.package}/bin/ssh-agent " + optionalString (cfg.agentTimeout != null) ("-t ${cfg.agentTimeout} ") + - optionalString (cfg.agentPKCS11Whitelist != null) ("-P ${cfg.agentPKCS11Whitelist} ") + optionalString (cfg.agentPKCS11Whitelist != null) ("-P ${cfg.agentPKCS11Whitelist} ") + "-a %t/ssh-agent"; StandardOutput = "null"; Type = "forking"; diff --git a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix index 7184e5d9b9a8..c84d26a7921e 100644 --- a/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix +++ b/nixos/modules/programs/zsh/zsh-syntax-highlighting.nix @@ -81,7 +81,7 @@ in ]; programs.zsh.interactiveShellInit = with pkgs; - lib.concatStringsSep "\n" ([ + lib.mkAfter (lib.concatStringsSep "\n" ([ "source ${zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] ++ optional (length(cfg.highlighters) > 0) "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})" @@ -95,6 +95,6 @@ in styles: design: "ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'" ) cfg.styles) - ); + )); }; } diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 886e2e83ba62..7d8cf55b827a 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -234,6 +234,7 @@ with lib; (mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.") (mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.") (mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.") + (mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.") # ZSH (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) @@ -291,5 +292,14 @@ with lib; (opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] '' The prometheus exporters are now configured using `services.prometheus.exporters'. See the 18.03 release notes for more information. + '' )) + + ++ (forEach [ "enable" "substitutions" "preset" ] + (opt: mkRemovedOptionModule [ "fonts" "fontconfig" "ultimate" "${opt}" ] '' + The fonts.fontconfig.ultimate module and configuration is obsolete. + The repository has since been archived and activity has ceased. + https://github.com/bohoomil/fontconfig-ultimate/issues/171. + No action should be needed for font configuration, as the fonts.fontconfig + module is already used by default. '' )); } diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix index 5695eeaf74cb..95128a641d94 100644 --- a/nixos/modules/services/databases/redis.nix +++ b/nixos/modules/services/databases/redis.nix @@ -185,10 +185,10 @@ in ###### implementation config = mkIf config.services.redis.enable { - - boot.kernel.sysctl = { - "vm.nr_hugepages" = "0"; - } // mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; }; + boot.kernel.sysctl = (mkMerge [ + { "vm.nr_hugepages" = "0"; } + ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } ) + ]); networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; diff --git a/nixos/modules/services/mail/opensmtpd.nix b/nixos/modules/services/mail/opensmtpd.nix index a870550ba50b..1fabe2da45c5 100644 --- a/nixos/modules/services/mail/opensmtpd.nix +++ b/nixos/modules/services/mail/opensmtpd.nix @@ -101,6 +101,12 @@ in { }; }; + systemd.tmpfiles.rules = [ + "d /var/spool/smtpd 711 root - - -" + "d /var/spool/smtpd/offline 770 root smtpq - -" + "d /var/spool/smtpd/purge 700 smtpq root - -" + ]; + systemd.services.opensmtpd = let procEnv = pkgs.buildEnv { name = "opensmtpd-procs"; @@ -110,18 +116,6 @@ in { in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; - preStart = '' - mkdir -p /var/spool/smtpd - chmod 711 /var/spool/smtpd - - mkdir -p /var/spool/smtpd/offline - chown root.smtpq /var/spool/smtpd/offline - chmod 770 /var/spool/smtpd/offline - - mkdir -p /var/spool/smtpd/purge - chown smtpq.root /var/spool/smtpd/purge - chmod 700 /var/spool/smtpd/purge - ''; serviceConfig.ExecStart = "${cfg.package}/sbin/smtpd -d -f ${conf} ${args}"; environment.OPENSMTPD_PROC_PATH = "${procEnv}/libexec/opensmtpd"; }; diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix index 24b9e27ac2da..bf9a6914a483 100644 --- a/nixos/modules/services/misc/redmine.nix +++ b/nixos/modules/services/misc/redmine.nix @@ -62,20 +62,11 @@ in services.redmine = { enable = mkEnableOption "Redmine"; - # default to the 4.x series not forcing major version upgrade of those on the 3.x series package = mkOption { type = types.package; - default = if versionAtLeast config.system.stateVersion "19.03" - then pkgs.redmine_4 - else pkgs.redmine - ; - defaultText = "pkgs.redmine"; - description = '' - Which Redmine package to use. This defaults to version 3.x if - <literal>system.stateVersion < 19.03</literal> and version 4.x - otherwise. - ''; - example = "pkgs.redmine_4.override { ruby = pkgs.ruby_2_4; }"; + default = pkgs.redmine; + description = "Which Redmine package to use."; + example = "pkgs.redmine.override { ruby = pkgs.ruby_2_4; }"; }; user = mkOption { diff --git a/nixos/modules/services/misc/zoneminder.nix b/nixos/modules/services/misc/zoneminder.nix index 3bff04e7127d..d7f7324580c0 100644 --- a/nixos/modules/services/misc/zoneminder.nix +++ b/nixos/modules/services/misc/zoneminder.nix @@ -265,7 +265,7 @@ in { } location /cache/ { - alias /var/cache/${dirName}; + alias /var/cache/${dirName}/; } location ~ \.php$ { diff --git a/nixos/modules/services/network-filesystems/ceph.nix b/nixos/modules/services/network-filesystems/ceph.nix index 656a2d21b868..543a7b25d5d6 100644 --- a/nixos/modules/services/network-filesystems/ceph.nix +++ b/nixos/modules/services/network-filesystems/ceph.nix @@ -9,12 +9,14 @@ let expandCamelCase = replaceStrings upperChars (map (s: " ${s}") lowerChars); expandCamelCaseAttrs = mapAttrs' (name: value: nameValuePair (expandCamelCase name) value); - makeServices = (daemonType: daemonIds: extraServiceConfig: + makeServices = (daemonType: daemonIds: mkMerge (map (daemonId: - { "ceph-${daemonType}-${daemonId}" = makeService daemonType daemonId cfg.global.clusterName pkgs.ceph extraServiceConfig; }) + { "ceph-${daemonType}-${daemonId}" = makeService daemonType daemonId cfg.global.clusterName pkgs.ceph; }) daemonIds)); - makeService = (daemonType: daemonId: clusterName: ceph: extraServiceConfig: { + makeService = (daemonType: daemonId: clusterName: ceph: + let + stateDirectory = "ceph/${if daemonType == "rgw" then "radosgw" else daemonType}/${clusterName}-${daemonId}"; in { enable = true; description = "Ceph ${builtins.replaceStrings lowerChars upperChars daemonType} daemon ${daemonId}"; after = [ "network-online.target" "time-sync.target" ] ++ optional (daemonType == "osd") "ceph-mon.target"; @@ -22,6 +24,11 @@ let partOf = [ "ceph-${daemonType}.target" ]; wantedBy = [ "ceph-${daemonType}.target" ]; + path = [ pkgs.getopt ]; + + # Don't start services that are not yet initialized + unitConfig.ConditionPathExists = "/var/lib/${stateDirectory}/keyring"; + serviceConfig = { LimitNOFILE = 1048576; LimitNPROC = 1048576; @@ -34,22 +41,22 @@ let Restart = "on-failure"; StartLimitBurst = "5"; StartLimitInterval = "30min"; + StateDirectory = stateDirectory; + User = "ceph"; + Group = if daemonType == "osd" then "disk" else "ceph"; ExecStart = ''${ceph.out}/bin/${if daemonType == "rgw" then "radosgw" else "ceph-${daemonType}"} \ - -f --cluster ${clusterName} --id ${daemonId} --setuser ceph \ - --setgroup ${if daemonType == "osd" then "disk" else "ceph"}''; - } // extraServiceConfig - // optionalAttrs (daemonType == "osd") { ExecStartPre = ''${ceph.lib}/libexec/ceph/ceph-osd-prestart.sh \ - --id ${daemonId} --cluster ${clusterName}''; }; - } // optionalAttrs (builtins.elem daemonType [ "mds" "mon" "rgw" "mgr" ]) { - preStart = '' - daemonPath="/var/lib/ceph/${if daemonType == "rgw" then "radosgw" else daemonType}/${clusterName}-${daemonId}" - if [ ! -d $daemonPath ]; then - mkdir -m 755 -p $daemonPath - chown -R ceph:ceph $daemonPath - fi - ''; - } // optionalAttrs (daemonType == "osd") { path = [ pkgs.getopt ]; } - ); + -f --cluster ${clusterName} --id ${daemonId}''; + } // optionalAttrs (daemonType == "osd") { + ExecStartPre = ''${ceph.lib}/libexec/ceph/ceph-osd-prestart.sh --id ${daemonId} --cluster ${clusterName}''; + StartLimitBurst = "30"; + RestartSec = "20s"; + PrivateDevices = "no"; # osd needs disk access + } // optionalAttrs ( daemonType == "mon") { + RestartSec = "10"; + } // optionalAttrs (lib.elem daemonType ["mgr" "mds"]) { + StartLimitBurst = "3"; + }; + }); makeTarget = (daemonType: { @@ -58,6 +65,7 @@ let partOf = [ "ceph.target" ]; wantedBy = [ "ceph.target" ]; before = [ "ceph.target" ]; + unitConfig.StopWhenUnneeded = true; }; } ); @@ -377,22 +385,22 @@ in systemd.services = let services = [] - ++ optional cfg.mon.enable (makeServices "mon" cfg.mon.daemons { RestartSec = "10"; }) - ++ optional cfg.mds.enable (makeServices "mds" cfg.mds.daemons { StartLimitBurst = "3"; }) - ++ optional cfg.osd.enable (makeServices "osd" cfg.osd.daemons { StartLimitBurst = "30"; - RestartSec = "20s"; - PrivateDevices = "no"; # osd needs disk access - }) - ++ optional cfg.rgw.enable (makeServices "rgw" cfg.rgw.daemons { }) - ++ optional cfg.mgr.enable (makeServices "mgr" cfg.mgr.daemons { StartLimitBurst = "3"; }); + ++ optional cfg.mon.enable (makeServices "mon" cfg.mon.daemons) + ++ optional cfg.mds.enable (makeServices "mds" cfg.mds.daemons) + ++ optional cfg.osd.enable (makeServices "osd" cfg.osd.daemons) + ++ optional cfg.rgw.enable (makeServices "rgw" cfg.rgw.daemons) + ++ optional cfg.mgr.enable (makeServices "mgr" cfg.mgr.daemons); in mkMerge services; systemd.targets = let targets = [ - { ceph = { description = "Ceph target allowing to start/stop all ceph service instances at once"; - wantedBy = [ "multi-user.target" ]; }; } - ] ++ optional cfg.mon.enable (makeTarget "mon") + { ceph = { + description = "Ceph target allowing to start/stop all ceph service instances at once"; + wantedBy = [ "multi-user.target" ]; + unitConfig.StopWhenUnneeded = true; + }; } ] + ++ optional cfg.mon.enable (makeTarget "mon") ++ optional cfg.mds.enable (makeTarget "mds") ++ optional cfg.osd.enable (makeTarget "osd") ++ optional cfg.rgw.enable (makeTarget "rgw") @@ -401,7 +409,11 @@ in mkMerge targets; systemd.tmpfiles.rules = [ + "d /etc/ceph - ceph ceph - -" "d /run/ceph 0770 ceph ceph -" - ]; + "d /var/lib/ceph - ceph ceph - -"] + ++ optionals cfg.mgr.enable [ "d /var/lib/ceph/mgr - ceph ceph - -"] + ++ optionals cfg.mon.enable [ "d /var/lib/ceph/mon - ceph ceph - -"] + ++ optionals cfg.osd.enable [ "d /var/lib/ceph/osd - ceph ceph - -"]; }; } diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index ce565dbaab81..83995d281792 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -12,11 +12,6 @@ let samba = cfg.package; - setupScript = - '' - mkdir -p /var/lock/samba /var/log/samba /var/cache/samba /var/lib/samba/private - ''; - shareConfig = name: let share = getAttr name cfg.shares; in "[${name}]\n " + (smbToString ( @@ -62,6 +57,7 @@ let Type = "notify"; NotifyAccess = "all"; #may not do anything... }; + unitConfig.RequiresMountsFor = "/var/lib/samba"; restartTriggers = [ configFile ]; }; @@ -228,8 +224,7 @@ in systemd = { targets.samba = { description = "Samba Server"; - requires = [ "samba-setup.service" ]; - after = [ "samba-setup.service" "network.target" ]; + after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; }; # Refer to https://github.com/samba-team/samba/tree/master/packaging/systemd @@ -238,12 +233,13 @@ in samba-smbd = daemonService "smbd" ""; samba-nmbd = mkIf cfg.enableNmbd (daemonService "nmbd" ""); samba-winbindd = mkIf cfg.enableWinbindd (daemonService "winbindd" ""); - samba-setup = { - description = "Samba Setup Task"; - script = setupScript; - unitConfig.RequiresMountsFor = "/var/lib/samba"; - }; }; + tmpfiles.rules = [ + "d /var/lock/samba - - - - -" + "d /var/log/samba - - - - -" + "d /var/cache/samba - - - - -" + "d /var/lib/samba/private - - - - -" + ]; }; security.pam.services.samba = {}; diff --git a/nixos/modules/services/networking/dnsdist.nix b/nixos/modules/services/networking/dnsdist.nix index 12eee136e639..8249da69bc1a 100644 --- a/nixos/modules/services/networking/dnsdist.nix +++ b/nixos/modules/services/networking/dnsdist.nix @@ -46,11 +46,10 @@ in { RestartSec="1"; DynamicUser = true; StartLimitInterval="0"; - PrivateTmp=true; PrivateDevices=true; - CapabilityBoundingSet="CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID"; + AmbientCapabilities="CAP_NET_BIND_SERVICE"; + CapabilityBoundingSet="CAP_NET_BIND_SERVICE"; ExecStart = "${pkgs.dnsdist}/bin/dnsdist --supervised --disable-syslog --config ${configFile}"; - ProtectSystem="full"; ProtectHome=true; RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6"; LimitNOFILE="16384"; diff --git a/nixos/modules/services/networking/haproxy.nix b/nixos/modules/services/networking/haproxy.nix index 0438d0bf8d86..aff71e5e97da 100644 --- a/nixos/modules/services/networking/haproxy.nix +++ b/nixos/modules/services/networking/haproxy.nix @@ -1,7 +1,16 @@ { config, lib, pkgs, ... }: + let cfg = config.services.haproxy; - haproxyCfg = pkgs.writeText "haproxy.conf" cfg.config; + + haproxyCfg = pkgs.writeText "haproxy.conf" '' + global + # needed for hot-reload to work without dropping packets in multi-worker mode + stats socket /run/haproxy/haproxy.sock mode 600 expose-fd listeners level user + + ${cfg.config} + ''; + in with lib; { @@ -25,9 +34,7 @@ with lib; <filename>haproxy.conf</filename>. ''; }; - }; - }; config = mkIf cfg.enable { @@ -42,21 +49,16 @@ with lib; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { - Type = "forking"; - PIDFile = "/run/haproxy.pid"; - ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -q -f ${haproxyCfg}"; - ExecStart = "${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid"; - ExecReload = "-${pkgs.bash}/bin/bash -c \"exec ${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid -sf $MAINPID\""; + DynamicUser = true; + Type = "notify"; + # when running the config test, don't be quiet so we can see what goes wrong + ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}"; + ExecStart = "${pkgs.haproxy}/sbin/haproxy -Ws -f ${haproxyCfg}"; + Restart = "on-failure"; + RuntimeDirectory = "haproxy"; + # needed in case we bind to port < 1024 + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; }; }; - - environment.systemPackages = [ pkgs.haproxy ]; - - users.users.haproxy = { - group = "haproxy"; - uid = config.ids.uids.haproxy; - }; - - users.groups.haproxy.gid = config.ids.uids.haproxy; }; } diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 918bf891b103..90d1032c41b4 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -456,15 +456,19 @@ in { }; # Turn off NixOS' network management when networking is managed entirely by NetworkManager - networking = (mkIf (!delegateWireless) { - useDHCP = false; - # Use mkDefault to trigger the assertion about the conflict above - wireless.enable = mkDefault false; - }) // (mkIf cfg.enableStrongSwan { - networkmanager.packages = [ pkgs.networkmanager_strongswan ]; - }) // (mkIf enableIwd { - wireless.iwd.enable = true; - }); + networking = mkMerge [ + (mkIf (!delegateWireless) { + useDHCP = false; + }) + + (mkIf cfg.enableStrongSwan { + networkmanager.packages = [ pkgs.networkmanager_strongswan ]; + }) + + (mkIf enableIwd { + wireless.iwd.enable = true; + }) + ]; security.polkit.extraConfig = polkitConf; diff --git a/nixos/modules/services/networking/tinydns.nix b/nixos/modules/services/networking/tinydns.nix index 7b2c464ab46b..79507b2ebcdd 100644 --- a/nixos/modules/services/networking/tinydns.nix +++ b/nixos/modules/services/networking/tinydns.nix @@ -37,6 +37,7 @@ with lib; systemd.services.tinydns = { description = "djbdns tinydns server"; wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; path = with pkgs; [ daemontools djbdns ]; preStart = '' rm -rf /var/lib/tinydns diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index 99304d0e48ae..f5a6051b4b5f 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -6,6 +6,8 @@ let mainCfg = config.services.httpd; + runtimeDir = "/run/httpd"; + httpd = mainCfg.package.out; httpdConf = mainCfg.configFile; @@ -27,41 +29,29 @@ let listenToString = l: "${l.ip}:${toString l.port}"; - extraModules = attrByPath ["extraModules"] [] mainCfg; - extraForeignModules = filter isAttrs extraModules; - extraApacheModules = filter isString extraModules; - allHosts = [mainCfg] ++ mainCfg.virtualHosts; enableSSL = any (vhost: vhost.enableSSL) allHosts; + enableUserDir = any (vhost: vhost.enableUserDir) allHosts; - # Names of modules from ${httpd}/modules that we want to load. - apacheModules = - [ # HTTP authentication mechanisms: basic and digest. - "auth_basic" "auth_digest" - - # Authentication: is the user who he claims to be? - "authn_file" "authn_dbm" "authn_anon" "authn_core" - - # Authorization: is the user allowed access? - "authz_user" "authz_groupfile" "authz_host" "authz_core" - - # Other modules. - "ext_filter" "include" "log_config" "env" "mime_magic" - "cern_meta" "expires" "headers" "usertrack" /* "unique_id" */ "setenvif" - "mime" "dav" "status" "autoindex" "asis" "info" "dav_fs" - "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" - "userdir" "alias" "rewrite" "proxy" "proxy_http" - "unixd" "cache" "cache_disk" "slotmem_shm" "socache_shmcb" + # NOTE: generally speaking order of modules is very important + modules = + [ # required apache modules our httpd service cannot run without + "authn_core" "authz_core" + "log_config" + "mime" "autoindex" "negotiation" "dir" + "alias" "rewrite" + "unixd" "slotmem_shm" "socache_shmcb" "mpm_${mainCfg.multiProcessingModule}" - - # For compatibility with old configurations, the new module mod_access_compat is provided. - "access_compat" ] ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) ++ optional enableSSL "ssl" - ++ extraApacheModules; + ++ optional enableUserDir "userdir" + ++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; } + ++ optional mainCfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; } + ++ optional mainCfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; } + ++ mainCfg.extraModules; allDenied = "Require all denied"; @@ -85,20 +75,22 @@ let browserHacks = '' - BrowserMatch "Mozilla/2" nokeepalive - BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 - BrowserMatch "RealPlayer 4\.0" force-response-1.0 - BrowserMatch "Java/1\.0" force-response-1.0 - BrowserMatch "JDK/1\.0" force-response-1.0 - BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully - BrowserMatch "^WebDrive" redirect-carefully - BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully - BrowserMatch "^gnome-vfs" redirect-carefully + <IfModule mod_setenvif.c> + BrowserMatch "Mozilla/2" nokeepalive + BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 + BrowserMatch "RealPlayer 4\.0" force-response-1.0 + BrowserMatch "Java/1\.0" force-response-1.0 + BrowserMatch "JDK/1\.0" force-response-1.0 + BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully + BrowserMatch "^WebDrive" redirect-carefully + BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully + BrowserMatch "^gnome-vfs" redirect-carefully + </IfModule> ''; sslConf = '' - SSLSessionCache shmcb:${mainCfg.stateDir}/ssl_scache(512000) + SSLSessionCache shmcb:${runtimeDir}/ssl_scache(512000) Mutex posixsem @@ -239,13 +231,13 @@ let ServerRoot ${httpd} - DefaultRuntimeDir ${mainCfg.stateDir}/runtime + DefaultRuntimeDir ${runtimeDir}/runtime - PidFile ${mainCfg.stateDir}/httpd.pid + PidFile ${runtimeDir}/httpd.pid ${optionalString (mainCfg.multiProcessingModule != "prefork") '' # mod_cgid requires this. - ScriptSock ${mainCfg.stateDir}/cgisock + ScriptSock ${runtimeDir}/cgisock ''} <IfModule prefork.c> @@ -264,13 +256,12 @@ let Group ${mainCfg.group} ${let - load = {name, path}: "LoadModule ${name}_module ${path}\n"; - allModules = map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules - ++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; } - ++ optional mainCfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; } - ++ optional mainCfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; } - ++ extraForeignModules; - in concatMapStrings load (unique allModules) + mkModule = module: + if isString module then { name = module; path = "${httpd}/modules/mod_${module}.so"; } + else if isAttrs module then { inherit (module) name path; } + else throw "Expecting either a string or attribute set including a name and path."; + in + concatMapStringsSep "\n" (module: "LoadModule ${module.name}_module ${module.path}") (unique (map mkModule modules)) } AddHandler type-map var @@ -337,6 +328,7 @@ in imports = [ (mkRemovedOptionModule [ "services" "httpd" "extraSubservices" ] "Most existing subservices have been ported to the NixOS module system. Please update your configuration accordingly.") + (mkRemovedOptionModule [ "services" "httpd" "stateDir" ] "The httpd module now uses /run/httpd as a runtime directory.") ]; ###### interface @@ -384,7 +376,12 @@ in extraModules = mkOption { type = types.listOf types.unspecified; default = []; - example = literalExample ''[ "proxy_connect" { name = "php5"; path = "''${pkgs.php}/modules/libphp5.so"; } ]''; + example = literalExample '' + [ + "proxy_connect" + { name = "jk"; path = "''${pkgs.tomcat_connectors}/modules/mod_jk.so"; } + ] + ''; description = '' Additional Apache modules to be used. These can be specified as a string in the case of modules distributed @@ -431,16 +428,6 @@ in ''; }; - stateDir = mkOption { - type = types.path; - default = "/run/httpd"; - description = '' - Directory for Apache's transient runtime state (such as PID - files). It is created automatically. Note that the default, - <filename>/run/httpd</filename>, is deleted at boot time. - ''; - }; - virtualHosts = mkOption { type = types.listOf (types.submodule ( { options = import ./per-server-options.nix { @@ -595,6 +582,28 @@ in date.timezone = "${config.time.timeZone}" ''; + services.httpd.extraModules = mkBefore [ + # HTTP authentication mechanisms: basic and digest. + "auth_basic" "auth_digest" + + # Authentication: is the user who he claims to be? + "authn_file" "authn_dbm" "authn_anon" + + # Authorization: is the user allowed access? + "authz_user" "authz_groupfile" "authz_host" + + # Other modules. + "ext_filter" "include" "env" "mime_magic" + "cern_meta" "expires" "headers" "usertrack" "setenvif" + "dav" "status" "asis" "info" "dav_fs" + "vhost_alias" "imagemap" "actions" "speling" + "proxy" "proxy_http" + "cache" "cache_disk" + + # For compatibility with old configurations, the new module mod_access_compat is provided. + "access_compat" + ]; + systemd.services.httpd = { description = "Apache HTTPD"; @@ -611,12 +620,6 @@ in preStart = '' - mkdir -m 0750 -p ${mainCfg.stateDir} - [ $(id -u) != 0 ] || chown root.${mainCfg.group} ${mainCfg.stateDir} - - mkdir -m 0750 -p "${mainCfg.stateDir}/runtime" - [ $(id -u) != 0 ] || chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime" - mkdir -m 0700 -p ${mainCfg.logDir} # Get rid of old semaphores. These tend to accumulate across @@ -630,10 +633,13 @@ in serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}"; serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop"; serviceConfig.ExecReload = "${httpd}/bin/httpd -f ${httpdConf} -k graceful"; + serviceConfig.Group = mainCfg.group; serviceConfig.Type = "forking"; - serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid"; + serviceConfig.PIDFile = "${runtimeDir}/httpd.pid"; serviceConfig.Restart = "always"; serviceConfig.RestartSec = "5s"; + serviceConfig.RuntimeDirectory = "httpd httpd/runtime"; + serviceConfig.RuntimeDirectoryMode = "0750"; }; }; diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix index 4ab7e3f0c0a9..095de64dfb14 100644 --- a/nixos/modules/services/web-servers/phpfpm/default.nix +++ b/nixos/modules/services/web-servers/phpfpm/default.nix @@ -31,7 +31,7 @@ let ''; passAsFile = [ "nixDefaults" "phpOptions" ]; } '' - cat $phpPackage/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out + cat ${poolOpts.phpPackage}/etc/php.ini $nixDefaultsPath $phpOptionsPath > $out ''; poolOpts = { name, ... }: @@ -69,8 +69,6 @@ let phpOptions = mkOption { type = types.lines; - default = cfg.phpOptions; - defaultText = "config.services.phpfpm.phpOptions"; description = '' "Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool." ''; @@ -137,6 +135,7 @@ let config = { socket = if poolOpts.listen == "" then "${runtimeDir}/${name}.sock" else poolOpts.listen; group = mkDefault poolOpts.user; + phpOptions = mkBefore cfg.phpOptions; settings = mapAttrs (name: mkDefault){ listen = poolOpts.socket; diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 5ad31e5b9d00..88350a176506 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -184,6 +184,13 @@ in enableGnomeKeyring = true; }; + systemd.packages = with pkgs.gnome3; [ + gnome-flashback + ] ++ (map + (wm: gnome-flashback.mkSystemdTargetForWm { + inherit (wm) wmName; + }) cfg.flashback.customSessions); + services.dbus.packages = [ pkgs.gnome3.gnome-screensaver ]; @@ -217,6 +224,12 @@ in services.xserver.updateDbusEnvironment = true; + # gnome has a custom alert theme but it still + # inherits from the freedesktop theme. + environment.systemPackages = with pkgs; [ + sound-theme-freedesktop + ]; + # Needed for themes and backgrounds environment.pathsToLink = [ "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173 diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 8847acb0c604..899dd8665a25 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -14,7 +14,7 @@ let xserverWrapper = pkgs.writeScript "xserver-wrapper" '' #!/bin/sh ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} - exec systemd-cat ${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} "$@" + exec systemd-cat -t xserver-wrapper ${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} "$@" ''; Xsetup = pkgs.writeScript "Xsetup" '' diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix index 0e1314122767..30c59b88f82f 100644 --- a/nixos/modules/services/x11/window-managers/xmonad.nix +++ b/nixos/modules/services/x11/window-managers/xmonad.nix @@ -86,7 +86,7 @@ in ${xmonadBin} waitPID=$! '' else '' - ${xmonad}/bin/xmonad & + systemd-cat -t xmonad ${xmonad}/bin/xmonad & waitPID=$! ''; }]; diff --git a/nixos/modules/system/boot/plymouth.nix b/nixos/modules/system/boot/plymouth.nix index adca3c3f66e7..23fce22366d8 100644 --- a/nixos/modules/system/boot/plymouth.nix +++ b/nixos/modules/system/boot/plymouth.nix @@ -25,6 +25,7 @@ let [Daemon] ShowDelay=0 Theme=${cfg.theme} + ${cfg.extraConfig} ''; in @@ -65,6 +66,15 @@ in ''; }; + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Literal string to append to <literal>configFile</literal> + and the config file generated by the plymouth module. + ''; + }; + }; }; diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index c1f2c98afcd8..bee21f1a8f36 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -24,7 +24,7 @@ in rec { in if isList (head defs'') then concatLists defs'' - else mergeOneOption loc defs'; + else mergeEqualOption loc defs'; }; sharedOptions = { diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 5e7c8a7f4b5f..9db505a27d41 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -48,7 +48,6 @@ in clickhouse = handleTest ./clickhouse.nix {}; cloud-init = handleTest ./cloud-init.nix {}; codimd = handleTest ./codimd.nix {}; - colord = handleTest ./colord.nix {}; containers-bridge = handleTest ./containers-bridge.nix {}; containers-ephemeral = handleTest ./containers-ephemeral.nix {}; containers-extra_veth = handleTest ./containers-extra_veth.nix {}; @@ -88,27 +87,20 @@ in firewall = handleTest ./firewall.nix {}; fish = handleTest ./fish.nix {}; flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {}; - flatpak = handleTest ./flatpak.nix {}; - flatpak-builder = handleTest ./flatpak-builder.nix {}; fluentd = handleTest ./fluentd.nix {}; fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {}; fsck = handleTest ./fsck.nix {}; - fwupd = handleTestOn ["x86_64-linux"] ./fwupd.nix {}; # libsmbios is unsupported on aarch64 - gdk-pixbuf = handleTest ./gdk-pixbuf.nix {}; gotify-server = handleTest ./gotify-server.nix {}; gitea = handleTest ./gitea.nix {}; gitlab = handleTest ./gitlab.nix {}; gitolite = handleTest ./gitolite.nix {}; - gjs = handleTest ./gjs.nix {}; - glib-networking = handleTest ./glib-networking.nix {}; glusterfs = handleTest ./glusterfs.nix {}; gnome3-xorg = handleTest ./gnome3-xorg.nix {}; gnome3 = handleTest ./gnome3.nix {}; - gnome-photos = handleTest ./gnome-photos.nix {}; + installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {}); gocd-agent = handleTest ./gocd-agent.nix {}; gocd-server = handleTest ./gocd-server.nix {}; google-oslogin = handleTest ./google-oslogin {}; - graphene = handleTest ./graphene.nix {}; grafana = handleTest ./grafana.nix {}; graphite = handleTest ./graphite.nix {}; graylog = handleTest ./graylog.nix {}; @@ -149,8 +141,6 @@ in latestKernel.login = handleTest ./login.nix { latestKernel = true; }; ldap = handleTest ./ldap.nix {}; leaps = handleTest ./leaps.nix {}; - libgdata = handleTest ./libgdata.nix {}; - libxmlb = handleTest ./libxmlb.nix {}; lidarr = handleTest ./lidarr.nix {}; lightdm = handleTest ./lightdm.nix {}; limesurvey = handleTest ./limesurvey.nix {}; @@ -216,7 +206,6 @@ in os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {}; osquery = handleTest ./osquery.nix {}; osrm-backend = handleTest ./osrm-backend.nix {}; - ostree = handleTest ./ostree.nix {}; overlayfs = handleTest ./overlayfs.nix {}; packagekit = handleTest ./packagekit.nix {}; pam-oath-login = handleTest ./pam-oath-login.nix {}; @@ -255,6 +244,7 @@ in rxe = handleTest ./rxe.nix {}; samba = handleTest ./samba.nix {}; sddm = handleTest ./sddm.nix {}; + shiori = handleTest ./shiori.nix {}; signal-desktop = handleTest ./signal-desktop.nix {}; simple = handleTest ./simple.nix {}; slim = handleTest ./slim.nix {}; @@ -291,7 +281,6 @@ in wireguard-generated = handleTest ./wireguard/generated.nix {}; wordpress = handleTest ./wordpress.nix {}; xautolock = handleTest ./xautolock.nix {}; - xdg-desktop-portal = handleTest ./xdg-desktop-portal.nix {}; xfce = handleTest ./xfce.nix {}; xfce4-14 = handleTest ./xfce4-14.nix {}; xmonad = handleTest ./xmonad.nix {}; diff --git a/nixos/tests/caddy.nix b/nixos/tests/caddy.nix index ab9d2fbf4d1d..fc10df0c79b5 100644 --- a/nixos/tests/caddy.nix +++ b/nixos/tests/caddy.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "caddy"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ xfix ]; @@ -50,33 +50,38 @@ import ./make-test.nix ({ pkgs, ... }: { etagSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-1"; justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-2"; in '' - my $url = 'http://localhost/example.html'; - $webserver->waitForUnit("caddy"); - $webserver->waitForOpenPort("80"); + url = "http://localhost/example.html" + webserver.wait_for_unit("caddy") + webserver.wait_for_open_port("80") - sub checkEtag { - my $etag = $webserver->succeed( - 'curl -v '.$url.' 2>&1 | sed -n -e "s/^< [Ee][Tt][Aa][Gg]: *//p"' - ); - $etag =~ s/\r?\n$//; - my $httpCode = $webserver->succeed( - 'curl -w "%{http_code}" -X HEAD -H \'If-None-Match: '.$etag.'\' '.$url - ); - die "HTTP code is not 304" unless $httpCode == 304; - return $etag; - } - subtest "check ETag if serving Nix store paths", sub { - my $oldEtag = checkEtag; - $webserver->succeed("${etagSystem}/bin/switch-to-configuration test >&2"); - $webserver->sleep(1); # race condition - my $newEtag = checkEtag; - die "Old ETag $oldEtag is the same as $newEtag" if $oldEtag eq $newEtag; - }; + def check_etag(url): + etag = webserver.succeed( + "curl -v '{}' 2>&1 | sed -n -e \"s/^< [Ee][Tt][Aa][Gg]: *//p\"".format(url) + ) + etag = etag.replace("\r\n", " ") + http_code = webserver.succeed( + "curl -w \"%{{http_code}}\" -X HEAD -H 'If-None-Match: {}' {}".format(etag, url) + ) + assert int(http_code) == 304, "HTTP code is not 304" + return etag - subtest "config is reloaded on nixos-rebuild switch", sub { - $webserver->succeed("${justReloadSystem}/bin/switch-to-configuration test >&2"); - $webserver->waitForOpenPort("8080"); - }; + + with subtest("check ETag if serving Nix store paths"): + old_etag = check_etag(url) + webserver.succeed( + "${etagSystem}/bin/switch-to-configuration test >&2" + ) + webserver.sleep(1) + new_etag = check_etag(url) + assert old_etag != new_etag, "Old ETag {} is the same as {}".format( + old_etag, new_etag + ) + + with subtest("config is reloaded on nixos-rebuild switch"): + webserver.succeed( + "${justReloadSystem}/bin/switch-to-configuration test >&2" + ) + webserver.wait_for_open_port("8080") ''; }) diff --git a/nixos/tests/cadvisor.nix b/nixos/tests/cadvisor.nix index e60bae4b7003..60c04f147800 100644 --- a/nixos/tests/cadvisor.nix +++ b/nixos/tests/cadvisor.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... } : { +import ./make-test-python.nix ({ pkgs, ... } : { name = "cadvisor"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ offline ]; @@ -16,20 +16,19 @@ import ./make-test.nix ({ pkgs, ... } : { }; }; - testScript = - '' - startAll; - $machine->waitForUnit("cadvisor.service"); - $machine->succeed("curl http://localhost:8080/containers/"); + testScript = '' + start_all() + machine.wait_for_unit("cadvisor.service") + machine.succeed("curl http://localhost:8080/containers/") - $influxdb->waitForUnit("influxdb.service"); + influxdb.wait_for_unit("influxdb.service") # create influxdb database - $influxdb->succeed(q~ - curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE root" - ~); + influxdb.succeed( + 'curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE root"' + ) - $influxdb->waitForUnit("cadvisor.service"); - $influxdb->succeed("curl http://localhost:8080/containers/"); + influxdb.wait_for_unit("cadvisor.service") + influxdb.succeed("curl http://localhost:8080/containers/") ''; }) diff --git a/nixos/tests/cassandra.nix b/nixos/tests/cassandra.nix index c55733c9be7b..05607956a9d6 100644 --- a/nixos/tests/cassandra.nix +++ b/nixos/tests/cassandra.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ... }: +import ./make-test-python.nix ({ pkgs, lib, ... }: let # Change this to test a different version of Cassandra: testPackage = pkgs.cassandra; @@ -9,13 +9,16 @@ let jmxRolesFile = ./cassandra-jmx-roles; jmxAuthArgs = "-u ${(builtins.elemAt jmxRoles 0).username} -pw ${(builtins.elemAt jmxRoles 0).password}"; jmxPort = 7200; # Non-standard port so it doesn't accidentally work + jmxPortStr = toString jmxPort; - # Would usually be assigned to 512M + # Would usually be assigned to 512M. + # Set it to a different value, so that we can check whether our config + # actually changes it. numMaxHeapSize = "400"; getHeapLimitCommand = '' - nodetool info -p ${toString jmxPort} | grep "^Heap Memory" | awk \'{print $NF}\' + nodetool info -p ${jmxPortStr} | grep "^Heap Memory" | awk '{print $NF}' ''; - checkHeapLimitCommand = '' + checkHeapLimitCommand = pkgs.writeShellScript "check-heap-limit.sh" '' [ 1 -eq "$(echo "$(${getHeapLimitCommand}) < ${numMaxHeapSize}" | ${pkgs.bc}/bin/bc)" ] ''; @@ -44,7 +47,10 @@ let }; in { - name = "cassandra-ci"; + name = "cassandra"; + meta = { + maintainers = with lib.maintainers; [ johnazoidberg ]; + }; nodes = { cass0 = nodeCfg "192.168.1.1" {}; @@ -52,66 +58,74 @@ in cass2 = nodeCfg "192.168.1.3" { jvmOpts = [ "-Dcassandra.replace_address=cass1" ]; }; }; - testScript = let - jmxPortS = toString jmxPort; - in '' + testScript = '' # Check configuration - subtest "Timers exist", sub { - $cass0->succeed("systemctl list-timers | grep cassandra-full-repair.timer"); - $cass0->succeed("systemctl list-timers | grep cassandra-incremental-repair.timer"); - }; - subtest "Can connect via cqlsh", sub { - $cass0->waitForUnit("cassandra.service"); - $cass0->waitUntilSucceeds("nc -z cass0 9042"); - $cass0->succeed("echo 'show version;' | cqlsh cass0"); - }; - subtest "Nodetool is operational", sub { - $cass0->waitForUnit("cassandra.service"); - $cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); - $cass0->succeed("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass0'"); - }; - subtest "Cluster name was set", sub { - $cass0->waitForUnit("cassandra.service"); - $cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); - $cass0->waitUntilSucceeds("nodetool describecluster -p ${jmxPortS} | grep 'Name: ${clusterName}'"); - }; - subtest "Heap limit set correctly", sub { - # Nodetool takes a while until it can display info - $cass0->waitUntilSucceeds('nodetool info -p ${jmxPortS}'); - $cass0->succeed('${checkHeapLimitCommand}'); - }; + with subtest("Timers exist"): + cass0.succeed("systemctl list-timers | grep cassandra-full-repair.timer") + cass0.succeed("systemctl list-timers | grep cassandra-incremental-repair.timer") + + with subtest("Can connect via cqlsh"): + cass0.wait_for_unit("cassandra.service") + cass0.wait_until_succeeds("nc -z cass0 9042") + cass0.succeed("echo 'show version;' | cqlsh cass0") + + with subtest("Nodetool is operational"): + cass0.wait_for_unit("cassandra.service") + cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") + cass0.succeed("nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass0'") + + with subtest("Cluster name was set"): + cass0.wait_for_unit("cassandra.service") + cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") + cass0.wait_until_succeeds( + "nodetool describecluster -p ${jmxPortStr} | grep 'Name: ${clusterName}'" + ) + + with subtest("Heap limit set correctly"): + # Nodetool takes a while until it can display info + cass0.wait_until_succeeds("nodetool info -p ${jmxPortStr}") + cass0.succeed("${checkHeapLimitCommand}") # Check cluster interaction - subtest "Bring up cluster", sub { - $cass1->waitForUnit("cassandra.service"); - $cass1->waitUntilSucceeds("nodetool -p ${jmxPortS} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2"); - $cass0->succeed("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass1'"); - }; + with subtest("Bring up cluster"): + cass1.wait_for_unit("cassandra.service") + cass1.wait_until_succeeds( + "nodetool -p ${jmxPortStr} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2" + ) + cass0.succeed("nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass1'") '' + lib.optionalString testRemoteAuth '' - subtest "Remote authenticated jmx", sub { - # Doesn't work if not enabled - $cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); - $cass1->fail("nc -z 192.168.1.1 ${toString jmxPort}"); - $cass1->fail("nodetool -p ${jmxPortS} -h 192.168.1.1 status"); + with subtest("Remote authenticated jmx"): + # Doesn't work if not enabled + cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}") + cass1.fail("nc -z 192.168.1.1 ${jmxPortStr}") + cass1.fail("nodetool -p ${jmxPortStr} -h 192.168.1.1 status") - # Works if enabled - $cass1->waitUntilSucceeds("nc -z localhost ${toString jmxPort}"); - $cass0->succeed("nodetool -p ${jmxPortS} -h 192.168.1.2 ${jmxAuthArgs} status"); - }; + # Works if enabled + cass1.wait_until_succeeds("nc -z localhost ${jmxPortStr}") + cass0.succeed("nodetool -p ${jmxPortStr} -h 192.168.1.2 ${jmxAuthArgs} status") '' + '' - subtest "Break and fix node", sub { - $cass1->block; - $cass0->waitUntilSucceeds("nodetool status -p ${jmxPortS} --resolve-ip | egrep -c '^DN[[:space:]]+cass1'"); - $cass0->succeed("nodetool status -p ${jmxPortS} | egrep -c '^UN' | grep 1"); - $cass1->unblock; - $cass1->waitUntilSucceeds("nodetool -p ${jmxPortS} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2"); - $cass0->succeed("nodetool status -p ${jmxPortS} | egrep -c '^UN' | grep 2"); - }; - subtest "Replace crashed node", sub { - $cass1->crash; - $cass2->waitForUnit("cassandra.service"); - $cass0->waitUntilFails("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass1'"); - $cass0->waitUntilSucceeds("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass2'"); - }; + with subtest("Break and fix node"): + cass1.block() + cass0.wait_until_succeeds( + "nodetool status -p ${jmxPortStr} --resolve-ip | egrep -c '^DN[[:space:]]+cass1'" + ) + cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 1") + cass1.unblock() + cass1.wait_until_succeeds( + "nodetool -p ${jmxPortStr} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2" + ) + cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 2") + + with subtest("Replace crashed node"): + cass1.block() # .crash() waits until it's fully shutdown + cass2.start() + cass0.wait_until_fails( + "nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass1'" + ) + + cass2.wait_for_unit("cassandra.service") + cass0.wait_until_succeeds( + "nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass2'" + ) ''; }) diff --git a/nixos/tests/ceph-multi-node.nix b/nixos/tests/ceph-multi-node.nix index 6698aac3f271..ed493d6a1b34 100644 --- a/nixos/tests/ceph-multi-node.nix +++ b/nixos/tests/ceph-multi-node.nix @@ -49,9 +49,6 @@ let boot.kernelModules = [ "xfs" ]; services.ceph = cephConfig; - - # So that we don't have to battle systemd when bootstraping - systemd.targets.ceph.wantedBy = lib.mkForce []; }; networkMonA = { @@ -107,6 +104,10 @@ let }; }; }; + # Following deployment is based on the manual deployment described here: + # https://docs.ceph.com/docs/master/install/manual-deployment/ + # For other ways to deploy a ceph cluster, look at the documentation at + # https://docs.ceph.com/docs/master/ testscript = { ... }: '' startAll; @@ -114,27 +115,6 @@ let $osd0->waitForUnit("network.target"); $osd1->waitForUnit("network.target"); - # Create the ceph-related directories - $monA->mustSucceed( - "mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}", - "mkdir -p /var/lib/ceph/mon/ceph-${cfg.monA.name}", - "chown ceph:ceph -R /var/lib/ceph/", - "mkdir -p /etc/ceph", - "chown ceph:ceph -R /etc/ceph" - ); - $osd0->mustSucceed( - "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}", - "chown ceph:ceph -R /var/lib/ceph/", - "mkdir -p /etc/ceph", - "chown ceph:ceph -R /etc/ceph" - ); - $osd1->mustSucceed( - "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}", - "chown ceph:ceph -R /var/lib/ceph/", - "mkdir -p /etc/ceph", - "chown ceph:ceph -R /etc/ceph" - ); - # Bootstrap ceph-mon daemon $monA->mustSucceed( "sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'", @@ -142,6 +122,7 @@ let "sudo -u ceph ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring", "monmaptool --create --add ${cfg.monA.name} ${cfg.monA.ip} --fsid ${cfg.clusterId} /tmp/monmap", "sudo -u ceph ceph-mon --mkfs -i ${cfg.monA.name} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring", + "sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/", "sudo -u ceph touch /var/lib/ceph/mon/ceph-${cfg.monA.name}/done", "systemctl start ceph-mon-${cfg.monA.name}" ); @@ -168,12 +149,14 @@ let # Bootstrap both OSDs $osd0->mustSucceed( "mkfs.xfs /dev/vdb", + "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}", "mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd0.name}", "ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}", "echo '{\"cephx_secret\": \"${cfg.osd0.key}\"}' | ceph osd new ${cfg.osd0.uuid} -i -", ); $osd1->mustSucceed( "mkfs.xfs /dev/vdb", + "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}", "mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd1.name}", "ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}", "echo '{\"cephx_secret\": \"${cfg.osd1.key}\"}' | ceph osd new ${cfg.osd1.uuid} -i -" @@ -209,22 +192,17 @@ let "ceph osd pool delete multi-node-other-test multi-node-other-test --yes-i-really-really-mean-it" ); - # As we disable the target in the config, we still want to test that it works as intended - $osd0->mustSucceed("systemctl stop ceph-osd-${cfg.osd0.name}"); - $osd1->mustSucceed("systemctl stop ceph-osd-${cfg.osd1.name}"); - $monA->mustSucceed( - "systemctl stop ceph-mgr-${cfg.monA.name}", - "systemctl stop ceph-mon-${cfg.monA.name}" - ); - - $monA->succeed("systemctl start ceph.target"); - $monA->waitForUnit("ceph-mon-${cfg.monA.name}"); - $monA->waitForUnit("ceph-mgr-${cfg.monA.name}"); - $osd0->succeed("systemctl start ceph.target"); - $osd0->waitForUnit("ceph-osd-${cfg.osd0.name}"); - $osd1->succeed("systemctl start ceph.target"); - $osd1->waitForUnit("ceph-osd-${cfg.osd1.name}"); - + # Shut down ceph on all machines in a very unpolite way + $monA->crash; + $osd0->crash; + $osd1->crash; + + # Start it up + $osd0->start; + $osd1->start; + $monA->start; + + # Ensure the cluster comes back up again $monA->succeed("ceph -s | grep 'mon: 1 daemons'"); $monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'"); $monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'"); diff --git a/nixos/tests/ceph-single-node.nix b/nixos/tests/ceph-single-node.nix index 10b77cff5a31..041fbd7e8e64 100644 --- a/nixos/tests/ceph-single-node.nix +++ b/nixos/tests/ceph-single-node.nix @@ -46,9 +46,6 @@ let boot.kernelModules = [ "xfs" ]; services.ceph = cephConfig; - - # So that we don't have to battle systemd when bootstraping - systemd.targets.ceph.wantedBy = lib.mkForce []; }; networkMonA = { @@ -72,22 +69,15 @@ let }; }; }; + # Following deployment is based on the manual deployment described here: + # https://docs.ceph.com/docs/master/install/manual-deployment/ + # For other ways to deploy a ceph cluster, look at the documentation at + # https://docs.ceph.com/docs/master/ testscript = { ... }: '' startAll; $monA->waitForUnit("network.target"); - # Create the ceph-related directories - $monA->mustSucceed( - "mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}", - "mkdir -p /var/lib/ceph/mon/ceph-${cfg.monA.name}", - "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}", - "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}", - "mkdir -p /etc/ceph", - "chown ceph:ceph -R /etc/ceph", - "chown ceph:ceph -R /var/lib/ceph/", - ); - # Bootstrap ceph-mon daemon $monA->mustSucceed( "sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'", @@ -104,8 +94,9 @@ let # Can't check ceph status until a mon is up $monA->succeed("ceph -s | grep 'mon: 1 daemons'"); - # Start the ceph-mgr daemon, it has no deps and hardly any setup + # Start the ceph-mgr daemon, after copying in the keyring $monA->mustSucceed( + "sudo -u ceph mkdir -p /var/lib/ceph/mgr/ceph-${cfg.monA.name}/", "ceph auth get-or-create mgr.${cfg.monA.name} mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-${cfg.monA.name}/keyring", "systemctl start ceph-mgr-${cfg.monA.name}" ); @@ -117,7 +108,9 @@ let $monA->mustSucceed( "mkfs.xfs /dev/vdb", "mkfs.xfs /dev/vdc", + "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd0.name}", "mount /dev/vdb /var/lib/ceph/osd/ceph-${cfg.osd0.name}", + "mkdir -p /var/lib/ceph/osd/ceph-${cfg.osd1.name}", "mount /dev/vdc /var/lib/ceph/osd/ceph-${cfg.osd1.name}", "ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd0.name}/keyring --name osd.${cfg.osd0.name} --add-key ${cfg.osd0.key}", "ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-${cfg.osd1.name}/keyring --name osd.${cfg.osd1.name} --add-key ${cfg.osd1.key}", @@ -159,20 +152,17 @@ let "ceph osd pool delete single-node-other-test single-node-other-test --yes-i-really-really-mean-it" ); - # As we disable the target in the config, we still want to test that it works as intended - $monA->mustSucceed( - "systemctl stop ceph-osd-${cfg.osd0.name}", - "systemctl stop ceph-osd-${cfg.osd1.name}", - "systemctl stop ceph-mgr-${cfg.monA.name}", - "systemctl stop ceph-mon-${cfg.monA.name}" - ); - + # Shut down ceph by stopping ceph.target. + $monA->mustSucceed("systemctl stop ceph.target"); + + # Start it up $monA->succeed("systemctl start ceph.target"); $monA->waitForUnit("ceph-mon-${cfg.monA.name}"); $monA->waitForUnit("ceph-mgr-${cfg.monA.name}"); $monA->waitForUnit("ceph-osd-${cfg.osd0.name}"); $monA->waitForUnit("ceph-osd-${cfg.osd1.name}"); - + + # Ensure the cluster comes back up again $monA->succeed("ceph -s | grep 'mon: 1 daemons'"); $monA->waitUntilSucceeds("ceph -s | grep 'quorum ${cfg.monA.name}'"); $monA->waitUntilSucceeds("ceph osd stat | grep -e '2 osds: 2 up[^,]*, 2 in'"); diff --git a/nixos/tests/certmgr.nix b/nixos/tests/certmgr.nix index fe67833808ce..cb69f35e862f 100644 --- a/nixos/tests/certmgr.nix +++ b/nixos/tests/certmgr.nix @@ -3,7 +3,7 @@ pkgs ? import ../.. { inherit system config; } }: -with import ../lib/testing.nix { inherit system pkgs; }; +with import ../lib/testing-python.nix { inherit system pkgs; }; let mkSpec = { host, service ? null, action }: { inherit action; @@ -123,17 +123,17 @@ in ))); }; testScript = '' - $machine->waitForUnit('cfssl.service'); - $machine->waitUntilSucceeds('ls /tmp/decl.example.org-ca.pem'); - $machine->waitUntilSucceeds('ls /tmp/decl.example.org-key.pem'); - $machine->waitUntilSucceeds('ls /tmp/decl.example.org-cert.pem'); - $machine->waitUntilSucceeds('ls /tmp/imp.example.org-ca.pem'); - $machine->waitUntilSucceeds('ls /tmp/imp.example.org-key.pem'); - $machine->waitUntilSucceeds('ls /tmp/imp.example.org-cert.pem'); - $machine->waitForUnit('nginx.service'); - $machine->succeed('[ "1" -lt "$(journalctl -u nginx | grep "Starting Nginx" | wc -l)" ]'); - $machine->succeed('curl --cacert /tmp/imp.example.org-ca.pem https://imp.example.org'); - $machine->succeed('curl --cacert /tmp/decl.example.org-ca.pem https://decl.example.org'); + machine.wait_for_unit("cfssl.service") + machine.wait_until_succeeds("ls /tmp/decl.example.org-ca.pem") + machine.wait_until_succeeds("ls /tmp/decl.example.org-key.pem") + machine.wait_until_succeeds("ls /tmp/decl.example.org-cert.pem") + machine.wait_until_succeeds("ls /tmp/imp.example.org-ca.pem") + machine.wait_until_succeeds("ls /tmp/imp.example.org-key.pem") + machine.wait_until_succeeds("ls /tmp/imp.example.org-cert.pem") + machine.wait_for_unit("nginx.service") + assert 1 < int(machine.succeed('journalctl -u nginx | grep "Starting Nginx" | wc -l')) + machine.succeed("curl --cacert /tmp/imp.example.org-ca.pem https://imp.example.org") + machine.succeed("curl --cacert /tmp/decl.example.org-ca.pem https://decl.example.org") ''; }; @@ -143,8 +143,8 @@ in test = mkSpec { host = "command.example.org"; action = "touch /tmp/command.executed"; }; }; testScript = '' - $machine->waitForUnit('cfssl.service'); - $machine->waitUntilSucceeds('stat /tmp/command.executed'); + machine.wait_for_unit("cfssl.service") + machine.wait_until_succeeds("stat /tmp/command.executed") ''; }; diff --git a/nixos/tests/cfssl.nix b/nixos/tests/cfssl.nix index 513ed8c45741..e291fc285fba 100644 --- a/nixos/tests/cfssl.nix +++ b/nixos/tests/cfssl.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "cfssl"; machine = { config, lib, pkgs, ... }: @@ -60,8 +60,8 @@ import ./make-test.nix ({ pkgs, ...} : { }); in '' - $machine->waitForUnit('cfssl.service'); - $machine->waitUntilSucceeds('${cfsslrequest}'); - $machine->succeed('ls /tmp/certificate-key.pem'); + machine.wait_for_unit("cfssl.service") + machine.wait_until_succeeds("${cfsslrequest}") + machine.succeed("ls /tmp/certificate-key.pem") ''; }) diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix index 6660eecf05b9..d72236d415d4 100644 --- a/nixos/tests/cjdns.nix +++ b/nixos/tests/cjdns.nix @@ -17,7 +17,7 @@ let in -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "cjdns"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ehmry ]; @@ -83,36 +83,39 @@ import ./make-test.nix ({ pkgs, ...} : { testScript = '' - startAll; + import re - $alice->waitForUnit("cjdns.service"); - $bob->waitForUnit("cjdns.service"); - $carol->waitForUnit("cjdns.service"); + start_all() - sub cjdnsIp { - my ($machine) = @_; - my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev tun0"))[3]; - $machine->log("has ip $ip"); - return $ip; - } + alice.wait_for_unit("cjdns.service") + bob.wait_for_unit("cjdns.service") + carol.wait_for_unit("cjdns.service") - my $aliceIp6 = cjdnsIp $alice; - my $bobIp6 = cjdnsIp $bob; - my $carolIp6 = cjdnsIp $carol; + + def cjdns_ip(machine): + res = machine.succeed("ip -o -6 addr show dev tun0") + ip = re.split("\s+|/", res)[3] + machine.log("has ip {}".format(ip)) + return ip + + + alice_ip6 = cjdns_ip(alice) + bob_ip6 = cjdns_ip(bob) + carol_ip6 = cjdns_ip(carol) # ping a few times each to let the routing table establish itself - $alice->succeed("ping -c 4 $carolIp6"); - $bob->succeed("ping -c 4 $carolIp6"); + alice.succeed("ping -c 4 {}".format(carol_ip6)) + bob.succeed("ping -c 4 {}".format(carol_ip6)) - $carol->succeed("ping -c 4 $aliceIp6"); - $carol->succeed("ping -c 4 $bobIp6"); + carol.succeed("ping -c 4 {}".format(alice_ip6)) + carol.succeed("ping -c 4 {}".format(bob_ip6)) - $alice->succeed("ping -c 4 $bobIp6"); - $bob->succeed("ping -c 4 $aliceIp6"); + alice.succeed("ping -c 4 {}".format(bob_ip6)) + bob.succeed("ping -c 4 {}".format(alice_ip6)) - $alice->waitForUnit("httpd.service"); + alice.wait_for_unit("httpd.service") - $bob->succeed("curl --fail -g http://[$aliceIp6]"); + bob.succeed("curl --fail -g http://[{}]".format(alice_ip6)) ''; }) diff --git a/nixos/tests/cloud-init.nix b/nixos/tests/cloud-init.nix index 516d29c9036b..aafa6e24e84a 100644 --- a/nixos/tests/cloud-init.nix +++ b/nixos/tests/cloud-init.nix @@ -3,7 +3,7 @@ pkgs ? import ../.. { inherit system config; } }: -with import ../lib/testing.nix { inherit system pkgs; }; +with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; let @@ -30,6 +30,7 @@ let ''; }; in makeTest { + name = "cloud-init"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ lewo ]; }; @@ -40,10 +41,12 @@ in makeTest { services.cloud-init.enable = true; }; testScript = '' - $machine->start; - $machine->waitForUnit("cloud-init.service"); - $machine->succeed("cat /tmp/cloudinit-write-file | grep -q 'cloudinit'"); + machine.start() + machine.wait_for_unit("cloud-init.service") + machine.succeed("cat /tmp/cloudinit-write-file | grep -q 'cloudinit'") - $machine->waitUntilSucceeds("cat /root/.ssh/authorized_keys | grep -q 'should be a key!'"); + machine.wait_until_succeeds( + "cat /root/.ssh/authorized_keys | grep -q 'should be a key!'" + ) ''; } diff --git a/nixos/tests/colord.nix b/nixos/tests/colord.nix deleted file mode 100644 index ce38aaca4bf2..000000000000 --- a/nixos/tests/colord.nix +++ /dev/null @@ -1,18 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "colord"; - - meta = { - maintainers = pkgs.colord.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.colord.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/couchdb.nix b/nixos/tests/couchdb.nix index 48ea48eebbb3..10e95701acdb 100644 --- a/nixos/tests/couchdb.nix +++ b/nixos/tests/couchdb.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ...}: +import ./make-test-python.nix ({ pkgs, lib, ...}: with lib; @@ -35,22 +35,42 @@ with lib; fi ''; in '' - startAll; - - $couchdb1->waitForUnit("couchdb.service"); - $couchdb1->waitUntilSucceeds("${curlJqCheck "GET" "" ".couchdb" "Welcome"}"); - $couchdb1->waitUntilSucceeds("${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"); - $couchdb1->succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}"); - $couchdb1->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "3"}"); - $couchdb1->succeed("${curlJqCheck "DELETE" "foo" ".ok" "true"}"); - $couchdb1->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"); - - $couchdb2->waitForUnit("couchdb.service"); - $couchdb2->waitUntilSucceeds("${curlJqCheck "GET" "" ".couchdb" "Welcome"}"); - $couchdb2->waitUntilSucceeds("${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"); - $couchdb2->succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}"); - $couchdb2->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "1"}"); - $couchdb2->succeed("${curlJqCheck "DELETE" "foo" ".ok" "true"}"); - $couchdb2->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"); + start_all() + + couchdb1.wait_for_unit("couchdb.service") + couchdb1.wait_until_succeeds( + "${curlJqCheck "GET" "" ".couchdb" "Welcome"}" + ) + couchdb1.wait_until_succeeds( + "${curlJqCheck "GET" "_all_dbs" ". | length" "2"}" + ) + couchdb1.succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}") + couchdb1.succeed( + "${curlJqCheck "GET" "_all_dbs" ". | length" "3"}" + ) + couchdb1.succeed( + "${curlJqCheck "DELETE" "foo" ".ok" "true"}" + ) + couchdb1.succeed( + "${curlJqCheck "GET" "_all_dbs" ". | length" "2"}" + ) + + couchdb2.wait_for_unit("couchdb.service") + couchdb2.wait_until_succeeds( + "${curlJqCheck "GET" "" ".couchdb" "Welcome"}" + ) + couchdb2.wait_until_succeeds( + "${curlJqCheck "GET" "_all_dbs" ". | length" "0"}" + ) + couchdb2.succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}") + couchdb2.succeed( + "${curlJqCheck "GET" "_all_dbs" ". | length" "1"}" + ) + couchdb2.succeed( + "${curlJqCheck "DELETE" "foo" ".ok" "true"}" + ) + couchdb2.succeed( + "${curlJqCheck "GET" "_all_dbs" ". | length" "0"}" + ) ''; }) diff --git a/nixos/tests/dnscrypt-proxy.nix b/nixos/tests/dnscrypt-proxy.nix index 13bc9d3d9168..98153d5c9047 100644 --- a/nixos/tests/dnscrypt-proxy.nix +++ b/nixos/tests/dnscrypt-proxy.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "dnscrypt-proxy"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ joachifm ]; @@ -23,11 +23,13 @@ import ./make-test.nix ({ pkgs, ... }: { }; testScript = '' - $client->waitForUnit("dnsmasq"); + client.wait_for_unit("dnsmasq") # The daemon is socket activated; sending a single ping should activate it. - $client->fail("systemctl is-active dnscrypt-proxy"); - $client->execute("${pkgs.iputils}/bin/ping -c1 example.com"); - $client->waitUntilSucceeds("systemctl is-active dnscrypt-proxy"); + client.fail("systemctl is-active dnscrypt-proxy") + client.execute( + "${pkgs.iputils}/bin/ping -c1 example.com" + ) + client.wait_until_succeeds("systemctl is-active dnscrypt-proxy") ''; }) diff --git a/nixos/tests/docker-edge.nix b/nixos/tests/docker-edge.nix index b306c149be91..96de885a554a 100644 --- a/nixos/tests/docker-edge.nix +++ b/nixos/tests/docker-edge.nix @@ -1,6 +1,6 @@ # This test runs docker and checks if simple container starts -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "docker"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ nequissimus offline ]; @@ -31,17 +31,19 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; + start_all() - $docker->waitForUnit("sockets.target"); - $docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); - $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"); - $docker->succeed("docker ps | grep sleeping"); - $docker->succeed("sudo -u hasprivs docker ps"); - $docker->fail("sudo -u noprivs docker ps"); - $docker->succeed("docker stop sleeping"); + docker.wait_for_unit("sockets.target") + docker.succeed("tar cv --files-from /dev/null | docker import - scratchimg") + docker.succeed( + "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" + ) + docker.succeed("docker ps | grep sleeping") + docker.succeed("sudo -u hasprivs docker ps") + docker.fail("sudo -u noprivs docker ps") + docker.succeed("docker stop sleeping") # Must match version twice to ensure client and server versions are correct - $docker->succeed('[ $(docker version | grep ${pkgs.docker-edge.version} | wc -l) = "2" ]'); + docker.succeed('[ $(docker version | grep ${pkgs.docker-edge.version} | wc -l) = "2" ]') ''; }) diff --git a/nixos/tests/docker.nix b/nixos/tests/docker.nix index d67b2f8743d8..8fda7c1395ef 100644 --- a/nixos/tests/docker.nix +++ b/nixos/tests/docker.nix @@ -1,6 +1,6 @@ # This test runs docker and checks if simple container starts -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "docker"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ nequissimus offline ]; @@ -31,17 +31,19 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; + start_all() - $docker->waitForUnit("sockets.target"); - $docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); - $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"); - $docker->succeed("docker ps | grep sleeping"); - $docker->succeed("sudo -u hasprivs docker ps"); - $docker->fail("sudo -u noprivs docker ps"); - $docker->succeed("docker stop sleeping"); + docker.wait_for_unit("sockets.target") + docker.succeed("tar cv --files-from /dev/null | docker import - scratchimg") + docker.succeed( + "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" + ) + docker.succeed("docker ps | grep sleeping") + docker.succeed("sudo -u hasprivs docker ps") + docker.fail("sudo -u noprivs docker ps") + docker.succeed("docker stop sleeping") # Must match version twice to ensure client and server versions are correct - $docker->succeed('[ $(docker version | grep ${pkgs.docker.version} | wc -l) = "2" ]'); + docker.succeed('[ $(docker version | grep ${pkgs.docker.version} | wc -l) = "2" ]') ''; }) diff --git a/nixos/tests/documize.nix b/nixos/tests/documize.nix index 8b852a4f7795..3be20a780d31 100644 --- a/nixos/tests/documize.nix +++ b/nixos/tests/documize.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ...} : { +import ./make-test-python.nix ({ pkgs, lib, ...} : { name = "documize"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ma27 ]; @@ -29,30 +29,34 @@ import ./make-test.nix ({ pkgs, lib, ...} : { }; testScript = '' - startAll; - - $machine->waitForUnit("documize-server.service"); - $machine->waitForOpenPort(3000); - - my $dbhash = $machine->succeed("curl -f localhost:3000 " - . " | grep 'property=\"dbhash' " - . " | grep -Po 'content=\"\\K[^\"]*'" - ); - - chomp($dbhash); - - $machine->succeed("curl -X POST " - . "--data 'dbname=documize' " - . "--data 'dbhash=$dbhash' " - . "--data 'title=NixOS' " - . "--data 'message=Docs' " - . "--data 'firstname=John' " - . "--data 'lastname=Doe' " - . "--data 'email=john.doe\@nixos.org' " - . "--data 'password=verysafe' " - . "-f localhost:3000/api/setup" - ); - - $machine->succeed('test "$(curl -f localhost:3000/api/public/meta | jq ".title" | xargs echo)" = "NixOS"'); + start_all() + + machine.wait_for_unit("documize-server.service") + machine.wait_for_open_port(3000) + + dbhash = machine.succeed( + "curl -f localhost:3000 | grep 'property=\"dbhash' | grep -Po 'content=\"\\K[^\"]*'" + ) + + dbhash = dbhash.strip() + + machine.succeed( + ( + "curl -X POST" + " --data 'dbname=documize'" + " --data 'dbhash={}'" + " --data 'title=NixOS'" + " --data 'message=Docs'" + " --data 'firstname=John'" + " --data 'lastname=Doe'" + " --data 'email=john.doe@nixos.org'" + " --data 'password=verysafe'" + " -f localhost:3000/api/setup" + ).format(dbhash) + ) + + machine.succeed( + 'test "$(curl -f localhost:3000/api/public/meta | jq ".title" | xargs echo)" = "NixOS"' + ) ''; }) diff --git a/nixos/tests/firefox.nix b/nixos/tests/firefox.nix index f5b946a08810..56ddabbae771 100644 --- a/nixos/tests/firefox.nix +++ b/nixos/tests/firefox.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "firefox"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ eelco shlevy ]; @@ -11,19 +11,27 @@ import ./make-test.nix ({ pkgs, ... }: { environment.systemPackages = [ pkgs.firefox pkgs.xdotool ]; }; - testScript = - '' - $machine->waitForX; - $machine->execute("xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' &"); - $machine->waitForWindow(qr/Valgrind/); - $machine->sleep(40); # wait until Firefox has finished loading the page - $machine->execute("xdotool key space"); # do I want to make Firefox the - # default browser? I just want to close the dialog - $machine->sleep(2); # wait until Firefox hides the default browser window - $machine->execute("xdotool key F12"); - $machine->sleep(10); # wait until Firefox draws the developer tool panel - $machine->succeed("xwininfo -root -tree | grep Valgrind"); - $machine->screenshot("screen"); + testScript = '' + machine.wait_for_x() + + with subtest("wait until Firefox has finished loading the Valgrind docs page"): + machine.execute( + "xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' &" + ) + machine.wait_for_window("Valgrind") + machine.sleep(40) + + with subtest("Close default browser prompt"): + machine.execute("xdotool key space") + + with subtest("Hide default browser window"): + machine.sleep(2) + machine.execute("xdotool key F12") + + with subtest("wait until Firefox draws the developer tool panel"): + machine.sleep(10) + machine.succeed("xwininfo -root -tree | grep Valgrind") + machine.screenshot("screen") ''; }) diff --git a/nixos/tests/flatpak-builder.nix b/nixos/tests/flatpak-builder.nix deleted file mode 100644 index 49b97e8ca99e..000000000000 --- a/nixos/tests/flatpak-builder.nix +++ /dev/null @@ -1,20 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "flatpak-builder"; - meta = { - maintainers = pkgs.flatpak-builder.meta.maintainers; - }; - - machine = { pkgs, ... }: { - services.flatpak.enable = true; - xdg.portal.enable = true; - environment.systemPackages = with pkgs; [ gnome-desktop-testing flatpak-builder ] ++ flatpak-builder.installedTestsDependencies; - virtualisation.diskSize = 2048; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.flatpak-builder.installedTests}/share' --timeout 3600"); - ''; -}) diff --git a/nixos/tests/flatpak.nix b/nixos/tests/flatpak.nix deleted file mode 100644 index b0c61830d05a..000000000000 --- a/nixos/tests/flatpak.nix +++ /dev/null @@ -1,26 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "flatpak"; - meta = { - maintainers = pkgs.flatpak.meta.maintainers; - }; - - machine = { pkgs, ... }: { - imports = [ ./common/x11.nix ]; - services.xserver.desktopManager.gnome3.enable = true; # TODO: figure out minimal environment where the tests work - # common/x11.nix enables the auto display manager (lightdm) - services.xserver.displayManager.gdm.enable = false; - environment.gnome3.excludePackages = pkgs.gnome3.optionalPackages; - services.flatpak.enable = true; - environment.systemPackages = with pkgs; [ gnupg gnome-desktop-testing ostree python2 ]; - virtualisation.memorySize = 2047; - virtualisation.diskSize = 1024; - }; - - testScript = '' - $machine->waitForX(); - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.flatpak.installedTests}/share' --timeout 3600"); - ''; -}) diff --git a/nixos/tests/fontconfig-default-fonts.nix b/nixos/tests/fontconfig-default-fonts.nix index 1991cec92189..68c6ac9e9c83 100644 --- a/nixos/tests/fontconfig-default-fonts.nix +++ b/nixos/tests/fontconfig-default-fonts.nix @@ -1,7 +1,12 @@ -import ./make-test.nix ({ lib, ... }: +import ./make-test-python.nix ({ lib, ... }: { name = "fontconfig-default-fonts"; + meta.maintainers = with lib.maintainers; [ + jtojnar + worldofpeace + ]; + machine = { config, pkgs, ... }: { fonts.enableDefaultFonts = true; # Background fonts fonts.fonts = with pkgs; [ @@ -20,9 +25,9 @@ import ./make-test.nix ({ lib, ... }: }; testScript = '' - $machine->succeed("fc-match serif | grep '\"Gentium Plus\"'"); - $machine->succeed("fc-match sans-serif | grep '\"Cantarell\"'"); - $machine->succeed("fc-match monospace | grep '\"Source Code Pro\"'"); - $machine->succeed("fc-match emoji | grep '\"Twitter Color Emoji\"'"); + machine.succeed("fc-match serif | grep '\"Gentium Plus\"'") + machine.succeed("fc-match sans-serif | grep '\"Cantarell\"'") + machine.succeed("fc-match monospace | grep '\"Source Code Pro\"'") + machine.succeed("fc-match emoji | grep '\"Twitter Color Emoji\"'") ''; }) diff --git a/nixos/tests/fwupd.nix b/nixos/tests/fwupd.nix deleted file mode 100644 index 88dac8ccbcdb..000000000000 --- a/nixos/tests/fwupd.nix +++ /dev/null @@ -1,21 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: { - name = "fwupd"; - - meta = { - maintainers = pkgs.fwupd.meta.maintainers; - }; - - machine = { pkgs, ... }: { - services.fwupd.enable = true; - services.fwupd.blacklistPlugins = []; # don't blacklist test plugin - services.fwupd.enableTestRemote = true; - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - environment.variables.XDG_DATA_DIRS = [ "${pkgs.fwupd.installedTests}/share" ]; - virtualisation.memorySize = 768; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner"); - ''; -}) diff --git a/nixos/tests/gdk-pixbuf.nix b/nixos/tests/gdk-pixbuf.nix deleted file mode 100644 index 9a62b593f46d..000000000000 --- a/nixos/tests/gdk-pixbuf.nix +++ /dev/null @@ -1,21 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: { - name = "gdk-pixbuf"; - - meta = { - maintainers = pkgs.gdk-pixbuf.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - environment.variables.XDG_DATA_DIRS = [ "${pkgs.gdk-pixbuf.installedTests}/share" ]; - - # Tests allocate a lot of memory trying to exploit a CVE - # but qemu-system-i386 has a 2047M memory limit - virtualisation.memorySize = if pkgs.stdenv.isi686 then 2047 else 4096; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -t 1800"); # increase timeout to 1800s - ''; -}) diff --git a/nixos/tests/gjs.nix b/nixos/tests/gjs.nix deleted file mode 100644 index 87c8d7f2817d..000000000000 --- a/nixos/tests/gjs.nix +++ /dev/null @@ -1,19 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: { - name = "gjs"; - - meta = { - maintainers = pkgs.gjs.meta.maintainers; - }; - - machine = { pkgs, ... }: { - imports = [ ./common/x11.nix ]; - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - environment.variables.XDG_DATA_DIRS = [ "${pkgs.gjs.installedTests}/share" ]; - }; - - testScript = '' - $machine->waitForX; - $machine->succeed("gnome-desktop-testing-runner"); - ''; -}) diff --git a/nixos/tests/glib-networking.nix b/nixos/tests/glib-networking.nix deleted file mode 100644 index c0bbb2b3554b..000000000000 --- a/nixos/tests/glib-networking.nix +++ /dev/null @@ -1,17 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "glib-networking"; - meta = { - maintainers = pkgs.glib-networking.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.glib-networking.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/gnome-photos.nix b/nixos/tests/gnome-photos.nix deleted file mode 100644 index 2ecda1d68ce3..000000000000 --- a/nixos/tests/gnome-photos.nix +++ /dev/null @@ -1,42 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, lib, ... }: - -let - - # gsettings tool with access to gsettings-desktop-schemas - desktop-gsettings = with pkgs; stdenv.mkDerivation { - name = "desktop-gsettings"; - dontUnpack = true; - nativeBuildInputs = [ glib wrapGAppsHook ]; - buildInputs = [ gsettings-desktop-schemas ]; - installPhase = '' - runHook preInstall - mkdir -p $out/bin - ln -s ${glib.bin}/bin/gsettings $out/bin/desktop-gsettings - runHook postInstall - ''; - }; - -in - -{ - name = "gnome-photos"; - meta = { - maintainers = pkgs.gnome-photos.meta.maintainers; - }; - - machine = { pkgs, ... }: { - imports = [ ./common/x11.nix ]; - programs.dconf.enable = true; - services.gnome3.at-spi2-core.enable = true; # needed for dogtail - environment.systemPackages = with pkgs; [ gnome-desktop-testing desktop-gsettings ]; - services.dbus.packages = with pkgs; [ gnome-photos ]; - }; - - testScript = '' - $machine->waitForX; - # dogtail needs accessibility enabled - $machine->succeed("desktop-gsettings set org.gnome.desktop.interface toolkit-accessibility true 2>&1"); - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.gnome-photos.installedTests}/share' 2>&1"); - ''; -}) diff --git a/nixos/tests/grafana.nix b/nixos/tests/grafana.nix index 7a1b4c8ffbbc..4b453ece7f1e 100644 --- a/nixos/tests/grafana.nix +++ b/nixos/tests/grafana.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, pkgs, ... }: +import ./make-test-python.nix ({ lib, pkgs, ... }: let inherit (lib) mkMerge nameValuePair maintainers; @@ -64,28 +64,34 @@ in { inherit nodes; testScript = '' - startAll(); + start_all() - subtest "Grafana sqlite", sub { - $sqlite->waitForUnit("grafana.service"); - $sqlite->waitForOpenPort(3000); - $sqlite->succeed("curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost"); - }; + with subtest("Successful API query as admin user with sqlite db"): + sqlite.wait_for_unit("grafana.service") + sqlite.wait_for_open_port(3000) + sqlite.succeed( + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost" + ) + sqlite.shutdown() - subtest "Grafana postgresql", sub { - $postgresql->waitForUnit("grafana.service"); - $postgresql->waitForUnit("postgresql.service"); - $postgresql->waitForOpenPort(3000); - $postgresql->waitForOpenPort(5432); - $postgresql->succeed("curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost"); - }; + with subtest("Successful API query as admin user with postgresql db"): + postgresql.wait_for_unit("grafana.service") + postgresql.wait_for_unit("postgresql.service") + postgresql.wait_for_open_port(3000) + postgresql.wait_for_open_port(5432) + postgresql.succeed( + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost" + ) + postgresql.shutdown() - subtest "Grafana mysql", sub { - $mysql->waitForUnit("grafana.service"); - $mysql->waitForUnit("mysql.service"); - $mysql->waitForOpenPort(3000); - $mysql->waitForOpenPort(3306); - $mysql->succeed("curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost"); - }; + with subtest("Successful API query as admin user with mysql db"): + mysql.wait_for_unit("grafana.service") + mysql.wait_for_unit("mysql.service") + mysql.wait_for_open_port(3000) + mysql.wait_for_open_port(3306) + mysql.succeed( + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost" + ) + mysql.shutdown() ''; }) diff --git a/nixos/tests/graphene.nix b/nixos/tests/graphene.nix deleted file mode 100644 index 5591bcc30c07..000000000000 --- a/nixos/tests/graphene.nix +++ /dev/null @@ -1,18 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "graphene"; - - meta = { - maintainers = pkgs.graphene.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.graphene.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/haproxy.nix b/nixos/tests/haproxy.nix index 22a83e9d1eab..72e77a68193e 100644 --- a/nixos/tests/haproxy.nix +++ b/nixos/tests/haproxy.nix @@ -16,6 +16,8 @@ import ./make-test.nix ({ pkgs, ...}: { frontend http bind *:80 mode http + option http-use-htx + http-request use-service prometheus-exporter if { path /metrics } use_backend http_server ''; }; @@ -36,6 +38,6 @@ import ./make-test.nix ({ pkgs, ...}: { $machine->waitForUnit('haproxy.service'); $machine->waitForUnit('httpd.service'); $machine->succeed('curl -k http://localhost:80/index.txt | grep "We are all good!"'); - + $machine->succeed('curl -k http://localhost:80/metrics | grep haproxy_process_pool_allocated_bytes'); ''; }) diff --git a/nixos/tests/initrd-network-ssh/default.nix b/nixos/tests/initrd-network-ssh/default.nix index 796c50c610e3..73d9f938e226 100644 --- a/nixos/tests/initrd-network-ssh/default.nix +++ b/nixos/tests/initrd-network-ssh/default.nix @@ -1,4 +1,4 @@ -import ../make-test.nix ({ lib, ... }: +import ../make-test-python.nix ({ lib, ... }: { name = "initrd-network-ssh"; @@ -35,25 +35,31 @@ import ../make-test.nix ({ lib, ... }: client = { config, ... }: { - environment.etc.knownHosts = { - text = concatStrings [ - "server," - "${toString (head (splitString " " ( - toString (elemAt (splitString "\n" config.networking.extraHosts) 2) - )))} " - "${readFile ./dropbear.pub}" - ]; + environment.etc = { + knownHosts = { + text = concatStrings [ + "server," + "${toString (head (splitString " " ( + toString (elemAt (splitString "\n" config.networking.extraHosts) 2) + )))} " + "${readFile ./dropbear.pub}" + ]; + }; + sshKey = { + source = ./openssh.priv; # dont use this anywhere else + mode = "0600"; + }; }; }; }; testScript = '' - startAll; - $client->waitForUnit("network.target"); - $client->copyFileFromHost("${./openssh.priv}","/etc/sshKey"); - $client->succeed("chmod 0600 /etc/sshKey"); - $client->waitUntilSucceeds("ping -c 1 server"); - $client->succeed("ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'touch /fnord'"); - $client->shutdown; + start_all() + client.wait_for_unit("network.target") + client.wait_until_succeeds("ping -c 1 server") + client.succeed( + "ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'touch /fnord'" + ) + client.shutdown() ''; }) diff --git a/nixos/tests/installed-tests/colord.nix b/nixos/tests/installed-tests/colord.nix new file mode 100644 index 000000000000..77e6b917fe68 --- /dev/null +++ b/nixos/tests/installed-tests/colord.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.colord; +} diff --git a/nixos/tests/installed-tests/default.nix b/nixos/tests/installed-tests/default.nix new file mode 100644 index 000000000000..f4780bdcfc97 --- /dev/null +++ b/nixos/tests/installed-tests/default.nix @@ -0,0 +1,80 @@ +# NixOS tests for gnome-desktop-testing-runner using software +# See https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests + +{ system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; } +}: + +with import ../../lib/testing-python.nix { inherit system pkgs; }; +with pkgs.lib; + +let + + callInstalledTest = pkgs.newScope { inherit makeInstalledTest; }; + + makeInstalledTest = + { # Package to test. Needs to have an installedTests output + tested + + # Config to inject into machine + , testConfig ? {} + + # Test script snippet to inject before gnome-desktop-testing-runner begins. + # This is useful for extra setup the environment may need before the runner begins. + , preTestScript ? "" + + # Does test need X11? + , withX11 ? false + + # Extra flags to pass to gnome-desktop-testing-runner. + , testRunnerFlags ? "" + }: + makeTest rec { + name = tested.name; + + meta = { + maintainers = tested.meta.maintainers; + }; + + machine = { ... }: { + imports = [ + testConfig + ] ++ optional withX11 ../common/x11.nix; + + environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; + + }; + + testScript = + optionalString withX11 '' + machine.wait_for_x() + '' + + optionalString (preTestScript != "") '' + ${preTestScript} + '' + + '' + machine.succeed( + "gnome-desktop-testing-runner ${testRunnerFlags} -d '${tested.installedTests}/share'" + ) + ''; + }; + +in + +{ + colord = callInstalledTest ./colord.nix {}; + flatpak = callInstalledTest ./flatpak.nix {}; + flatpak-builder = callInstalledTest ./flatpak-builder.nix {}; + fwupd = callInstalledTest ./fwupd.nix {}; + gcab = callInstalledTest ./gcab.nix {}; + gdk-pixbuf = callInstalledTest ./gdk-pixbuf.nix {}; + gjs = callInstalledTest ./gjs.nix {}; + glib-networking = callInstalledTest ./glib-networking.nix {}; + gnome-photos = callInstalledTest ./gnome-photos.nix {}; + graphene = callInstalledTest ./graphene.nix {}; + libgdata = callInstalledTest ./libgdata.nix {}; + libxmlb = callInstalledTest ./libxmlb.nix {}; + ostree = callInstalledTest ./ostree.nix {}; + xdg-desktop-portal = callInstalledTest ./xdg-desktop-portal.nix {}; +} diff --git a/nixos/tests/installed-tests/flatpak-builder.nix b/nixos/tests/installed-tests/flatpak-builder.nix new file mode 100644 index 000000000000..31b9f2b258fd --- /dev/null +++ b/nixos/tests/installed-tests/flatpak-builder.nix @@ -0,0 +1,14 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.flatpak-builder; + + testConfig = { + services.flatpak.enable = true; + xdg.portal.enable = true; + environment.systemPackages = with pkgs; [ flatpak-builder ] ++ flatpak-builder.installedTestsDependencies; + virtualisation.diskSize = 2048; + }; + + testRunnerFlags = "--timeout 3600"; +} diff --git a/nixos/tests/installed-tests/flatpak.nix b/nixos/tests/installed-tests/flatpak.nix new file mode 100644 index 000000000000..091c99326629 --- /dev/null +++ b/nixos/tests/installed-tests/flatpak.nix @@ -0,0 +1,19 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.flatpak; + withX11 = true; + + testConfig = { + services.xserver.desktopManager.gnome3.enable = true; # TODO: figure out minimal environment where the tests work + # common/x11.nix enables the auto display manager (lightdm) + services.xserver.displayManager.gdm.enable = false; + services.gnome3.core-utilities.enable = false; + services.flatpak.enable = true; + environment.systemPackages = with pkgs; [ gnupg ostree python2 ]; + virtualisation.memorySize = 2047; + virtualisation.diskSize = 1024; + }; + + testRunnerFlags = "--timeout 3600"; +} diff --git a/nixos/tests/installed-tests/fwupd.nix b/nixos/tests/installed-tests/fwupd.nix new file mode 100644 index 000000000000..b9f761e99582 --- /dev/null +++ b/nixos/tests/installed-tests/fwupd.nix @@ -0,0 +1,12 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.fwupd; + + testConfig = { + services.fwupd.enable = true; + services.fwupd.blacklistPlugins = []; # don't blacklist test plugin + services.fwupd.enableTestRemote = true; + virtualisation.memorySize = 768; + }; +} diff --git a/nixos/tests/installed-tests/gcab.nix b/nixos/tests/installed-tests/gcab.nix new file mode 100644 index 000000000000..b24cc2e01267 --- /dev/null +++ b/nixos/tests/installed-tests/gcab.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.gcab; +} diff --git a/nixos/tests/installed-tests/gdk-pixbuf.nix b/nixos/tests/installed-tests/gdk-pixbuf.nix new file mode 100644 index 000000000000..3d0011a427a4 --- /dev/null +++ b/nixos/tests/installed-tests/gdk-pixbuf.nix @@ -0,0 +1,13 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.gdk-pixbuf; + + testConfig = { + # Tests allocate a lot of memory trying to exploit a CVE + # but qemu-system-i386 has a 2047M memory limit + virtualisation.memorySize = if pkgs.stdenv.isi686 then 2047 else 4096; + }; + + testRunnerFlags = "--timeout 1800"; +} diff --git a/nixos/tests/installed-tests/gjs.nix b/nixos/tests/installed-tests/gjs.nix new file mode 100644 index 000000000000..1656e9de171b --- /dev/null +++ b/nixos/tests/installed-tests/gjs.nix @@ -0,0 +1,6 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.gjs; + withX11 = true; +} diff --git a/nixos/tests/installed-tests/glib-networking.nix b/nixos/tests/installed-tests/glib-networking.nix new file mode 100644 index 000000000000..b58d4df21fca --- /dev/null +++ b/nixos/tests/installed-tests/glib-networking.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.glib-networking; +} diff --git a/nixos/tests/installed-tests/gnome-photos.nix b/nixos/tests/installed-tests/gnome-photos.nix new file mode 100644 index 000000000000..05e7ccb65ad5 --- /dev/null +++ b/nixos/tests/installed-tests/gnome-photos.nix @@ -0,0 +1,35 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.gnome-photos; + + withX11 = true; + + testConfig = { + programs.dconf.enable = true; + services.gnome3.at-spi2-core.enable = true; # needed for dogtail + environment.systemPackages = with pkgs; [ + # gsettings tool with access to gsettings-desktop-schemas + (stdenv.mkDerivation { + name = "desktop-gsettings"; + dontUnpack = true; + nativeBuildInputs = [ glib wrapGAppsHook ]; + buildInputs = [ gsettings-desktop-schemas ]; + installPhase = '' + runHook preInstall + mkdir -p $out/bin + ln -s ${glib.bin}/bin/gsettings $out/bin/desktop-gsettings + runHook postInstall + ''; + }) + ]; + services.dbus.packages = with pkgs; [ gnome-photos ]; + }; + + preTestScript = '' + # dogtail needs accessibility enabled + machine.succeed( + "desktop-gsettings set org.gnome.desktop.interface toolkit-accessibility true 2>&1" + ) + ''; +} diff --git a/nixos/tests/installed-tests/graphene.nix b/nixos/tests/installed-tests/graphene.nix new file mode 100644 index 000000000000..e43339abd88c --- /dev/null +++ b/nixos/tests/installed-tests/graphene.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.graphene; +} diff --git a/nixos/tests/installed-tests/libgdata.nix b/nixos/tests/installed-tests/libgdata.nix new file mode 100644 index 000000000000..f11a7bc1bc51 --- /dev/null +++ b/nixos/tests/installed-tests/libgdata.nix @@ -0,0 +1,11 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.libgdata; + + testConfig = { + # # GLib-GIO-DEBUG: _g_io_module_get_default: Found default implementation dummy (GDummyTlsBackend) for ‘gio-tls-backend’ + # Bail out! libgdata:ERROR:../gdata/tests/common.c:134:gdata_test_init: assertion failed (child_error == NULL): TLS support is not available (g-tls-error-quark, 0) + services.gnome3.glib-networking.enable = true; + }; +} diff --git a/nixos/tests/installed-tests/libxmlb.nix b/nixos/tests/installed-tests/libxmlb.nix new file mode 100644 index 000000000000..af2bbe9c35e2 --- /dev/null +++ b/nixos/tests/installed-tests/libxmlb.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.libxmlb; +} diff --git a/nixos/tests/installed-tests/ostree.nix b/nixos/tests/installed-tests/ostree.nix new file mode 100644 index 000000000000..eef7cace54cc --- /dev/null +++ b/nixos/tests/installed-tests/ostree.nix @@ -0,0 +1,23 @@ +{ pkgs, lib, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.ostree; + + # TODO: Wrap/patch the tests directly in the package + testConfig = { + environment.systemPackages = with pkgs; [ + (python3.withPackages (p: with p; [ pyyaml ])) + gnupg + ostree + ]; + + # for GJS tests + environment.variables.GI_TYPELIB_PATH = lib.makeSearchPath "lib/girepository-1.0" (with pkgs; [ + gtk3 + pango.out + ostree + gdk-pixbuf + atk + ]); + }; +} diff --git a/nixos/tests/installed-tests/xdg-desktop-portal.nix b/nixos/tests/installed-tests/xdg-desktop-portal.nix new file mode 100644 index 000000000000..b16008ff4add --- /dev/null +++ b/nixos/tests/installed-tests/xdg-desktop-portal.nix @@ -0,0 +1,5 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + tested = pkgs.xdg-desktop-portal; +} diff --git a/nixos/tests/libgdata.nix b/nixos/tests/libgdata.nix deleted file mode 100644 index 10a3ca97dd22..000000000000 --- a/nixos/tests/libgdata.nix +++ /dev/null @@ -1,21 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "libgdata"; - - meta = { - maintainers = pkgs.libgdata.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - # # GLib-GIO-DEBUG: _g_io_module_get_default: Found default implementation dummy (GDummyTlsBackend) for ‘gio-tls-backend’ - # Bail out! libgdata:ERROR:../gdata/tests/common.c:134:gdata_test_init: assertion failed (child_error == NULL): TLS support is not available (g-tls-error-quark, 0) - services.gnome3.glib-networking.enable = true; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.libgdata.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/libxmlb.nix b/nixos/tests/libxmlb.nix deleted file mode 100644 index 3bee568ac5a2..000000000000 --- a/nixos/tests/libxmlb.nix +++ /dev/null @@ -1,17 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "libxmlb"; - meta = { - maintainers = pkgs.libxmlb.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.libxmlb.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/lightdm.nix b/nixos/tests/lightdm.nix index c805f1ed9f3c..ef30f7741e23 100644 --- a/nixos/tests/lightdm.nix +++ b/nixos/tests/lightdm.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "lightdm"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ aszlig worldofpeace ]; @@ -18,12 +18,12 @@ import ./make-test.nix ({ pkgs, ...} : { testScript = { nodes, ... }: let user = nodes.machine.config.users.users.alice; in '' - startAll; - $machine->waitForText(qr/${user.description}/); - $machine->screenshot("lightdm"); - $machine->sendChars("${user.password}\n"); - $machine->waitForFile("/home/alice/.Xauthority"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->waitForWindow("^IceWM "); + start_all() + machine.wait_for_text("${user.description}") + machine.screenshot("lightdm") + machine.send_chars("${user.password}\n") + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + machine.wait_for_window("^IceWM ") ''; }) diff --git a/nixos/tests/loki.nix b/nixos/tests/loki.nix index 9c3058d02f84..dbf1e8a650f5 100644 --- a/nixos/tests/loki.nix +++ b/nixos/tests/loki.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, pkgs, ... }: +import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "loki"; @@ -26,12 +26,14 @@ import ./make-test.nix ({ lib, pkgs, ... }: }; testScript = '' - $machine->start; - $machine->waitForUnit("loki.service"); - $machine->waitForUnit("promtail.service"); - $machine->waitForOpenPort(3100); - $machine->waitForOpenPort(9080); - $machine->succeed("echo 'Loki Ingestion Test' > /var/log/testlog"); - $machine->waitUntilSucceeds("${pkgs.grafana-loki}/bin/logcli --addr='http://localhost:3100' query --no-labels '{job=\"varlogs\",filename=\"/var/log/testlog\"}' | grep -q 'Loki Ingestion Test'"); + machine.start + machine.wait_for_unit("loki.service") + machine.wait_for_unit("promtail.service") + machine.wait_for_open_port(3100) + machine.wait_for_open_port(9080) + machine.succeed("echo 'Loki Ingestion Test' > /var/log/testlog") + machine.wait_until_succeeds( + "${pkgs.grafana-loki}/bin/logcli --addr='http://localhost:3100' query --no-labels '{job=\"varlogs\",filename=\"/var/log/testlog\"}' | grep -q 'Loki Ingestion Test'" + ) ''; }) diff --git a/nixos/tests/matrix-synapse.nix b/nixos/tests/matrix-synapse.nix index 882e4b75814b..fca53009083a 100644 --- a/nixos/tests/matrix-synapse.nix +++ b/nixos/tests/matrix-synapse.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... } : let +import ./make-test-python.nix ({ pkgs, ... } : let runWithOpenSSL = file: cmd: pkgs.runCommand file { @@ -55,13 +55,17 @@ in { }; testScript = '' - startAll; - $serverpostgres->waitForUnit("matrix-synapse.service"); - $serverpostgres->waitUntilSucceeds("curl -L --cacert ${ca_pem} https://localhost:8448/"); - $serverpostgres->requireActiveUnit("postgresql.service"); - $serversqlite->waitForUnit("matrix-synapse.service"); - $serversqlite->waitUntilSucceeds("curl -L --cacert ${ca_pem} https://localhost:8448/"); - $serversqlite->mustSucceed("[ -e /var/lib/matrix-synapse/homeserver.db ]"); + start_all() + serverpostgres.wait_for_unit("matrix-synapse.service") + serverpostgres.wait_until_succeeds( + "curl -L --cacert ${ca_pem} https://localhost:8448/" + ) + serverpostgres.require_unit_state("postgresql.service") + serversqlite.wait_for_unit("matrix-synapse.service") + serversqlite.wait_until_succeeds( + "curl -L --cacert ${ca_pem} https://localhost:8448/" + ) + serversqlite.succeed("[ -e /var/lib/matrix-synapse/homeserver.db ]") ''; }) diff --git a/nixos/tests/moodle.nix b/nixos/tests/moodle.nix index 565a6b636949..56aa62596c07 100644 --- a/nixos/tests/moodle.nix +++ b/nixos/tests/moodle.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ... }: { +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "moodle"; meta.maintainers = [ lib.maintainers.aanderse ]; @@ -15,8 +15,8 @@ import ./make-test.nix ({ pkgs, lib, ... }: { }; testScript = '' - startAll; - $machine->waitForUnit('phpfpm-moodle.service'); - $machine->succeed('curl http://localhost/') =~ /You are not logged in/ or die; + start_all() + machine.wait_for_unit("phpfpm-moodle.service") + machine.wait_until_succeeds("curl http://localhost/ | grep 'You are not logged in'") ''; }) diff --git a/nixos/tests/morty.nix b/nixos/tests/morty.nix index eab123bd50f8..64c5a27665d6 100644 --- a/nixos/tests/morty.nix +++ b/nixos/tests/morty.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: { name = "morty"; @@ -22,11 +22,9 @@ import ./make-test.nix ({ pkgs, ... }: testScript = { ... }: '' - $mortyProxyWithKey->waitForUnit("default.target"); - - $mortyProxyWithKey->waitForOpenPort(3001); - $mortyProxyWithKey->succeed("curl -L 127.0.0.1:3001 | grep MortyProxy"); - + mortyProxyWithKey.wait_for_unit("default.target") + mortyProxyWithKey.wait_for_open_port(3001) + mortyProxyWithKey.succeed("curl -L 127.0.0.1:3001 | grep MortyProxy") ''; }) diff --git a/nixos/tests/opensmtpd.nix b/nixos/tests/opensmtpd.nix index 883ad7604941..e6f52db1d984 100644 --- a/nixos/tests/opensmtpd.nix +++ b/nixos/tests/opensmtpd.nix @@ -1,4 +1,4 @@ -import ./make-test.nix { +import ./make-test-python.nix { name = "opensmtpd"; nodes = { @@ -102,23 +102,23 @@ import ./make-test.nix { }; testScript = '' - startAll; + start_all() - $client->waitForUnit("network-online.target"); - $smtp1->waitForUnit('opensmtpd'); - $smtp2->waitForUnit('opensmtpd'); - $smtp2->waitForUnit('dovecot2'); + client.wait_for_unit("network-online.target") + smtp1.wait_for_unit("opensmtpd") + smtp2.wait_for_unit("opensmtpd") + smtp2.wait_for_unit("dovecot2") # To prevent sporadic failures during daemon startup, make sure # services are listening on their ports before sending requests - $smtp1->waitForOpenPort(25); - $smtp2->waitForOpenPort(25); - $smtp2->waitForOpenPort(143); + smtp1.wait_for_open_port(25) + smtp2.wait_for_open_port(25) + smtp2.wait_for_open_port(143) - $client->succeed('send-a-test-mail'); - $smtp1->waitUntilFails('smtpctl show queue | egrep .'); - $smtp2->waitUntilFails('smtpctl show queue | egrep .'); - $client->succeed('check-mail-landed >&2'); + client.succeed("send-a-test-mail") + smtp1.wait_until_fails("smtpctl show queue | egrep .") + smtp2.wait_until_fails("smtpctl show queue | egrep .") + client.succeed("check-mail-landed >&2") ''; meta.timeout = 30; diff --git a/nixos/tests/ostree.nix b/nixos/tests/ostree.nix deleted file mode 100644 index d7ad84a1a5f0..000000000000 --- a/nixos/tests/ostree.nix +++ /dev/null @@ -1,21 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, lib, ... }: { - name = "ostree"; - - meta = { - maintainers = pkgs.ostree.meta.maintainers; - }; - - # TODO: Wrap/patch the tests directly in the package - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ - gnome-desktop-testing ostree gnupg (python3.withPackages (p: with p; [ pyyaml ])) - ]; - - environment.variables.GI_TYPELIB_PATH = lib.makeSearchPath "lib/girepository-1.0" (with pkgs; [ gtk3 pango.out ostree gdk-pixbuf atk ]); # for GJS tests - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d ${pkgs.ostree.installedTests}/share"); - ''; -}) diff --git a/nixos/tests/packagekit.nix b/nixos/tests/packagekit.nix index e2d68af661f8..7e93ad35e80a 100644 --- a/nixos/tests/packagekit.nix +++ b/nixos/tests/packagekit.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "packagekit"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ peterhoeg ]; @@ -13,12 +13,14 @@ import ./make-test.nix ({ pkgs, ... }: { }; testScript = '' - startAll; + start_all() # send a dbus message to activate the service - $machine->succeed("dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.DBus.Introspectable.Introspect"); + machine.succeed( + "dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.DBus.Introspectable.Introspect" + ) # so now it should be running - $machine->succeed("systemctl is-active packagekit.service"); + machine.wait_for_unit("packagekit.service") ''; }) diff --git a/nixos/tests/pgjwt.nix b/nixos/tests/pgjwt.nix index a2d81288c812..4793a3e31503 100644 --- a/nixos/tests/pgjwt.nix +++ b/nixos/tests/pgjwt.nix @@ -1,12 +1,5 @@ -import ./make-test.nix ({ pkgs, lib, ...}: -let - test = with pkgs; runCommand "patch-test" { - nativeBuildInputs = [ pgjwt ]; - } - '' - sed -e '12 i CREATE EXTENSION pgcrypto;\nCREATE EXTENSION pgtap;\nSET search_path TO tap,public;' ${pgjwt.src}/test.sql > $out; - ''; -in +import ./make-test-python.nix ({ pkgs, lib, ...}: + with pkgs; { name = "pgjwt"; meta = with lib.maintainers; { @@ -29,9 +22,13 @@ with pkgs; { pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}"; in '' - startAll; - $master->waitForUnit("postgresql"); - $master->copyFileFromHost("${test}","/tmp/test.sql"); - $master->succeed("${pkgs.sudo}/bin/sudo -u ${sqlSU} PGOPTIONS=--search_path=tap,public ${pgProve}/bin/pg_prove -d postgres -v -f /tmp/test.sql"); + start_all() + master.wait_for_unit("postgresql") + master.succeed( + "${pkgs.gnused}/bin/sed -e '12 i CREATE EXTENSION pgcrypto;\\nCREATE EXTENSION pgtap;\\nSET search_path TO tap,public;' ${pgjwt.src}/test.sql > /tmp/test.sql" + ) + master.succeed( + "${pkgs.sudo}/bin/sudo -u ${sqlSU} PGOPTIONS=--search_path=tap,public ${pgProve}/bin/pg_prove -d postgres -v -f /tmp/test.sql" + ) ''; }) diff --git a/nixos/tests/powerdns.nix b/nixos/tests/powerdns.nix index 8addcc784012..75d71315e644 100644 --- a/nixos/tests/powerdns.nix +++ b/nixos/tests/powerdns.nix @@ -1,12 +1,13 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "powerdns"; nodes.server = { ... }: { services.powerdns.enable = true; + environment.systemPackages = [ pkgs.dnsutils ]; }; testScript = '' - $server->waitForUnit("pdns"); - $server->succeed("${pkgs.dnsutils}/bin/dig version.bind txt chaos \@127.0.0.1"); + server.wait_for_unit("pdns") + server.succeed("dig version.bind txt chaos \@127.0.0.1") ''; }) diff --git a/nixos/tests/pppd.nix b/nixos/tests/pppd.nix index 91f811859093..bda0aa75bb50 100644 --- a/nixos/tests/pppd.nix +++ b/nixos/tests/pppd.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ( +import ./make-test-python.nix ( let chap-secrets = { text = ''"flynn" * "reindeerflotilla" *''; @@ -53,10 +53,10 @@ import ./make-test.nix ( environment.etc."ppp/chap-secrets" = chap-secrets; }; }; - + testScript = '' - startAll; - $client->waitUntilSucceeds("ping -c1 -W1 192.0.2.1"); - $server->waitUntilSucceeds("ping -c1 -W1 192.0.2.2"); + start_all() + client.wait_until_succeeds("ping -c1 -W1 192.0.2.1") + server.wait_until_succeeds("ping -c1 -W1 192.0.2.2") ''; - }) + }) diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 676183f6356f..76cecb7433a9 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -4,12 +4,10 @@ }: let - inherit (import ../lib/testing.nix { inherit system pkgs; }) makeTest; + inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest; inherit (pkgs.lib) concatStringsSep maintainers mapAttrs mkMerge removeSuffix replaceChars singleton splitString; - escape' = str: replaceChars [''"'' "$" "\n"] [''\\\"'' "\\$" ""] str; - /* * The attrset `exporterTests` contains one attribute * for each exporter test. Each of these attributes @@ -33,9 +31,9 @@ let * services.<metricProvider>.enable = true; * }; * exporterTest = '' - * waitForUnit("prometheus-<exporterName>-exporter.service"); - * waitForOpenPort("1234"); - * succeed("curl -sSf 'localhost:1234/metrics'"); + * wait_for_unit("prometheus-<exporterName>-exporter.service") + * wait_for_open_port("1234") + * succeed("curl -sSf 'localhost:1234/metrics'") * ''; * }; * @@ -49,11 +47,11 @@ let * }; * * testScript = '' - * $<exporterName>->start(); - * $<exporterName>->waitForUnit("prometheus-<exporterName>-exporter.service"); - * $<exporterName>->waitForOpenPort("1234"); - * $<exporterName>->succeed("curl -sSf 'localhost:1234/metrics'"); - * $<exporterName>->shutdown(); + * <exporterName>.start() + * <exporterName>.wait_for_unit("prometheus-<exporterName>-exporter.service") + * <exporterName>.wait_for_open_port("1234") + * <exporterName>.succeed("curl -sSf 'localhost:1234/metrics'") + * <exporterName>.shutdown() * ''; */ @@ -72,9 +70,11 @@ let ''; }; exporterTest = '' - waitForUnit("prometheus-bind-exporter.service"); - waitForOpenPort(9119); - succeed("curl -sSf http://localhost:9119/metrics | grep -q 'bind_query_recursions_total 0'"); + wait_for_unit("prometheus-bind-exporter.service") + wait_for_open_port(9119) + succeed( + "curl -sSf http://localhost:9119/metrics | grep -q 'bind_query_recursions_total 0'" + ) ''; }; @@ -89,9 +89,11 @@ let }); }; exporterTest = '' - waitForUnit("prometheus-blackbox-exporter.service"); - waitForOpenPort(9115); - succeed("curl -sSf 'http://localhost:9115/probe?target=localhost&module=icmp_v6' | grep -q 'probe_success 1'"); + wait_for_unit("prometheus-blackbox-exporter.service") + wait_for_open_port(9115) + succeed( + "curl -sSf 'http://localhost:9115/probe?target=localhost&module=icmp_v6' | grep -q 'probe_success 1'" + ) ''; }; @@ -100,7 +102,7 @@ let enable = true; extraFlags = [ "--web.collectd-push-path /collectd" ]; }; - exporterTest =let postData = escape' '' + exporterTest = let postData = replaceChars [ "\n" ] [ "" ] '' [{ "values":[23], "dstypes":["gauge"], @@ -108,13 +110,21 @@ let "interval":1000, "host":"testhost", "plugin":"testplugin", - "time":$(date +%s) + "time":DATE }] ''; in '' - waitForUnit("prometheus-collectd-exporter.service"); - waitForOpenPort(9103); - succeed("curl -sSfH 'Content-Type: application/json' -X POST --data \"${postData}\" localhost:9103/collectd"); - succeed("curl -sSf localhost:9103/metrics | grep -q 'collectd_testplugin_gauge{instance=\"testhost\"} 23'"); + wait_for_unit("prometheus-collectd-exporter.service") + wait_for_open_port(9103) + succeed( + 'echo \'${postData}\'> /tmp/data.json' + ) + succeed('sed -ie "s DATE $(date +%s) " /tmp/data.json') + succeed( + "curl -sSfH 'Content-Type: application/json' -X POST --data @/tmp/data.json localhost:9103/collectd" + ) + succeed( + "curl -sSf localhost:9103/metrics | grep -q 'collectd_testplugin_gauge{instance=\"testhost\"} 23'" + ) ''; }; @@ -127,9 +137,9 @@ let services.dnsmasq.enable = true; }; exporterTest = '' - waitForUnit("prometheus-dnsmasq-exporter.service"); - waitForOpenPort(9153); - succeed("curl -sSf http://localhost:9153/metrics | grep -q 'dnsmasq_leases 0'"); + wait_for_unit("prometheus-dnsmasq-exporter.service") + wait_for_open_port(9153) + succeed("curl -sSf http://localhost:9153/metrics | grep -q 'dnsmasq_leases 0'") ''; }; @@ -144,9 +154,11 @@ let services.dovecot2.enable = true; }; exporterTest = '' - waitForUnit("prometheus-dovecot-exporter.service"); - waitForOpenPort(9166); - succeed("curl -sSf http://localhost:9166/metrics | grep -q 'dovecot_up{scope=\"global\"} 1'"); + wait_for_unit("prometheus-dovecot-exporter.service") + wait_for_open_port(9166) + succeed( + "curl -sSf http://localhost:9166/metrics | grep -q 'dovecot_up{scope=\"global\"} 1'" + ) ''; }; @@ -155,9 +167,11 @@ let enable = true; }; exporterTest = '' - waitForUnit("prometheus-fritzbox-exporter.service"); - waitForOpenPort(9133); - succeed("curl -sSf http://localhost:9133/metrics | grep -q 'fritzbox_exporter_collect_errors 0'"); + wait_for_unit("prometheus-fritzbox-exporter.service") + wait_for_open_port(9133) + succeed( + "curl -sSf http://localhost:9133/metrics | grep -q 'fritzbox_exporter_collect_errors 0'" + ) ''; }; @@ -180,11 +194,11 @@ let }; }; exporterTest = '' - waitForUnit("nginx.service"); - waitForOpenPort(80); - waitForUnit("prometheus-json-exporter.service"); - waitForOpenPort(7979); - succeed("curl -sSf localhost:7979/metrics | grep -q 'json_test_metric 1'"); + wait_for_unit("nginx.service") + wait_for_open_port(80) + wait_for_unit("prometheus-json-exporter.service") + wait_for_open_port(7979) + succeed("curl -sSf localhost:7979/metrics | grep -q 'json_test_metric 1'") ''; }; @@ -222,10 +236,12 @@ let users.users.mailexporter.isSystemUser = true; }; exporterTest = '' - waitForUnit("postfix.service") - waitForUnit("prometheus-mail-exporter.service") - waitForOpenPort(9225) - waitUntilSucceeds("curl -sSf http://localhost:9225/metrics | grep -q 'mail_deliver_success{configname=\"testserver\"} 1'") + wait_for_unit("postfix.service") + wait_for_unit("prometheus-mail-exporter.service") + wait_for_open_port(9225) + wait_until_succeeds( + "curl -sSf http://localhost:9225/metrics | grep -q 'mail_deliver_success{configname=\"testserver\"} 1'" + ) ''; }; @@ -256,9 +272,9 @@ let }; }; exporterTest = '' - waitForUnit("nginx.service") - waitForUnit("prometheus-nextcloud-exporter.service") - waitForOpenPort(9205) + wait_for_unit("nginx.service") + wait_for_unit("prometheus-nextcloud-exporter.service") + wait_for_open_port(9205) succeed("curl -sSf http://localhost:9205/metrics | grep -q 'nextcloud_up 1'") ''; }; @@ -275,9 +291,9 @@ let }; }; exporterTest = '' - waitForUnit("nginx.service") - waitForUnit("prometheus-nginx-exporter.service") - waitForOpenPort(9113) + wait_for_unit("nginx.service") + wait_for_unit("prometheus-nginx-exporter.service") + wait_for_open_port(9113) succeed("curl -sSf http://localhost:9113/metrics | grep -q 'nginx_up 1'") ''; }; @@ -287,9 +303,11 @@ let enable = true; }; exporterTest = '' - waitForUnit("prometheus-node-exporter.service"); - waitForOpenPort(9100); - succeed("curl -sSf http://localhost:9100/metrics | grep -q 'node_exporter_build_info{.\\+} 1'"); + wait_for_unit("prometheus-node-exporter.service") + wait_for_open_port(9100) + succeed( + "curl -sSf http://localhost:9100/metrics | grep -q 'node_exporter_build_info{.\\+} 1'" + ) ''; }; @@ -301,9 +319,11 @@ let services.postfix.enable = true; }; exporterTest = '' - waitForUnit("prometheus-postfix-exporter.service"); - waitForOpenPort(9154); - succeed("curl -sSf http://localhost:9154/metrics | grep -q 'postfix_smtpd_connects_total 0'"); + wait_for_unit("prometheus-postfix-exporter.service") + wait_for_open_port(9154) + succeed( + "curl -sSf http://localhost:9154/metrics | grep -q 'postfix_smtpd_connects_total 0'" + ) ''; }; @@ -316,18 +336,24 @@ let services.postgresql.enable = true; }; exporterTest = '' - waitForUnit("prometheus-postgres-exporter.service"); - waitForOpenPort(9187); - waitForUnit("postgresql.service"); - succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'"); - succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 1'"); - systemctl("stop postgresql.service"); - succeed("curl -sSf http://localhost:9187/metrics | grep -qv 'pg_exporter_last_scrape_error 0'"); - succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 0'"); - systemctl("start postgresql.service"); - waitForUnit("postgresql.service"); - succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'"); - succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 1'"); + wait_for_unit("prometheus-postgres-exporter.service") + wait_for_open_port(9187) + wait_for_unit("postgresql.service") + succeed( + "curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'" + ) + succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 1'") + systemctl("stop postgresql.service") + succeed( + "curl -sSf http://localhost:9187/metrics | grep -qv 'pg_exporter_last_scrape_error 0'" + ) + succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 0'") + systemctl("start postgresql.service") + wait_for_unit("postgresql.service") + succeed( + "curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'" + ) + succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 1'") ''; }; @@ -339,11 +365,13 @@ let services.rspamd.enable = true; }; exporterTest = '' - waitForUnit("rspamd.service"); - waitForUnit("prometheus-rspamd-exporter.service"); - waitForOpenPort(11334); - waitForOpenPort(7980); - waitUntilSucceeds("curl -sSf localhost:7980/metrics | grep -q 'rspamd_scanned{host=\"rspamd\"} 0'"); + wait_for_unit("rspamd.service") + wait_for_unit("prometheus-rspamd-exporter.service") + wait_for_open_port(11334) + wait_for_open_port(7980) + wait_until_succeeds( + "curl -sSf localhost:7980/metrics | grep -q 'rspamd_scanned{host=\"rspamd\"} 0'" + ) ''; }; @@ -356,9 +384,9 @@ let }; }; exporterTest = '' - waitForUnit("prometheus-snmp-exporter.service"); - waitForOpenPort(9116); - succeed("curl -sSf localhost:9116/metrics | grep -q 'snmp_request_errors_total 0'"); + wait_for_unit("prometheus-snmp-exporter.service") + wait_for_open_port(9116) + succeed("curl -sSf localhost:9116/metrics | grep -q 'snmp_request_errors_total 0'") ''; }; @@ -377,11 +405,11 @@ let }; }; exporterTest = '' - waitForUnit("nginx.service"); - waitForOpenPort(80); - waitForUnit("prometheus-surfboard-exporter.service"); - waitForOpenPort(9239); - succeed("curl -sSf localhost:9239/metrics | grep -q 'surfboard_up 1'"); + wait_for_unit("nginx.service") + wait_for_open_port(80) + wait_for_unit("prometheus-surfboard-exporter.service") + wait_for_open_port(9239) + succeed("curl -sSf localhost:9239/metrics | grep -q 'surfboard_up 1'") ''; }; @@ -396,11 +424,11 @@ let services.tor.controlPort = 9051; }; exporterTest = '' - waitForUnit("tor.service"); - waitForOpenPort(9051); - waitForUnit("prometheus-tor-exporter.service"); - waitForOpenPort(9130); - succeed("curl -sSf localhost:9130/metrics | grep -q 'tor_version{.\\+} 1'"); + wait_for_unit("tor.service") + wait_for_open_port(9051) + wait_for_unit("prometheus-tor-exporter.service") + wait_for_open_port(9130) + succeed("curl -sSf localhost:9130/metrics | grep -q 'tor_version{.\\+} 1'") ''; }; @@ -426,10 +454,12 @@ let }; }; exporterTest = '' - waitForUnit("prometheus-varnish-exporter.service"); - waitForOpenPort(6081); - waitForOpenPort(9131); - succeed("curl -sSf http://localhost:9131/metrics | grep -q 'varnish_up 1'"); + wait_for_unit("prometheus-varnish-exporter.service") + wait_for_open_port(6081) + wait_for_open_port(9131) + succeed( + "curl -sSf http://localhost:9131/metrics | grep -q 'varnish_up 1'" + ) ''; }; @@ -451,9 +481,11 @@ let systemd.services.prometheus-wireguard-exporter.after = [ "wireguard-wg0.service" ]; }; exporterTest = '' - waitForUnit("prometheus-wireguard-exporter.service"); - waitForOpenPort(9586); - waitUntilSucceeds("curl -sSf http://localhost:9586/metrics | grep '${snakeoil.peer1.publicKey}'"); + wait_for_unit("prometheus-wireguard-exporter.service") + wait_for_open_port(9586) + wait_until_succeeds( + "curl -sSf http://localhost:9586/metrics | grep '${snakeoil.peer1.publicKey}'" + ) ''; }; }; @@ -466,11 +498,13 @@ mapAttrs (exporter: testConfig: (makeTest { } testConfig.metricProvider or {}]; testScript = '' - ${"$"+exporter}->start(); - ${concatStringsSep " " (map (line: '' - ${"$"+exporter}->${line}; - '') (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))} - ${"$"+exporter}->shutdown(); + ${exporter}.start() + ${concatStringsSep "\n" (map (line: + if (builtins.substring 0 1 line == " " || builtins.substring 0 1 line == ")") + then line + else "${exporter}.${line}" + ) (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))} + ${exporter}.shutdown() ''; meta = with maintainers; { diff --git a/nixos/tests/radarr.nix b/nixos/tests/radarr.nix index 9bc5607ccd5a..ed90025ac420 100644 --- a/nixos/tests/radarr.nix +++ b/nixos/tests/radarr.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, ... }: +import ./make-test-python.nix ({ lib, ... }: with lib; @@ -11,8 +11,8 @@ with lib; { services.radarr.enable = true; }; testScript = '' - $machine->waitForUnit('radarr.service'); - $machine->waitForOpenPort('7878'); - $machine->succeed("curl --fail http://localhost:7878/"); + machine.wait_for_unit("radarr.service") + machine.wait_for_open_port("7878") + machine.succeed("curl --fail http://localhost:7878/") ''; }) diff --git a/nixos/tests/redis.nix b/nixos/tests/redis.nix index 325d93424dd7..529965d7acde 100644 --- a/nixos/tests/redis.nix +++ b/nixos/tests/redis.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "redis"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ flokli ]; @@ -15,12 +15,10 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; - - $machine->waitForUnit("redis"); - $machine->waitForOpenPort("6379"); - - $machine->succeed("redis-cli ping | grep PONG"); - $machine->succeed("redis-cli -s /run/redis/redis.sock ping | grep PONG"); + start_all() + machine.wait_for_unit("redis") + machine.wait_for_open_port("6379") + machine.succeed("redis-cli ping | grep PONG") + machine.succeed("redis-cli -s /run/redis/redis.sock ping | grep PONG") ''; }) diff --git a/nixos/tests/redmine.nix b/nixos/tests/redmine.nix index 2d4df288b055..f0f4cbf6a21c 100644 --- a/nixos/tests/redmine.nix +++ b/nixos/tests/redmine.nix @@ -64,18 +64,13 @@ let }; in { - v3-mysql = mysqlTest pkgs.redmine // { - name = "v3-mysql"; + mysql = mysqlTest pkgs.redmine // { + name = "mysql"; meta.maintainers = [ maintainers.aanderse ]; }; - v4-mysql = mysqlTest pkgs.redmine_4 // { - name = "v4-mysql"; - meta.maintainers = [ maintainers.aanderse ]; - }; - - v4-pgsql = pgsqlTest pkgs.redmine_4 // { - name = "v4-pgsql"; + pgsql = pgsqlTest pkgs.redmine // { + name = "pgsql"; meta.maintainers = [ maintainers.aanderse ]; }; } diff --git a/nixos/tests/roundcube.nix b/nixos/tests/roundcube.nix index ed0ebd7dd19d..4f2560ce8c2f 100644 --- a/nixos/tests/roundcube.nix +++ b/nixos/tests/roundcube.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "roundcube"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ globin ]; @@ -21,10 +21,10 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - $roundcube->start; - $roundcube->waitForUnit("postgresql.service"); - $roundcube->waitForUnit("phpfpm-roundcube.service"); - $roundcube->waitForUnit("nginx.service"); - $roundcube->succeed("curl -sSfL http://roundcube/ | grep 'Keep me logged in'"); + roundcube.start + roundcube.wait_for_unit("postgresql.service") + roundcube.wait_for_unit("phpfpm-roundcube.service") + roundcube.wait_for_unit("nginx.service") + roundcube.succeed("curl -sSfL http://roundcube/ | grep 'Keep me logged in'") ''; }) diff --git a/nixos/tests/rss2email.nix b/nixos/tests/rss2email.nix index 492d47da9f56..d62207a417b8 100644 --- a/nixos/tests/rss2email.nix +++ b/nixos/tests/rss2email.nix @@ -1,4 +1,4 @@ -import ./make-test.nix { +import ./make-test-python.nix { name = "opensmtpd"; nodes = { @@ -53,14 +53,14 @@ import ./make-test.nix { }; testScript = '' - startAll; + start_all() - $server->waitForUnit("network-online.target"); - $server->waitForUnit("opensmtpd"); - $server->waitForUnit("dovecot2"); - $server->waitForUnit("nginx"); - $server->waitForUnit("rss2email"); + server.wait_for_unit("network-online.target") + server.wait_for_unit("opensmtpd") + server.wait_for_unit("dovecot2") + server.wait_for_unit("nginx") + server.wait_for_unit("rss2email") - $server->waitUntilSucceeds('check-mail-landed >&2'); + server.wait_until_succeeds("check-mail-landed >&2") ''; } diff --git a/nixos/tests/samba.nix b/nixos/tests/samba.nix index 2802e00a5b1a..142269752b34 100644 --- a/nixos/tests/samba.nix +++ b/nixos/tests/samba.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: { name = "samba"; @@ -36,12 +36,12 @@ import ./make-test.nix ({ pkgs, ... }: testScript = '' - $server->start; - $server->waitForUnit("samba.target"); - $server->succeed("mkdir -p /public; echo bar > /public/foo"); + server.start() + server.wait_for_unit("samba.target") + server.succeed("mkdir -p /public; echo bar > /public/foo") - $client->start; - $client->waitForUnit("remote-fs.target"); - $client->succeed("[[ \$(cat /public/foo) = bar ]]"); + client.start() + client.wait_for_unit("remote-fs.target") + client.succeed("[[ $(cat /public/foo) = bar ]]") ''; }) diff --git a/nixos/tests/sddm.nix b/nixos/tests/sddm.nix index 678bcbeab20a..11d60598445e 100644 --- a/nixos/tests/sddm.nix +++ b/nixos/tests/sddm.nix @@ -3,7 +3,7 @@ pkgs ? import ../.. { inherit system config; } }: -with import ../lib/testing.nix { inherit system pkgs; }; +with import ../lib/testing-python.nix { inherit system pkgs; }; let inherit (pkgs) lib; @@ -26,13 +26,13 @@ let testScript = { nodes, ... }: let user = nodes.machine.config.users.users.alice; in '' - startAll; - $machine->waitForText(qr/select your user/i); - $machine->screenshot("sddm"); - $machine->sendChars("${user.password}\n"); - $machine->waitForFile("/home/alice/.Xauthority"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->waitForWindow("^IceWM "); + start_all() + machine.wait_for_text("select your user") + machine.screenshot("sddm") + machine.send_chars("${user.password}\n") + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + machine.wait_for_window("^IceWM ") ''; }; @@ -57,11 +57,13 @@ let services.xserver.desktopManager.default = "none"; }; - testScript = { ... }: '' - startAll; - $machine->waitForFile("/home/alice/.Xauthority"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->waitForWindow("^IceWM "); + testScript = { nodes, ... }: let + user = nodes.machine.config.users.users.alice; + in '' + start_all() + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + machine.wait_for_window("^IceWM ") ''; }; }; diff --git a/nixos/tests/shiori.nix b/nixos/tests/shiori.nix index 0022a7220fe2..a5771262c6f2 100644 --- a/nixos/tests/shiori.nix +++ b/nixos/tests/shiori.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, ...}: +import ./make-test-python.nix ({ pkgs, lib, ...}: { name = "shiori"; @@ -8,10 +8,74 @@ import ./make-test.nix ({ lib, ...}: { ... }: { services.shiori.enable = true; }; - testScript = '' - $machine->waitForUnit('shiori.service'); - $machine->waitForOpenPort('8080'); - $machine->succeed("curl --fail http://localhost:8080/"); - $machine->succeed("curl --fail --location http://localhost:8080/ | grep -qi shiori"); + testScript = let + authJSON = pkgs.writeText "auth.json" (builtins.toJSON { + username = "shiori"; + password = "gopher"; + remember = 1; # hour + owner = true; + }); + + insertBookmark = { + url = "http://example.org"; + title = "Example Bookmark"; + }; + + insertBookmarkJSON = pkgs.writeText "insertBookmark.json" (builtins.toJSON insertBookmark); + in '' + import json + + machine.wait_for_unit("shiori.service") + machine.wait_for_open_port(8080) + machine.succeed("curl --fail http://localhost:8080/") + machine.succeed("curl --fail --location http://localhost:8080/ | grep -qi shiori") + + with subtest("login"): + auth_json = machine.succeed( + "curl --fail --location http://localhost:8080/api/login " + "-X POST -H 'Content-Type:application/json' -d @${authJSON}" + ) + auth_ret = json.loads(auth_json) + session_id = auth_ret["session"] + + with subtest("bookmarks"): + with subtest("first use no bookmarks"): + bookmarks_json = machine.succeed( + ( + "curl --fail --location http://localhost:8080/api/bookmarks " + "-H 'X-Session-Id:{}'" + ).format(session_id) + ) + + if json.loads(bookmarks_json)["bookmarks"] != []: + raise Exception("Shiori have a bookmark on first use") + + with subtest("insert bookmark"): + machine.succeed( + ( + "curl --fail --location http://localhost:8080/api/bookmarks " + "-X POST -H 'X-Session-Id:{}' " + "-H 'Content-Type:application/json' -d @${insertBookmarkJSON}" + ).format(session_id) + ) + + with subtest("get inserted bookmark"): + bookmarks_json = machine.succeed( + ( + "curl --fail --location http://localhost:8080/api/bookmarks " + "-H 'X-Session-Id:{}'" + ).format(session_id) + ) + + bookmarks = json.loads(bookmarks_json)["bookmarks"] + if len(bookmarks) != 1: + raise Exception("Shiori didn't save the bookmark") + + bookmark = bookmarks[0] + if ( + bookmark["url"] != "${insertBookmark.url}" + or bookmark["title"] != "${insertBookmark.title}" + ): + raise Exception("Inserted bookmark doesn't have same URL or title") ''; }) diff --git a/nixos/tests/signal-desktop.nix b/nixos/tests/signal-desktop.nix index 605b9c3e1301..c746d46dc550 100644 --- a/nixos/tests/signal-desktop.nix +++ b/nixos/tests/signal-desktop.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, ...} : { name = "signal-desktop"; @@ -24,14 +24,14 @@ import ./make-test.nix ({ pkgs, ...} : testScript = { nodes, ... }: let user = nodes.machine.config.users.users.alice; in '' - startAll; - $machine->waitForX; + start_all() + machine.wait_for_x() # start signal desktop - $machine->execute("su - alice -c signal-desktop &"); + machine.execute("su - alice -c signal-desktop &") # wait for the "Link your phone to Signal Desktop" message - $machine->waitForText(qr/Link your phone to Signal Desktop/); - $machine->screenshot("signal_desktop"); + machine.wait_for_text("Link your phone to Signal Desktop") + machine.screenshot("signal_desktop") ''; }) diff --git a/nixos/tests/smokeping.nix b/nixos/tests/smokeping.nix index 07d228051127..4f8f0fcc9fe2 100644 --- a/nixos/tests/smokeping.nix +++ b/nixos/tests/smokeping.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "smokeping"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ cransom ]; @@ -22,12 +22,12 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; - $sm->waitForUnit("smokeping"); - $sm->waitForUnit("thttpd"); - $sm->waitForFile("/var/lib/smokeping/data/Local/LocalMachine.rrd"); - $sm->succeed("curl -s -f localhost:8081/smokeping.fcgi?target=Local"); - $sm->succeed("ls /var/lib/smokeping/cache/Local/LocalMachine_mini.png"); - $sm->succeed("ls /var/lib/smokeping/cache/index.html"); + start_all() + sm.wait_for_unit("smokeping") + sm.wait_for_unit("thttpd") + sm.wait_for_file("/var/lib/smokeping/data/Local/LocalMachine.rrd") + sm.succeed("curl -s -f localhost:8081/smokeping.fcgi?target=Local") + sm.succeed("ls /var/lib/smokeping/cache/Local/LocalMachine_mini.png") + sm.succeed("ls /var/lib/smokeping/cache/index.html") ''; }) diff --git a/nixos/tests/snapper.nix b/nixos/tests/snapper.nix index 74ec22fd3499..018102d7f640 100644 --- a/nixos/tests/snapper.nix +++ b/nixos/tests/snapper.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ ... }: +import ./make-test-python.nix ({ ... }: { name = "snapper"; @@ -20,24 +20,16 @@ import ./make-test.nix ({ ... }: }; testScript = '' - $machine->succeed("btrfs subvolume create /home/.snapshots"); - - $machine->succeed("snapper -c home list"); - - $machine->succeed("snapper -c home create --description empty"); - - $machine->succeed("echo test > /home/file"); - $machine->succeed("snapper -c home create --description file"); - - $machine->succeed("snapper -c home status 1..2"); - - $machine->succeed("snapper -c home undochange 1..2"); - $machine->fail("ls /home/file"); - - $machine->succeed("snapper -c home delete 2"); - - $machine->succeed("systemctl --wait start snapper-timeline.service"); - - $machine->succeed("systemctl --wait start snapper-cleanup.service"); + machine.succeed("btrfs subvolume create /home/.snapshots") + machine.succeed("snapper -c home list") + machine.succeed("snapper -c home create --description empty") + machine.succeed("echo test > /home/file") + machine.succeed("snapper -c home create --description file") + machine.succeed("snapper -c home status 1..2") + machine.succeed("snapper -c home undochange 1..2") + machine.fail("ls /home/file") + machine.succeed("snapper -c home delete 2") + machine.succeed("systemctl --wait start snapper-timeline.service") + machine.succeed("systemctl --wait start snapper-cleanup.service") ''; }) diff --git a/nixos/tests/strongswan-swanctl.nix b/nixos/tests/strongswan-swanctl.nix index 9bab9349ea73..152c0d61c543 100644 --- a/nixos/tests/strongswan-swanctl.nix +++ b/nixos/tests/strongswan-swanctl.nix @@ -16,7 +16,7 @@ # See the NixOS manual for how to run this test: # https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively -import ./make-test.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, ...} : let allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT"; @@ -142,7 +142,7 @@ in { }; testScript = '' - startAll(); - $carol->waitUntilSucceeds("ping -c 1 alice"); + start_all() + carol.wait_until_succeeds("ping -c 1 alice") ''; }) diff --git a/nixos/tests/telegraf.nix b/nixos/tests/telegraf.nix index 6776f8d8c37f..73f741b11357 100644 --- a/nixos/tests/telegraf.nix +++ b/nixos/tests/telegraf.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "telegraf"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ mic92 ]; @@ -22,9 +22,9 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; + start_all() - $machine->waitForUnit("telegraf.service"); - $machine->waitUntilSucceeds("grep -q example /tmp/metrics.out"); + machine.wait_for_unit("telegraf.service") + machine.wait_until_succeeds("grep -q example /tmp/metrics.out") ''; }) diff --git a/nixos/tests/tinydns.nix b/nixos/tests/tinydns.nix index cb7ee0c5fb5e..c7740d5ade35 100644 --- a/nixos/tests/tinydns.nix +++ b/nixos/tests/tinydns.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ lib, ...} : { +import ./make-test-python.nix ({ lib, ...} : { name = "tinydns"; meta = { maintainers = with lib.maintainers; [ basvandijk ]; @@ -19,8 +19,8 @@ import ./make-test.nix ({ lib, ...} : { }; }; testScript = '' - $nameserver->start; - $nameserver->waitForUnit("tinydns.service"); - $nameserver->succeed("host bla.foo.bar | grep '1\.2\.3\.4'"); + nameserver.start() + nameserver.wait_for_unit("tinydns.service") + nameserver.succeed("host bla.foo.bar | grep '1\.2\.3\.4'") ''; }) diff --git a/nixos/tests/trickster.nix b/nixos/tests/trickster.nix index 1461a32bb07e..e2ca00980d53 100644 --- a/nixos/tests/trickster.nix +++ b/nixos/tests/trickster.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, ... }: { name = "trickster"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ "1000101" ]; @@ -15,15 +15,23 @@ import ./make-test.nix ({ pkgs, ... }: { }; testScript = '' - startAll; - $prometheus->waitForUnit("prometheus.service"); - $prometheus->waitForOpenPort(9090); - $prometheus->waitUntilSucceeds("curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); - $trickster->waitForUnit("trickster.service"); - $trickster->waitForOpenPort(8082); - $trickster->waitForOpenPort(9090); - $trickster->waitUntilSucceeds("curl -L http://localhost:8082/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); - $trickster->waitUntilSucceeds("curl -L http://prometheus:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); - $trickster->waitUntilSucceeds("curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); + start_all() + prometheus.wait_for_unit("prometheus.service") + prometheus.wait_for_open_port(9090) + prometheus.wait_until_succeeds( + "curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'" + ) + trickster.wait_for_unit("trickster.service") + trickster.wait_for_open_port(8082) + trickster.wait_for_open_port(9090) + trickster.wait_until_succeeds( + "curl -L http://localhost:8082/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'" + ) + trickster.wait_until_succeeds( + "curl -L http://prometheus:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'" + ) + trickster.wait_until_succeeds( + "curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'" + ) ''; }) \ No newline at end of file diff --git a/nixos/tests/udisks2.nix b/nixos/tests/udisks2.nix index dcf869908d82..0cbfa0c4c7be 100644 --- a/nixos/tests/udisks2.nix +++ b/nixos/tests/udisks2.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: let @@ -30,32 +30,40 @@ in testScript = '' - my $stick = $machine->stateDir . "/usbstick.img"; - system("xz -d < ${stick} > $stick") == 0 or die; + import lzma - $machine->succeed("udisksctl info -b /dev/vda >&2"); - $machine->fail("udisksctl info -b /dev/sda1"); + with lzma.open( + "${stick}" + ) as data, open(machine.state_dir + "/usbstick.img", "wb") as stick: + stick.write(data.read()) + + machine.succeed("udisksctl info -b /dev/vda >&2") + machine.fail("udisksctl info -b /dev/sda1") # Attach a USB stick and wait for it to show up. - $machine->sendMonitorCommand("drive_add 0 id=stick,if=none,file=$stick,format=raw"); - $machine->sendMonitorCommand("device_add usb-storage,id=stick,drive=stick"); - $machine->waitUntilSucceeds("udisksctl info -b /dev/sda1"); - $machine->succeed("udisksctl info -b /dev/sda1 | grep 'IdLabel:.*USBSTICK'"); + machine.send_monitor_command( + f"drive_add 0 id=stick,if=none,file={stick.name},format=raw" + ) + machine.send_monitor_command("device_add usb-storage,id=stick,drive=stick") + machine.wait_until_succeeds("udisksctl info -b /dev/sda1") + machine.succeed("udisksctl info -b /dev/sda1 | grep 'IdLabel:.*USBSTICK'") # Mount the stick as a non-root user and do some stuff with it. - $machine->succeed("su - alice -c 'udisksctl info -b /dev/sda1'"); - $machine->succeed("su - alice -c 'udisksctl mount -b /dev/sda1'"); - $machine->succeed("su - alice -c 'cat /run/media/alice/USBSTICK/test.txt'") =~ /Hello World/ or die; - $machine->succeed("su - alice -c 'echo foo > /run/media/alice/USBSTICK/bar.txt'"); + machine.succeed("su - alice -c 'udisksctl info -b /dev/sda1'") + machine.succeed("su - alice -c 'udisksctl mount -b /dev/sda1'") + machine.succeed( + "su - alice -c 'cat /run/media/alice/USBSTICK/test.txt' | grep -q 'Hello World'" + ) + machine.succeed("su - alice -c 'echo foo > /run/media/alice/USBSTICK/bar.txt'") # Unmounting the stick should make the mountpoint disappear. - $machine->succeed("su - alice -c 'udisksctl unmount -b /dev/sda1'"); - $machine->fail("[ -d /run/media/alice/USBSTICK ]"); + machine.succeed("su - alice -c 'udisksctl unmount -b /dev/sda1'") + machine.fail("[ -d /run/media/alice/USBSTICK ]") # Remove the USB stick. - $machine->sendMonitorCommand("device_del stick"); - $machine->waitUntilFails("udisksctl info -b /dev/sda1"); - $machine->fail("[ -e /dev/sda ]"); + machine.send_monitor_command("device_del stick") + machine.wait_until_fails("udisksctl info -b /dev/sda1") + machine.fail("[ -e /dev/sda ]") ''; }) diff --git a/nixos/tests/upnp.nix b/nixos/tests/upnp.nix index 98344aee3efa..d2e7fdd4fbeb 100644 --- a/nixos/tests/upnp.nix +++ b/nixos/tests/upnp.nix @@ -5,7 +5,7 @@ # this succeeds an external client will try to connect to the port # mapping. -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: let internalRouterAddress = "192.168.3.1"; @@ -75,20 +75,20 @@ in testScript = { nodes, ... }: '' - startAll; + start_all() # Wait for network and miniupnpd. - $router->waitForUnit("network-online.target"); - # $router->waitForUnit("nat"); - $router->waitForUnit("firewall.service"); - $router->waitForUnit("miniupnpd"); + router.wait_for_unit("network-online.target") + # $router.wait_for_unit("nat") + router.wait_for_unit("firewall.service") + router.wait_for_unit("miniupnpd") - $client1->waitForUnit("network-online.target"); + client1.wait_for_unit("network-online.target") - $client1->succeed("upnpc -a ${internalClient1Address} 9000 9000 TCP"); + client1.succeed("upnpc -a ${internalClient1Address} 9000 9000 TCP") - $client1->waitForUnit("httpd"); - $client2->waitUntilSucceeds("curl http://${externalRouterAddress}:9000/"); + client1.wait_for_unit("httpd") + client2.wait_until_succeeds("curl http://${externalRouterAddress}:9000/") ''; }) diff --git a/nixos/tests/xautolock.nix b/nixos/tests/xautolock.nix index ee46d9e05b06..10e92b40e956 100644 --- a/nixos/tests/xautolock.nix +++ b/nixos/tests/xautolock.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ... }: +import ./make-test-python.nix ({ pkgs, lib, ... }: with lib; @@ -15,10 +15,10 @@ with lib; }; testScript = '' - $machine->start; - $machine->waitForX; - $machine->mustFail("pgrep xlock"); - $machine->sleep(120); - $machine->mustSucceed("pgrep xlock"); + machine.start() + machine.wait_for_x() + machine.fail("pgrep xlock") + machine.sleep(120) + machine.succeed("pgrep xlock") ''; }) diff --git a/nixos/tests/xdg-desktop-portal.nix b/nixos/tests/xdg-desktop-portal.nix deleted file mode 100644 index 79ebb83c49a5..000000000000 --- a/nixos/tests/xdg-desktop-portal.nix +++ /dev/null @@ -1,17 +0,0 @@ -# run installed tests -import ./make-test.nix ({ pkgs, ... }: - -{ - name = "xdg-desktop-portal"; - meta = { - maintainers = pkgs.xdg-desktop-portal.meta.maintainers; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ gnome-desktop-testing ]; - }; - - testScript = '' - $machine->succeed("gnome-desktop-testing-runner -d '${pkgs.xdg-desktop-portal.installedTests}/share'"); - ''; -}) diff --git a/nixos/tests/xmonad.nix b/nixos/tests/xmonad.nix index 79c15ccffecd..c2e5ba60d7bc 100644 --- a/nixos/tests/xmonad.nix +++ b/nixos/tests/xmonad.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "xmonad"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ nequissimus ]; @@ -21,19 +21,21 @@ import ./make-test.nix ({ pkgs, ...} : { }; }; - testScript = { ... }: '' - $machine->waitForX; - $machine->waitForFile("/home/alice/.Xauthority"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->sendKeys("alt-ctrl-x"); - $machine->waitForWindow(qr/alice.*machine/); - $machine->sleep(1); - $machine->screenshot("terminal"); - $machine->waitUntilSucceeds("xmonad --restart"); - $machine->sleep(3); - $machine->sendKeys("alt-shift-ret"); - $machine->waitForWindow(qr/alice.*machine/); - $machine->sleep(1); - $machine->screenshot("terminal"); + testScript = { nodes, ... }: let + user = nodes.machine.config.users.users.alice; + in '' + machine.wait_for_x() + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + machine.send_chars("alt-ctrl-x") + machine.wait_for_window("${user.name}.*machine") + machine.sleep(1) + machine.screenshot("terminal") + machine.wait_until_succeeds("xmonad --restart") + machine.sleep(3) + machine.send_chars("alt-shift-ret") + machine.wait_for_window("${user.name}.*machine") + machine.sleep(1) + machine.screenshot("terminal") ''; }) diff --git a/nixos/tests/yabar.nix b/nixos/tests/yabar.nix index bbc0cf4c7dd7..9108004d4df9 100644 --- a/nixos/tests/yabar.nix +++ b/nixos/tests/yabar.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, lib, ... }: +import ./make-test-python.nix ({ pkgs, lib, ... }: with lib; @@ -20,14 +20,14 @@ with lib; }; testScript = '' - $machine->start; - $machine->waitForX; + machine.start() + machine.wait_for_x() # confirm proper startup - $machine->waitForUnit("yabar.service", "bob"); - $machine->sleep(10); - $machine->waitForUnit("yabar.service", "bob"); + machine.wait_for_unit("yabar.service", "bob") + machine.sleep(10) + machine.wait_for_unit("yabar.service", "bob") - $machine->screenshot("top_bar"); + machine.screenshot("top_bar") ''; }) diff --git a/nixos/tests/zookeeper.nix b/nixos/tests/zookeeper.nix index f343ebd39e44..42cf20b39c52 100644 --- a/nixos/tests/zookeeper.nix +++ b/nixos/tests/zookeeper.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "zookeeper"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ nequissimus ]; @@ -15,14 +15,20 @@ import ./make-test.nix ({ pkgs, ...} : { }; testScript = '' - startAll; + start_all() - $server->waitForUnit("zookeeper"); - $server->waitForUnit("network.target"); - $server->waitForOpenPort(2181); + server.wait_for_unit("zookeeper") + server.wait_for_unit("network.target") + server.wait_for_open_port(2181) - $server->waitUntilSucceeds("${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 create /foo bar"); - $server->waitUntilSucceeds("${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 set /foo hello"); - $server->waitUntilSucceeds("${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 get /foo | grep hello"); + server.wait_until_succeeds( + "${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 create /foo bar" + ) + server.wait_until_succeeds( + "${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 set /foo hello" + ) + server.wait_until_succeeds( + "${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 get /foo | grep hello" + ) ''; }) |