Merge branch 'master' into staging-next

~4k rebuilds on each Linux.
This commit is contained in:
Vladimír Čunát 2019-11-09 07:20:00 +01:00
commit 457e94d900
No known key found for this signature in database
GPG Key ID: E747DF1F9575A3AA
321 changed files with 20336 additions and 16482 deletions

View File

@ -189,6 +189,12 @@
githubId = 1250775; githubId = 1250775;
name = "Adolfo E. García Castro"; name = "Adolfo E. García Castro";
}; };
adsr = {
email = "as@php.net";
github = "adsr";
githubId = 315003;
name = "Adam Saponara";
};
aepsil0n = { aepsil0n = {
email = "eduard.bopp@aepsil0n.de"; email = "eduard.bopp@aepsil0n.de";
github = "aepsil0n"; github = "aepsil0n";
@ -563,6 +569,12 @@
githubId = 718812; githubId = 718812;
name = "Antoine R. Dumont"; name = "Antoine R. Dumont";
}; };
arianvp = {
email = "arian.vanputten@gmail.com";
github = "arianvp";
githubId = 628387;
name = "Arian van Putten";
};
aristid = { aristid = {
email = "aristidb@gmail.com"; email = "aristidb@gmail.com";
github = "aristidb"; github = "aristidb";
@ -2245,6 +2257,16 @@
githubId = 8182846; githubId = 8182846;
name = "Francesco Gazzetta"; name = "Francesco Gazzetta";
}; };
filalex77 = {
email = "brightone@protonmail.com";
github = "filalex77";
githubId = 12615679;
name = "Oleksii Filonenko";
keys = [{
longkeyid = "rsa3072/0xA1BC8428323ECFE8";
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
}];
};
FireyFly = { FireyFly = {
email = "nix@firefly.nu"; email = "nix@firefly.nu";
github = "FireyFly"; github = "FireyFly";
@ -3110,6 +3132,11 @@
githubId = 184898; githubId = 184898;
name = "Jirka Marsik"; name = "Jirka Marsik";
}; };
jitwit = {
email = "jrn@bluefarm.ca";
github = "jitwit";
name = "jitwit";
};
jlesquembre = { jlesquembre = {
email = "jl@lafuente.me"; email = "jl@lafuente.me";
github = "jlesquembre"; github = "jlesquembre";
@ -6677,6 +6704,16 @@
githubId = 13026; githubId = 13026;
name = "Jonathan Rudenberg"; name = "Jonathan Rudenberg";
}; };
tkerber = {
email = "tk@drwx.org";
github = "tkerber";
githubId = 5722198;
name = "Thomas Kerber";
keys = [ {
longkeyid = "rsa4096/0x8489B911F9ED617B";
fingerprint = "556A 403F B0A2 D423 F656 3424 8489 B911 F9ED 617B";
} ];
};
tmplt = { tmplt = {
email = "tmplt@dragons.rocks"; email = "tmplt@dragons.rocks";
github = "tmplt"; github = "tmplt";
@ -6760,6 +6797,12 @@
githubId = 1312290; githubId = 1312290;
name = "Trevor Joynson"; name = "Trevor Joynson";
}; };
tricktron = {
email = "tgagnaux@gmail.com";
github = "tricktron";
githubId = 16036882;
name = "Thibault Gagnaux";
};
trino = { trino = {
email = "muehlhans.hubert@ekodia.de"; email = "muehlhans.hubert@ekodia.de";
github = "hmuehlhans"; github = "hmuehlhans";
@ -7314,14 +7357,24 @@
githubId = 1866448; githubId = 1866448;
name = "Eric Bailey"; name = "Eric Bailey";
}; };
Yumasi = {
email = "gpagnoux@gmail.com";
github = "Yumasi";
githubId = 24368641;
name = "Guillaume Pagnoux";
keys = [{
longkeyid = "rsa4096/0xEC5065899AEAAF4C";
fingerprint = "85F8 E850 F8F2 F823 F934 535B EC50 6589 9AEA AF4C";
}];
};
yvt = { yvt = {
email = "i@yvt.jp"; email = "i@yvt.jp";
github = "yvt"; github = "yvt";
githubId = 5253988; githubId = 5253988;
name = "yvt"; name = "yvt";
}; };
z77z = { maggesi = {
email = "maggesi@math.unifi.it"; email = "marco.maggesi@gmail.com";
github = "maggesi"; github = "maggesi";
githubId = 1809783; githubId = 1809783;
name = "Marco Maggesi"; name = "Marco Maggesi";
@ -7365,6 +7418,12 @@
email = "zef@zef.me"; email = "zef@zef.me";
name = "Zef Hemel"; name = "Zef Hemel";
}; };
zfnmxt = {
name = "zfnmxt";
email = "zfnmxt@zfnmxt.com";
github = "zfnmxt";
githubId = 37446532;
};
zgrannan = { zgrannan = {
email = "zgrannan@gmail.com"; email = "zgrannan@gmail.com";
github = "zgrannan"; github = "zgrannan";

View File

@ -47,6 +47,11 @@
acceleration acceleration
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Click on Settings / Display / Screen and select VBoxVGA as Graphics Controller
</para>
</listitem>
<listitem> <listitem>
<para> <para>
Save the settings, start the virtual machine, and continue installation Save the settings, start the virtual machine, and continue installation

View File

@ -494,6 +494,20 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
<para> <para>

View File

@ -4,7 +4,9 @@ from contextlib import contextmanager
from xml.sax.saxutils import XMLGenerator from xml.sax.saxutils import XMLGenerator
import _thread import _thread
import atexit import atexit
import json
import os import os
import ptpython.repl
import pty import pty
import queue import queue
import re import re
@ -15,7 +17,6 @@ import sys
import tempfile import tempfile
import time import time
import unicodedata import unicodedata
import ptpython.repl
CHAR_TO_KEY = { CHAR_TO_KEY = {
"A": "shift-a", "A": "shift-a",
@ -305,7 +306,7 @@ class Machine:
if state == "inactive": if state == "inactive":
status, jobs = self.systemctl("list-jobs --full 2>&1", user) status, jobs = self.systemctl("list-jobs --full 2>&1", user)
if "No jobs" in jobs: if "No jobs" in jobs:
info = self.get_unit_info(unit) info = self.get_unit_info(unit, user)
if info["ActiveState"] == state: if info["ActiveState"] == state:
raise Exception( raise Exception(
( (
@ -318,7 +319,11 @@ class Machine:
def get_unit_info(self, unit, user=None): def get_unit_info(self, unit, user=None):
status, lines = self.systemctl('--no-pager show "{}"'.format(unit), user) status, lines = self.systemctl('--no-pager show "{}"'.format(unit), user)
if status != 0: 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"^([^=]+)=(.*)$") line_pattern = re.compile(r"^([^=]+)=(.*)$")
@ -344,6 +349,18 @@ class Machine:
) )
return self.execute("systemctl {}".format(q)) 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): def execute(self, command):
self.connect() self.connect()
@ -494,6 +511,11 @@ class Machine:
if ret.returncode != 0: if ret.returncode != 0:
raise Exception("Cannot convert screenshot") 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): def get_screen_text(self):
if shutil.which("tesseract") is None: if shutil.which("tesseract") is None:
raise Exception("get_screen_text used but enableOCR is false") raise Exception("get_screen_text used but enableOCR is false")
@ -588,7 +610,7 @@ class Machine:
stdin=subprocess.DEVNULL, stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
shell=False, shell=True,
cwd=self.state_dir, cwd=self.state_dir,
env=environment, env=environment,
) )
@ -597,7 +619,7 @@ class Machine:
def process_serial_output(): def process_serial_output():
for line in self.process.stdout: 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)) eprint("{} # {}".format(self.name, line))
self.logger.enqueue({"msg": line, "machine": self.name}) self.logger.enqueue({"msg": line, "machine": self.name})
@ -611,14 +633,14 @@ class Machine:
self.log("QEMU running (pid {})".format(self.pid)) self.log("QEMU running (pid {})".format(self.pid))
def shutdown(self): def shutdown(self):
if self.booted: if not self.booted:
return return
self.shell.send("poweroff\n".encode()) self.shell.send("poweroff\n".encode())
self.wait_for_shutdown() self.wait_for_shutdown()
def crash(self): def crash(self):
if self.booted: if not self.booted:
return return
self.log("forced crash") self.log("forced crash")
@ -642,9 +664,38 @@ class Machine:
if status == 0: if status == 0:
return 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): def sleep(self, secs):
time.sleep(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): def block(self):
"""Make the machine unreachable by shutting down eth1 (the multicast """Make the machine unreachable by shutting down eth1 (the multicast
interface used to talk to the other VMs). We keep eth0 up so that interface used to talk to the other VMs). We keep eth0 up so that

View File

@ -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 ];
};
}

View File

@ -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;
};
}

View File

@ -90,6 +90,11 @@ while [ "$#" -gt 0 ]; do
targetHost="$1" targetHost="$1"
shift 1 shift 1
;; ;;
--use-remote-sudo)
# note the trailing space
maybeSudo="sudo "
shift 1
;;
*) *)
echo "$0: unknown option \`$i'" echo "$0: unknown option \`$i'"
exit 1 exit 1
@ -97,10 +102,6 @@ while [ "$#" -gt 0 ]; do
esac esac
done done
if [ -n "$SUDO_USER" ]; then
maybeSudo="sudo "
fi
if [ -z "$buildHost" -a -n "$targetHost" ]; then if [ -z "$buildHost" -a -n "$targetHost" ]; then
buildHost="$targetHost" buildHost="$targetHost"
fi fi

View File

@ -1,9 +1,7 @@
[ [
./config/debug-info.nix ./config/debug-info.nix
./config/fonts/corefonts.nix
./config/fonts/fontconfig.nix ./config/fonts/fontconfig.nix
./config/fonts/fontconfig-penultimate.nix ./config/fonts/fontconfig-penultimate.nix
./config/fonts/fontconfig-ultimate.nix
./config/fonts/fontdir.nix ./config/fonts/fontdir.nix
./config/fonts/fonts.nix ./config/fonts/fonts.nix
./config/fonts/ghostscript.nix ./config/fonts/ghostscript.nix

View File

@ -251,7 +251,7 @@ in
ExecStart = ExecStart =
"${cfg.package}/bin/ssh-agent " + "${cfg.package}/bin/ssh-agent " +
optionalString (cfg.agentTimeout != null) ("-t ${cfg.agentTimeout} ") + 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"; "-a %t/ssh-agent";
StandardOutput = "null"; StandardOutput = "null";
Type = "forking"; Type = "forking";

View File

@ -81,7 +81,7 @@ in
]; ];
programs.zsh.interactiveShellInit = with pkgs; 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" "source ${zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
] ++ optional (length(cfg.highlighters) > 0) ] ++ optional (length(cfg.highlighters) > 0)
"ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})" "ZSH_HIGHLIGHT_HIGHLIGHTERS=(${concatStringsSep " " cfg.highlighters})"
@ -95,6 +95,6 @@ in
styles: design: styles: design:
"ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'" "ZSH_HIGHLIGHT_STYLES[${styles}]='${design}'"
) cfg.styles) ) cfg.styles)
); ));
}; };
} }

View File

@ -234,6 +234,7 @@ with lib;
(mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.") (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 [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.")
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.") (mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
(mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
# ZSH # ZSH
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
@ -291,5 +292,14 @@ with lib;
(opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] '' (opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] ''
The prometheus exporters are now configured using `services.prometheus.exporters'. The prometheus exporters are now configured using `services.prometheus.exporters'.
See the 18.03 release notes for more information. 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.
'' )); '' ));
} }

View File

@ -185,10 +185,10 @@ in
###### implementation ###### implementation
config = mkIf config.services.redis.enable { config = mkIf config.services.redis.enable {
boot.kernel.sysctl = (mkMerge [
boot.kernel.sysctl = { { "vm.nr_hugepages" = "0"; }
"vm.nr_hugepages" = "0"; ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } )
} // mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; }; ]);
networking.firewall = mkIf cfg.openFirewall { networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.port ]; allowedTCPPorts = [ cfg.port ];

View File

@ -62,20 +62,11 @@ in
services.redmine = { services.redmine = {
enable = mkEnableOption "Redmine"; enable = mkEnableOption "Redmine";
# default to the 4.x series not forcing major version upgrade of those on the 3.x series
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = if versionAtLeast config.system.stateVersion "19.03" default = pkgs.redmine;
then pkgs.redmine_4 description = "Which Redmine package to use.";
else pkgs.redmine example = "pkgs.redmine.override { ruby = pkgs.ruby_2_4; }";
;
defaultText = "pkgs.redmine";
description = ''
Which Redmine package to use. This defaults to version 3.x if
<literal>system.stateVersion &lt; 19.03</literal> and version 4.x
otherwise.
'';
example = "pkgs.redmine_4.override { ruby = pkgs.ruby_2_4; }";
}; };
user = mkOption { user = mkOption {

View File

@ -265,7 +265,7 @@ in {
} }
location /cache/ { location /cache/ {
alias /var/cache/${dirName}; alias /var/cache/${dirName}/;
} }
location ~ \.php$ { location ~ \.php$ {

View File

@ -46,11 +46,10 @@ in {
RestartSec="1"; RestartSec="1";
DynamicUser = true; DynamicUser = true;
StartLimitInterval="0"; StartLimitInterval="0";
PrivateTmp=true;
PrivateDevices=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}"; ExecStart = "${pkgs.dnsdist}/bin/dnsdist --supervised --disable-syslog --config ${configFile}";
ProtectSystem="full";
ProtectHome=true; ProtectHome=true;
RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6"; RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6";
LimitNOFILE="16384"; LimitNOFILE="16384";

View File

@ -456,15 +456,19 @@ in {
}; };
# Turn off NixOS' network management when networking is managed entirely by NetworkManager # Turn off NixOS' network management when networking is managed entirely by NetworkManager
networking = (mkIf (!delegateWireless) { networking = mkMerge [
useDHCP = false; (mkIf (!delegateWireless) {
# Use mkDefault to trigger the assertion about the conflict above useDHCP = false;
wireless.enable = mkDefault false; })
}) // (mkIf cfg.enableStrongSwan {
networkmanager.packages = [ pkgs.networkmanager_strongswan ]; (mkIf cfg.enableStrongSwan {
}) // (mkIf enableIwd { networkmanager.packages = [ pkgs.networkmanager_strongswan ];
wireless.iwd.enable = true; })
});
(mkIf enableIwd {
wireless.iwd.enable = true;
})
];
security.polkit.extraConfig = polkitConf; security.polkit.extraConfig = polkitConf;

View File

@ -6,6 +6,8 @@ let
mainCfg = config.services.httpd; mainCfg = config.services.httpd;
runtimeDir = "/run/httpd";
httpd = mainCfg.package.out; httpd = mainCfg.package.out;
httpdConf = mainCfg.configFile; httpdConf = mainCfg.configFile;
@ -27,41 +29,29 @@ let
listenToString = l: "${l.ip}:${toString l.port}"; listenToString = l: "${l.ip}:${toString l.port}";
extraModules = attrByPath ["extraModules"] [] mainCfg;
extraForeignModules = filter isAttrs extraModules;
extraApacheModules = filter isString extraModules;
allHosts = [mainCfg] ++ mainCfg.virtualHosts; allHosts = [mainCfg] ++ mainCfg.virtualHosts;
enableSSL = any (vhost: vhost.enableSSL) allHosts; enableSSL = any (vhost: vhost.enableSSL) allHosts;
enableUserDir = any (vhost: vhost.enableUserDir) allHosts;
# Names of modules from ${httpd}/modules that we want to load. # NOTE: generally speaking order of modules is very important
apacheModules = modules =
[ # HTTP authentication mechanisms: basic and digest. [ # required apache modules our httpd service cannot run without
"auth_basic" "auth_digest" "authn_core" "authz_core"
"log_config"
# Authentication: is the user who he claims to be? "mime" "autoindex" "negotiation" "dir"
"authn_file" "authn_dbm" "authn_anon" "authn_core" "alias" "rewrite"
"unixd" "slotmem_shm" "socache_shmcb"
# 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"
"mpm_${mainCfg.multiProcessingModule}" "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" ]) ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
++ optional enableSSL "ssl" ++ 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"; allDenied = "Require all denied";
@ -85,20 +75,22 @@ let
browserHacks = '' browserHacks = ''
BrowserMatch "Mozilla/2" nokeepalive <IfModule mod_setenvif.c>
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "JDK/1\.0" force-response-1.0
BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully
BrowserMatch "^gnome-vfs" redirect-carefully BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully
BrowserMatch "^gnome-vfs" redirect-carefully
</IfModule>
''; '';
sslConf = '' sslConf = ''
SSLSessionCache shmcb:${mainCfg.stateDir}/ssl_scache(512000) SSLSessionCache shmcb:${runtimeDir}/ssl_scache(512000)
Mutex posixsem Mutex posixsem
@ -239,13 +231,13 @@ let
ServerRoot ${httpd} ServerRoot ${httpd}
DefaultRuntimeDir ${mainCfg.stateDir}/runtime DefaultRuntimeDir ${runtimeDir}/runtime
PidFile ${mainCfg.stateDir}/httpd.pid PidFile ${runtimeDir}/httpd.pid
${optionalString (mainCfg.multiProcessingModule != "prefork") '' ${optionalString (mainCfg.multiProcessingModule != "prefork") ''
# mod_cgid requires this. # mod_cgid requires this.
ScriptSock ${mainCfg.stateDir}/cgisock ScriptSock ${runtimeDir}/cgisock
''} ''}
<IfModule prefork.c> <IfModule prefork.c>
@ -264,13 +256,12 @@ let
Group ${mainCfg.group} Group ${mainCfg.group}
${let ${let
load = {name, path}: "LoadModule ${name}_module ${path}\n"; mkModule = module:
allModules = map (name: {inherit name; path = "${httpd}/modules/mod_${name}.so";}) apacheModules if isString module then { name = module; path = "${httpd}/modules/mod_${module}.so"; }
++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; } else if isAttrs module then { inherit (module) name path; }
++ optional mainCfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; } else throw "Expecting either a string or attribute set including a name and path.";
++ optional mainCfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; } in
++ extraForeignModules; concatMapStringsSep "\n" (module: "LoadModule ${module.name}_module ${module.path}") (unique (map mkModule modules))
in concatMapStrings load (unique allModules)
} }
AddHandler type-map var AddHandler type-map var
@ -337,6 +328,7 @@ in
imports = [ imports = [
(mkRemovedOptionModule [ "services" "httpd" "extraSubservices" ] "Most existing subservices have been ported to the NixOS module system. Please update your configuration accordingly.") (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 ###### interface
@ -384,7 +376,12 @@ in
extraModules = mkOption { extraModules = mkOption {
type = types.listOf types.unspecified; type = types.listOf types.unspecified;
default = []; 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 = '' description = ''
Additional Apache modules to be used. These can be Additional Apache modules to be used. These can be
specified as a string in the case of modules distributed 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 { virtualHosts = mkOption {
type = types.listOf (types.submodule ( type = types.listOf (types.submodule (
{ options = import ./per-server-options.nix { { options = import ./per-server-options.nix {
@ -595,6 +582,28 @@ in
date.timezone = "${config.time.timeZone}" 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 = systemd.services.httpd =
{ description = "Apache HTTPD"; { description = "Apache HTTPD";
@ -611,12 +620,6 @@ in
preStart = 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} mkdir -m 0700 -p ${mainCfg.logDir}
# Get rid of old semaphores. These tend to accumulate across # Get rid of old semaphores. These tend to accumulate across
@ -630,10 +633,13 @@ in
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}"; serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}";
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop"; serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
serviceConfig.ExecReload = "${httpd}/bin/httpd -f ${httpdConf} -k graceful"; serviceConfig.ExecReload = "${httpd}/bin/httpd -f ${httpdConf} -k graceful";
serviceConfig.Group = mainCfg.group;
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid"; serviceConfig.PIDFile = "${runtimeDir}/httpd.pid";
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.RestartSec = "5s"; serviceConfig.RestartSec = "5s";
serviceConfig.RuntimeDirectory = "httpd httpd/runtime";
serviceConfig.RuntimeDirectoryMode = "0750";
}; };
}; };

View File

@ -14,7 +14,7 @@ let
xserverWrapper = pkgs.writeScript "xserver-wrapper" '' xserverWrapper = pkgs.writeScript "xserver-wrapper" ''
#!/bin/sh #!/bin/sh
${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} ${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" '' Xsetup = pkgs.writeScript "Xsetup" ''

View File

@ -86,7 +86,7 @@ in
${xmonadBin} ${xmonadBin}
waitPID=$! waitPID=$!
'' else '' '' else ''
${xmonad}/bin/xmonad & systemd-cat -t xmonad ${xmonad}/bin/xmonad &
waitPID=$! waitPID=$!
''; '';
}]; }];

View File

@ -24,7 +24,7 @@ in rec {
in in
if isList (head defs'') if isList (head defs'')
then concatLists defs'' then concatLists defs''
else mergeOneOption loc defs'; else mergeEqualOption loc defs';
}; };
sharedOptions = { sharedOptions = {

View File

@ -48,7 +48,6 @@ in
clickhouse = handleTest ./clickhouse.nix {}; clickhouse = handleTest ./clickhouse.nix {};
cloud-init = handleTest ./cloud-init.nix {}; cloud-init = handleTest ./cloud-init.nix {};
codimd = handleTest ./codimd.nix {}; codimd = handleTest ./codimd.nix {};
colord = handleTest ./colord.nix {};
containers-bridge = handleTest ./containers-bridge.nix {}; containers-bridge = handleTest ./containers-bridge.nix {};
containers-ephemeral = handleTest ./containers-ephemeral.nix {}; containers-ephemeral = handleTest ./containers-ephemeral.nix {};
containers-extra_veth = handleTest ./containers-extra_veth.nix {}; containers-extra_veth = handleTest ./containers-extra_veth.nix {};
@ -88,27 +87,20 @@ in
firewall = handleTest ./firewall.nix {}; firewall = handleTest ./firewall.nix {};
fish = handleTest ./fish.nix {}; fish = handleTest ./fish.nix {};
flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {}; flannel = handleTestOn ["x86_64-linux"] ./flannel.nix {};
flatpak = handleTest ./flatpak.nix {};
flatpak-builder = handleTest ./flatpak-builder.nix {};
fluentd = handleTest ./fluentd.nix {}; fluentd = handleTest ./fluentd.nix {};
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {}; fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {};
fsck = handleTest ./fsck.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 {}; gotify-server = handleTest ./gotify-server.nix {};
gitea = handleTest ./gitea.nix {}; gitea = handleTest ./gitea.nix {};
gitlab = handleTest ./gitlab.nix {}; gitlab = handleTest ./gitlab.nix {};
gitolite = handleTest ./gitolite.nix {}; gitolite = handleTest ./gitolite.nix {};
gjs = handleTest ./gjs.nix {};
glib-networking = handleTest ./glib-networking.nix {};
glusterfs = handleTest ./glusterfs.nix {}; glusterfs = handleTest ./glusterfs.nix {};
gnome3-xorg = handleTest ./gnome3-xorg.nix {}; gnome3-xorg = handleTest ./gnome3-xorg.nix {};
gnome3 = handleTest ./gnome3.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-agent = handleTest ./gocd-agent.nix {};
gocd-server = handleTest ./gocd-server.nix {}; gocd-server = handleTest ./gocd-server.nix {};
google-oslogin = handleTest ./google-oslogin {}; google-oslogin = handleTest ./google-oslogin {};
graphene = handleTest ./graphene.nix {};
grafana = handleTest ./grafana.nix {}; grafana = handleTest ./grafana.nix {};
graphite = handleTest ./graphite.nix {}; graphite = handleTest ./graphite.nix {};
graylog = handleTest ./graylog.nix {}; graylog = handleTest ./graylog.nix {};
@ -149,8 +141,6 @@ in
latestKernel.login = handleTest ./login.nix { latestKernel = true; }; latestKernel.login = handleTest ./login.nix { latestKernel = true; };
ldap = handleTest ./ldap.nix {}; ldap = handleTest ./ldap.nix {};
leaps = handleTest ./leaps.nix {}; leaps = handleTest ./leaps.nix {};
libgdata = handleTest ./libgdata.nix {};
libxmlb = handleTest ./libxmlb.nix {};
lidarr = handleTest ./lidarr.nix {}; lidarr = handleTest ./lidarr.nix {};
lightdm = handleTest ./lightdm.nix {}; lightdm = handleTest ./lightdm.nix {};
limesurvey = handleTest ./limesurvey.nix {}; limesurvey = handleTest ./limesurvey.nix {};
@ -216,7 +206,6 @@ in
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {}; os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
osquery = handleTest ./osquery.nix {}; osquery = handleTest ./osquery.nix {};
osrm-backend = handleTest ./osrm-backend.nix {}; osrm-backend = handleTest ./osrm-backend.nix {};
ostree = handleTest ./ostree.nix {};
overlayfs = handleTest ./overlayfs.nix {}; overlayfs = handleTest ./overlayfs.nix {};
packagekit = handleTest ./packagekit.nix {}; packagekit = handleTest ./packagekit.nix {};
pam-oath-login = handleTest ./pam-oath-login.nix {}; pam-oath-login = handleTest ./pam-oath-login.nix {};
@ -255,6 +244,7 @@ in
rxe = handleTest ./rxe.nix {}; rxe = handleTest ./rxe.nix {};
samba = handleTest ./samba.nix {}; samba = handleTest ./samba.nix {};
sddm = handleTest ./sddm.nix {}; sddm = handleTest ./sddm.nix {};
shiori = handleTest ./shiori.nix {};
signal-desktop = handleTest ./signal-desktop.nix {}; signal-desktop = handleTest ./signal-desktop.nix {};
simple = handleTest ./simple.nix {}; simple = handleTest ./simple.nix {};
slim = handleTest ./slim.nix {}; slim = handleTest ./slim.nix {};
@ -291,7 +281,6 @@ in
wireguard-generated = handleTest ./wireguard/generated.nix {}; wireguard-generated = handleTest ./wireguard/generated.nix {};
wordpress = handleTest ./wordpress.nix {}; wordpress = handleTest ./wordpress.nix {};
xautolock = handleTest ./xautolock.nix {}; xautolock = handleTest ./xautolock.nix {};
xdg-desktop-portal = handleTest ./xdg-desktop-portal.nix {};
xfce = handleTest ./xfce.nix {}; xfce = handleTest ./xfce.nix {};
xfce4-14 = handleTest ./xfce4-14.nix {}; xfce4-14 = handleTest ./xfce4-14.nix {};
xmonad = handleTest ./xmonad.nix {}; xmonad = handleTest ./xmonad.nix {};

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "caddy"; name = "caddy";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ xfix ]; maintainers = [ xfix ];
@ -50,33 +50,38 @@ import ./make-test.nix ({ pkgs, ... }: {
etagSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-1"; etagSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-1";
justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-2"; justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/fine-tune/child-2";
in '' in ''
my $url = 'http://localhost/example.html'; url = "http://localhost/example.html"
$webserver->waitForUnit("caddy"); webserver.wait_for_unit("caddy")
$webserver->waitForOpenPort("80"); 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 { def check_etag(url):
my $oldEtag = checkEtag; etag = webserver.succeed(
$webserver->succeed("${etagSystem}/bin/switch-to-configuration test >&2"); "curl -v '{}' 2>&1 | sed -n -e \"s/^< [Ee][Tt][Aa][Gg]: *//p\"".format(url)
$webserver->sleep(1); # race condition )
my $newEtag = checkEtag; etag = etag.replace("\r\n", " ")
die "Old ETag $oldEtag is the same as $newEtag" if $oldEtag eq $newEtag; 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"); with subtest("check ETag if serving Nix store paths"):
$webserver->waitForOpenPort("8080"); 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")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... } : { import ./make-test-python.nix ({ pkgs, ... } : {
name = "cadvisor"; name = "cadvisor";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ offline ]; maintainers = [ offline ];
@ -16,20 +16,19 @@ import ./make-test.nix ({ pkgs, ... } : {
}; };
}; };
testScript = testScript = ''
'' start_all()
startAll; machine.wait_for_unit("cadvisor.service")
$machine->waitForUnit("cadvisor.service"); machine.succeed("curl http://localhost:8080/containers/")
$machine->succeed("curl http://localhost:8080/containers/");
$influxdb->waitForUnit("influxdb.service"); influxdb.wait_for_unit("influxdb.service")
# create influxdb database # create influxdb database
$influxdb->succeed(q~ influxdb.succeed(
curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE root" 'curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE root"'
~); )
$influxdb->waitForUnit("cadvisor.service"); influxdb.wait_for_unit("cadvisor.service")
$influxdb->succeed("curl http://localhost:8080/containers/"); influxdb.succeed("curl http://localhost:8080/containers/")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: import ./make-test-python.nix ({ pkgs, lib, ... }:
let let
# Change this to test a different version of Cassandra: # Change this to test a different version of Cassandra:
testPackage = pkgs.cassandra; testPackage = pkgs.cassandra;
@ -9,13 +9,16 @@ let
jmxRolesFile = ./cassandra-jmx-roles; jmxRolesFile = ./cassandra-jmx-roles;
jmxAuthArgs = "-u ${(builtins.elemAt jmxRoles 0).username} -pw ${(builtins.elemAt jmxRoles 0).password}"; jmxAuthArgs = "-u ${(builtins.elemAt jmxRoles 0).username} -pw ${(builtins.elemAt jmxRoles 0).password}";
jmxPort = 7200; # Non-standard port so it doesn't accidentally work 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"; numMaxHeapSize = "400";
getHeapLimitCommand = '' 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)" ] [ 1 -eq "$(echo "$(${getHeapLimitCommand}) < ${numMaxHeapSize}" | ${pkgs.bc}/bin/bc)" ]
''; '';
@ -44,7 +47,10 @@ let
}; };
in in
{ {
name = "cassandra-ci"; name = "cassandra";
meta = {
maintainers = with lib.maintainers; [ johnazoidberg ];
};
nodes = { nodes = {
cass0 = nodeCfg "192.168.1.1" {}; cass0 = nodeCfg "192.168.1.1" {};
@ -52,66 +58,74 @@ in
cass2 = nodeCfg "192.168.1.3" { jvmOpts = [ "-Dcassandra.replace_address=cass1" ]; }; cass2 = nodeCfg "192.168.1.3" { jvmOpts = [ "-Dcassandra.replace_address=cass1" ]; };
}; };
testScript = let testScript = ''
jmxPortS = toString jmxPort;
in ''
# Check configuration # Check configuration
subtest "Timers exist", sub { with subtest("Timers exist"):
$cass0->succeed("systemctl list-timers | grep cassandra-full-repair.timer"); cass0.succeed("systemctl list-timers | grep cassandra-full-repair.timer")
$cass0->succeed("systemctl list-timers | grep cassandra-incremental-repair.timer"); cass0.succeed("systemctl list-timers | grep cassandra-incremental-repair.timer")
};
subtest "Can connect via cqlsh", sub { with subtest("Can connect via cqlsh"):
$cass0->waitForUnit("cassandra.service"); cass0.wait_for_unit("cassandra.service")
$cass0->waitUntilSucceeds("nc -z cass0 9042"); cass0.wait_until_succeeds("nc -z cass0 9042")
$cass0->succeed("echo 'show version;' | cqlsh cass0"); cass0.succeed("echo 'show version;' | cqlsh cass0")
};
subtest "Nodetool is operational", sub { with subtest("Nodetool is operational"):
$cass0->waitForUnit("cassandra.service"); cass0.wait_for_unit("cassandra.service")
$cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}")
$cass0->succeed("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass0'"); cass0.succeed("nodetool status -p ${jmxPortStr} --resolve-ip | egrep '^UN[[:space:]]+cass0'")
};
subtest "Cluster name was set", sub { with subtest("Cluster name was set"):
$cass0->waitForUnit("cassandra.service"); cass0.wait_for_unit("cassandra.service")
$cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}")
$cass0->waitUntilSucceeds("nodetool describecluster -p ${jmxPortS} | grep 'Name: ${clusterName}'"); cass0.wait_until_succeeds(
}; "nodetool describecluster -p ${jmxPortStr} | grep 'Name: ${clusterName}'"
subtest "Heap limit set correctly", sub { )
# Nodetool takes a while until it can display info
$cass0->waitUntilSucceeds('nodetool info -p ${jmxPortS}'); with subtest("Heap limit set correctly"):
$cass0->succeed('${checkHeapLimitCommand}'); # Nodetool takes a while until it can display info
}; cass0.wait_until_succeeds("nodetool info -p ${jmxPortStr}")
cass0.succeed("${checkHeapLimitCommand}")
# Check cluster interaction # Check cluster interaction
subtest "Bring up cluster", sub { with subtest("Bring up cluster"):
$cass1->waitForUnit("cassandra.service"); cass1.wait_for_unit("cassandra.service")
$cass1->waitUntilSucceeds("nodetool -p ${jmxPortS} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2"); cass1.wait_until_succeeds(
$cass0->succeed("nodetool status -p ${jmxPortS} --resolve-ip | egrep '^UN[[:space:]]+cass1'"); "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 '' '' + lib.optionalString testRemoteAuth ''
subtest "Remote authenticated jmx", sub { with subtest("Remote authenticated jmx"):
# Doesn't work if not enabled # Doesn't work if not enabled
$cass0->waitUntilSucceeds("nc -z localhost ${jmxPortS}"); cass0.wait_until_succeeds("nc -z localhost ${jmxPortStr}")
$cass1->fail("nc -z 192.168.1.1 ${toString jmxPort}"); cass1.fail("nc -z 192.168.1.1 ${jmxPortStr}")
$cass1->fail("nodetool -p ${jmxPortS} -h 192.168.1.1 status"); cass1.fail("nodetool -p ${jmxPortStr} -h 192.168.1.1 status")
# Works if enabled # Works if enabled
$cass1->waitUntilSucceeds("nc -z localhost ${toString jmxPort}"); cass1.wait_until_succeeds("nc -z localhost ${jmxPortStr}")
$cass0->succeed("nodetool -p ${jmxPortS} -h 192.168.1.2 ${jmxAuthArgs} status"); cass0.succeed("nodetool -p ${jmxPortStr} -h 192.168.1.2 ${jmxAuthArgs} status")
};
'' + '' '' + ''
subtest "Break and fix node", sub { with subtest("Break and fix node"):
$cass1->block; cass1.block()
$cass0->waitUntilSucceeds("nodetool status -p ${jmxPortS} --resolve-ip | egrep -c '^DN[[:space:]]+cass1'"); cass0.wait_until_succeeds(
$cass0->succeed("nodetool status -p ${jmxPortS} | egrep -c '^UN' | grep 1"); "nodetool status -p ${jmxPortStr} --resolve-ip | egrep -c '^DN[[:space:]]+cass1'"
$cass1->unblock; )
$cass1->waitUntilSucceeds("nodetool -p ${jmxPortS} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2"); cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 1")
$cass0->succeed("nodetool status -p ${jmxPortS} | egrep -c '^UN' | grep 2"); cass1.unblock()
}; cass1.wait_until_succeeds(
subtest "Replace crashed node", sub { "nodetool -p ${jmxPortStr} ${jmxAuthArgs} status | egrep -c '^UN' | grep 2"
$cass1->crash; )
$cass2->waitForUnit("cassandra.service"); cass0.succeed("nodetool status -p ${jmxPortStr} | egrep -c '^UN' | grep 2")
$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("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'"
)
''; '';
}) })

View File

@ -3,7 +3,7 @@
pkgs ? import ../.. { inherit system config; } pkgs ? import ../.. { inherit system config; }
}: }:
with import ../lib/testing.nix { inherit system pkgs; }; with import ../lib/testing-python.nix { inherit system pkgs; };
let let
mkSpec = { host, service ? null, action }: { mkSpec = { host, service ? null, action }: {
inherit action; inherit action;
@ -123,17 +123,17 @@ in
))); )));
}; };
testScript = '' testScript = ''
$machine->waitForUnit('cfssl.service'); machine.wait_for_unit("cfssl.service")
$machine->waitUntilSucceeds('ls /tmp/decl.example.org-ca.pem'); machine.wait_until_succeeds("ls /tmp/decl.example.org-ca.pem")
$machine->waitUntilSucceeds('ls /tmp/decl.example.org-key.pem'); machine.wait_until_succeeds("ls /tmp/decl.example.org-key.pem")
$machine->waitUntilSucceeds('ls /tmp/decl.example.org-cert.pem'); machine.wait_until_succeeds("ls /tmp/decl.example.org-cert.pem")
$machine->waitUntilSucceeds('ls /tmp/imp.example.org-ca.pem'); machine.wait_until_succeeds("ls /tmp/imp.example.org-ca.pem")
$machine->waitUntilSucceeds('ls /tmp/imp.example.org-key.pem'); machine.wait_until_succeeds("ls /tmp/imp.example.org-key.pem")
$machine->waitUntilSucceeds('ls /tmp/imp.example.org-cert.pem'); machine.wait_until_succeeds("ls /tmp/imp.example.org-cert.pem")
$machine->waitForUnit('nginx.service'); machine.wait_for_unit("nginx.service")
$machine->succeed('[ "1" -lt "$(journalctl -u nginx | grep "Starting Nginx" | wc -l)" ]'); 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/imp.example.org-ca.pem https://imp.example.org")
$machine->succeed('curl --cacert /tmp/decl.example.org-ca.pem https://decl.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"; }; test = mkSpec { host = "command.example.org"; action = "touch /tmp/command.executed"; };
}; };
testScript = '' testScript = ''
$machine->waitForUnit('cfssl.service'); machine.wait_for_unit("cfssl.service")
$machine->waitUntilSucceeds('stat /tmp/command.executed'); machine.wait_until_succeeds("stat /tmp/command.executed")
''; '';
}; };

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "cfssl"; name = "cfssl";
machine = { config, lib, pkgs, ... }: machine = { config, lib, pkgs, ... }:
@ -60,8 +60,8 @@ import ./make-test.nix ({ pkgs, ...} : {
}); });
in in
'' ''
$machine->waitForUnit('cfssl.service'); machine.wait_for_unit("cfssl.service")
$machine->waitUntilSucceeds('${cfsslrequest}'); machine.wait_until_succeeds("${cfsslrequest}")
$machine->succeed('ls /tmp/certificate-key.pem'); machine.succeed("ls /tmp/certificate-key.pem")
''; '';
}) })

View File

@ -17,7 +17,7 @@ let
in in
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "cjdns"; name = "cjdns";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ehmry ]; maintainers = [ ehmry ];
@ -83,36 +83,39 @@ import ./make-test.nix ({ pkgs, ...} : {
testScript = testScript =
'' ''
startAll; import re
$alice->waitForUnit("cjdns.service"); start_all()
$bob->waitForUnit("cjdns.service");
$carol->waitForUnit("cjdns.service");
sub cjdnsIp { alice.wait_for_unit("cjdns.service")
my ($machine) = @_; bob.wait_for_unit("cjdns.service")
my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev tun0"))[3]; carol.wait_for_unit("cjdns.service")
$machine->log("has ip $ip");
return $ip;
}
my $aliceIp6 = cjdnsIp $alice;
my $bobIp6 = cjdnsIp $bob; def cjdns_ip(machine):
my $carolIp6 = cjdnsIp $carol; 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 # ping a few times each to let the routing table establish itself
$alice->succeed("ping -c 4 $carolIp6"); alice.succeed("ping -c 4 {}".format(carol_ip6))
$bob->succeed("ping -c 4 $carolIp6"); bob.succeed("ping -c 4 {}".format(carol_ip6))
$carol->succeed("ping -c 4 $aliceIp6"); carol.succeed("ping -c 4 {}".format(alice_ip6))
$carol->succeed("ping -c 4 $bobIp6"); carol.succeed("ping -c 4 {}".format(bob_ip6))
$alice->succeed("ping -c 4 $bobIp6"); alice.succeed("ping -c 4 {}".format(bob_ip6))
$bob->succeed("ping -c 4 $aliceIp6"); 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))
''; '';
}) })

View File

@ -3,7 +3,7 @@
pkgs ? import ../.. { inherit system config; } 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; with pkgs.lib;
let let
@ -30,6 +30,7 @@ let
''; '';
}; };
in makeTest { in makeTest {
name = "cloud-init";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ lewo ]; maintainers = [ lewo ];
}; };
@ -40,10 +41,12 @@ in makeTest {
services.cloud-init.enable = true; services.cloud-init.enable = true;
}; };
testScript = '' testScript = ''
$machine->start; machine.start()
$machine->waitForUnit("cloud-init.service"); machine.wait_for_unit("cloud-init.service")
$machine->succeed("cat /tmp/cloudinit-write-file | grep -q 'cloudinit'"); 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!'"
)
''; '';
} }

View File

@ -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'");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ...}: import ./make-test-python.nix ({ pkgs, lib, ...}:
with lib; with lib;
@ -35,22 +35,42 @@ with lib;
fi fi
''; '';
in '' in ''
startAll; start_all()
$couchdb1->waitForUnit("couchdb.service"); couchdb1.wait_for_unit("couchdb.service")
$couchdb1->waitUntilSucceeds("${curlJqCheck "GET" "" ".couchdb" "Welcome"}"); couchdb1.wait_until_succeeds(
$couchdb1->waitUntilSucceeds("${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"); "${curlJqCheck "GET" "" ".couchdb" "Welcome"}"
$couchdb1->succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}"); )
$couchdb1->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "3"}"); couchdb1.wait_until_succeeds(
$couchdb1->succeed("${curlJqCheck "DELETE" "foo" ".ok" "true"}"); "${curlJqCheck "GET" "_all_dbs" ". | length" "2"}"
$couchdb1->succeed("${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.wait_for_unit("couchdb.service")
$couchdb2->waitUntilSucceeds("${curlJqCheck "GET" "" ".couchdb" "Welcome"}"); couchdb2.wait_until_succeeds(
$couchdb2->waitUntilSucceeds("${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"); "${curlJqCheck "GET" "" ".couchdb" "Welcome"}"
$couchdb2->succeed("${curlJqCheck "PUT" "foo" ".ok" "true"}"); )
$couchdb2->succeed("${curlJqCheck "GET" "_all_dbs" ". | length" "1"}"); couchdb2.wait_until_succeeds(
$couchdb2->succeed("${curlJqCheck "DELETE" "foo" ".ok" "true"}"); "${curlJqCheck "GET" "_all_dbs" ". | length" "0"}"
$couchdb2->succeed("${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"}"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "dnscrypt-proxy"; name = "dnscrypt-proxy";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ joachifm ]; maintainers = [ joachifm ];
@ -23,11 +23,13 @@ import ./make-test.nix ({ pkgs, ... }: {
}; };
testScript = '' testScript = ''
$client->waitForUnit("dnsmasq"); client.wait_for_unit("dnsmasq")
# The daemon is socket activated; sending a single ping should activate it. # The daemon is socket activated; sending a single ping should activate it.
$client->fail("systemctl is-active dnscrypt-proxy"); client.fail("systemctl is-active dnscrypt-proxy")
$client->execute("${pkgs.iputils}/bin/ping -c1 example.com"); client.execute(
$client->waitUntilSucceeds("systemctl is-active dnscrypt-proxy"); "${pkgs.iputils}/bin/ping -c1 example.com"
)
client.wait_until_succeeds("systemctl is-active dnscrypt-proxy")
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs docker and checks if simple container starts # This test runs docker and checks if simple container starts
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "docker"; name = "docker";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ nequissimus offline ]; maintainers = [ nequissimus offline ];
@ -31,17 +31,19 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$docker->waitForUnit("sockets.target"); docker.wait_for_unit("sockets.target")
$docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); 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->succeed("docker ps | grep sleeping"); "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
$docker->succeed("sudo -u hasprivs docker ps"); )
$docker->fail("sudo -u noprivs docker ps"); docker.succeed("docker ps | grep sleeping")
$docker->succeed("docker stop 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 # 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" ]')
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs docker and checks if simple container starts # This test runs docker and checks if simple container starts
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "docker"; name = "docker";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ nequissimus offline ]; maintainers = [ nequissimus offline ];
@ -31,17 +31,19 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$docker->waitForUnit("sockets.target"); docker.wait_for_unit("sockets.target")
$docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); 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->succeed("docker ps | grep sleeping"); "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
$docker->succeed("sudo -u hasprivs docker ps"); )
$docker->fail("sudo -u noprivs docker ps"); docker.succeed("docker ps | grep sleeping")
$docker->succeed("docker stop 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 # 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" ]')
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ...} : { import ./make-test-python.nix ({ pkgs, lib, ...} : {
name = "documize"; name = "documize";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 ]; maintainers = [ ma27 ];
@ -29,30 +29,34 @@ import ./make-test.nix ({ pkgs, lib, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$machine->waitForUnit("documize-server.service"); machine.wait_for_unit("documize-server.service")
$machine->waitForOpenPort(3000); machine.wait_for_open_port(3000)
my $dbhash = $machine->succeed("curl -f localhost:3000 " dbhash = machine.succeed(
. " | grep 'property=\"dbhash' " "curl -f localhost:3000 | grep 'property=\"dbhash' | grep -Po 'content=\"\\K[^\"]*'"
. " | grep -Po 'content=\"\\K[^\"]*'" )
);
chomp($dbhash); dbhash = dbhash.strip()
$machine->succeed("curl -X POST " machine.succeed(
. "--data 'dbname=documize' " (
. "--data 'dbhash=$dbhash' " "curl -X POST"
. "--data 'title=NixOS' " " --data 'dbname=documize'"
. "--data 'message=Docs' " " --data 'dbhash={}'"
. "--data 'firstname=John' " " --data 'title=NixOS'"
. "--data 'lastname=Doe' " " --data 'message=Docs'"
. "--data 'email=john.doe\@nixos.org' " " --data 'firstname=John'"
. "--data 'password=verysafe' " " --data 'lastname=Doe'"
. "-f localhost:3000/api/setup" " --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"'); machine.succeed(
'test "$(curl -f localhost:3000/api/public/meta | jq ".title" | xargs echo)" = "NixOS"'
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "firefox"; name = "firefox";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ eelco shlevy ]; maintainers = [ eelco shlevy ];
@ -11,19 +11,27 @@ import ./make-test.nix ({ pkgs, ... }: {
environment.systemPackages = [ pkgs.firefox pkgs.xdotool ]; environment.systemPackages = [ pkgs.firefox pkgs.xdotool ];
}; };
testScript = testScript = ''
'' machine.wait_for_x()
$machine->waitForX;
$machine->execute("xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' &"); with subtest("wait until Firefox has finished loading the Valgrind docs page"):
$machine->waitForWindow(qr/Valgrind/); machine.execute(
$machine->sleep(40); # wait until Firefox has finished loading the page "xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' &"
$machine->execute("xdotool key space"); # do I want to make Firefox the )
# default browser? I just want to close the dialog machine.wait_for_window("Valgrind")
$machine->sleep(2); # wait until Firefox hides the default browser window machine.sleep(40)
$machine->execute("xdotool key F12");
$machine->sleep(10); # wait until Firefox draws the developer tool panel with subtest("Close default browser prompt"):
$machine->succeed("xwininfo -root -tree | grep Valgrind"); machine.execute("xdotool key space")
$machine->screenshot("screen");
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")
''; '';
}) })

View File

@ -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");
'';
})

View File

@ -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");
'';
})

View File

@ -1,7 +1,12 @@
import ./make-test.nix ({ lib, ... }: import ./make-test-python.nix ({ lib, ... }:
{ {
name = "fontconfig-default-fonts"; name = "fontconfig-default-fonts";
meta.maintainers = with lib.maintainers; [
jtojnar
worldofpeace
];
machine = { config, pkgs, ... }: { machine = { config, pkgs, ... }: {
fonts.enableDefaultFonts = true; # Background fonts fonts.enableDefaultFonts = true; # Background fonts
fonts.fonts = with pkgs; [ fonts.fonts = with pkgs; [
@ -20,9 +25,9 @@ import ./make-test.nix ({ lib, ... }:
}; };
testScript = '' testScript = ''
$machine->succeed("fc-match serif | grep '\"Gentium Plus\"'"); machine.succeed("fc-match serif | grep '\"Gentium Plus\"'")
$machine->succeed("fc-match sans-serif | grep '\"Cantarell\"'"); machine.succeed("fc-match sans-serif | grep '\"Cantarell\"'")
$machine->succeed("fc-match monospace | grep '\"Source Code Pro\"'"); machine.succeed("fc-match monospace | grep '\"Source Code Pro\"'")
$machine->succeed("fc-match emoji | grep '\"Twitter Color Emoji\"'"); machine.succeed("fc-match emoji | grep '\"Twitter Color Emoji\"'")
''; '';
}) })

View File

@ -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");
'';
})

View File

@ -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
'';
})

View File

@ -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");
'';
})

View File

@ -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'");
'';
})

View File

@ -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");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, pkgs, ... }: import ./make-test-python.nix ({ lib, pkgs, ... }:
let let
inherit (lib) mkMerge nameValuePair maintainers; inherit (lib) mkMerge nameValuePair maintainers;
@ -64,28 +64,34 @@ in {
inherit nodes; inherit nodes;
testScript = '' testScript = ''
startAll(); start_all()
subtest "Grafana sqlite", sub { with subtest("Successful API query as admin user with sqlite db"):
$sqlite->waitForUnit("grafana.service"); sqlite.wait_for_unit("grafana.service")
$sqlite->waitForOpenPort(3000); 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.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 { with subtest("Successful API query as admin user with postgresql db"):
$postgresql->waitForUnit("grafana.service"); postgresql.wait_for_unit("grafana.service")
$postgresql->waitForUnit("postgresql.service"); postgresql.wait_for_unit("postgresql.service")
$postgresql->waitForOpenPort(3000); postgresql.wait_for_open_port(3000)
$postgresql->waitForOpenPort(5432); 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.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 { with subtest("Successful API query as admin user with mysql db"):
$mysql->waitForUnit("grafana.service"); mysql.wait_for_unit("grafana.service")
$mysql->waitForUnit("mysql.service"); mysql.wait_for_unit("mysql.service")
$mysql->waitForOpenPort(3000); mysql.wait_for_open_port(3000)
$mysql->waitForOpenPort(3306); 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.succeed(
}; "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep -q testadmin\@localhost"
)
mysql.shutdown()
''; '';
}) })

View File

@ -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'");
'';
})

View File

@ -1,4 +1,4 @@
import ../make-test.nix ({ lib, ... }: import ../make-test-python.nix ({ lib, ... }:
{ {
name = "initrd-network-ssh"; name = "initrd-network-ssh";
@ -35,25 +35,31 @@ import ../make-test.nix ({ lib, ... }:
client = client =
{ config, ... }: { config, ... }:
{ {
environment.etc.knownHosts = { environment.etc = {
text = concatStrings [ knownHosts = {
"server," text = concatStrings [
"${toString (head (splitString " " ( "server,"
toString (elemAt (splitString "\n" config.networking.extraHosts) 2) "${toString (head (splitString " " (
)))} " toString (elemAt (splitString "\n" config.networking.extraHosts) 2)
"${readFile ./dropbear.pub}" )))} "
]; "${readFile ./dropbear.pub}"
];
};
sshKey = {
source = ./openssh.priv; # dont use this anywhere else
mode = "0600";
};
}; };
}; };
}; };
testScript = '' testScript = ''
startAll; start_all()
$client->waitForUnit("network.target"); client.wait_for_unit("network.target")
$client->copyFileFromHost("${./openssh.priv}","/etc/sshKey"); client.wait_until_succeeds("ping -c 1 server")
$client->succeed("chmod 0600 /etc/sshKey"); client.succeed(
$client->waitUntilSucceeds("ping -c 1 server"); "ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'touch /fnord'"
$client->succeed("ssh -i /etc/sshKey -o UserKnownHostsFile=/etc/knownHosts server 'touch /fnord'"); )
$client->shutdown; client.shutdown()
''; '';
}) })

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.colord;
}

View File

@ -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 {};
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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;
};
}

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.gcab;
}

View File

@ -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";
}

View File

@ -0,0 +1,6 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.gjs;
withX11 = true;
}

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.glib-networking;
}

View File

@ -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"
)
'';
}

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.graphene;
}

View File

@ -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;
};
}

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.libxmlb;
}

View File

@ -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
]);
};
}

View File

@ -0,0 +1,5 @@
{ pkgs, makeInstalledTest, ... }:
makeInstalledTest {
tested = pkgs.xdg-desktop-portal;
}

View File

@ -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'");
'';
})

View File

@ -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'");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, pkgs, ... }: import ./make-test-python.nix ({ lib, pkgs, ... }:
{ {
name = "loki"; name = "loki";
@ -26,12 +26,14 @@ import ./make-test.nix ({ lib, pkgs, ... }:
}; };
testScript = '' testScript = ''
$machine->start; machine.start
$machine->waitForUnit("loki.service"); machine.wait_for_unit("loki.service")
$machine->waitForUnit("promtail.service"); machine.wait_for_unit("promtail.service")
$machine->waitForOpenPort(3100); machine.wait_for_open_port(3100)
$machine->waitForOpenPort(9080); machine.wait_for_open_port(9080)
$machine->succeed("echo 'Loki Ingestion Test' > /var/log/testlog"); 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.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'"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... } : let import ./make-test-python.nix ({ pkgs, ... } : let
runWithOpenSSL = file: cmd: pkgs.runCommand file { runWithOpenSSL = file: cmd: pkgs.runCommand file {
@ -55,13 +55,17 @@ in {
}; };
testScript = '' testScript = ''
startAll; start_all()
$serverpostgres->waitForUnit("matrix-synapse.service"); serverpostgres.wait_for_unit("matrix-synapse.service")
$serverpostgres->waitUntilSucceeds("curl -L --cacert ${ca_pem} https://localhost:8448/"); serverpostgres.wait_until_succeeds(
$serverpostgres->requireActiveUnit("postgresql.service"); "curl -L --cacert ${ca_pem} https://localhost:8448/"
$serversqlite->waitForUnit("matrix-synapse.service"); )
$serversqlite->waitUntilSucceeds("curl -L --cacert ${ca_pem} https://localhost:8448/"); serverpostgres.require_unit_state("postgresql.service")
$serversqlite->mustSucceed("[ -e /var/lib/matrix-synapse/homeserver.db ]"); 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 ]")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: { import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "moodle"; name = "moodle";
meta.maintainers = [ lib.maintainers.aanderse ]; meta.maintainers = [ lib.maintainers.aanderse ];
@ -15,8 +15,8 @@ import ./make-test.nix ({ pkgs, lib, ... }: {
}; };
testScript = '' testScript = ''
startAll; start_all()
$machine->waitForUnit('phpfpm-moodle.service'); machine.wait_for_unit("phpfpm-moodle.service")
$machine->succeed('curl http://localhost/') =~ /You are not logged in/ or die; machine.wait_until_succeeds("curl http://localhost/ | grep 'You are not logged in'")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: import ./make-test-python.nix ({ pkgs, ... }:
{ {
name = "morty"; name = "morty";
@ -22,11 +22,9 @@ import ./make-test.nix ({ pkgs, ... }:
testScript = testScript =
{ ... }: { ... }:
'' ''
$mortyProxyWithKey->waitForUnit("default.target"); mortyProxyWithKey.wait_for_unit("default.target")
mortyProxyWithKey.wait_for_open_port(3001)
$mortyProxyWithKey->waitForOpenPort(3001); mortyProxyWithKey.succeed("curl -L 127.0.0.1:3001 | grep MortyProxy")
$mortyProxyWithKey->succeed("curl -L 127.0.0.1:3001 | grep MortyProxy");
''; '';
}) })

View File

@ -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");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "packagekit"; name = "packagekit";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ peterhoeg ]; maintainers = [ peterhoeg ];
@ -13,12 +13,14 @@ import ./make-test.nix ({ pkgs, ... }: {
}; };
testScript = '' testScript = ''
startAll; start_all()
# send a dbus message to activate the service # 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 # so now it should be running
$machine->succeed("systemctl is-active packagekit.service"); machine.wait_for_unit("packagekit.service")
''; '';
}) })

View File

@ -1,12 +1,5 @@
import ./make-test.nix ({ pkgs, lib, ...}: import ./make-test-python.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
with pkgs; { with pkgs; {
name = "pgjwt"; name = "pgjwt";
meta = with lib.maintainers; { meta = with lib.maintainers; {
@ -29,9 +22,13 @@ with pkgs; {
pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}"; pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}";
in in
'' ''
startAll; start_all()
$master->waitForUnit("postgresql"); master.wait_for_unit("postgresql")
$master->copyFileFromHost("${test}","/tmp/test.sql"); master.succeed(
$master->succeed("${pkgs.sudo}/bin/sudo -u ${sqlSU} PGOPTIONS=--search_path=tap,public ${pgProve}/bin/pg_prove -d postgres -v -f /tmp/test.sql"); "${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"
)
''; '';
}) })

View File

@ -1,12 +1,13 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "powerdns"; name = "powerdns";
nodes.server = { ... }: { nodes.server = { ... }: {
services.powerdns.enable = true; services.powerdns.enable = true;
environment.systemPackages = [ pkgs.dnsutils ];
}; };
testScript = '' testScript = ''
$server->waitForUnit("pdns"); server.wait_for_unit("pdns")
$server->succeed("${pkgs.dnsutils}/bin/dig version.bind txt chaos \@127.0.0.1"); server.succeed("dig version.bind txt chaos \@127.0.0.1")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ( import ./make-test-python.nix (
let let
chap-secrets = { chap-secrets = {
text = ''"flynn" * "reindeerflotilla" *''; text = ''"flynn" * "reindeerflotilla" *'';
@ -55,8 +55,8 @@ import ./make-test.nix (
}; };
testScript = '' testScript = ''
startAll; start_all()
$client->waitUntilSucceeds("ping -c1 -W1 192.0.2.1"); client.wait_until_succeeds("ping -c1 -W1 192.0.2.1")
$server->waitUntilSucceeds("ping -c1 -W1 192.0.2.2"); server.wait_until_succeeds("ping -c1 -W1 192.0.2.2")
''; '';
}) })

View File

@ -4,12 +4,10 @@
}: }:
let 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 inherit (pkgs.lib) concatStringsSep maintainers mapAttrs mkMerge
removeSuffix replaceChars singleton splitString; removeSuffix replaceChars singleton splitString;
escape' = str: replaceChars [''"'' "$" "\n"] [''\\\"'' "\\$" ""] str;
/* /*
* The attrset `exporterTests` contains one attribute * The attrset `exporterTests` contains one attribute
* for each exporter test. Each of these attributes * for each exporter test. Each of these attributes
@ -33,9 +31,9 @@ let
* services.<metricProvider>.enable = true; * services.<metricProvider>.enable = true;
* }; * };
* exporterTest = '' * exporterTest = ''
* waitForUnit("prometheus-<exporterName>-exporter.service"); * wait_for_unit("prometheus-<exporterName>-exporter.service")
* waitForOpenPort("1234"); * wait_for_open_port("1234")
* succeed("curl -sSf 'localhost:1234/metrics'"); * succeed("curl -sSf 'localhost:1234/metrics'")
* ''; * '';
* }; * };
* *
@ -49,11 +47,11 @@ let
* }; * };
* *
* testScript = '' * testScript = ''
* $<exporterName>->start(); * <exporterName>.start()
* $<exporterName>->waitForUnit("prometheus-<exporterName>-exporter.service"); * <exporterName>.wait_for_unit("prometheus-<exporterName>-exporter.service")
* $<exporterName>->waitForOpenPort("1234"); * <exporterName>.wait_for_open_port("1234")
* $<exporterName>->succeed("curl -sSf 'localhost:1234/metrics'"); * <exporterName>.succeed("curl -sSf 'localhost:1234/metrics'")
* $<exporterName>->shutdown(); * <exporterName>.shutdown()
* ''; * '';
*/ */
@ -72,9 +70,11 @@ let
''; '';
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-bind-exporter.service"); wait_for_unit("prometheus-bind-exporter.service")
waitForOpenPort(9119); wait_for_open_port(9119)
succeed("curl -sSf http://localhost:9119/metrics | grep -q 'bind_query_recursions_total 0'"); succeed(
"curl -sSf http://localhost:9119/metrics | grep -q 'bind_query_recursions_total 0'"
)
''; '';
}; };
@ -89,9 +89,11 @@ let
}); });
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-blackbox-exporter.service"); wait_for_unit("prometheus-blackbox-exporter.service")
waitForOpenPort(9115); wait_for_open_port(9115)
succeed("curl -sSf 'http://localhost:9115/probe?target=localhost&module=icmp_v6' | grep -q 'probe_success 1'"); succeed(
"curl -sSf 'http://localhost:9115/probe?target=localhost&module=icmp_v6' | grep -q 'probe_success 1'"
)
''; '';
}; };
@ -100,7 +102,7 @@ let
enable = true; enable = true;
extraFlags = [ "--web.collectd-push-path /collectd" ]; extraFlags = [ "--web.collectd-push-path /collectd" ];
}; };
exporterTest =let postData = escape' '' exporterTest = let postData = replaceChars [ "\n" ] [ "" ] ''
[{ [{
"values":[23], "values":[23],
"dstypes":["gauge"], "dstypes":["gauge"],
@ -108,13 +110,21 @@ let
"interval":1000, "interval":1000,
"host":"testhost", "host":"testhost",
"plugin":"testplugin", "plugin":"testplugin",
"time":$(date +%s) "time":DATE
}] }]
''; in '' ''; in ''
waitForUnit("prometheus-collectd-exporter.service"); wait_for_unit("prometheus-collectd-exporter.service")
waitForOpenPort(9103); wait_for_open_port(9103)
succeed("curl -sSfH 'Content-Type: application/json' -X POST --data \"${postData}\" localhost:9103/collectd"); succeed(
succeed("curl -sSf localhost:9103/metrics | grep -q 'collectd_testplugin_gauge{instance=\"testhost\"} 23'"); '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; services.dnsmasq.enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-dnsmasq-exporter.service"); wait_for_unit("prometheus-dnsmasq-exporter.service")
waitForOpenPort(9153); wait_for_open_port(9153)
succeed("curl -sSf http://localhost:9153/metrics | grep -q 'dnsmasq_leases 0'"); succeed("curl -sSf http://localhost:9153/metrics | grep -q 'dnsmasq_leases 0'")
''; '';
}; };
@ -144,9 +154,11 @@ let
services.dovecot2.enable = true; services.dovecot2.enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-dovecot-exporter.service"); wait_for_unit("prometheus-dovecot-exporter.service")
waitForOpenPort(9166); wait_for_open_port(9166)
succeed("curl -sSf http://localhost:9166/metrics | grep -q 'dovecot_up{scope=\"global\"} 1'"); succeed(
"curl -sSf http://localhost:9166/metrics | grep -q 'dovecot_up{scope=\"global\"} 1'"
)
''; '';
}; };
@ -155,9 +167,11 @@ let
enable = true; enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-fritzbox-exporter.service"); wait_for_unit("prometheus-fritzbox-exporter.service")
waitForOpenPort(9133); wait_for_open_port(9133)
succeed("curl -sSf http://localhost:9133/metrics | grep -q 'fritzbox_exporter_collect_errors 0'"); succeed(
"curl -sSf http://localhost:9133/metrics | grep -q 'fritzbox_exporter_collect_errors 0'"
)
''; '';
}; };
@ -180,11 +194,11 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("nginx.service"); wait_for_unit("nginx.service")
waitForOpenPort(80); wait_for_open_port(80)
waitForUnit("prometheus-json-exporter.service"); wait_for_unit("prometheus-json-exporter.service")
waitForOpenPort(7979); wait_for_open_port(7979)
succeed("curl -sSf localhost:7979/metrics | grep -q 'json_test_metric 1'"); succeed("curl -sSf localhost:7979/metrics | grep -q 'json_test_metric 1'")
''; '';
}; };
@ -222,10 +236,12 @@ let
users.users.mailexporter.isSystemUser = true; users.users.mailexporter.isSystemUser = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("postfix.service") wait_for_unit("postfix.service")
waitForUnit("prometheus-mail-exporter.service") wait_for_unit("prometheus-mail-exporter.service")
waitForOpenPort(9225) wait_for_open_port(9225)
waitUntilSucceeds("curl -sSf http://localhost:9225/metrics | grep -q 'mail_deliver_success{configname=\"testserver\"} 1'") wait_until_succeeds(
"curl -sSf http://localhost:9225/metrics | grep -q 'mail_deliver_success{configname=\"testserver\"} 1'"
)
''; '';
}; };
@ -256,9 +272,9 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("nginx.service") wait_for_unit("nginx.service")
waitForUnit("prometheus-nextcloud-exporter.service") wait_for_unit("prometheus-nextcloud-exporter.service")
waitForOpenPort(9205) wait_for_open_port(9205)
succeed("curl -sSf http://localhost:9205/metrics | grep -q 'nextcloud_up 1'") succeed("curl -sSf http://localhost:9205/metrics | grep -q 'nextcloud_up 1'")
''; '';
}; };
@ -275,9 +291,9 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("nginx.service") wait_for_unit("nginx.service")
waitForUnit("prometheus-nginx-exporter.service") wait_for_unit("prometheus-nginx-exporter.service")
waitForOpenPort(9113) wait_for_open_port(9113)
succeed("curl -sSf http://localhost:9113/metrics | grep -q 'nginx_up 1'") succeed("curl -sSf http://localhost:9113/metrics | grep -q 'nginx_up 1'")
''; '';
}; };
@ -287,9 +303,11 @@ let
enable = true; enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-node-exporter.service"); wait_for_unit("prometheus-node-exporter.service")
waitForOpenPort(9100); wait_for_open_port(9100)
succeed("curl -sSf http://localhost:9100/metrics | grep -q 'node_exporter_build_info{.\\+} 1'"); succeed(
"curl -sSf http://localhost:9100/metrics | grep -q 'node_exporter_build_info{.\\+} 1'"
)
''; '';
}; };
@ -301,9 +319,11 @@ let
services.postfix.enable = true; services.postfix.enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-postfix-exporter.service"); wait_for_unit("prometheus-postfix-exporter.service")
waitForOpenPort(9154); wait_for_open_port(9154)
succeed("curl -sSf http://localhost:9154/metrics | grep -q 'postfix_smtpd_connects_total 0'"); succeed(
"curl -sSf http://localhost:9154/metrics | grep -q 'postfix_smtpd_connects_total 0'"
)
''; '';
}; };
@ -316,18 +336,24 @@ let
services.postgresql.enable = true; services.postgresql.enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-postgres-exporter.service"); wait_for_unit("prometheus-postgres-exporter.service")
waitForOpenPort(9187); wait_for_open_port(9187)
waitForUnit("postgresql.service"); wait_for_unit("postgresql.service")
succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'"); succeed(
succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 1'"); "curl -sSf http://localhost:9187/metrics | grep -q 'pg_exporter_last_scrape_error 0'"
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 1'")
succeed("curl -sSf http://localhost:9187/metrics | grep -q 'pg_up 0'"); systemctl("stop postgresql.service")
systemctl("start postgresql.service"); succeed(
waitForUnit("postgresql.service"); "curl -sSf http://localhost:9187/metrics | grep -qv 'pg_exporter_last_scrape_error 0'"
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'"); 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; services.rspamd.enable = true;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("rspamd.service"); wait_for_unit("rspamd.service")
waitForUnit("prometheus-rspamd-exporter.service"); wait_for_unit("prometheus-rspamd-exporter.service")
waitForOpenPort(11334); wait_for_open_port(11334)
waitForOpenPort(7980); wait_for_open_port(7980)
waitUntilSucceeds("curl -sSf localhost:7980/metrics | grep -q 'rspamd_scanned{host=\"rspamd\"} 0'"); wait_until_succeeds(
"curl -sSf localhost:7980/metrics | grep -q 'rspamd_scanned{host=\"rspamd\"} 0'"
)
''; '';
}; };
@ -356,9 +384,9 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-snmp-exporter.service"); wait_for_unit("prometheus-snmp-exporter.service")
waitForOpenPort(9116); wait_for_open_port(9116)
succeed("curl -sSf localhost:9116/metrics | grep -q 'snmp_request_errors_total 0'"); succeed("curl -sSf localhost:9116/metrics | grep -q 'snmp_request_errors_total 0'")
''; '';
}; };
@ -377,11 +405,11 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("nginx.service"); wait_for_unit("nginx.service")
waitForOpenPort(80); wait_for_open_port(80)
waitForUnit("prometheus-surfboard-exporter.service"); wait_for_unit("prometheus-surfboard-exporter.service")
waitForOpenPort(9239); wait_for_open_port(9239)
succeed("curl -sSf localhost:9239/metrics | grep -q 'surfboard_up 1'"); succeed("curl -sSf localhost:9239/metrics | grep -q 'surfboard_up 1'")
''; '';
}; };
@ -396,11 +424,11 @@ let
services.tor.controlPort = 9051; services.tor.controlPort = 9051;
}; };
exporterTest = '' exporterTest = ''
waitForUnit("tor.service"); wait_for_unit("tor.service")
waitForOpenPort(9051); wait_for_open_port(9051)
waitForUnit("prometheus-tor-exporter.service"); wait_for_unit("prometheus-tor-exporter.service")
waitForOpenPort(9130); wait_for_open_port(9130)
succeed("curl -sSf localhost:9130/metrics | grep -q 'tor_version{.\\+} 1'"); succeed("curl -sSf localhost:9130/metrics | grep -q 'tor_version{.\\+} 1'")
''; '';
}; };
@ -426,10 +454,12 @@ let
}; };
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-varnish-exporter.service"); wait_for_unit("prometheus-varnish-exporter.service")
waitForOpenPort(6081); wait_for_open_port(6081)
waitForOpenPort(9131); wait_for_open_port(9131)
succeed("curl -sSf http://localhost:9131/metrics | grep -q 'varnish_up 1'"); 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" ]; systemd.services.prometheus-wireguard-exporter.after = [ "wireguard-wg0.service" ];
}; };
exporterTest = '' exporterTest = ''
waitForUnit("prometheus-wireguard-exporter.service"); wait_for_unit("prometheus-wireguard-exporter.service")
waitForOpenPort(9586); wait_for_open_port(9586)
waitUntilSucceeds("curl -sSf http://localhost:9586/metrics | grep '${snakeoil.peer1.publicKey}'"); wait_until_succeeds(
"curl -sSf http://localhost:9586/metrics | grep '${snakeoil.peer1.publicKey}'"
)
''; '';
}; };
}; };
@ -466,11 +498,13 @@ mapAttrs (exporter: testConfig: (makeTest {
} testConfig.metricProvider or {}]; } testConfig.metricProvider or {}];
testScript = '' testScript = ''
${"$"+exporter}->start(); ${exporter}.start()
${concatStringsSep " " (map (line: '' ${concatStringsSep "\n" (map (line:
${"$"+exporter}->${line}; if (builtins.substring 0 1 line == " " || builtins.substring 0 1 line == ")")
'') (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))} then line
${"$"+exporter}->shutdown(); else "${exporter}.${line}"
) (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))}
${exporter}.shutdown()
''; '';
meta = with maintainers; { meta = with maintainers; {

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, ... }: import ./make-test-python.nix ({ lib, ... }:
with lib; with lib;
@ -11,8 +11,8 @@ with lib;
{ services.radarr.enable = true; }; { services.radarr.enable = true; };
testScript = '' testScript = ''
$machine->waitForUnit('radarr.service'); machine.wait_for_unit("radarr.service")
$machine->waitForOpenPort('7878'); machine.wait_for_open_port("7878")
$machine->succeed("curl --fail http://localhost:7878/"); machine.succeed("curl --fail http://localhost:7878/")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "redis"; name = "redis";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ flokli ]; maintainers = [ flokli ];
@ -15,12 +15,10 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
machine.wait_for_unit("redis")
$machine->waitForUnit("redis"); machine.wait_for_open_port("6379")
$machine->waitForOpenPort("6379"); machine.succeed("redis-cli ping | grep PONG")
machine.succeed("redis-cli -s /run/redis/redis.sock ping | grep PONG")
$machine->succeed("redis-cli ping | grep PONG");
$machine->succeed("redis-cli -s /run/redis/redis.sock ping | grep PONG");
''; '';
}) })

View File

@ -64,18 +64,13 @@ let
}; };
in in
{ {
v3-mysql = mysqlTest pkgs.redmine // { mysql = mysqlTest pkgs.redmine // {
name = "v3-mysql"; name = "mysql";
meta.maintainers = [ maintainers.aanderse ]; meta.maintainers = [ maintainers.aanderse ];
}; };
v4-mysql = mysqlTest pkgs.redmine_4 // { pgsql = pgsqlTest pkgs.redmine // {
name = "v4-mysql"; name = "pgsql";
meta.maintainers = [ maintainers.aanderse ];
};
v4-pgsql = pgsqlTest pkgs.redmine_4 // {
name = "v4-pgsql";
meta.maintainers = [ maintainers.aanderse ]; meta.maintainers = [ maintainers.aanderse ];
}; };
} }

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "roundcube"; name = "roundcube";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ globin ]; maintainers = [ globin ];
@ -21,10 +21,10 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
$roundcube->start; roundcube.start
$roundcube->waitForUnit("postgresql.service"); roundcube.wait_for_unit("postgresql.service")
$roundcube->waitForUnit("phpfpm-roundcube.service"); roundcube.wait_for_unit("phpfpm-roundcube.service")
$roundcube->waitForUnit("nginx.service"); roundcube.wait_for_unit("nginx.service")
$roundcube->succeed("curl -sSfL http://roundcube/ | grep 'Keep me logged in'"); roundcube.succeed("curl -sSfL http://roundcube/ | grep 'Keep me logged in'")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix { import ./make-test-python.nix {
name = "opensmtpd"; name = "opensmtpd";
nodes = { nodes = {
@ -53,14 +53,14 @@ import ./make-test.nix {
}; };
testScript = '' testScript = ''
startAll; start_all()
$server->waitForUnit("network-online.target"); server.wait_for_unit("network-online.target")
$server->waitForUnit("opensmtpd"); server.wait_for_unit("opensmtpd")
$server->waitForUnit("dovecot2"); server.wait_for_unit("dovecot2")
$server->waitForUnit("nginx"); server.wait_for_unit("nginx")
$server->waitForUnit("rss2email"); server.wait_for_unit("rss2email")
$server->waitUntilSucceeds('check-mail-landed >&2'); server.wait_until_succeeds("check-mail-landed >&2")
''; '';
} }

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, ...}: import ./make-test-python.nix ({ pkgs, lib, ...}:
{ {
name = "shiori"; name = "shiori";
@ -8,10 +8,74 @@ import ./make-test.nix ({ lib, ...}:
{ ... }: { ... }:
{ services.shiori.enable = true; }; { services.shiori.enable = true; };
testScript = '' testScript = let
$machine->waitForUnit('shiori.service'); authJSON = pkgs.writeText "auth.json" (builtins.toJSON {
$machine->waitForOpenPort('8080'); username = "shiori";
$machine->succeed("curl --fail http://localhost:8080/"); password = "gopher";
$machine->succeed("curl --fail --location http://localhost:8080/ | grep -qi shiori"); 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")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
{ {
name = "signal-desktop"; name = "signal-desktop";
@ -24,14 +24,14 @@ import ./make-test.nix ({ pkgs, ...} :
testScript = { nodes, ... }: let testScript = { nodes, ... }: let
user = nodes.machine.config.users.users.alice; user = nodes.machine.config.users.users.alice;
in '' in ''
startAll; start_all()
$machine->waitForX; machine.wait_for_x()
# start signal desktop # 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 # wait for the "Link your phone to Signal Desktop" message
$machine->waitForText(qr/Link your phone to Signal Desktop/); machine.wait_for_text("Link your phone to Signal Desktop")
$machine->screenshot("signal_desktop"); machine.screenshot("signal_desktop")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "smokeping"; name = "smokeping";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ cransom ]; maintainers = [ cransom ];
@ -22,12 +22,12 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$sm->waitForUnit("smokeping"); sm.wait_for_unit("smokeping")
$sm->waitForUnit("thttpd"); sm.wait_for_unit("thttpd")
$sm->waitForFile("/var/lib/smokeping/data/Local/LocalMachine.rrd"); sm.wait_for_file("/var/lib/smokeping/data/Local/LocalMachine.rrd")
$sm->succeed("curl -s -f localhost:8081/smokeping.fcgi?target=Local"); 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/Local/LocalMachine_mini.png")
$sm->succeed("ls /var/lib/smokeping/cache/index.html"); sm.succeed("ls /var/lib/smokeping/cache/index.html")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ ... }: import ./make-test-python.nix ({ ... }:
{ {
name = "snapper"; name = "snapper";
@ -20,24 +20,16 @@ import ./make-test.nix ({ ... }:
}; };
testScript = '' testScript = ''
$machine->succeed("btrfs subvolume create /home/.snapshots"); machine.succeed("btrfs subvolume create /home/.snapshots")
machine.succeed("snapper -c home list")
$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 empty"); machine.succeed("snapper -c home create --description file")
machine.succeed("snapper -c home status 1..2")
$machine->succeed("echo test > /home/file"); machine.succeed("snapper -c home undochange 1..2")
$machine->succeed("snapper -c home create --description file"); machine.fail("ls /home/file")
machine.succeed("snapper -c home delete 2")
$machine->succeed("snapper -c home status 1..2"); machine.succeed("systemctl --wait start snapper-timeline.service")
machine.succeed("systemctl --wait start snapper-cleanup.service")
$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");
''; '';
}) })

View File

@ -16,7 +16,7 @@
# See the NixOS manual for how to run this test: # See the NixOS manual for how to run this test:
# https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively # https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
let let
allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT"; allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT";
@ -142,7 +142,7 @@ in {
}; };
testScript = '' testScript = ''
startAll(); start_all()
$carol->waitUntilSucceeds("ping -c 1 alice"); carol.wait_until_succeeds("ping -c 1 alice")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "telegraf"; name = "telegraf";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ mic92 ]; maintainers = [ mic92 ];
@ -22,9 +22,9 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$machine->waitForUnit("telegraf.service"); machine.wait_for_unit("telegraf.service")
$machine->waitUntilSucceeds("grep -q example /tmp/metrics.out"); machine.wait_until_succeeds("grep -q example /tmp/metrics.out")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "trickster"; name = "trickster";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ "1000101" ]; maintainers = [ "1000101" ];
@ -15,15 +15,23 @@ import ./make-test.nix ({ pkgs, ... }: {
}; };
testScript = '' testScript = ''
startAll; start_all()
$prometheus->waitForUnit("prometheus.service"); prometheus.wait_for_unit("prometheus.service")
$prometheus->waitForOpenPort(9090); prometheus.wait_for_open_port(9090)
$prometheus->waitUntilSucceeds("curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); prometheus.wait_until_succeeds(
$trickster->waitForUnit("trickster.service"); "curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"
$trickster->waitForOpenPort(8082); )
$trickster->waitForOpenPort(9090); trickster.wait_for_unit("trickster.service")
$trickster->waitUntilSucceeds("curl -L http://localhost:8082/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); trickster.wait_for_open_port(8082)
$trickster->waitUntilSucceeds("curl -L http://prometheus:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); trickster.wait_for_open_port(9090)
$trickster->waitUntilSucceeds("curl -L http://localhost:9090/metrics | grep 'promhttp_metric_handler_requests_total{code=\"500\"} 0'"); 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'"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: import ./make-test-python.nix ({ pkgs, ... }:
let let
@ -30,32 +30,40 @@ in
testScript = testScript =
'' ''
my $stick = $machine->stateDir . "/usbstick.img"; import lzma
system("xz -d < ${stick} > $stick") == 0 or die;
$machine->succeed("udisksctl info -b /dev/vda >&2"); with lzma.open(
$machine->fail("udisksctl info -b /dev/sda1"); "${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. # 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.send_monitor_command(
$machine->sendMonitorCommand("device_add usb-storage,id=stick,drive=stick"); f"drive_add 0 id=stick,if=none,file={stick.name},format=raw"
$machine->waitUntilSucceeds("udisksctl info -b /dev/sda1"); )
$machine->succeed("udisksctl info -b /dev/sda1 | grep 'IdLabel:.*USBSTICK'"); 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. # 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 info -b /dev/sda1'")
$machine->succeed("su - alice -c 'udisksctl mount -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(
$machine->succeed("su - alice -c 'echo foo > /run/media/alice/USBSTICK/bar.txt'"); "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. # Unmounting the stick should make the mountpoint disappear.
$machine->succeed("su - alice -c 'udisksctl unmount -b /dev/sda1'"); machine.succeed("su - alice -c 'udisksctl unmount -b /dev/sda1'")
$machine->fail("[ -d /run/media/alice/USBSTICK ]"); machine.fail("[ -d /run/media/alice/USBSTICK ]")
# Remove the USB stick. # Remove the USB stick.
$machine->sendMonitorCommand("device_del stick"); machine.send_monitor_command("device_del stick")
$machine->waitUntilFails("udisksctl info -b /dev/sda1"); machine.wait_until_fails("udisksctl info -b /dev/sda1")
$machine->fail("[ -e /dev/sda ]"); machine.fail("[ -e /dev/sda ]")
''; '';
}) })

View File

@ -5,7 +5,7 @@
# this succeeds an external client will try to connect to the port # this succeeds an external client will try to connect to the port
# mapping. # mapping.
import ./make-test.nix ({ pkgs, ... }: import ./make-test-python.nix ({ pkgs, ... }:
let let
internalRouterAddress = "192.168.3.1"; internalRouterAddress = "192.168.3.1";
@ -75,20 +75,20 @@ in
testScript = testScript =
{ nodes, ... }: { nodes, ... }:
'' ''
startAll; start_all()
# Wait for network and miniupnpd. # Wait for network and miniupnpd.
$router->waitForUnit("network-online.target"); router.wait_for_unit("network-online.target")
# $router->waitForUnit("nat"); # $router.wait_for_unit("nat")
$router->waitForUnit("firewall.service"); router.wait_for_unit("firewall.service")
$router->waitForUnit("miniupnpd"); 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"); client1.wait_for_unit("httpd")
$client2->waitUntilSucceeds("curl http://${externalRouterAddress}:9000/"); client2.wait_until_succeeds("curl http://${externalRouterAddress}:9000/")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: import ./make-test-python.nix ({ pkgs, lib, ... }:
with lib; with lib;
@ -15,10 +15,10 @@ with lib;
}; };
testScript = '' testScript = ''
$machine->start; machine.start()
$machine->waitForX; machine.wait_for_x()
$machine->mustFail("pgrep xlock"); machine.fail("pgrep xlock")
$machine->sleep(120); machine.sleep(120)
$machine->mustSucceed("pgrep xlock"); machine.succeed("pgrep xlock")
''; '';
}) })

View File

@ -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'");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: import ./make-test-python.nix ({ pkgs, lib, ... }:
with lib; with lib;
@ -20,14 +20,14 @@ with lib;
}; };
testScript = '' testScript = ''
$machine->start; machine.start()
$machine->waitForX; machine.wait_for_x()
# confirm proper startup # confirm proper startup
$machine->waitForUnit("yabar.service", "bob"); machine.wait_for_unit("yabar.service", "bob")
$machine->sleep(10); machine.sleep(10)
$machine->waitForUnit("yabar.service", "bob"); machine.wait_for_unit("yabar.service", "bob")
$machine->screenshot("top_bar"); machine.screenshot("top_bar")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "zookeeper"; name = "zookeeper";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ nequissimus ]; maintainers = [ nequissimus ];
@ -15,14 +15,20 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$server->waitForUnit("zookeeper"); server.wait_for_unit("zookeeper")
$server->waitForUnit("network.target"); server.wait_for_unit("network.target")
$server->waitForOpenPort(2181); server.wait_for_open_port(2181)
$server->waitUntilSucceeds("${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 create /foo bar"); server.wait_until_succeeds(
$server->waitUntilSucceeds("${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 set /foo hello"); "${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 create /foo bar"
$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 set /foo hello"
)
server.wait_until_succeeds(
"${pkgs.zookeeper}/bin/zkCli.sh -server localhost:2181 get /foo | grep hello"
)
''; '';
}) })

View File

@ -3,13 +3,13 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "ncmpc"; pname = "ncmpc";
version = "0.35"; version = "0.36";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "MusicPlayerDaemon"; owner = "MusicPlayerDaemon";
repo = "ncmpc"; repo = "ncmpc";
rev = "v${version}"; rev = "v${version}";
sha256 = "0hhc5snxy5fbg47ynz4b7fkmzdy974zxqr0cqc6kh15yvbr25ikh"; sha256 = "1ssmk1p43gjhcqi86sh6b7csqpwwpf3hs32cmnylv6pmbcwbs69h";
}; };
buildInputs = [ glib ncurses mpd_clientlib boost ]; buildInputs = [ glib ncurses mpd_clientlib boost ];

View File

@ -4,11 +4,11 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "setbfree"; pname = "setbfree";
version = "0.8.9"; version = "0.8.10";
src = fetchzip { src = fetchzip {
url = "https://github.com/pantherb/setBfree/archive/v${version}.tar.gz"; url = "https://github.com/pantherb/setBfree/archive/v${version}.tar.gz";
sha256 = "097bby2da47zlkaqy2jl8j6q0h5pxaq67lz473ygadqs5ic3nhc1"; sha256 = "1hpj8qb5mhkqm4yy8mzzrrq0ljw22y807qly90vjkg61ascyina4";
}; };
postPatch = '' postPatch = ''

View File

@ -14,6 +14,7 @@
, supercollider , supercollider
, qscintilla , qscintilla
, qwt , qwt
, osmid
}: }:
let let
@ -59,6 +60,10 @@ mkDerivation rec {
buildPhase = '' buildPhase = ''
export SONIC_PI_HOME=$TMPDIR export SONIC_PI_HOME=$TMPDIR
export AUBIO_LIB=${aubio}/lib/libaubio.so export AUBIO_LIB=${aubio}/lib/libaubio.so
export OSMID_DIR=app/server/native/osmid
mkdir -p $OSMID_DIR
cp ${osmid}/bin/{m2o,o2m} $OSMID_DIR
pushd app/server/ruby/bin pushd app/server/ruby/bin
./compile-extensions.rb ./compile-extensions.rb
@ -95,11 +100,10 @@ mkDerivation rec {
''; '';
meta = { meta = {
homepage = http://sonic-pi.net/; homepage = "https://sonic-pi.net/";
description = "Free live coding synth for everyone originally designed to support computing and music lessons within schools"; description = "Free live coding synth for everyone originally designed to support computing and music lessons within schools";
license = lib.licenses.mit; license = lib.licenses.mit;
maintainers = with lib.maintainers; [ Phlogistique kamilchm ]; maintainers = with lib.maintainers; [ Phlogistique kamilchm ];
platforms = lib.platforms.linux; platforms = lib.platforms.linux;
broken = true;
}; };
} }

View File

@ -1,7 +1,7 @@
{ fetchurl, stdenv, squashfsTools, xorg, alsaLib, makeWrapper, openssl, freetype { fetchurl, stdenv, squashfsTools, xorg, alsaLib, makeWrapper, openssl, freetype
, glib, pango, cairo, atk, gdk-pixbuf, gtk2, cups, nspr, nss, libpng, libnotify , glib, pango, cairo, atk, gdk-pixbuf, gtk2, cups, nspr, nss, libpng, libnotify
, libgcrypt, systemd, fontconfig, dbus, expat, ffmpeg_3, curl, zlib, gnome3 , libgcrypt, systemd, fontconfig, dbus, expat, ffmpeg_3, curl, zlib, gnome3
, at-spi2-atk , at-spi2-atk, at-spi2-core, libpulseaudio
}: }:
let let
@ -10,20 +10,21 @@ let
# If an update breaks things, one of those might have valuable info: # If an update breaks things, one of those might have valuable info:
# https://aur.archlinux.org/packages/spotify/ # https://aur.archlinux.org/packages/spotify/
# https://community.spotify.com/t5/Desktop-Linux # https://community.spotify.com/t5/Desktop-Linux
version = "1.0.96.181.gf6bc1b6b-12"; version = "1.1.10.546.ge08ef575-19";
# To get the latest stable revision: # To get the latest stable revision:
# curl -H 'X-Ubuntu-Series: 16' 'https://api.snapcraft.io/api/v1/snaps/details/spotify?channel=stable' | jq '.download_url,.version,.last_updated' # curl -H 'X-Ubuntu-Series: 16' 'https://api.snapcraft.io/api/v1/snaps/details/spotify?channel=stable' | jq '.download_url,.version,.last_updated'
# To get general information: # To get general information:
# curl -H 'Snap-Device-Series: 16' 'https://api.snapcraft.io/v2/snaps/info/spotify' | jq '.' # curl -H 'Snap-Device-Series: 16' 'https://api.snapcraft.io/v2/snaps/info/spotify' | jq '.'
# More examples of api usage: # More examples of api usage:
# https://github.com/canonical-websites/snapcraft.io/blob/master/webapp/publisher/snaps/views.py # https://github.com/canonical-websites/snapcraft.io/blob/master/webapp/publisher/snaps/views.py
rev = "30"; rev = "36";
deps = [ deps = [
alsaLib alsaLib
atk atk
at-spi2-atk at-spi2-atk
at-spi2-core
cairo cairo
cups cups
curl curl
@ -38,6 +39,7 @@ let
libgcrypt libgcrypt
libnotify libnotify
libpng libpng
libpulseaudio
nss nss
pango pango
stdenv.cc.cc stdenv.cc.cc
@ -73,7 +75,7 @@ stdenv.mkDerivation {
# https://community.spotify.com/t5/Desktop-Linux/Redistribute-Spotify-on-Linux-Distributions/td-p/1695334 # https://community.spotify.com/t5/Desktop-Linux/Redistribute-Spotify-on-Linux-Distributions/td-p/1695334
src = fetchurl { src = fetchurl {
url = "https://api.snapcraft.io/api/v1/snaps/download/pOBIoZ2LrCB3rDohMxoYGnbN14EHOgD7_${rev}.snap"; url = "https://api.snapcraft.io/api/v1/snaps/download/pOBIoZ2LrCB3rDohMxoYGnbN14EHOgD7_${rev}.snap";
sha512 = "859730fbc80067f0828f7e13eee9a21b13b749f897a50e17c2da4ee672785cfd79e1af6336e609529d105e040dc40f61b6189524783ac93d49f991c4ea8b3c56"; sha512 = "c49f1a86a9b737e64a475bbe62754a36f607669e908eb725a2395f0a0a6b95968e0c8ce27ab2c8b6c92fe8cbacb1ef58de11c79b92dc0f58c2c6d3a140706a1f";
}; };
buildInputs = [ squashfsTools makeWrapper ]; buildInputs = [ squashfsTools makeWrapper ];

View File

@ -2,7 +2,7 @@
buildGoPackage rec { buildGoPackage rec {
pname = "go-ethereum"; pname = "go-ethereum";
version = "1.9.6"; version = "1.9.7";
goPackagePath = "github.com/ethereum/go-ethereum"; goPackagePath = "github.com/ethereum/go-ethereum";
@ -14,7 +14,7 @@ buildGoPackage rec {
owner = "ethereum"; owner = "ethereum";
repo = pname; repo = pname;
rev = "v${version}"; rev = "v${version}";
sha256 = "08k6p7mbszlg8mq8k3vi5xrfnhfbxlh2ynd0nr0j64qdhmhcdnq6"; sha256 = "07110dj91wmkpwz7iy0lmxx3y9wjxjrhk3rhkfdil74cxm0wkkn2";
}; };
meta = with stdenv.lib; { meta = with stdenv.lib; {

View File

@ -13,14 +13,14 @@ let
sha256Hash = "0kcd6kd5rn4b76damkfddin18d1r0dck05piv8mq1ns7x1n4hf7q"; sha256Hash = "0kcd6kd5rn4b76damkfddin18d1r0dck05piv8mq1ns7x1n4hf7q";
}; };
betaVersion = { betaVersion = {
version = "3.6.0.14"; # "Android Studio 3.6 Beta 2" version = "3.6.0.15"; # "Android Studio 3.6 Beta 3"
build = "192.5947919"; build = "192.5982640";
sha256Hash = "09l7mdjkzwnkkcgxp0x66bzm125ignrfssy7n141wvs2rd66i2fs"; sha256Hash = "0017g7nvjiadd64in9fl4wq5lf8b7pyrdasbnwzjcphpbzy1390x";
}; };
latestVersion = { # canary & dev latestVersion = { # canary & dev
version = "4.0.0.1"; # "Android Studio 4.0 Canary 1" version = "4.0.0.2"; # "Android Studio 4.0 Canary 2"
build = "192.5959023"; build = "192.5984562";
sha256Hash = "1d9hvyk0wnfiip1612ci4sbw58rq93cyy026cx6s33rvjk3cwfrl"; sha256Hash = "0p29a6np31396970lnb3di2yrcqi3z8nqcn27hcnb4c4g7kjm0qw";
}; };
in { in {
# Attributes are named by their corresponding release channels # Attributes are named by their corresponding release channels

View File

@ -7,6 +7,7 @@
kak-auto-pairs = pkgs.callPackage ./kak-auto-pairs.nix { }; kak-auto-pairs = pkgs.callPackage ./kak-auto-pairs.nix { };
kak-buffers = pkgs.callPackage ./kak-buffers.nix { }; kak-buffers = pkgs.callPackage ./kak-buffers.nix { };
kak-fzf = pkgs.callPackage ./kak-fzf.nix { }; kak-fzf = pkgs.callPackage ./kak-fzf.nix { };
kak-plumb = pkgs.callPackage ./kak-plumb.nix { };
kak-powerline = pkgs.callPackage ./kak-powerline.nix { }; kak-powerline = pkgs.callPackage ./kak-powerline.nix { };
kak-vertical-selection = pkgs.callPackage ./kak-vertical-selection.nix { }; kak-vertical-selection = pkgs.callPackage ./kak-vertical-selection.nix { };
} }

View File

@ -17,7 +17,7 @@ stdenv.mkDerivation {
meta = with stdenv.lib; meta = with stdenv.lib;
{ description = "Kakoune extension to enable automatic closing of pairs"; { description = "Kakoune extension to enable automatic closing of pairs";
homepage = "https://github.com/alexherbo2/auto-pairs.kak"; homepage = "https://github.com/alexherbo2/auto-pairs.kak";
license = licenses.publicDoman; license = licenses.unlicense;
maintainers = with maintainers; [ nrdxp ]; maintainers = with maintainers; [ nrdxp ];
platform = platforms.all; platform = platforms.all;
}; };

View File

@ -17,7 +17,7 @@ stdenv.mkDerivation {
meta = with stdenv.lib; meta = with stdenv.lib;
{ description = "Ease navigation between opened buffers in Kakoune"; { description = "Ease navigation between opened buffers in Kakoune";
homepage = "https://github.com/Delapouite/kakoune-buffers"; homepage = "https://github.com/Delapouite/kakoune-buffers";
license = licenses.publicDoman; license = licenses.mit;
maintainers = with maintainers; [ nrdxp ]; maintainers = with maintainers; [ nrdxp ];
platform = platforms.all; platform = platforms.all;
}; };

Some files were not shown because too many files have changed in this diff Show More