Merge master into staging-next

This commit is contained in:
Frederik Rietdijk 2019-11-25 21:51:57 +01:00
commit 06a054e6eb
252 changed files with 3160 additions and 2290 deletions

3
.github/CODEOWNERS vendored
View File

@ -47,6 +47,9 @@
/nixos/doc/manual/man-nixos-option.xml @nbp /nixos/doc/manual/man-nixos-option.xml @nbp
/nixos/modules/installer/tools/nixos-option.sh @nbp /nixos/modules/installer/tools/nixos-option.sh @nbp
# NixOS integration test driver
/nixos/lib/test-driver @tfc
# New NixOS modules # New NixOS modules
/nixos/modules/module-list.nix @Infinisil /nixos/modules/module-list.nix @Infinisil

View File

@ -141,11 +141,10 @@
For a more useful example, try the following. This configuration only allows unfree packages named flash player and visual studio code: For a more useful example, try the following. This configuration only allows unfree packages named flash player and visual studio code:
<programlisting> <programlisting>
{ {
allowUnfreePredicate = (pkg: builtins.elem allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
(pkg.pname or (builtins.parseDrvName pkg.name).name) [ "flashplayer"
"flashplayer" "vscode"
"vscode" ];
]);
} }
</programlisting> </programlisting>
</para> </para>
@ -217,7 +216,7 @@
The following configuration example only allows insecure packages with very short names: The following configuration example only allows insecure packages with very short names:
<programlisting> <programlisting>
{ {
allowInsecurePredicate = (pkg: (builtins.stringLength (builtins.parseDrvName pkg.name).name) &lt;= 5); allowInsecurePredicate = pkg: builtins.stringLength (lib.getName pkg) &lt;= 5;
} }
</programlisting> </programlisting>
</para> </para>

View File

@ -84,7 +84,8 @@ let
hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape hasInfix hasPrefix hasSuffix stringToCharacters stringAsChars escape
escapeShellArg escapeShellArgs replaceChars lowerChars escapeShellArg escapeShellArgs replaceChars lowerChars
upperChars toLower toUpper addContextFrom splitString upperChars toLower toUpper addContextFrom splitString
removePrefix removeSuffix versionOlder versionAtLeast getVersion removePrefix removeSuffix versionOlder versionAtLeast
getName getVersion
nameFromURL enableFeature enableFeatureAs withFeature nameFromURL enableFeature enableFeatureAs withFeature
withFeatureAs fixedWidthString fixedWidthNumber isStorePath withFeatureAs fixedWidthString fixedWidthNumber isStorePath
toInt readPathsFromFile fileContents; toInt readPathsFromFile fileContents;

View File

@ -472,6 +472,23 @@ rec {
*/ */
versionAtLeast = v1: v2: !versionOlder v1 v2; versionAtLeast = v1: v2: !versionOlder v1 v2;
/* This function takes an argument that's either a derivation or a
derivation's "name" attribute and extracts the name part from that
argument.
Example:
getName "youtube-dl-2016.01.01"
=> "youtube-dl"
getName pkgs.youtube-dl
=> "youtube-dl"
*/
getName = x:
let
parse = drv: (builtins.parseDrvName drv).name;
in if isString x
then parse x
else x.pname or (parse x.name);
/* This function takes an argument that's either a derivation or a /* This function takes an argument that's either a derivation or a
derivation's "name" attribute and extracts the version part from that derivation's "name" attribute and extracts the version part from that
argument. argument.

View File

@ -37,6 +37,7 @@ rec {
else if final.isAndroid then "bionic" else if final.isAndroid then "bionic"
else if final.isLinux /* default */ then "glibc" else if final.isLinux /* default */ then "glibc"
else if final.isMsp430 then "newlib" else if final.isMsp430 then "newlib"
else if final.isVc4 then "newlib"
else if final.isAvr then "avrlibc" else if final.isAvr then "avrlibc"
else if final.isNetBSD then "nblibc" else if final.isNetBSD then "nblibc"
# TODO(@Ericson2314) think more about other operating systems # TODO(@Ericson2314) think more about other operating systems

View File

@ -26,7 +26,7 @@ let
"riscv32-linux" "riscv64-linux" "riscv32-linux" "riscv64-linux"
"aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none" "aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none" "vc4-none"
]; ];
allParsed = map parse.mkSystemFromString all; allParsed = map parse.mkSystemFromString all;
@ -45,6 +45,7 @@ in {
x86_64 = filterDoubles predicates.isx86_64; x86_64 = filterDoubles predicates.isx86_64;
mips = filterDoubles predicates.isMips; mips = filterDoubles predicates.isMips;
riscv = filterDoubles predicates.isRiscV; riscv = filterDoubles predicates.isRiscV;
vc4 = filterDoubles predicates.isVc4;
cygwin = filterDoubles predicates.isCygwin; cygwin = filterDoubles predicates.isCygwin;
darwin = filterDoubles predicates.isDarwin; darwin = filterDoubles predicates.isDarwin;

View File

@ -118,6 +118,12 @@ rec {
config = "avr"; config = "avr";
}; };
vc4 = {
config = "vc4-elf";
libc = "newlib";
platform = {};
};
arm-embedded = { arm-embedded = {
config = "arm-none-eabi"; config = "arm-none-eabi";
libc = "newlib"; libc = "newlib";

View File

@ -21,6 +21,7 @@ rec {
isSparc = { cpu = { family = "sparc"; }; }; isSparc = { cpu = { family = "sparc"; }; };
isWasm = { cpu = { family = "wasm"; }; }; isWasm = { cpu = { family = "wasm"; }; };
isMsp430 = { cpu = { family = "msp430"; }; }; isMsp430 = { cpu = { family = "msp430"; }; };
isVc4 = { cpu = { family = "vc4"; }; };
isAvr = { cpu = { family = "avr"; }; }; isAvr = { cpu = { family = "avr"; }; };
isAlpha = { cpu = { family = "alpha"; }; }; isAlpha = { cpu = { family = "alpha"; }; };
isJavaScript = { cpu = cpuTypes.js; }; isJavaScript = { cpu = cpuTypes.js; };

View File

@ -112,6 +112,8 @@ rec {
msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; }; msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; };
avr = { bits = 8; family = "avr"; }; avr = { bits = 8; family = "avr"; };
vc4 = { bits = 32; significantByte = littleEndian; family = "vc4"; };
js = { bits = 32; significantByte = littleEndian; family = "js"; }; js = { bits = 32; significantByte = littleEndian; family = "js"; };
}; };

View File

@ -3601,6 +3601,12 @@
github = "klntsky"; github = "klntsky";
githubId = 18447310; githubId = 18447310;
}; };
kmcopper = {
email = "kmcopper@danwin1210.me";
name = "Kyle Copperfield";
github = "kmcopper";
githubId = 57132115;
};
kmeakin = { kmeakin = {
email = "karlwfmeakin@gmail.com"; email = "karlwfmeakin@gmail.com";
name = "Karl Meakin"; name = "Karl Meakin";
@ -4524,6 +4530,12 @@
githubId = 117842; githubId = 117842;
name = "Henri Bourcereau"; name = "Henri Bourcereau";
}; };
mmilata = {
email = "martin@martinmilata.cz";
github = "mmilata";
gitHubId = 85857;
name = "Martin Milata";
};
mmlb = { mmlb = {
email = "me.mmlb@mmlb.me"; email = "me.mmlb@mmlb.me";
github = "mmlb"; github = "mmlb";
@ -6727,6 +6739,12 @@
githubId = 42933; githubId = 42933;
name = "Andrew Childs"; name = "Andrew Childs";
}; };
thefenriswolf = {
email = "stefan.rohrbacher97@gmail.com";
github = "thefenriswolf";
githubId = "8547242";
name = "Stefan Rohrbacher";
};
thesola10 = { thesola10 = {
email = "thesola10@bobile.fr"; email = "thesola10@bobile.fr";
github = "thesola10"; github = "thesola10";

View File

@ -126,7 +126,7 @@ let
packageData = package: { packageData = package: {
name = package.name; name = package.name;
pname = (builtins.parseDrvName package.name).name; pname = pkgs.lib.getName package;
updateScript = map builtins.toString (pkgs.lib.toList package.updateScript); updateScript = map builtins.toString (pkgs.lib.toList package.updateScript);
}; };

View File

@ -176,6 +176,16 @@
KDEs old multimedia framework Phonon no longer supports Qt 4. For that reason, Plasma desktop also does not have <option>enableQt4Support</option> option any more. KDEs old multimedia framework Phonon no longer supports Qt 4. For that reason, Plasma desktop also does not have <option>enableQt4Support</option> option any more.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The BeeGFS module has been removed.
</para>
</listitem>
<listitem>
<para>
The osquery module has been removed.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>

View File

@ -86,7 +86,7 @@ let
optionsList = lib.sort optionLess optionsListDesc; optionsList = lib.sort optionLess optionsListDesc;
# Convert the list of options into an XML file. # Convert the list of options into an XML file.
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList); optionsXML = pkgs.writeText "options.xml" (builtins.toXML optionsList);
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList); optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);

View File

@ -3,7 +3,6 @@ from contextlib import contextmanager, _GeneratorContextManager
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 ptpython.repl
import pty import pty
@ -16,7 +15,7 @@ import sys
import tempfile import tempfile
import time import time
import unicodedata import unicodedata
from typing import Tuple, TextIO, Any, Callable, Dict, Iterator, Optional, List from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List
CHAR_TO_KEY = { CHAR_TO_KEY = {
"A": "shift-a", "A": "shift-a",
@ -771,7 +770,9 @@ def run_tests() -> None:
machine.execute("sync") machine.execute("sync")
if nr_tests != 0: if nr_tests != 0:
log.log("{} out of {} tests succeeded".format(nr_succeeded, nr_tests)) eprint("{} out of {} tests succeeded".format(nr_succeeded, nr_tests))
if nr_tests > nr_succeeded:
sys.exit(1)
@contextmanager @contextmanager

View File

@ -1,41 +0,0 @@
{ config, lib, ... }:
with lib;
let
cfg = config.networking.vpnc;
mkServiceDef = name: value:
{
name = "vpnc/${name}.conf";
value = { text = value; };
};
in
{
options = {
networking.vpnc = {
services = mkOption {
type = types.attrsOf types.str;
default = {};
example = literalExample ''
{ test = '''
IPSec gateway 192.168.1.1
IPSec ID someID
IPSec secret secretKey
Xauth username name
Xauth password pass
''';
}
'';
description =
''
The names of cisco VPNs and their associated definitions
'';
};
};
};
config.environment.etc = mapAttrs' mkServiceDef cfg.services;
}

View File

@ -35,7 +35,6 @@
./config/terminfo.nix ./config/terminfo.nix
./config/unix-odbc-drivers.nix ./config/unix-odbc-drivers.nix
./config/users-groups.nix ./config/users-groups.nix
./config/vpnc.nix
./config/vte.nix ./config/vte.nix
./config/zram.nix ./config/zram.nix
./hardware/acpilight.nix ./hardware/acpilight.nix
@ -519,7 +518,6 @@
./services/monitoring/munin.nix ./services/monitoring/munin.nix
./services/monitoring/nagios.nix ./services/monitoring/nagios.nix
./services/monitoring/netdata.nix ./services/monitoring/netdata.nix
./services/monitoring/osquery.nix
./services/monitoring/prometheus/default.nix ./services/monitoring/prometheus/default.nix
./services/monitoring/prometheus/alertmanager.nix ./services/monitoring/prometheus/alertmanager.nix
./services/monitoring/prometheus/exporters.nix ./services/monitoring/prometheus/exporters.nix
@ -539,7 +537,6 @@
./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-agent.nix
./services/monitoring/zabbix-proxy.nix ./services/monitoring/zabbix-proxy.nix
./services/monitoring/zabbix-server.nix ./services/monitoring/zabbix-server.nix
./services/network-filesystems/beegfs.nix
./services/network-filesystems/cachefilesd.nix ./services/network-filesystems/cachefilesd.nix
./services/network-filesystems/davfs2.nix ./services/network-filesystems/davfs2.nix
./services/network-filesystems/drbd.nix ./services/network-filesystems/drbd.nix

View File

@ -10,6 +10,7 @@ with lib;
(mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ]) (mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
(mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ]) (mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
(mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ]) (mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ])
(mkRenamedOptionModule [ "networking" "connman" ] [ "services" "connman" ])
(mkChangedOptionModule [ "services" "printing" "gutenprint" ] [ "services" "printing" "drivers" ] (mkChangedOptionModule [ "services" "printing" "gutenprint" ] [ "services" "printing" "drivers" ]
(config: (config:
let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config; let enabled = getAttrFromPath [ "services" "printing" "gutenprint" ] config;
@ -235,6 +236,7 @@ with lib;
(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.") (mkRemovedOptionModule [ "fonts" "enableCoreFonts" ] "Use fonts.fonts = [ pkgs.corefonts ]; instead.")
(mkRemovedOptionModule [ "networking" "vpnc" ] "Use environment.etc.\"vpnc/service.conf\" instead.")
# ZSH # ZSH
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
@ -279,6 +281,13 @@ with lib;
# BLCR # BLCR
(mkRemovedOptionModule [ "environment.blcr.enable" ] "The BLCR module has been removed") (mkRemovedOptionModule [ "environment.blcr.enable" ] "The BLCR module has been removed")
# beegfs
(mkRemovedOptionModule [ "services.beegfsEnable" ] "The BeeGFS module has been removed")
(mkRemovedOptionModule [ "services.beegfs" ] "The BeeGFS module has been removed")
# osquery
(mkRemovedOptionModule [ "services.osquery" ] "The osquery module has been removed")
# Redis # Redis
(mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.") (mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.")
(mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.") (mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.")

View File

@ -8,15 +8,11 @@ let
mysql = cfg.package; mysql = cfg.package;
isMariaDB = isMariaDB = lib.getName mysql == lib.getName pkgs.mariadb;
let
pName = _p: (builtins.parseDrvName (_p.name)).name;
in pName mysql == pName pkgs.mariadb;
isMysqlAtLeast57 = isMysqlAtLeast57 =
let (lib.getName mysql == lib.getName pkgs.mysql57)
pName = _p: (builtins.parseDrvName (_p.name)).name; && (builtins.compareVersions mysql.version "5.7" >= 0);
in (pName mysql == pName pkgs.mysql57)
&& ((builtins.compareVersions mysql.version "5.7") >= 0);
mysqldOptions = mysqldOptions =
"--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}"; "--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${mysql}";

View File

@ -43,7 +43,7 @@ in
serviceConfig = { serviceConfig = {
DynamicUser = true; DynamicUser = true;
StateDirectory = "openarena"; StateDirectory = "openarena";
ExecStart = "${pkgs.openarena}/bin/openarena-server +set fs_basepath ${pkgs.openarena}/openarena-0.8.8 +set fs_homepath /var/lib/openarena ${concatStringsSep " " cfg.extraFlags}"; ExecStart = "${pkgs.openarena}/bin/oa_ded +set fs_basepath ${pkgs.openarena}/openarena-0.8.8 +set fs_homepath /var/lib/openarena ${concatStringsSep " " cfg.extraFlags}";
Restart = "on-failure"; Restart = "on-failure";
# Hardening # Hardening

View File

@ -1,91 +0,0 @@
{ config, lib, pkgs, ... }:
with builtins;
with lib;
let
cfg = config.services.osquery;
in
{
options = {
services.osquery = {
enable = mkEnableOption "osquery";
loggerPath = mkOption {
type = types.path;
description = "Base directory used for logging.";
default = "/var/log/osquery";
};
pidfile = mkOption {
type = types.path;
description = "Path used for pid file.";
default = "/var/osquery/osqueryd.pidfile";
};
utc = mkOption {
type = types.bool;
description = "Attempt to convert all UNIX calendar times to UTC.";
default = true;
};
databasePath = mkOption {
type = types.path;
description = "Path used for database file.";
default = "/var/osquery/osquery.db";
};
extraConfig = mkOption {
type = types.attrs // {
merge = loc: foldl' (res: def: recursiveUpdate res def.value) {};
};
description = "Extra config to be recursively merged into the JSON config file.";
default = { };
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.osquery ];
environment.etc."osquery/osquery.conf".text = toJSON (
recursiveUpdate {
options = {
config_plugin = "filesystem";
logger_plugin = "filesystem";
logger_path = cfg.loggerPath;
database_path = cfg.databasePath;
utc = cfg.utc;
};
} cfg.extraConfig
);
systemd.services.osqueryd = {
description = "The osquery Daemon";
after = [ "network.target" "syslog.service" ];
wantedBy = [ "multi-user.target" ];
path = [ pkgs.osquery ];
preStart = ''
mkdir -p ${escapeShellArg cfg.loggerPath}
mkdir -p "$(dirname ${escapeShellArg cfg.pidfile})"
mkdir -p "$(dirname ${escapeShellArg cfg.databasePath})"
'';
serviceConfig = {
TimeoutStartSec = "infinity";
ExecStart = "${pkgs.osquery}/bin/osqueryd --logger_path ${escapeShellArg cfg.loggerPath} --pidfile ${escapeShellArg cfg.pidfile} --database_path ${escapeShellArg cfg.databasePath}";
KillMode = "process";
KillSignal = "SIGTERM";
Restart = "on-failure";
};
};
};
}

View File

@ -1,357 +0,0 @@
{ config, lib, pkgs, ...} :
with lib;
let
cfg = config.services.beegfs;
# functions for the generations of config files
configMgmtd = name: cfg: pkgs.writeText "mgmt-${name}.conf" ''
storeMgmtdDirectory = ${cfg.mgmtd.storeDir}
storeAllowFirstRunInit = false
connAuthFile = ${cfg.connAuthFile}
connPortShift = ${toString cfg.connPortShift}
${cfg.mgmtd.extraConfig}
'';
configAdmon = name: cfg: pkgs.writeText "admon-${name}.conf" ''
sysMgmtdHost = ${cfg.mgmtdHost}
connAuthFile = ${cfg.connAuthFile}
connPortShift = ${toString cfg.connPortShift}
${cfg.admon.extraConfig}
'';
configMeta = name: cfg: pkgs.writeText "meta-${name}.conf" ''
storeMetaDirectory = ${cfg.meta.storeDir}
sysMgmtdHost = ${cfg.mgmtdHost}
connAuthFile = ${cfg.connAuthFile}
connPortShift = ${toString cfg.connPortShift}
storeAllowFirstRunInit = false
${cfg.meta.extraConfig}
'';
configStorage = name: cfg: pkgs.writeText "storage-${name}.conf" ''
storeStorageDirectory = ${cfg.storage.storeDir}
sysMgmtdHost = ${cfg.mgmtdHost}
connAuthFile = ${cfg.connAuthFile}
connPortShift = ${toString cfg.connPortShift}
storeAllowFirstRunInit = false
${cfg.storage.extraConfig}
'';
configHelperd = name: cfg: pkgs.writeText "helperd-${name}.conf" ''
connAuthFile = ${cfg.connAuthFile}
${cfg.helperd.extraConfig}
'';
configClientFilename = name : "/etc/beegfs/client-${name}.conf";
configClient = name: cfg: ''
sysMgmtdHost = ${cfg.mgmtdHost}
connAuthFile = ${cfg.connAuthFile}
connPortShift = ${toString cfg.connPortShift}
${cfg.client.extraConfig}
'';
serviceList = [
{ service = "admon"; cfgFile = configAdmon; }
{ service = "meta"; cfgFile = configMeta; }
{ service = "mgmtd"; cfgFile = configMgmtd; }
{ service = "storage"; cfgFile = configStorage; }
];
# functions to generate systemd.service entries
systemdEntry = service: cfgFile: (mapAttrs' ( name: cfg:
(nameValuePair "beegfs-${service}-${name}" (mkIf cfg.${service}.enable {
wantedBy = [ "multi-user.target" ];
requires = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = rec {
ExecStart = ''
${pkgs.beegfs}/bin/beegfs-${service} \
cfgFile=${cfgFile name cfg} \
pidFile=${PIDFile}
'';
PIDFile = "/run/beegfs-${service}-${name}.pid";
TimeoutStopSec = "300";
};
}))) cfg);
systemdHelperd = mapAttrs' ( name: cfg:
(nameValuePair "beegfs-helperd-${name}" (mkIf cfg.client.enable {
wantedBy = [ "multi-user.target" ];
requires = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = rec {
ExecStart = ''
${pkgs.beegfs}/bin/beegfs-helperd \
cfgFile=${configHelperd name cfg} \
pidFile=${PIDFile}
'';
PIDFile = "/run/beegfs-helperd-${name}.pid";
TimeoutStopSec = "300";
};
}))) cfg;
# wrappers to beegfs tools. Avoid typing path of config files
utilWrappers = mapAttrsToList ( name: cfg:
( pkgs.runCommand "beegfs-utils-${name}" {
nativeBuildInputs = [ pkgs.makeWrapper ];
preferLocalBuild = true;
} ''
mkdir -p $out/bin
makeWrapper ${pkgs.beegfs}/bin/beegfs-check-servers \
$out/bin/beegfs-check-servers-${name} \
--add-flags "-c ${configClientFilename name}" \
--prefix PATH : ${lib.makeBinPath [ pkgs.beegfs ]}
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
$out/bin/beegfs-ctl-${name} \
--add-flags "--cfgFile=${configClientFilename name}"
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
$out/bin/beegfs-df-${name} \
--add-flags "--cfgFile=${configClientFilename name}" \
--add-flags --listtargets \
--add-flags --hidenodeid \
--add-flags --pools \
--add-flags --spaceinfo
makeWrapper ${pkgs.beegfs}/bin/beegfs-fsck \
$out/bin/beegfs-fsck-${name} \
--add-flags "--cfgFile=${configClientFilename name}"
''
)) cfg;
in
{
###### interface
options = {
services.beegfsEnable = mkEnableOption "BeeGFS";
services.beegfs = mkOption {
default = {};
description = ''
BeeGFS configurations. Every mount point requires a separate configuration.
'';
type = with types; attrsOf (submodule ({ ... } : {
options = {
mgmtdHost = mkOption {
type = types.str;
default = null;
example = "master";
description = ''Hostname of managament host.'';
};
connAuthFile = mkOption {
type = types.str;
default = "";
example = "/etc/my.key";
description = "File containing shared secret authentication.";
};
connPortShift = mkOption {
type = types.int;
default = 0;
example = 5;
description = ''
For each additional beegfs configuration shift all
service TCP/UDP ports by at least 5.
'';
};
client = {
enable = mkEnableOption "BeeGFS client";
mount = mkOption {
type = types.bool;
default = true;
description = "Create fstab entry automatically";
};
mountPoint = mkOption {
type = types.str;
default = "/run/beegfs";
description = ''
Mount point under which the beegfs filesytem should be mounted.
If mounted manually the mount option specifing the config file is needed:
cfgFile=/etc/beegfs/beegfs-client-&lt;name&gt;.conf
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional lines for beegfs-client.conf.
See documentation for further details.
'';
};
};
helperd = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Enable the BeeGFS helperd.
The helpered is need for logging purposes on the client.
Disabling <literal>helperd</literal> allows for runing the client
with <literal>allowUnfree = false</literal>.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional lines for beegfs-helperd.conf. See documentation
for further details.
'';
};
};
mgmtd = {
enable = mkEnableOption "BeeGFS mgmtd daemon";
storeDir = mkOption {
type = types.path;
default = null;
example = "/data/beegfs-mgmtd";
description = ''
Data directory for mgmtd.
Must not be shared with other beegfs daemons.
This directory must exist and it must be initialized
with beegfs-setup-mgmtd, e.g. "beegfs-setup-mgmtd -C -p &lt;storeDir&gt;"
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional lines for beegfs-mgmtd.conf. See documentation
for further details.
'';
};
};
admon = {
enable = mkEnableOption "BeeGFS admon daemon";
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional lines for beegfs-admon.conf. See documentation
for further details.
'';
};
};
meta = {
enable = mkEnableOption "BeeGFS meta data daemon";
storeDir = mkOption {
type = types.path;
default = null;
example = "/data/beegfs-meta";
description = ''
Data directory for meta data service.
Must not be shared with other beegfs daemons.
The underlying filesystem must be mounted with xattr turned on.
This directory must exist and it must be initialized
with beegfs-setup-meta, e.g.
"beegfs-setup-meta -C -s &lt;serviceID&gt; -p &lt;storeDir&gt;"
'';
};
extraConfig = mkOption {
type = types.str;
default = "";
description = ''
Additional lines for beegfs-meta.conf. See documentation
for further details.
'';
};
};
storage = {
enable = mkEnableOption "BeeGFS storage daemon";
storeDir = mkOption {
type = types.path;
default = null;
example = "/data/beegfs-storage";
description = ''
Data directories for storage service.
Must not be shared with other beegfs daemons.
The underlying filesystem must be mounted with xattr turned on.
This directory must exist and it must be initialized
with beegfs-setup-storage, e.g.
"beegfs-setup-storage -C -s &lt;serviceID&gt; -i &lt;storageTargetID&gt; -p &lt;storeDir&gt;"
'';
};
extraConfig = mkOption {
type = types.str;
default = "";
description = ''
Addional lines for beegfs-storage.conf. See documentation
for further details.
'';
};
};
};
}));
};
};
###### implementation
config =
mkIf config.services.beegfsEnable {
environment.systemPackages = utilWrappers;
# Put the client.conf files in /etc since they are needed
# by the commandline tools
environment.etc = mapAttrs' ( name: cfg:
(nameValuePair "beegfs/client-${name}.conf" (mkIf (cfg.client.enable)
{
enable = true;
text = configClient name cfg;
}))) cfg;
# Kernel module, we need it only once per host.
boot = mkIf (
foldr (a: b: a || b) false
(map (x: x.client.enable) (collect (x: x ? client) cfg)))
{
kernelModules = [ "beegfs" ];
extraModulePackages = [ pkgs.linuxPackages.beegfs-module ];
};
# generate fstab entries
fileSystems = mapAttrs' (name: cfg:
(nameValuePair cfg.client.mountPoint (optionalAttrs cfg.client.mount (mkIf cfg.client.enable {
device = "beegfs_nodev";
fsType = "beegfs";
mountPoint = cfg.client.mountPoint;
options = [ "cfgFile=${configClientFilename name}" "_netdev" ];
})))) cfg;
# generate systemd services
systemd.services = systemdHelperd //
foldr (a: b: a // b) {}
(map (x: systemdEntry x.service x.cfgFile) serviceList);
};
}

View File

@ -4,7 +4,7 @@ with pkgs;
with lib; with lib;
let let
cfg = config.networking.connman; cfg = config.services.connman;
configFile = pkgs.writeText "connman.conf" '' configFile = pkgs.writeText "connman.conf" ''
[General] [General]
NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist} NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist}
@ -17,7 +17,7 @@ in {
options = { options = {
networking.connman = { services.connman = {
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
@ -71,13 +71,13 @@ in {
assertions = [{ assertions = [{
assertion = !config.networking.useDHCP; assertion = !config.networking.useDHCP;
message = "You can not use services.networking.connman with services.networking.useDHCP"; message = "You can not use services.connman with networking.useDHCP";
}{ }{
assertion = config.networking.wireless.enable; assertion = config.networking.wireless.enable;
message = "You must use services.networking.connman with services.networking.wireless"; message = "You must use services.connman with networking.wireless";
}{ }{
assertion = !config.networking.networkmanager.enable; assertion = !config.networking.networkmanager.enable;
message = "You can not use services.networking.connman with services.networking.networkmanager"; message = "You can not use services.connman with networking.networkmanager";
}]; }];
environment.systemPackages = [ connman ]; environment.systemPackages = [ connman ];

View File

@ -239,7 +239,7 @@ in
services.znc = { services.znc = {
configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString); configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString);
config = { config = {
Version = (builtins.parseDrvName pkgs.znc.name).version; Version = lib.getVersion pkgs.znc;
Listener.l.Port = mkDefault 5000; Listener.l.Port = mkDefault 5000;
Listener.l.SSL = mkDefault true; Listener.l.SSL = mkDefault true;
}; };

View File

@ -47,8 +47,8 @@ let
grub = f grub; grub = f grub;
grubTarget = f (grub.grubTarget or ""); grubTarget = f (grub.grubTarget or "");
shell = "${pkgs.runtimeShell}"; shell = "${pkgs.runtimeShell}";
fullName = (builtins.parseDrvName realGrub.name).name; fullName = lib.getName realGrub;
fullVersion = (builtins.parseDrvName realGrub.name).version; fullVersion = lib.getVersion realGrub;
grubEfi = f grubEfi; grubEfi = f grubEfi;
grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else ""; grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
bootPath = args.path; bootPath = args.path;

View File

@ -924,6 +924,8 @@ in
config = mkIf config.systemd.network.enable { config = mkIf config.systemd.network.enable {
users.users.systemd-network.group = "systemd-network";
systemd.additionalUpstreamSystemUnits = [ systemd.additionalUpstreamSystemUnits = [
"systemd-networkd.service" "systemd-networkd-wait-online.service" "systemd-networkd.service" "systemd-networkd-wait-online.service"
]; ];

View File

@ -136,6 +136,8 @@ in
} }
]; ];
users.users.resolved.group = "systemd-resolve";
systemd.additionalUpstreamSystemUnits = [ systemd.additionalUpstreamSystemUnits = [
"systemd-resolved.service" "systemd-resolved.service"
]; ];

View File

@ -50,7 +50,10 @@ with lib;
${config.services.timesyncd.extraConfig} ${config.services.timesyncd.extraConfig}
''; '';
users.users.systemd-timesync.uid = config.ids.uids.systemd-timesync; users.users.systemd-timesync = {
uid = config.ids.uids.systemd-timesync;
group = "systemd-timesync";
};
users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync; users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
system.activationScripts.systemd-timesyncd-migration = mkIf (versionOlder config.system.stateVersion "19.09") '' system.activationScripts.systemd-timesyncd-migration = mkIf (versionOlder config.system.stateVersion "19.09") ''

View File

@ -149,7 +149,7 @@ let
--setenv PATH="$PATH" \ --setenv PATH="$PATH" \
${optionalString cfg.ephemeral "--ephemeral"} \ ${optionalString cfg.ephemeral "--ephemeral"} \
${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then ${if cfg.additionalCapabilities != null && cfg.additionalCapabilities != [] then
''--capability="${concatStringsSep " " cfg.additionalCapabilities}"'' else "" ''--capability="${concatStringsSep "," cfg.additionalCapabilities}"'' else ""
} \ } \
${if cfg.tmpfs != null && cfg.tmpfs != [] then ${if cfg.tmpfs != null && cfg.tmpfs != [] then
''--tmpfs=${concatStringsSep " --tmpfs=" cfg.tmpfs}'' else "" ''--tmpfs=${concatStringsSep " --tmpfs=" cfg.tmpfs}'' else ""

View File

@ -0,0 +1,197 @@
{ config, pkgs, lib, modulesPath, ... }:
with lib;
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/virtualisation/digital-ocean-init.nix")
];
options.virtualisation.digitalOcean = with types; {
setRootPassword = mkOption {
type = bool;
default = false;
example = true;
description = "Whether to set the root password from the Digital Ocean metadata";
};
setSshKeys = mkOption {
type = bool;
default = true;
example = true;
description = "Whether to fetch ssh keys from Digital Ocean";
};
seedEntropy = mkOption {
type = bool;
default = true;
example = true;
description = "Whether to run the kernel RNG entropy seeding script from the Digital Ocean vendor data";
};
};
config =
let
cfg = config.virtualisation.digitalOcean;
hostName = config.networking.hostName;
doMetadataFile = "/run/do-metadata/v1.json";
in mkMerge [{
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
boot = {
growPartition = true;
kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ];
initrd.kernelModules = [ "virtio_scsi" ];
kernelModules = [ "virtio_pci" "virtio_net" ];
loader = {
grub.device = "/dev/vda";
timeout = 0;
grub.configurationLimit = 0;
};
};
services.openssh = {
enable = mkDefault true;
passwordAuthentication = mkDefault false;
};
services.do-agent.enable = mkDefault true;
networking = {
hostName = mkDefault ""; # use Digital Ocean metadata server
};
/* Check for and wait for the metadata server to become reachable.
* This serves as a dependency for all the other metadata services. */
systemd.services.digitalocean-metadata = {
path = [ pkgs.curl ];
description = "Get host metadata provided by Digitalocean";
script = ''
set -eu
DO_DELAY_ATTEMPTS=0
while ! curl -fsSL -o $RUNTIME_DIRECTORY/v1.json http://169.254.169.254/metadata/v1.json; do
DO_DELAY_ATTEMPTS=$((DO_DELAY_ATTEMPTS + 1))
if (( $DO_DELAY_ATTEMPTS >= $DO_DELAY_ATTEMPTS_MAX )); then
echo "giving up"
exit 1
fi
echo "metadata unavailable, trying again in 1s..."
sleep 1
done
chmod 600 $RUNTIME_DIRECTORY/v1.json
'';
environment = {
DO_DELAY_ATTEMPTS_MAX = "10";
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
RuntimeDirectory = "do-metadata";
RuntimeDirectoryPreserve = "yes";
};
unitConfig = {
ConditionPathExists = "!${doMetadataFile}";
After = [ "network-pre.target" ] ++
optional config.networking.dhcpcd.enable "dhcpcd.service" ++
optional config.systemd.network.enable "systemd-networkd.service";
};
};
/* Fetch the root password from the digital ocean metadata.
* There is no specific route for this, so we use jq to get
* it from the One Big JSON metadata blob */
systemd.services.digitalocean-set-root-password = mkIf cfg.setRootPassword {
path = [ pkgs.shadow pkgs.jq ];
description = "Set root password provided by Digitalocean";
wantedBy = [ "multi-user.target" ];
script = ''
set -eo pipefail
ROOT_PASSWORD=$(jq -er '.auth_key' ${doMetadataFile})
echo "root:$ROOT_PASSWORD" | chpasswd
mkdir -p /etc/do-metadata/set-root-password
'';
unitConfig = {
ConditionPathExists = "!/etc/do-metadata/set-root-password";
Before = optional config.services.openssh.enable "sshd.service";
After = [ "digitalocean-metadata.service" ];
Requires = [ "digitalocean-metadata.service" ];
};
serviceConfig = {
Type = "oneshot";
};
};
/* Set the hostname from Digital Ocean, unless the user configured it in
* the NixOS configuration. The cached metadata file isn't used here
* because the hostname is a mutable part of the droplet. */
systemd.services.digitalocean-set-hostname = mkIf (hostName == "") {
path = [ pkgs.curl pkgs.nettools ];
description = "Set hostname provided by Digitalocean";
wantedBy = [ "network.target" ];
script = ''
set -e
DIGITALOCEAN_HOSTNAME=$(curl -fsSL http://169.254.169.254/metadata/v1/hostname)
hostname "$DIGITALOCEAN_HOSTNAME"
if [[ ! -e /etc/hostname || -w /etc/hostname ]]; then
printf "%s\n" "$DIGITALOCEAN_HOSTNAME" > /etc/hostname
fi
'';
unitConfig = {
Before = [ "network.target" ];
After = [ "digitalocean-metadata.service" ];
Wants = [ "digitalocean-metadata.service" ];
};
serviceConfig = {
Type = "oneshot";
};
};
/* Fetch the ssh keys for root from Digital Ocean */
systemd.services.digitalocean-ssh-keys = mkIf cfg.setSshKeys {
description = "Set root ssh keys provided by Digital Ocean";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.jq ];
script = ''
set -e
mkdir -m 0700 -p /root/.ssh
jq -er '.public_keys[]' ${doMetadataFile} > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
unitConfig = {
ConditionPathExists = "!/root/.ssh/authorized_keys";
Before = optional config.services.openssh.enable "sshd.service";
After = [ "digitalocean-metadata.service" ];
Requires = [ "digitalocean-metadata.service" ];
};
};
/* Initialize the RNG by running the entropy-seed script from the
* Digital Ocean metadata
*/
systemd.services.digitalocean-entropy-seed = mkIf cfg.seedEntropy {
description = "Run the kernel RNG entropy seeding script from the Digital Ocean vendor data";
wantedBy = [ "network.target" ];
path = [ pkgs.jq pkgs.mpack ];
script = ''
set -eo pipefail
TEMPDIR=$(mktemp -d)
jq -er '.vendor_data' ${doMetadataFile} | munpack -tC $TEMPDIR
ENTROPY_SEED=$(grep -rl "DigitalOcean Entropy Seed script" $TEMPDIR)
${pkgs.runtimeShell} $ENTROPY_SEED
rm -rf $TEMPDIR
'';
unitConfig = {
Before = [ "network.target" ];
After = [ "digitalocean-metadata.service" ];
Requires = [ "digitalocean-metadata.service" ];
};
serviceConfig = {
Type = "oneshot";
};
};
}
];
meta.maintainers = with maintainers; [ arianvp eamsden ];
}

View File

@ -0,0 +1,69 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.digitalOceanImage;
in
{
imports = [ ./digital-ocean-config.nix ];
options = {
virtualisation.digitalOceanImage.diskSize = mkOption {
type = with types; int;
default = 4096;
description = ''
Size of disk image. Unit is MB.
'';
};
virtualisation.digitalOceanImage.configFile = mkOption {
type = with types; nullOr path;
default = null;
description = ''
A path to a configuration file which will be placed at
<literal>/etc/nixos/configuration.nix</literal> and be used when switching
to a new configuration. If set to <literal>null</literal>, a default
configuration is used that imports
<literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>.
'';
};
virtualisation.digitalOceanImage.compressionMethod = mkOption {
type = types.enum [ "gzip" "bzip2" ];
default = "gzip";
example = "bzip2";
description = ''
Disk image compression method. Choose bzip2 to generate smaller images that
take longer to generate but will consume less metered storage space on your
Digital Ocean account.
'';
};
};
#### implementation
config = {
system.build.digitalOceanImage = import ../../lib/make-disk-image.nix {
name = "digital-ocean-image";
format = "qcow2";
postVM = let
compress = {
"gzip" = "${pkgs.gzip}/bin/gzip";
"bzip2" = "${pkgs.bzip2}/bin/bzip2";
}.${cfg.compressionMethod};
in ''
${compress} $diskImage
'';
configFile = if cfg.configFile == null
then config.virtualisation.digitalOcean.defaultConfigFile
else cfg.configFile;
inherit (cfg) diskSize;
inherit config lib pkgs;
};
};
meta.maintainers = with maintainers; [ arianvp eamsden ];
}

View File

@ -0,0 +1,95 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.virtualisation.digitalOcean;
defaultConfigFile = pkgs.writeText "digitalocean-configuration.nix" ''
{ modulesPath, lib, ... }:
{
imports = lib.optional (builtins.pathExists ./do-userdata.nix) ./do-userdata.nix ++ [
(modulesPath + "/virtualisation/digital-ocean-config.nix")
];
}
'';
in {
options.virtualisation.digitalOcean.rebuildFromUserData = mkOption {
type = types.bool;
default = true;
example = true;
description = "Whether to reconfigure the system from Digital Ocean user data";
};
options.virtualisation.digitalOcean.defaultConfigFile = mkOption {
type = types.path;
default = defaultConfigFile;
defaultText = ''
The default configuration imports user-data if applicable and
<literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>.
'';
description = ''
A path to a configuration file which will be placed at
<literal>/etc/nixos/configuration.nix</literal> and be used when switching to
a new configuration.
'';
};
config = {
systemd.services.digitalocean-init = mkIf cfg.rebuildFromUserData {
description = "Reconfigure the system from Digital Ocean userdata on startup";
wantedBy = [ "network-online.target" ];
unitConfig = {
ConditionPathExists = "!/etc/nixos/do-userdata.nix";
After = [ "digitalocean-metadata.service" "network-online.target" ];
Requires = [ "digitalocean-metadata.service" ];
X-StopOnRemoval = false;
};
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
restartIfChanged = false;
path = [ pkgs.jq pkgs.gnused pkgs.gnugrep pkgs.systemd config.nix.package config.system.build.nixos-rebuild ];
environment = {
HOME = "/root";
NIX_PATH = concatStringsSep ":" [
"/nix/var/nix/profiles/per-user/root/channels/nixos"
"nixos-config=/etc/nixos/configuration.nix"
"/nix/var/nix/profiles/per-user/root/channels"
];
};
script = ''
set -e
echo "attempting to fetch configuration from Digital Ocean user data..."
userData=$(mktemp)
if jq -er '.user_data' /run/do-metadata/v1.json > $userData; then
# If the user-data looks like it could be a nix expression,
# copy it over. Also, look for a magic three-hash comment and set
# that as the channel.
if nix-instantiate --parse $userData > /dev/null; then
channels="$(grep '^###' "$userData" | sed 's|###\s*||')"
printf "%s" "$channels" | while read channel; do
echo "writing channel: $channel"
done
if [[ -n "$channels" ]]; then
printf "%s" "$channels" > /root/.nix-channels
nix-channel --update
fi
echo "setting configuration from Digital Ocean user data"
cp "$userData" /etc/nixos/do-userdata.nix
if [[ ! -e /etc/nixos/configuration.nix ]]; then
install -m0644 ${cfg.defaultConfigFile} /etc/nixos/configuration.nix
fi
else
echo "user data does not appear to be a Nix expression; ignoring"
exit
fi
nixos-rebuild switch
else
echo "no user data is available"
fi
'';
};
};
meta.maintainers = with maintainers; [ arianvp eamsden ];
}

View File

@ -42,6 +42,9 @@ in {
default = false; default = false;
description = '' description = ''
Whether to start racoon service for openvswitch. Whether to start racoon service for openvswitch.
Supported only if openvswitch version is less than 2.6.0.
Use <literal>virtualisation.vswitch.package = pkgs.openvswitch-lts</literal>
for a version that supports ipsec over GRE.
''; '';
}; };
}; };
@ -89,6 +92,13 @@ in {
"${cfg.package}/share/openvswitch/vswitch.ovsschema" "${cfg.package}/share/openvswitch/vswitch.ovsschema"
fi fi
chmod -R +w /var/db/openvswitch chmod -R +w /var/db/openvswitch
if ${cfg.package}/bin/ovsdb-tool needs-conversion /var/db/openvswitch/conf.db | grep -q "yes"
then
echo "Performing database upgrade"
${cfg.package}/bin/ovsdb-tool convert /var/db/openvswitch/conf.db
else
echo "Database already up to date"
fi
''; '';
serviceConfig = { serviceConfig = {
ExecStart = ExecStart =
@ -133,7 +143,7 @@ in {
}; };
} }
(mkIf cfg.ipsec { (mkIf (cfg.ipsec && (versionOlder cfg.package.version "2.6.0")) {
services.racoon.enable = true; services.racoon.enable = true;
services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf"; services.racoon.configPath = "${runDir}/ipsec/etc/racoon/racoon.conf";
@ -172,5 +182,4 @@ in {
''; '';
}; };
})])); })]));
} }

View File

@ -620,7 +620,7 @@ in
# Wireless won't work in the VM. # Wireless won't work in the VM.
networking.wireless.enable = mkVMOverride false; networking.wireless.enable = mkVMOverride false;
networking.connman.enable = mkVMOverride false; services.connman.enable = mkVMOverride false;
# Speed up booting by not waiting for ARP. # Speed up booting by not waiting for ARP.
networking.dhcpcd.extraConfig = "noarp"; networking.dhcpcd.extraConfig = "noarp";

View File

@ -28,7 +28,7 @@ in
babeld = handleTest ./babeld.nix {}; babeld = handleTest ./babeld.nix {};
bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64 bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
beanstalkd = handleTest ./beanstalkd.nix {}; beanstalkd = handleTest ./beanstalkd.nix {};
beegfs = handleTestOn ["x86_64-linux"] ./beegfs.nix {}; # beegfs is unsupported on aarch64 bees = handleTest ./bees.nix {};
bind = handleTest ./bind.nix {}; bind = handleTest ./bind.nix {};
bittorrent = handleTest ./bittorrent.nix {}; bittorrent = handleTest ./bittorrent.nix {};
#blivet = handleTest ./blivet.nix {}; # broken since 2017-07024 #blivet = handleTest ./blivet.nix {}; # broken since 2017-07024
@ -206,7 +206,6 @@ in
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {}; openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
orangefs = handleTest ./orangefs.nix {}; orangefs = handleTest ./orangefs.nix {};
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {}; os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
osquery = handleTest ./osquery.nix {};
osrm-backend = handleTest ./osrm-backend.nix {}; osrm-backend = handleTest ./osrm-backend.nix {};
overlayfs = handleTest ./overlayfs.nix {}; overlayfs = handleTest ./overlayfs.nix {};
packagekit = handleTest ./packagekit.nix {}; packagekit = handleTest ./packagekit.nix {};

View File

@ -1,115 +0,0 @@
import ./make-test.nix ({ ... } :
let
connAuthFile="beegfs/auth-def.key";
client = { pkgs, ... } : {
networking.firewall.enable = false;
services.beegfsEnable = true;
services.beegfs.default = {
mgmtdHost = "mgmt";
connAuthFile = "/etc/${connAuthFile}";
client = {
mount = false;
enable = true;
};
};
fileSystems = pkgs.lib.mkVMOverride # FIXME: this should be creatd by the module
[ { mountPoint = "/beegfs";
device = "default";
fsType = "beegfs";
options = [ "cfgFile=/etc/beegfs/client-default.conf" "_netdev" ];
}
];
environment.etc.${connAuthFile} = {
enable = true;
text = "ThisIsALousySecret";
mode = "0600";
};
};
server = service : { pkgs, ... } : {
networking.firewall.enable = false;
boot.initrd.postDeviceCommands = ''
${pkgs.e2fsprogs}/bin/mkfs.ext4 -L data /dev/vdb
'';
virtualisation.emptyDiskImages = [ 4096 ];
fileSystems = pkgs.lib.mkVMOverride
[ { mountPoint = "/data";
device = "/dev/disk/by-label/data";
fsType = "ext4";
}
];
environment.systemPackages = with pkgs; [ beegfs ];
environment.etc.${connAuthFile} = {
enable = true;
text = "ThisIsALousySecret";
mode = "0600";
};
services.beegfsEnable = true;
services.beegfs.default = {
mgmtdHost = "mgmt";
connAuthFile = "/etc/${connAuthFile}";
${service} = {
enable = true;
storeDir = "/data";
};
};
};
in
{
name = "beegfs";
nodes = {
meta = server "meta";
mgmt = server "mgmtd";
storage1 = server "storage";
storage2 = server "storage";
client1 = client;
client2 = client;
};
testScript = ''
# Initalize the data directories
$mgmt->waitForUnit("default.target");
$mgmt->succeed("beegfs-setup-mgmtd -C -f -p /data");
$mgmt->succeed("systemctl start beegfs-mgmtd-default");
$meta->waitForUnit("default.target");
$meta->succeed("beegfs-setup-meta -C -f -s 1 -p /data");
$meta->succeed("systemctl start beegfs-meta-default");
$storage1->waitForUnit("default.target");
$storage1->succeed("beegfs-setup-storage -C -f -s 1 -i 1 -p /data");
$storage1->succeed("systemctl start beegfs-storage-default");
$storage2->waitForUnit("default.target");
$storage2->succeed("beegfs-setup-storage -C -f -s 2 -i 2 -p /data");
$storage2->succeed("systemctl start beegfs-storage-default");
#
# Basic test
$client1->waitForUnit("beegfs.mount");
$client1->succeed("beegfs-check-servers-default");
$client1->succeed("echo test > /beegfs/test");
$client2->waitForUnit("beegfs.mount");
$client2->succeed("test -e /beegfs/test");
$client2->succeed("cat /beegfs/test | grep test");
# test raid0/stripping
$client1->succeed("dd if=/dev/urandom bs=1M count=10 of=/beegfs/striped");
$client2->succeed("cat /beegfs/striped > /dev/null");
# check if fs is still healthy
$client1->succeed("beegfs-fsck-default --checkfs");
'';
})

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, ... }: import ./make-test-python.nix ({ lib, pkgs, ... }:
{ {
name = "bees"; name = "bees";
@ -29,27 +29,34 @@ import ./make-test.nix ({ lib, ... }:
testScript = testScript =
let let
withRetry = content: maxTests: sleepTime: '' someContentIsShared = loc: pkgs.writeShellScript "some-content-is-shared" ''
max_tests=${lib.escapeShellArg maxTests}; sleep_time=${lib.escapeShellArg sleepTime}; for ((i=0; i<max_tests; i++)); do ${content} && exit 0; sleep "$sleep_time"; done; exit 1; [[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]]
''; '';
someContentIsShared = loc: ''[[ $(btrfs fi du -s --raw ${lib.escapeShellArg loc}/dedup-me-{1,2} | awk 'BEGIN { count=0; } NR>1 && $3 == 0 { count++ } END { print count }') -eq 0 ]]'';
in '' in ''
# shut down the instance started by systemd at boot, so we can test our test procedure # shut down the instance started by systemd at boot, so we can test our test procedure
$machine->succeed("systemctl stop beesd\@aux1.service"); machine.succeed("systemctl stop beesd@aux1.service")
$machine->succeed("dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8"); machine.succeed(
$machine->succeed("cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2"); "dd if=/dev/urandom of=/aux1/dedup-me-1 bs=1M count=8",
$machine->succeed("cp --reflink=never /aux1/* /aux2/"); "cp --reflink=never /aux1/dedup-me-1 /aux1/dedup-me-2",
$machine->succeed("sync"); "cp --reflink=never /aux1/* /aux2/",
$machine->fail(q(${someContentIsShared "/aux1"})); "sync",
$machine->fail(q(${someContentIsShared "/aux2"})); )
$machine->succeed("systemctl start beesd\@aux1.service"); machine.fail(
"${someContentIsShared "/aux1"}",
"${someContentIsShared "/aux2"}",
)
machine.succeed("systemctl start beesd@aux1.service")
# assert that "Set Shared" column is nonzero # assert that "Set Shared" column is nonzero
$machine->succeed(q(${withRetry (someContentIsShared "/aux1") 20 2})); machine.wait_until_succeeds(
$machine->fail(q(${someContentIsShared "/aux2"})); "${someContentIsShared "/aux1"}",
)
machine.fail("${someContentIsShared "/aux2"}")
# assert that 16MB hash table size requested was honored # assert that 16MB hash table size requested was honored
$machine->succeed(q([[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]])) machine.succeed(
"[[ $(stat -c %s /aux1/.beeshome/beeshash.dat) = $(( 16 * 1024 * 1024)) ]]"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: import ./make-test-python.nix ({ pkgs, lib, ... }:
{ {
name = "codimd"; name = "codimd";
@ -35,20 +35,18 @@ import ./make-test.nix ({ pkgs, lib, ... }:
}; };
testScript = '' testScript = ''
startAll(); start_all()
subtest "CodiMD sqlite", sub { with subtest("CodiMD sqlite"):
$codimdSqlite->waitForUnit("codimd.service"); codimdSqlite.wait_for_unit("codimd.service")
$codimdSqlite->waitForOpenPort(3000); codimdSqlite.wait_for_open_port(3000)
$codimdSqlite->waitUntilSucceeds("curl -sSf http://localhost:3000/new"); codimdSqlite.wait_until_succeeds("curl -sSf http://localhost:3000/new")
};
subtest "CodiMD postgres", sub { with subtest("CodiMD postgres"):
$codimdPostgres->waitForUnit("postgresql.service"); codimdPostgres.wait_for_unit("postgresql.service")
$codimdPostgres->waitForUnit("codimd.service"); codimdPostgres.wait_for_unit("codimd.service")
$codimdPostgres->waitForOpenPort(5432); codimdPostgres.wait_for_open_port(5432)
$codimdPostgres->waitForOpenPort(3000); codimdPostgres.wait_for_open_port(3000)
$codimdPostgres->waitUntilSucceeds("curl -sSf http://localhost:3000/new"); codimdPostgres.wait_until_succeeds("curl -sSf http://localhost:3000/new")
};
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs docker-registry and check if it works # This test runs docker-registry and check if it works
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "docker-registry"; name = "docker-registry";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ globin ma27 ironpinguin ]; maintainers = [ globin ma27 ironpinguin ];
@ -28,36 +28,34 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
$client1->start(); client1.start()
$client1->waitForUnit("docker.service"); client1.wait_for_unit("docker.service")
$client1->succeed("tar cv --files-from /dev/null | docker import - scratch"); client1.succeed("tar cv --files-from /dev/null | docker import - scratch")
$client1->succeed("docker tag scratch registry:8080/scratch"); client1.succeed("docker tag scratch registry:8080/scratch")
$registry->start(); registry.start()
$registry->waitForUnit("docker-registry.service"); registry.wait_for_unit("docker-registry.service")
$registry->waitForOpenPort("8080"); registry.wait_for_open_port("8080")
$client1->succeed("docker push registry:8080/scratch"); client1.succeed("docker push registry:8080/scratch")
$client2->start(); client2.start()
$client2->waitForUnit("docker.service"); client2.wait_for_unit("docker.service")
$client2->succeed("docker pull registry:8080/scratch"); client2.succeed("docker pull registry:8080/scratch")
$client2->succeed("docker images | grep scratch"); client2.succeed("docker images | grep scratch")
$client2->succeed( client2.succeed(
'curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H"Accept: application/vnd.docker.distribution.manifest.v2+json" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e \'s/Docker-Content-Digest: //\' | tr -d \'\r\')' "curl -fsS -X DELETE registry:8080/v2/scratch/manifests/$(curl -fsS -I -H\"Accept: application/vnd.docker.distribution.manifest.v2+json\" registry:8080/v2/scratch/manifests/latest | grep Docker-Content-Digest | sed -e 's/Docker-Content-Digest: //' | tr -d '\\r')"
); )
$registry->systemctl("start docker-registry-garbage-collect.service"); registry.systemctl("start docker-registry-garbage-collect.service")
$registry->waitUntilFails("systemctl status docker-registry-garbage-collect.service"); registry.wait_until_fails("systemctl status docker-registry-garbage-collect.service")
$registry->waitForUnit("docker-registry.service"); registry.wait_for_unit("docker-registry.service")
$registry->fail( registry.fail("ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data")
'ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data'
);
$client1->succeed("docker push registry:8080/scratch"); client1.succeed("docker push registry:8080/scratch")
$registry->succeed( registry.succeed(
'ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data' "ls -l /var/lib/docker-registry/docker/registry/v2/blobs/sha256/*/*/data"
); )
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs simple etcd cluster # This test runs simple etcd cluster
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 {
buildInputs = [ pkgs.openssl ]; buildInputs = [ pkgs.openssl ];
@ -129,29 +129,26 @@ in {
}; };
testScript = '' testScript = ''
subtest "should start etcd cluster", sub { with subtest("should start etcd cluster"):
$node1->start(); node1.start()
$node2->start(); node2.start()
$node1->waitForUnit("etcd.service"); node1.wait_for_unit("etcd.service")
$node2->waitForUnit("etcd.service"); node2.wait_for_unit("etcd.service")
$node2->waitUntilSucceeds("etcdctl cluster-health"); node2.wait_until_succeeds("etcdctl cluster-health")
$node1->succeed("etcdctl set /foo/bar 'Hello world'"); node1.succeed("etcdctl set /foo/bar 'Hello world'")
$node2->succeed("etcdctl get /foo/bar | grep 'Hello world'"); node2.succeed("etcdctl get /foo/bar | grep 'Hello world'")
};
subtest "should add another member", sub { with subtest("should add another member"):
$node1->waitUntilSucceeds("etcdctl member add node3 https://node3:2380"); node1.wait_until_succeeds("etcdctl member add node3 https://node3:2380")
$node3->start(); node3.start()
$node3->waitForUnit("etcd.service"); node3.wait_for_unit("etcd.service")
$node3->waitUntilSucceeds("etcdctl member list | grep 'node3'"); node3.wait_until_succeeds("etcdctl member list | grep 'node3'")
$node3->succeed("etcdctl cluster-health"); node3.succeed("etcdctl cluster-health")
};
subtest "should survive member crash", sub { with subtest("should survive member crash"):
$node3->crash; node3.crash()
$node1->succeed("etcdctl cluster-health"); node1.succeed("etcdctl cluster-health")
$node1->succeed("etcdctl set /foo/bar 'Hello degraded world'"); node1.succeed("etcdctl set /foo/bar 'Hello degraded world'")
$node1->succeed("etcdctl get /foo/bar | grep 'Hello degraded world'"); node1.succeed("etcdctl get /foo/bar | grep 'Hello degraded world'")
};
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs simple etcd node # This test runs simple etcd node
import ./make-test.nix ({ pkgs, ... } : { import ./make-test-python.nix ({ pkgs, ... } : {
name = "etcd"; name = "etcd";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
@ -14,14 +14,12 @@ import ./make-test.nix ({ pkgs, ... } : {
}; };
testScript = '' testScript = ''
subtest "should start etcd node", sub { with subtest("should start etcd node"):
$node->start(); node.start()
$node->waitForUnit("etcd.service"); node.wait_for_unit("etcd.service")
};
subtest "should write and read some values to etcd", sub { with subtest("should write and read some values to etcd"):
$node->succeed("etcdctl set /foo/bar 'Hello world'"); node.succeed("etcdctl set /foo/bar 'Hello world'")
$node->succeed("etcdctl get /foo/bar | grep 'Hello world'"); node.succeed("etcdctl get /foo/bar | grep 'Hello world'")
}
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...}: import ./make-test-python.nix ({ pkgs, ...}:
let let
adminPrivateKey = pkgs.writeText "id_ed25519" '' adminPrivateKey = pkgs.writeText "id_ed25519" ''
@ -43,7 +43,7 @@ let
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZNonUP1ePHLrvn0W9D2hdN6zWWZYFyJc+QR6pOKQEw bob@client
''; '';
gitoliteAdminConfSnippet = '' gitoliteAdminConfSnippet = pkgs.writeText "gitolite-admin-conf-snippet" ''
repo alice-project repo alice-project
RW+ = alice RW+ = alice
''; '';
@ -85,55 +85,54 @@ in
}; };
testScript = '' testScript = ''
startAll; start_all()
subtest "can setup ssh keys on system", sub { with subtest("can setup ssh keys on system"):
$client->mustSucceed("mkdir -p ~root/.ssh"); client.succeed(
$client->mustSucceed("cp ${adminPrivateKey} ~root/.ssh/id_ed25519"); "mkdir -p ~root/.ssh",
$client->mustSucceed("chmod 600 ~root/.ssh/id_ed25519"); "cp ${adminPrivateKey} ~root/.ssh/id_ed25519",
"chmod 600 ~root/.ssh/id_ed25519",
)
client.succeed(
"sudo -u alice mkdir -p ~alice/.ssh",
"sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519",
"sudo -u alice chmod 600 ~alice/.ssh/id_ed25519",
)
client.succeed(
"sudo -u bob mkdir -p ~bob/.ssh",
"sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519",
"sudo -u bob chmod 600 ~bob/.ssh/id_ed25519",
)
$client->mustSucceed("sudo -u alice mkdir -p ~alice/.ssh"); with subtest("gitolite server starts"):
$client->mustSucceed("sudo -u alice cp ${alicePrivateKey} ~alice/.ssh/id_ed25519"); server.wait_for_unit("gitolite-init.service")
$client->mustSucceed("sudo -u alice chmod 600 ~alice/.ssh/id_ed25519"); server.wait_for_unit("sshd.service")
client.succeed("ssh gitolite@server info")
$client->mustSucceed("sudo -u bob mkdir -p ~bob/.ssh"); with subtest("admin can clone and configure gitolite-admin.git"):
$client->mustSucceed("sudo -u bob cp ${bobPrivateKey} ~bob/.ssh/id_ed25519"); client.succeed(
$client->mustSucceed("sudo -u bob chmod 600 ~bob/.ssh/id_ed25519"); "git clone gitolite@server:gitolite-admin.git",
}; "git config --global user.name 'System Administrator'",
"git config --global user.email root\@domain.example",
"cp ${alicePublicKey} gitolite-admin/keydir/alice.pub",
"cp ${bobPublicKey} gitolite-admin/keydir/bob.pub",
"(cd gitolite-admin && git add . && git commit -m 'Add keys for alice, bob' && git push)",
"cat ${gitoliteAdminConfSnippet} >> gitolite-admin/conf/gitolite.conf",
"(cd gitolite-admin && git add . && git commit -m 'Add repo for alice' && git push)",
)
subtest "gitolite server starts", sub { with subtest("non-admins cannot clone gitolite-admin.git"):
$server->waitForUnit("gitolite-init.service"); client.fail("sudo -i -u alice git clone gitolite@server:gitolite-admin.git")
$server->waitForUnit("sshd.service"); client.fail("sudo -i -u bob git clone gitolite@server:gitolite-admin.git")
$client->mustSucceed('ssh gitolite@server info');
};
subtest "admin can clone and configure gitolite-admin.git", sub { with subtest("non-admins can clone testing.git"):
$client->mustSucceed('git clone gitolite@server:gitolite-admin.git'); client.succeed("sudo -i -u alice git clone gitolite@server:testing.git")
$client->mustSucceed("git config --global user.name 'System Administrator'"); client.succeed("sudo -i -u bob git clone gitolite@server:testing.git")
$client->mustSucceed("git config --global user.email root\@domain.example");
$client->mustSucceed("cp ${alicePublicKey} gitolite-admin/keydir/alice.pub");
$client->mustSucceed("cp ${bobPublicKey} gitolite-admin/keydir/bob.pub");
$client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add keys for alice, bob" && git push)');
$client->mustSucceed("printf '${gitoliteAdminConfSnippet}' >> gitolite-admin/conf/gitolite.conf");
$client->mustSucceed('(cd gitolite-admin && git add . && git commit -m "Add repo for alice" && git push)');
};
subtest "non-admins cannot clone gitolite-admin.git", sub { with subtest("alice can clone alice-project.git"):
$client->mustFail('sudo -i -u alice git clone gitolite@server:gitolite-admin.git'); client.succeed("sudo -i -u alice git clone gitolite@server:alice-project.git")
$client->mustFail('sudo -i -u bob git clone gitolite@server:gitolite-admin.git');
};
subtest "non-admins can clone testing.git", sub { with subtest("bob cannot clone alice-project.git"):
$client->mustSucceed('sudo -i -u alice git clone gitolite@server:testing.git'); client.fail("sudo -i -u bob git clone gitolite@server:alice-project.git")
$client->mustSucceed('sudo -i -u bob git clone gitolite@server:testing.git');
};
subtest "alice can clone alice-project.git", sub {
$client->mustSucceed('sudo -i -u alice git clone gitolite@server:alice-project.git');
};
subtest "bob cannot clone alice-project.git", sub {
$client->mustFail('sudo -i -u bob git clone gitolite@server:alice-project.git');
};
''; '';
}) })

View File

@ -1,7 +1,14 @@
import ../make-test.nix ({ pkgs, ... } : import ../make-test-python.nix ({ pkgs, ... } :
let let
inherit (import ./../ssh-keys.nix pkgs) inherit (import ./../ssh-keys.nix pkgs)
snakeOilPrivateKey snakeOilPublicKey; snakeOilPrivateKey snakeOilPublicKey;
# don't check host keys or known hosts, use the snakeoil ssh key
ssh-config = builtins.toFile "ssh.conf" ''
UserKnownHostsFile=/dev/null
StrictHostKeyChecking=no
IdentityFile=~/.ssh/id_snakeoil
'';
in { in {
name = "google-oslogin"; name = "google-oslogin";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
@ -15,38 +22,49 @@ in {
client = { ... }: {}; client = { ... }: {};
}; };
testScript = '' testScript = ''
startAll; start_all()
$server->waitForUnit("mock-google-metadata.service"); server.wait_for_unit("mock-google-metadata.service")
$server->waitForOpenPort(80); server.wait_for_open_port(80)
# mockserver should return a non-expired ssh key for both mockuser and mockadmin # mockserver should return a non-expired ssh key for both mockuser and mockadmin
$server->succeed('${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockuser | grep -q "${snakeOilPublicKey}"'); server.succeed(
$server->succeed('${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockadmin | grep -q "${snakeOilPublicKey}"'); '${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockuser | grep -q "${snakeOilPublicKey}"'
)
server.succeed(
'${pkgs.google-compute-engine-oslogin}/bin/google_authorized_keys mockadmin | grep -q "${snakeOilPublicKey}"'
)
# install snakeoil ssh key on the client # install snakeoil ssh key on the client, and provision .ssh/config file
$client->succeed("mkdir -p ~/.ssh"); client.succeed("mkdir -p ~/.ssh")
$client->succeed("cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil"); client.succeed(
$client->succeed("chmod 600 ~/.ssh/id_snakeoil"); "cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil"
)
client.succeed("chmod 600 ~/.ssh/id_snakeoil")
client.succeed("cp ${ssh-config} ~/.ssh/config")
$client->waitForUnit("network.target"); client.wait_for_unit("network.target")
$server->waitForUnit("sshd.service"); server.wait_for_unit("sshd.service")
# we should not be able to connect as non-existing user # we should not be able to connect as non-existing user
$client->fail("ssh -o User=ghost -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'"); client.fail("ssh ghost@server 'true'")
# we should be able to connect as mockuser # we should be able to connect as mockuser
$client->succeed("ssh -o User=mockuser -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'"); client.succeed("ssh mockuser@server 'true'")
# but we shouldn't be able to sudo # but we shouldn't be able to sudo
$client->fail("ssh -o User=mockuser -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"); client.fail(
"ssh mockuser@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
# we should also be able to log in as mockadmin # we should also be able to log in as mockadmin
$client->succeed("ssh -o User=mockadmin -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil 'true'"); client.succeed("ssh mockadmin@server 'true'")
# pam_oslogin_admin.so should now have generated a sudoers file # pam_oslogin_admin.so should now have generated a sudoers file
$server->succeed("find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/mockadmin'"); server.succeed("find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/mockadmin'")
# and we should be able to sudo # and we should be able to sudo
$client->succeed("ssh -o User=mockadmin -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server -i ~/.ssh/id_snakeoil '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"); client.succeed(
"ssh mockadmin@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ...} : { import ./make-test-python.nix ({ pkgs, lib, ...} : {
name = "gotify-server"; name = "gotify-server";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 ]; maintainers = [ ma27 ];
@ -14,32 +14,32 @@ import ./make-test.nix ({ pkgs, lib, ...} : {
}; };
testScript = '' testScript = ''
startAll; machine.start()
$machine->waitForUnit("gotify-server"); machine.wait_for_unit("gotify-server.service")
$machine->waitForOpenPort(3000); machine.wait_for_open_port(3000)
my $token = $machine->succeed( token = machine.succeed(
"curl --fail -sS -X POST localhost:3000/application -F name=nixos " . "curl --fail -sS -X POST localhost:3000/application -F name=nixos "
'-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' . + '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" '
'| jq .token | xargs echo -n' + "| jq .token | xargs echo -n"
); )
my $usertoken = $machine->succeed( usertoken = machine.succeed(
"curl --fail -sS -X POST localhost:3000/client -F name=nixos " . "curl --fail -sS -X POST localhost:3000/client -F name=nixos "
'-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' . + '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" '
'| jq .token | xargs echo -n' + "| jq .token | xargs echo -n"
); )
$machine->succeed( machine.succeed(
"curl --fail -sS -X POST 'localhost:3000/message?token=$token' -H 'Accept: application/json' " . f"curl --fail -sS -X POST 'localhost:3000/message?token={token}' -H 'Accept: application/json' "
'-F title=Gotify -F message=Works' + "-F title=Gotify -F message=Works"
); )
my $title = $machine->succeed( title = machine.succeed(
"curl --fail -sS 'localhost:3000/message?since=0&token=$usertoken' | jq '.messages|.[0]|.title' | xargs echo -n" f"curl --fail -sS 'localhost:3000/message?since=0&token={usertoken}' | jq '.messages|.[0]|.title' | xargs echo -n"
); )
$title eq "Gotify" or die "Wrong title ($title), expected 'Gotify'!"; assert title == "Gotify"
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: { import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "graylog"; name = "graylog";
meta.maintainers = with lib.maintainers; [ ma27 ]; meta.maintainers = with lib.maintainers; [ ma27 ];
@ -64,48 +64,52 @@ import ./make-test.nix ({ pkgs, lib, ... }: {
facility = "Test"; facility = "Test";
}); });
in '' in ''
$machine->start; machine.start()
$machine->waitForUnit("graylog.service"); machine.wait_for_unit("graylog.service")
$machine->waitForOpenPort(9000); machine.wait_for_open_port(9000)
$machine->succeed("curl -sSfL http://127.0.0.1:9000/"); machine.succeed("curl -sSfL http://127.0.0.1:9000/")
my $session = $machine->succeed("curl -X POST " session = machine.succeed(
. "-sSfL http://127.0.0.1:9000/api/system/sessions " "curl -X POST "
. "-d \$(cat ${payloads.login}) " + "-sSfL http://127.0.0.1:9000/api/system/sessions "
. "-H 'Content-Type: application/json' " + "-d $(cat ${payloads.login}) "
. "-H 'Accept: application/json' " + "-H 'Content-Type: application/json' "
. "-H 'x-requested-by: cli' " + "-H 'Accept: application/json' "
. "| jq .session_id | xargs echo" + "-H 'x-requested-by: cli' "
); + "| jq .session_id | xargs echo"
).rstrip()
chomp($session); machine.succeed(
"curl -X POST "
+ f"-sSfL http://127.0.0.1:9000/api/system/inputs -u {session}:session "
+ '-d $(cat ${payloads.input} | sed -e "s,@node@,$(cat /var/lib/graylog/server/node-id),") '
+ "-H 'Accept: application/json' "
+ "-H 'Content-Type: application/json' "
+ "-H 'x-requested-by: cli' "
)
$machine->succeed("curl -X POST " machine.wait_until_succeeds(
. "-sSfL http://127.0.0.1:9000/api/system/inputs -u $session:session " "test \"$(curl -sSfL 'http://127.0.0.1:9000/api/cluster/inputstates' "
. "-d \$(cat ${payloads.input} | sed -e \"s,\@node\@,\$(cat /var/lib/graylog/server/node-id),\") " + f"-u {session}:session "
. "-H 'Accept: application/json' " + "-H 'Accept: application/json' "
. "-H 'Content-Type: application/json' " + "-H 'Content-Type: application/json' "
. "-H 'x-requested-by: cli' " + "-H 'x-requested-by: cli'"
); + "| jq 'to_entries[]|.value|.[0]|.state' | xargs echo"
+ ')" = "RUNNING"'
)
$machine->waitUntilSucceeds("test \"\$(curl -sSfL 'http://127.0.0.1:9000/api/cluster/inputstates' " machine.succeed(
. "-u $session:session " "echo -n $(cat ${payloads.gelf_message}) | nc -w10 -u 127.0.0.1 12201"
. "-H 'Accept: application/json' " )
. "-H 'Content-Type: application/json' "
. "-H 'x-requested-by: cli'"
. "| jq 'to_entries[]|.value|.[0]|.state' | xargs echo"
. ")\" = \"RUNNING\""
);
$machine->succeed("echo -n \$(cat ${payloads.gelf_message}) | nc -w10 -u 127.0.0.1 12201"); machine.succeed(
'test "$(curl -X GET '
$machine->succeed("test \"\$(curl -X GET " + "-sSfL 'http://127.0.0.1:9000/api/search/universal/relative?query=*' "
. "-sSfL 'http://127.0.0.1:9000/api/search/universal/relative?query=*' " + f"-u {session}:session "
. "-u $session:session " + "-H 'Accept: application/json' "
. "-H 'Accept: application/json' " + "-H 'Content-Type: application/json' "
. "-H 'Content-Type: application/json' " + "-H 'x-requested-by: cli'"
. "-H 'x-requested-by: cli'" + ' | jq \'.total_results\' | xargs echo)" = "1"'
. " | jq '.total_results' | xargs echo)\" = \"1\"" )
);
''; '';
}) })

View File

@ -1,6 +1,6 @@
# This test runs influxdb and checks if influxdb is up and running # This test runs influxdb and checks if influxdb is up and running
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "influxdb"; name = "influxdb";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ offline ]; maintainers = [ offline ];
@ -9,25 +9,32 @@ import ./make-test.nix ({ pkgs, ...} : {
nodes = { nodes = {
one = { ... }: { one = { ... }: {
services.influxdb.enable = true; services.influxdb.enable = true;
environment.systemPackages = [ pkgs.httpie ];
}; };
}; };
testScript = '' testScript = ''
startAll; import shlex
$one->waitForUnit("influxdb.service"); start_all()
one.wait_for_unit("influxdb.service")
# create database # create database
$one->succeed(q~ one.succeed(
curl -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE test" "curl -XPOST http://localhost:8086/query --data-urlencode 'q=CREATE DATABASE test'"
~); )
# write some points and run simple query # write some points and run simple query
$one->succeed(q~ out = one.succeed(
curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000' "curl -XPOST 'http://localhost:8086/write?db=test' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'"
~); )
$one->succeed(q~
curl -GET 'http://localhost:8086/query' --data-urlencode "db=test" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west'" | grep "0\.64" qv = "SELECT value FROM cpu_load_short WHERE region='us-west'"
~); cmd = f'curl -GET "http://localhost:8086/query?db=test" --data-urlencode {shlex.quote("q="+ qv)}'
out = one.succeed(cmd)
assert "2015-06-11T20:46:02Z" in out
assert "0.64" in out
''; '';
}) })

View File

@ -3,7 +3,7 @@
# 2. jenkins user can be extended on both master and slave # 2. jenkins user can be extended on both master and slave
# 3. jenkins service not started on slave node # 3. jenkins service not started on slave node
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "jenkins"; name = "jenkins";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ bjornfor coconnor domenkozar eelco ]; maintainers = [ bjornfor coconnor domenkozar eelco ];
@ -33,18 +33,17 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$master->waitForUnit("jenkins"); master.wait_for_unit("jenkins")
$master->mustSucceed("curl http://localhost:8080 | grep 'Authentication required'"); assert "Authentication required" in master.succeed("curl http://localhost:8080")
print $master->execute("sudo -u jenkins groups"); for host in master, slave:
$master->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users"); groups = host.succeed("sudo -u jenkins groups")
assert "jenkins" in groups
assert "users" in groups
print $slave->execute("sudo -u jenkins groups"); slave.fail("systemctl is-enabled jenkins.service")
$slave->mustSucceed("sudo -u jenkins groups | grep jenkins | grep users");
$slave->mustFail("systemctl is-enabled jenkins.service");
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
let let
accessKey = "BKIKJAA5BMMU2RHO6IBB"; accessKey = "BKIKJAA5BMMU2RHO6IBB";
secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12"; secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
@ -18,7 +18,7 @@ let
sio.seek(0) sio.seek(0)
minioClient.put_object('test-bucket', 'test.txt', sio, sio_len, content_type='text/plain') minioClient.put_object('test-bucket', 'test.txt', sio, sio_len, content_type='text/plain')
''; '';
in { in {
name = "minio"; name = "minio";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ bachp ]; maintainers = [ bachp ];
@ -37,19 +37,19 @@ let
}; };
}; };
testScript = testScript = ''
'' start_all()
startAll; machine.wait_for_unit("minio.service")
$machine->waitForUnit("minio.service"); machine.wait_for_open_port(9000)
$machine->waitForOpenPort(9000);
# Create a test bucket on the server # Create a test bucket on the server
$machine->succeed("mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} S3v4"); machine.succeed(
$machine->succeed("mc mb minio/test-bucket"); "mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} S3v4"
$machine->succeed("${minioPythonScript}"); )
$machine->succeed("mc ls minio") =~ /test-bucket/ or die; machine.succeed("mc mb minio/test-bucket")
$machine->succeed("mc cat minio/test-bucket/test.txt") =~ /Test from Python/ or die; machine.succeed("${minioPythonScript}")
$machine->shutdown; assert "test-bucket" in machine.succeed("mc ls minio")
assert "Test from Python" in machine.succeed("mc cat minio/test-bucket/test.txt")
''; machine.shutdown()
'';
}) })

View File

@ -1,5 +1,5 @@
# Test whether mysqlBackup option works # Test whether mysqlBackup option works
import ./make-test.nix ({ pkgs, ... } : { import ./make-test-python.nix ({ pkgs, ... } : {
name = "mysql-backup"; name = "mysql-backup";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ rvl ]; maintainers = [ rvl ];
@ -20,31 +20,37 @@ import ./make-test.nix ({ pkgs, ... } : {
}; };
}; };
testScript = testScript = ''
'' startAll; start_all()
# Delete backup file that may be left over from a previous test run. # Delete backup file that may be left over from a previous test run.
# This is not needed on Hydra but useful for repeated local test runs. # This is not needed on Hydra but useful for repeated local test runs.
$master->execute("rm -f /var/backup/mysql/testdb.gz"); master.execute("rm -f /var/backup/mysql/testdb.gz")
# Need to have mysql started so that it can be populated with data. # Need to have mysql started so that it can be populated with data.
$master->waitForUnit("mysql.service"); master.wait_for_unit("mysql.service")
# Wait for testdb to be fully populated (5 rows). # Wait for testdb to be fully populated (5 rows).
$master->waitUntilSucceeds("mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"); master.wait_until_succeeds(
"mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"
)
# Do a backup and wait for it to start # Do a backup and wait for it to start
$master->startJob("mysql-backup.service"); master.start_job("mysql-backup.service")
$master->waitForJob("mysql-backup.service"); master.wait_for_unit("mysql-backup.service")
# wait for backup to fail, because of database 'doesnotexist' # wait for backup to fail, because of database 'doesnotexist'
$master->waitUntilFails("systemctl is-active -q mysql-backup.service"); master.wait_until_fails("systemctl is-active -q mysql-backup.service")
# wait for backup file and check that data appears in backup # wait for backup file and check that data appears in backup
$master->waitForFile("/var/backup/mysql/testdb.gz"); master.wait_for_file("/var/backup/mysql/testdb.gz")
$master->succeed("${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello"); master.succeed(
"${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello"
)
# Check that a failed backup is logged # Check that a failed backup is logged
$master->succeed("journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null"); master.succeed(
''; "journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null"
)
'';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
let let
replicateUser = "replicate"; replicateUser = "replicate";
@ -54,28 +54,36 @@ in
}; };
testScript = '' testScript = ''
$master->start; master.start()
$master->waitForUnit("mysql"); master.wait_for_unit("mysql")
$master->waitForOpenPort(3306); master.wait_for_open_port(3306)
# Wait for testdb to be fully populated (5 rows). # Wait for testdb to be fully populated (5 rows).
$master->waitUntilSucceeds("mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"); master.wait_until_succeeds(
"mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"
)
$slave1->start; slave1.start()
$slave2->start; slave2.start()
$slave1->waitForUnit("mysql"); slave1.wait_for_unit("mysql")
$slave1->waitForOpenPort(3306); slave1.wait_for_open_port(3306)
$slave2->waitForUnit("mysql"); slave2.wait_for_unit("mysql")
$slave2->waitForOpenPort(3306); slave2.wait_for_open_port(3306)
# wait for replications to finish # wait for replications to finish
$slave1->waitUntilSucceeds("mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"); slave1.wait_until_succeeds(
$slave2->waitUntilSucceeds("mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"); "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"
)
slave2.wait_until_succeeds(
"mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5"
)
$slave2->succeed("systemctl stop mysql"); slave2.succeed("systemctl stop mysql")
$master->succeed("echo 'insert into testdb.tests values (123, 456);' | mysql -u root -N"); master.succeed("echo 'insert into testdb.tests values (123, 456);' | mysql -u root -N")
$slave2->succeed("systemctl start mysql"); slave2.succeed("systemctl start mysql")
$slave2->waitForUnit("mysql"); slave2.wait_for_unit("mysql")
$slave2->waitForOpenPort(3306); slave2.wait_for_open_port(3306)
$slave2->waitUntilSucceeds("echo 'select * from testdb.tests where Id = 123;' | mysql -u root -N | grep 456"); slave2.wait_until_succeeds(
"echo 'select * from testdb.tests where Id = 123;' | mysql -u root -N | grep 456"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "mysql"; name = "mysql";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ eelco shlevy ]; maintainers = [ eelco shlevy ];
@ -47,17 +47,23 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all
$mysql->waitForUnit("mysql"); mysql.wait_for_unit("mysql")
$mysql->succeed("echo 'use empty_testdb;' | mysql -u root"); mysql.succeed("echo 'use empty_testdb;' | mysql -u root")
$mysql->succeed("echo 'use testdb; select * from tests;' | mysql -u root -N | grep 4"); mysql.succeed("echo 'use testdb; select * from tests;' | mysql -u root -N | grep 4")
# ';' acts as no-op, just check whether login succeeds with the user created from the initialScript # ';' acts as no-op, just check whether login succeeds with the user created from the initialScript
$mysql->succeed("echo ';' | mysql -u passworduser --password=password123"); mysql.succeed("echo ';' | mysql -u passworduser --password=password123")
$mariadb->waitForUnit("mysql"); mariadb.wait_for_unit("mysql")
$mariadb->succeed("echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser"); mariadb.succeed(
$mariadb->succeed("echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser"); "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser"
$mariadb->succeed("echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42"); )
mariadb.succeed(
"echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser"
)
mariadb.succeed(
"echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42"
)
''; '';
}) })

View File

@ -3,7 +3,7 @@
# 2. nexus service can startup on server (creating database and all other initial stuff) # 2. nexus service can startup on server (creating database and all other initial stuff)
# 3. the web application is reachable via HTTP # 3. the web application is reachable via HTTP
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "nexus"; name = "nexus";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ironpinguin ma27 ]; maintainers = [ ironpinguin ma27 ];
@ -22,11 +22,11 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
testScript = '' testScript = ''
startAll; start_all()
$server->waitForUnit("nexus"); server.wait_for_unit("nexus")
$server->waitForOpenPort(8081); server.wait_for_open_port(8081)
$server->succeed("curl -f 127.0.0.1:8081"); server.succeed("curl -f 127.0.0.1:8081")
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, lib, ... }: import ./make-test-python.nix ({ pkgs, lib, ... }:
let inherit (import ./ssh-keys.nix pkgs) let inherit (import ./ssh-keys.nix pkgs)
snakeOilPrivateKey snakeOilPublicKey; snakeOilPrivateKey snakeOilPublicKey;
ssh-config = builtins.toFile "ssh.conf" '' ssh-config = builtins.toFile "ssh.conf" ''
@ -18,22 +18,28 @@ in
client.nix.package = pkgs.nix; client.nix.package = pkgs.nix;
}; };
testScript = '' testScript = ''
startAll; start_all()
$client->succeed("mkdir -m 700 /root/.ssh"); client.succeed("mkdir -m 700 /root/.ssh")
$client->copyFileFromHost("${ssh-config}", "/root/.ssh/config"); client.succeed(
$client->succeed("cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa"); "cat ${ssh-config} > /root/.ssh/config"
$client->succeed("chmod 600 /root/.ssh/id_ecdsa"); )
client.succeed(
"cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa"
)
client.succeed("chmod 600 /root/.ssh/id_ecdsa")
$client->succeed("nix-store --add /etc/machine-id > mach-id-path"); client.succeed("nix-store --add /etc/machine-id > mach-id-path")
$server->waitForUnit("sshd"); server.wait_for_unit("sshd")
$client->fail("diff /root/other-store\$(cat mach-id-path) /etc/machine-id"); client.fail("diff /root/other-store$(cat mach-id-path) /etc/machine-id")
# Currently due to shared store this is a noop :( # Currently due to shared store this is a noop :(
$client->succeed("nix copy --to ssh-ng://nix-ssh\@server \$(cat mach-id-path)"); client.succeed("nix copy --to ssh-ng://nix-ssh@server $(cat mach-id-path)")
$client->succeed("nix-store --realise \$(cat mach-id-path) --store /root/other-store --substituters ssh-ng://nix-ssh\@server"); client.succeed(
$client->succeed("diff /root/other-store\$(cat mach-id-path) /etc/machine-id"); "nix-store --realise $(cat mach-id-path) --store /root/other-store --substituters ssh-ng://nix-ssh@server"
)
client.succeed("diff /root/other-store$(cat mach-id-path) /etc/machine-id")
''; '';
} }
) )

View File

@ -1,28 +0,0 @@
import ./make-test.nix ({ pkgs, lib, ... }:
with lib;
{
name = "osquery";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 ];
};
machine = {
services.osquery.enable = true;
services.osquery.loggerPath = "/var/log/osquery/logs";
services.osquery.pidfile = "/run/osqueryd.pid";
};
testScript = ''
$machine->start;
$machine->waitForUnit("osqueryd.service");
$machine->succeed("echo 'SELECT address FROM etc_hosts LIMIT 1;' | osqueryi | grep '127.0.0.1'");
$machine->succeed(
"echo 'SELECT value FROM osquery_flags WHERE name = \"logger_path\";' | osqueryi | grep /var/log/osquery/logs"
);
$machine->succeed("echo 'SELECT value FROM osquery_flags WHERE name = \"pidfile\";' | osqueryi | grep /run/osqueryd.pid");
'';
})

View File

@ -1,9 +1,10 @@
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
{ {
name = "pantheon"; name = "pantheon";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ worldofpeace ]; maintainers = pkgs.pantheon.maintainers;
}; };
machine = { ... }: machine = { ... }:
@ -21,35 +22,37 @@ 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;
bob = nodes.machine.config.users.users.bob;
in '' in ''
startAll; machine.wait_for_unit("display-manager.service")
# Wait for display manager to start with subtest("Test we can see usernames in elementary-greeter"):
$machine->waitForText(qr/${user.description}/); machine.wait_for_text("${user.description}")
$machine->screenshot("lightdm"); machine.wait_for_text("${bob.description}")
machine.screenshot("elementary_greeter_lightdm")
# Log in with subtest("Login with elementary-greeter"):
$machine->sendChars("${user.password}\n"); machine.send_chars("${user.password}\n")
$machine->waitForFile("/home/alice/.Xauthority"); machine.wait_for_x()
$machine->succeed("xauth merge ~alice/.Xauthority"); machine.wait_for_file("${user.home}/.Xauthority")
machine.succeed("xauth merge ${user.home}/.Xauthority")
# Check if "pantheon-shell" components actually start with subtest("Check that logging in has given the user ownership of devices"):
$machine->waitUntilSucceeds("pgrep gala"); machine.succeed("getfacl -p /dev/snd/timer | grep -q ${user.name}")
$machine->waitForWindow(qr/gala/);
$machine->waitUntilSucceeds("pgrep wingpanel");
$machine->waitForWindow("wingpanel");
$machine->waitUntilSucceeds("pgrep plank");
$machine->waitForWindow(qr/plank/);
# Check that logging in has given the user ownership of devices. # TODO: DBus API could eliminate this? Pantheon uses Bamf.
$machine->succeed("getfacl -p /dev/snd/timer | grep -q alice"); with subtest("Check if pantheon session components actually start"):
machine.wait_until_succeeds("pgrep gala")
machine.wait_for_window("gala")
machine.wait_until_succeeds("pgrep wingpanel")
machine.wait_for_window("wingpanel")
machine.wait_until_succeeds("pgrep plank")
machine.wait_for_window("plank")
# Open elementary terminal with subtest("Open elementary terminal"):
$machine->execute("su - alice -c 'DISPLAY=:0.0 io.elementary.terminal &'"); machine.execute("su - ${user.name} -c 'DISPLAY=:0 io.elementary.terminal &'")
$machine->waitForWindow(qr/io.elementary.terminal/); machine.wait_for_window("io.elementary.terminal")
machine.sleep(20)
# Take a screenshot of the desktop machine.screenshot("screen")
$machine->sleep(20);
$machine->screenshot("screen");
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ...} : import ./make-test-python.nix ({ pkgs, ...} :
{ {
name = "plasma5"; name = "plasma5";
@ -7,23 +7,11 @@ import ./make-test.nix ({ pkgs, ...} :
}; };
machine = { ... }: machine = { ... }:
let
sddm_theme = pkgs.stdenv.mkDerivation {
name = "breeze-ocr-theme";
phases = "buildPhase";
buildCommand = ''
mkdir -p $out/share/sddm/themes/
cp -r ${pkgs.plasma-workspace}/share/sddm/themes/breeze $out/share/sddm/themes/breeze-ocr-theme
chmod -R +w $out/share/sddm/themes/breeze-ocr-theme
printf "[General]\ntype=color\ncolor=#1d99f3\nbackground=\n" > $out/share/sddm/themes/breeze-ocr-theme/theme.conf
'';
};
in
{ {
imports = [ ./common/user-account.nix ]; imports = [ ./common/user-account.nix ];
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.sddm.enable = true; services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.sddm.theme = "breeze-ocr-theme";
services.xserver.desktopManager.plasma5.enable = true; services.xserver.desktopManager.plasma5.enable = true;
services.xserver.desktopManager.default = "plasma5"; services.xserver.desktopManager.default = "plasma5";
services.xserver.displayManager.sddm.autoLogin = { services.xserver.displayManager.sddm.autoLogin = {
@ -32,34 +20,40 @@ import ./make-test.nix ({ pkgs, ...} :
}; };
hardware.pulseaudio.enable = true; # needed for the factl test, /dev/snd/* exists without them but udev doesn't care then hardware.pulseaudio.enable = true; # needed for the factl test, /dev/snd/* exists without them but udev doesn't care then
virtualisation.memorySize = 1024; virtualisation.memorySize = 1024;
environment.systemPackages = [ sddm_theme ];
}; };
testScript = { nodes, ... }: let testScript = { nodes, ... }: let
user = nodes.machine.config.users.users.alice; user = nodes.machine.config.users.users.alice;
xdo = "${pkgs.xdotool}/bin/xdotool"; xdo = "${pkgs.xdotool}/bin/xdotool";
in '' in ''
startAll; with subtest("Wait for login"):
# wait for log in start_all()
$machine->waitForFile("/home/alice/.Xauthority"); machine.wait_for_file("${user.home}/.Xauthority")
$machine->succeed("xauth merge ~alice/.Xauthority"); machine.succeed("xauth merge ${user.home}/.Xauthority")
$machine->waitUntilSucceeds("pgrep plasmashell"); with subtest("Check plasmashell started"):
$machine->waitForWindow("^Desktop "); machine.wait_until_succeeds("pgrep plasmashell")
machine.wait_for_window("^Desktop ")
# Check that logging in has given the user ownership of devices. with subtest("Check that logging in has given the user ownership of devices"):
$machine->succeed("getfacl -p /dev/snd/timer | grep -q alice"); machine.succeed("getfacl -p /dev/snd/timer | grep -q ${user.name}")
$machine->execute("su - alice -c 'DISPLAY=:0.0 dolphin &'"); with subtest("Run Dolphin"):
$machine->waitForWindow(" Dolphin"); machine.execute("su - ${user.name} -c 'DISPLAY=:0.0 dolphin &'")
machine.wait_for_window(" Dolphin")
$machine->execute("su - alice -c 'DISPLAY=:0.0 konsole &'"); with subtest("Run Konsole"):
$machine->waitForWindow("Konsole"); machine.execute("su - ${user.name} -c 'DISPLAY=:0.0 konsole &'")
machine.wait_for_window("Konsole")
$machine->execute("su - alice -c 'DISPLAY=:0.0 systemsettings5 &'"); with subtest("Run systemsettings"):
$machine->waitForWindow("Settings"); machine.execute("su - ${user.name} -c 'DISPLAY=:0.0 systemsettings5 &'")
machine.wait_for_window("Settings")
$machine->execute("${xdo} key Alt+F1 sleep 10"); with subtest("Wait to get a screenshot"):
$machine->screenshot("screen"); machine.execute(
"${xdo} key Alt+F1 sleep 10"
)
machine.screenshot("screen")
''; '';
}) })

View File

@ -31,7 +31,7 @@ let
}; };
}; };
in import ./make-test.nix { in import ./make-test-python.nix {
name = "prometheus"; name = "prometheus";
nodes = { nodes = {
@ -173,67 +173,73 @@ in import ./make-test.nix {
testScript = { nodes, ... } : '' testScript = { nodes, ... } : ''
# Before starting the other machines we first make sure that our S3 service is online # Before starting the other machines we first make sure that our S3 service is online
# and has a bucket added for thanos: # and has a bucket added for thanos:
$s3->start; s3.start()
$s3->waitForUnit("minio.service"); s3.wait_for_unit("minio.service")
$s3->waitForOpenPort(${toString minioPort}); s3.wait_for_open_port(${toString minioPort})
$s3->succeed( s3.succeed(
"mc config host add minio " . "mc config host add minio "
"http://localhost:${toString minioPort} ${s3.accessKey} ${s3.secretKey} S3v4"); + "http://localhost:${toString minioPort} "
$s3->succeed("mc mb minio/thanos-bucket"); + "${s3.accessKey} ${s3.secretKey} S3v4",
"mc mb minio/thanos-bucket",
)
# Now that s3 has started we can start the other machines: # Now that s3 has started we can start the other machines:
$prometheus->start; for machine in prometheus, query, store:
$query->start; machine.start()
$store->start;
# Check if prometheus responds to requests: # Check if prometheus responds to requests:
$prometheus->waitForUnit("prometheus.service"); prometheus.wait_for_unit("prometheus.service")
$prometheus->waitForOpenPort(${toString queryPort}); prometheus.wait_for_open_port(${toString queryPort})
$prometheus->succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics"); prometheus.succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics")
# Let's test if pushing a metric to the pushgateway succeeds: # Let's test if pushing a metric to the pushgateway succeeds:
$prometheus->waitForUnit("pushgateway.service"); prometheus.wait_for_unit("pushgateway.service")
$prometheus->succeed( prometheus.succeed(
"echo 'some_metric 3.14' | " . "echo 'some_metric 3.14' | "
"curl --data-binary \@- http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job"); + "curl --data-binary \@- "
+ "http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job"
)
# Now check whether that metric gets ingested by prometheus. # Now check whether that metric gets ingested by prometheus.
# Since we'll check for the metric several times on different machines # Since we'll check for the metric several times on different machines
# we abstract the test using the following function: # we abstract the test using the following function:
# Function to check if the metric "some_metric" has been received and returns the correct value. # Function to check if the metric "some_metric" has been received and returns the correct value.
local *Machine::waitForMetric = sub { def wait_for_metric(machine):
my ($self) = @_; return machine.wait_until_succeeds(
$self->waitUntilSucceeds( "curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' | "
"curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' " . + "jq '.data.result[0].value[1]' | grep '\"3.14\"'"
"| jq '.data.result[0].value[1]' | grep '\"3.14\"'"); )
};
$prometheus->waitForMetric;
wait_for_metric(prometheus)
# Let's test if the pushgateway persists metrics to the configured location. # Let's test if the pushgateway persists metrics to the configured location.
$prometheus->waitUntilSucceeds("test -e /var/lib/prometheus-pushgateway/metrics"); prometheus.wait_until_succeeds("test -e /var/lib/prometheus-pushgateway/metrics")
# Test thanos # Test thanos
$prometheus->waitForUnit("thanos-sidecar.service"); prometheus.wait_for_unit("thanos-sidecar.service")
# Test if the Thanos query service can correctly retrieve the metric that was send above. # Test if the Thanos query service can correctly retrieve the metric that was send above.
$query->waitForUnit("thanos-query.service"); query.wait_for_unit("thanos-query.service")
$query->waitForMetric; wait_for_metric(query)
# Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the # Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the
# Thanos storage service has correctly downloaded it from S3 and if the Thanos # Thanos storage service has correctly downloaded it from S3 and if the Thanos
# query service running on $store can correctly retrieve the metric: # query service running on $store can correctly retrieve the metric:
$store->waitForUnit("thanos-store.service"); store.wait_for_unit("thanos-store.service")
$store->waitForMetric; wait_for_metric(store)
$store->waitForUnit("thanos-compact.service"); store.wait_for_unit("thanos-compact.service")
# Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket # Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
# and check if the blocks have the correct labels: # and check if the blocks have the correct labels:
$store->succeed( store.succeed(
"thanos bucket ls" . "thanos bucket ls "
" --objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file}" . + "--objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file} "
" --output=json | jq .thanos.labels.some_label | grep 'required by thanos'"); + "--output=json | "
+ "jq .thanos.labels.some_label | "
+ "grep 'required by thanos'"
)
''; '';
} }

View File

@ -4,7 +4,7 @@ let
password = "helloworld"; password = "helloworld";
in in
import ./make-test.nix ({ pkgs, ...} : { import ./make-test-python.nix ({ pkgs, ...} : {
name = "sudo"; name = "sudo";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ lschuermann ]; maintainers = [ lschuermann ];
@ -50,44 +50,34 @@ in
testScript = testScript =
'' ''
subtest "users in wheel group should have passwordless sudo", sub { with subtest("users in wheel group should have passwordless sudo"):
$machine->succeed("su - test0 -c \"sudo -u root true\""); machine.succeed('su - test0 -c "sudo -u root true"')
};
subtest "test1 user should have sudo with password", sub { with subtest("test1 user should have sudo with password"):
$machine->succeed("su - test1 -c \"echo ${password} | sudo -S -u root true\""); machine.succeed('su - test1 -c "echo ${password} | sudo -S -u root true"')
};
subtest "test1 user should not be able to use sudo without password", sub { with subtest("test1 user should not be able to use sudo without password"):
$machine->fail("su - test1 -c \"sudo -n -u root true\""); machine.fail('su - test1 -c "sudo -n -u root true"')
};
subtest "users in group 'foobar' should be able to use sudo with password", sub { with subtest("users in group 'foobar' should be able to use sudo with password"):
$machine->succeed("sudo -u test2 echo ${password} | sudo -S -u root true"); machine.succeed("sudo -u test2 echo ${password} | sudo -S -u root true")
};
subtest "users in group 'barfoo' should be able to use sudo without password", sub { with subtest("users in group 'barfoo' should be able to use sudo without password"):
$machine->succeed("sudo -u test3 sudo -n -u root true"); machine.succeed("sudo -u test3 sudo -n -u root true")
};
subtest "users in group 'baz' (GID 1337) should be able to use sudo without password", sub { with subtest("users in group 'baz' (GID 1337)"):
$machine->succeed("sudo -u test4 sudo -n -u root echo true"); machine.succeed("sudo -u test4 sudo -n -u root echo true")
};
subtest "test5 user should be able to run commands under test1", sub { with subtest("test5 user should be able to run commands under test1"):
$machine->succeed("sudo -u test5 sudo -n -u test1 true"); machine.succeed("sudo -u test5 sudo -n -u test1 true")
};
subtest "test5 user should not be able to run commands under root", sub { with subtest("test5 user should not be able to run commands under root"):
$machine->fail("sudo -u test5 sudo -n -u root true"); machine.fail("sudo -u test5 sudo -n -u root true")
};
subtest "test5 user should be able to keep his environment", sub { with subtest("test5 user should be able to keep his environment"):
$machine->succeed("sudo -u test5 sudo -n -E -u test1 true"); machine.succeed("sudo -u test5 sudo -n -E -u test1 true")
};
subtest "users in group 'barfoo' should not be able to keep their environment", sub { with subtest("users in group 'barfoo' should not be able to keep their environment"):
$machine->fail("sudo -u test3 sudo -n -E -u root true"); machine.fail("sudo -u test3 sudo -n -E -u root true")
};
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, pkgs, ... }: let import ./make-test-python.nix ({ lib, pkgs, ... }: let
testId = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU"; testId = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
@ -22,13 +22,11 @@ in {
}; };
testScript = '' testScript = ''
my $config; machine.wait_for_unit("syncthing-init.service")
config = machine.succeed("cat /var/lib/syncthing/.config/syncthing/config.xml")
$machine->waitForUnit("syncthing-init.service");
$config = $machine->succeed("cat /var/lib/syncthing/.config/syncthing/config.xml");
$config =~ /${testId}/ or die; assert "testFolder" in config
$config =~ /testFolder/ or die; assert "${testId}" in config
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ lib, pkgs, ... }: { import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "syncthing-relay"; name = "syncthing-relay";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ delroth ]; meta.maintainers = with pkgs.stdenv.lib.maintainers; [ delroth ];
@ -14,9 +14,13 @@ import ./make-test.nix ({ lib, pkgs, ... }: {
}; };
testScript = '' testScript = ''
$machine->waitForUnit("syncthing-relay.service"); machine.wait_for_unit("syncthing-relay.service")
$machine->waitForOpenPort(12345); machine.wait_for_open_port(12345)
$machine->waitForOpenPort(12346); machine.wait_for_open_port(12346)
$machine->succeed("curl http://localhost:12346/status | jq -r '.options.\"provided-by\"'") =~ /nixos-test/ or die;
out = machine.succeed(
"curl -sS http://localhost:12346/status | jq -r '.options.\"provided-by\"'"
)
assert "nixos-test" in out
''; '';
}) })

View File

@ -1,4 +1,4 @@
let generateNodeConf = { lib, pkgs, config, privkpath, pubk, peerId, nodeId, ...}: { let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
imports = [ common/user-account.nix ]; imports = [ common/user-account.nix ];
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
networking.useNetworkd = true; networking.useNetworkd = true;
@ -7,13 +7,16 @@ let generateNodeConf = { lib, pkgs, config, privkpath, pubk, peerId, nodeId, ...
virtualisation.vlans = [ 1 ]; virtualisation.vlans = [ 1 ];
environment.systemPackages = with pkgs; [ wireguard-tools ]; environment.systemPackages = with pkgs; [ wireguard-tools ];
boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ]; boot.extraModulePackages = [ config.boot.kernelPackages.wireguard ];
systemd.tmpfiles.rules = [
"f /run/wg_priv 0640 root systemd-network - ${privk}"
];
systemd.network = { systemd.network = {
enable = true; enable = true;
netdevs = { netdevs = {
"90-wg0" = { "90-wg0" = {
netdevConfig = { Kind = "wireguard"; Name = "wg0"; }; netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
wireguardConfig = { wireguardConfig = {
PrivateKeyFile = privkpath ; PrivateKeyFile = "/run/wg_priv";
ListenPort = 51820; ListenPort = 51820;
FwMark = 42; FwMark = 42;
}; };
@ -53,7 +56,7 @@ in import ./make-test-python.nix ({pkgs, ... }: {
nodes = { nodes = {
node1 = { pkgs, ... }@attrs: node1 = { pkgs, ... }@attrs:
let localConf = { let localConf = {
privkpath = pkgs.writeText "priv.key" "GDiXWlMQKb379XthwX0haAbK6hTdjblllpjGX0heP00="; privk = "GDiXWlMQKb379XthwX0haAbK6hTdjblllpjGX0heP00=";
pubk = "iRxpqj42nnY0Qz8MAQbSm7bXxXP5hkPqWYIULmvW+EE="; pubk = "iRxpqj42nnY0Qz8MAQbSm7bXxXP5hkPqWYIULmvW+EE=";
nodeId = "1"; nodeId = "1";
peerId = "2"; peerId = "2";
@ -62,7 +65,7 @@ in import ./make-test-python.nix ({pkgs, ... }: {
node2 = { pkgs, ... }@attrs: node2 = { pkgs, ... }@attrs:
let localConf = { let localConf = {
privkpath = pkgs.writeText "priv.key" "eHxSI2jwX/P4AOI0r8YppPw0+4NZnjOxfbS5mt06K2k="; privk = "eHxSI2jwX/P4AOI0r8YppPw0+4NZnjOxfbS5mt06K2k=";
pubk = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g="; pubk = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g=";
nodeId = "2"; nodeId = "2";
peerId = "1"; peerId = "1";

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({pkgs, lib, ...}: import ./make-test-python.nix ({pkgs, lib, ...}:
let let
gpgKeyring = (pkgs.runCommand "gpg-keyring" { buildInputs = [ pkgs.gnupg ]; } '' gpgKeyring = (pkgs.runCommand "gpg-keyring" { buildInputs = [ pkgs.gnupg ]; } ''
mkdir -p $out mkdir -p $out
@ -32,7 +32,7 @@ let
gpg --batch --sign --detach-sign --output SHA256SUMS.gpg SHA256SUMS gpg --batch --sign --detach-sign --output SHA256SUMS.gpg SHA256SUMS
''); '');
in { in {
name = "opensmtpd"; name = "systemd-nspawn";
nodes = { nodes = {
server = { pkgs, ... }: { server = { pkgs, ... }: {
@ -48,11 +48,13 @@ in {
}; };
testScript = '' testScript = ''
startAll; start_all()
$server->waitForUnit("nginx.service"); server.wait_for_unit("nginx.service")
$client->waitForUnit("network-online.target"); client.wait_for_unit("network-online.target")
$client->succeed("machinectl pull-raw --verify=signature http://server/testimage.raw"); client.succeed("machinectl pull-raw --verify=signature http://server/testimage.raw")
$client->succeed("cmp /var/lib/machines/testimage.raw ${nspawnImages}/testimage.raw"); client.succeed(
"cmp /var/lib/machines/testimage.raw ${nspawnImages}/testimage.raw"
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: import ./make-test-python.nix ({ pkgs, ... }:
{ {
name = "uwsgi"; name = "uwsgi";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
@ -30,9 +30,9 @@ import ./make-test.nix ({ pkgs, ... }:
testScript = testScript =
'' ''
$machine->waitForUnit('multi-user.target'); machine.wait_for_unit("multi-user.target")
$machine->waitForUnit('uwsgi.service'); machine.wait_for_unit("uwsgi.service")
$machine->waitForOpenPort(8000); machine.wait_for_open_port(8000)
$machine->succeed('curl -v 127.0.0.1:8000 | grep "Hello World!"'); assert "Hello World" in machine.succeed("curl -v 127.0.0.1:8000")
''; '';
}) })

View File

@ -1,9 +1,13 @@
import ./make-test.nix ({ pkgs, ... }: import ./make-test-python.nix ({ pkgs, ... }:
{ {
name = "wordpress"; name = "wordpress";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ grahamc ]; # under duress! maintainers = [
flokli
grahamc # under duress!
mmilata
];
}; };
machine = machine =
@ -23,19 +27,31 @@ import ./make-test.nix ({ pkgs, ... }:
}; };
testScript = '' testScript = ''
startAll; import re
$machine->waitForUnit("httpd"); start_all()
$machine->waitForUnit("phpfpm-wordpress-site1.local");
$machine->waitForUnit("phpfpm-wordpress-site2.local");
$machine->succeed("curl -L site1.local | grep 'Welcome to the famous'"); machine.wait_for_unit("httpd")
$machine->succeed("curl -L site2.local | grep 'Welcome to the famous'");
$machine->succeed("systemctl --no-pager show wordpress-init-site1.local.service | grep 'ExecStart=.*status=0'"); machine.wait_for_unit("phpfpm-wordpress-site1.local")
$machine->succeed("systemctl --no-pager show wordpress-init-site2.local.service | grep 'ExecStart=.*status=0'"); machine.wait_for_unit("phpfpm-wordpress-site2.local")
$machine->succeed("grep -E '^define.*NONCE_SALT.{64,};\$' /var/lib/wordpress/site1.local/secret-keys.php");
$machine->succeed("grep -E '^define.*NONCE_SALT.{64,};\$' /var/lib/wordpress/site2.local/secret-keys.php"); site_names = ["site1.local", "site2.local"]
with subtest("website returns welcome screen"):
for site_name in site_names:
assert "Welcome to the famous" in machine.succeed(f"curl -L {site_name}")
with subtest("wordpress-init went through"):
for site_name in site_names:
info = machine.get_unit_info(f"wordpress-init-{site_name}")
assert info["Result"] == "success"
with subtest("secret keys are set"):
pattern = re.compile(r"^define.*NONCE_SALT.{64,};$", re.MULTILINE)
for site_name in site_names:
assert pattern.search(
machine.succeed(f"cat /var/lib/wordpress/{site_name}/secret-keys.php")
)
''; '';
}) })

View File

@ -1,4 +1,4 @@
import ../make-test.nix { import ../make-test-python.nix {
name = "prosody-mysql"; name = "prosody-mysql";
nodes = { nodes = {
@ -57,21 +57,21 @@ import ../make-test.nix {
}; };
testScript = { nodes, ... }: '' testScript = { nodes, ... }: ''
$mysql->waitForUnit('mysql.service'); mysql.wait_for_unit("mysql.service")
$server->waitForUnit('prosody.service'); server.wait_for_unit("prosody.service")
$server->succeed('prosodyctl status') =~ /Prosody is running/; server.succeed('prosodyctl status | grep "Prosody is running"')
# set password to 'nothunter2' (it's asked twice) # set password to 'nothunter2' (it's asked twice)
$server->succeed('yes nothunter2 | prosodyctl adduser cthon98@example.com'); server.succeed("yes nothunter2 | prosodyctl adduser cthon98@example.com")
# set password to 'y' # set password to 'y'
$server->succeed('yes | prosodyctl adduser azurediamond@example.com'); server.succeed("yes | prosodyctl adduser azurediamond@example.com")
# correct password to 'hunter2' # correct password to 'hunter2'
$server->succeed('yes hunter2 | prosodyctl passwd azurediamond@example.com'); server.succeed("yes hunter2 | prosodyctl passwd azurediamond@example.com")
$client->succeed("send-message"); client.succeed("send-message")
$server->succeed('prosodyctl deluser cthon98@example.com'); server.succeed("prosodyctl deluser cthon98@example.com")
$server->succeed('prosodyctl deluser azurediamond@example.com'); server.succeed("prosodyctl deluser azurediamond@example.com")
''; '';
} }

View File

@ -1,4 +1,4 @@
import ../make-test.nix { import ../make-test-python.nix {
name = "prosody"; name = "prosody";
nodes = { nodes = {
@ -28,19 +28,19 @@ import ../make-test.nix {
}; };
testScript = { nodes, ... }: '' testScript = { nodes, ... }: ''
$server->waitForUnit('prosody.service'); server.wait_for_unit("prosody.service")
$server->succeed('prosodyctl status') =~ /Prosody is running/; server.succeed('prosodyctl status | grep "Prosody is running"')
# set password to 'nothunter2' (it's asked twice) # set password to 'nothunter2' (it's asked twice)
$server->succeed('yes nothunter2 | prosodyctl adduser cthon98@example.com'); server.succeed("yes nothunter2 | prosodyctl adduser cthon98@example.com")
# set password to 'y' # set password to 'y'
$server->succeed('yes | prosodyctl adduser azurediamond@example.com'); server.succeed("yes | prosodyctl adduser azurediamond@example.com")
# correct password to 'hunter2' # correct password to "hunter2"
$server->succeed('yes hunter2 | prosodyctl passwd azurediamond@example.com'); server.succeed("yes hunter2 | prosodyctl passwd azurediamond@example.com")
$client->succeed("send-message"); client.succeed("send-message")
$server->succeed('prosodyctl deluser cthon98@example.com'); server.succeed("prosodyctl deluser cthon98@example.com")
$server->succeed('prosodyctl deluser azurediamond@example.com'); server.succeed("prosodyctl deluser azurediamond@example.com")
''; '';
} }

View File

@ -7,12 +7,12 @@
with stdenv.lib; with stdenv.lib;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
version = "2.3.2"; version = "2.3.3";
pname = "audacity"; pname = "audacity";
src = fetchzip { src = fetchzip {
url = "https://github.com/audacity/audacity/archive/Audacity-${version}.tar.gz"; url = "https://github.com/audacity/audacity/archive/Audacity-${version}.tar.gz";
sha256 = "08w96124vv8k4myd4vifq73ningq6404x889wvg2sk016kc4dfv1"; sha256 = "0ddc03dbm4ixy877czmwd03fpjgr3y68bxfgb6n2q6cv4prp30ig";
}; };
preConfigure = /* we prefer system-wide libs */ '' preConfigure = /* we prefer system-wide libs */ ''

View File

@ -1,9 +1,9 @@
{ stdenv, fetchFromGitHub, cmake, pkgconfig, alsaLib ? null, fftwFloat, fltk13 { stdenv, fetchFromGitHub, cmake, pkgconfig, alsaLib ? null, fftwFloat, fltk13
, fluidsynth_1 ? null, lame ? null, libgig ? null, libjack2 ? null, libpulseaudio ? null , fluidsynth_1 ? null, lame ? null, libgig ? null, libjack2 ? null, libpulseaudio ? null
, libsamplerate, libsoundio ? null, libsndfile, libvorbis ? null, portaudio ? null , libsamplerate, libsoundio ? null, libsndfile, libvorbis ? null, portaudio ? null
, qtbase, qtx11extras, qttools, SDL ? null }: , qtbase, qtx11extras, qttools, SDL ? null, mkDerivation }:
stdenv.mkDerivation rec { mkDerivation rec {
pname = "lmms"; pname = "lmms";
version = "1.2.0-rc7"; version = "1.2.0-rc7";
@ -43,7 +43,7 @@ stdenv.mkDerivation rec {
description = "DAW similar to FL Studio (music production software)"; description = "DAW similar to FL Studio (music production software)";
homepage = https://lmms.io; homepage = https://lmms.io;
license = licenses.gpl2Plus; license = licenses.gpl2Plus;
platforms = platforms.linux; platforms = [ "x86_64-linux" "i686-linux" ];
maintainers = with maintainers; [ goibhniu yegortimoshenko ]; maintainers = with maintainers; [ goibhniu yegortimoshenko ];
}; };
} }

View File

@ -6,16 +6,16 @@
rustPlatform.buildRustPackage rec { rustPlatform.buildRustPackage rec {
pname = "spotifyd"; pname = "spotifyd";
version = "0.2.19"; version = "0.2.20";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "Spotifyd"; owner = "Spotifyd";
repo = "spotifyd"; repo = "spotifyd";
rev = "v${version}"; rev = "v${version}";
sha256 = "063b28ysj224m6ngns9i574i7vnp1x4g07cqjw908ch04yngcg1c"; sha256 = "1hf4wpk7r0s4jpjhxaz67y1hd8jx9ns5imd85r3cdg4lxf3j5gph";
}; };
cargoSha256 = "0pqxqd5dyw9mjclrqkxzfnzsz74xl4bg0b86v5q6kc0a91zd49b9"; cargoSha256 = "1h3fis47hmxvppiv1icjhgp48nd46gayfcmzfjs34q6jask90n0w";
cargoBuildFlags = [ cargoBuildFlags = [
"--no-default-features" "--no-default-features"
@ -36,7 +36,7 @@ rustPlatform.buildRustPackage rec {
description = "An open source Spotify client running as a UNIX daemon"; description = "An open source Spotify client running as a UNIX daemon";
homepage = "https://github.com/Spotifyd/spotifyd"; homepage = "https://github.com/Spotifyd/spotifyd";
license = with licenses; [ gpl3 ]; license = with licenses; [ gpl3 ];
maintainers = [ maintainers.anderslundstedt maintainers.marsam ]; maintainers = with maintainers; [ anderslundstedt filalex77 marsam ];
platforms = platforms.unix; platforms = platforms.unix;
}; };
} }

View File

@ -37,7 +37,7 @@ mkDerivation rec {
# https://cgit.kde.org/kdevelop.git/commit/?id=716372ae2e8dff9c51e94d33443536786e4bd85b # https://cgit.kde.org/kdevelop.git/commit/?id=716372ae2e8dff9c51e94d33443536786e4bd85b
# required as nixos seems to be unable to find CLANG_BUILTIN_DIR # required as nixos seems to be unable to find CLANG_BUILTIN_DIR
cmakeFlags = [ cmakeFlags = [
"-DCLANG_BUILTIN_DIR=${llvmPackages.clang-unwrapped}/lib/clang/${(builtins.parseDrvName llvmPackages.clang.name).version}/include" "-DCLANG_BUILTIN_DIR=${llvmPackages.clang-unwrapped}/lib/clang/${lib.getVersion llvmPackages.clang}/include"
]; ];
dontWrapQtApps = true; dontWrapQtApps = true;

View File

@ -60,11 +60,11 @@ let
in mkDerivation rec { in mkDerivation rec {
pname = "drawpile"; pname = "drawpile";
version = "2.1.13"; version = "2.1.14";
src = fetchurl { src = fetchurl {
url = "https://drawpile.net/files/src/drawpile-${version}.tar.gz"; url = "https://drawpile.net/files/src/drawpile-${version}.tar.gz";
sha256 = "0r56hkzjdlg4615zvrjv60i3f06pv7ssh6bs6jb46qs8wbsawsxf"; sha256 = "0vpsq8swvli6xiykjqjmdcz33jd44nvhq1n350dm9qap9s9wdr47";
}; };
nativeBuildInputs = [ nativeBuildInputs = [

View File

@ -1,6 +1,7 @@
{ stdenv { stdenv
, mkDerivation , mkDerivation
, fetchFromGitHub , fetchFromGitHub
, fetchpatch
, cmake , cmake
, pkgconfig , pkgconfig
@ -9,7 +10,7 @@
, qtsvg , qtsvg
, exiv2 , exiv2
, opencv , opencv4
, libraw , libraw
, libtiff , libtiff
, quazip , quazip
@ -28,6 +29,12 @@ mkDerivation rec {
patches = [ patches = [
./nomacs-iostream.patch ./nomacs-iostream.patch
(fetchpatch {
name = "darwin-less-restrictive-opencv.patch";
url = "https://github.com/nomacs/nomacs/commit/d182fce4bcd9a25bd15e3de065ca67849a32458c.patch";
sha256 = "0j6sviwrjn69nqf59hjn30c4j838h8az7rnlwcx8ymlb21vd9x2h";
stripLen = 1;
})
]; ];
enableParallelBuilding = true; enableParallelBuilding = true;
@ -43,7 +50,7 @@ mkDerivation rec {
qttools qttools
qtsvg qtsvg
exiv2 exiv2
opencv opencv4
libraw libraw
libtiff libtiff
quazip]; quazip];

View File

@ -9,13 +9,13 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "clightd"; pname = "clightd";
version = "3.4"; version = "4.0";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "FedeDP"; owner = "FedeDP";
repo = "Clightd"; repo = "Clightd";
rev = version; rev = version;
sha256 = "0g6kawizwfhvigkwm7rbfq6rg872xn8igy8n355w4d7mmcxk0jf8"; sha256 = "0cskxy3xsy187in5vg8xcs3kwcx2s160qv009v0ahkcalp29ghz4";
}; };
# dbus-1.pc has datadir=/etc # dbus-1.pc has datadir=/etc

View File

@ -1,18 +1,18 @@
{ lib, stdenv, fetchFromGitHub { lib, stdenv, fetchFromGitHub
, dbus, cmake, pkgconfig, bash-completion , dbus, cmake, pkgconfig, bash-completion
, gsl, popt, clightd, systemd, libconfig , gsl, popt, clightd, systemd, libconfig, libmodule
, withGeoclue ? true, geoclue2 , withGeoclue ? true, geoclue2
, withUpower ? true, upower }: , withUpower ? true, upower }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "clight"; pname = "clight";
version = "3.1"; version = "4.0";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "FedeDP"; owner = "FedeDP";
repo = "Clight"; repo = "Clight";
rev = version; rev = version;
sha256 = "0rzcr1x9h4llnmklhgzs9r7xwhsrw1qkqvfffkp8fs90nycaqx81"; sha256 = "101fp9kwmfmfffpdvv41wf96kdjw0b16xk49g43w32a5wlr74zrq";
}; };
# bash-completion.pc completionsdir=${bash-completion.out} # bash-completion.pc completionsdir=${bash-completion.out}
@ -42,6 +42,7 @@ stdenv.mkDerivation rec {
systemd systemd
geoclue2 geoclue2
libconfig libconfig
libmodule
] ++ optional withGeoclue geoclue2 ] ++ optional withGeoclue geoclue2
++ optional withUpower upower; ++ optional withUpower upower;

View File

@ -5,13 +5,13 @@
mkDerivation rec { mkDerivation rec {
pname = "CopyQ"; pname = "CopyQ";
version = "3.9.2"; version = "3.9.3";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "hluk"; owner = "hluk";
repo = "CopyQ"; repo = "CopyQ";
rev = "v${version}"; rev = "v${version}";
sha256 = "02zs444i7hnqishs1i6vp8ffjxlxk3xkrw935pdwnwppv9s9v202"; sha256 = "0wlwq9xg8rzsbj0b29z358k4mbrqy04iraa8x0p26pa95yskgcma";
}; };
nativeBuildInputs = [ cmake ]; nativeBuildInputs = [ cmake ];

View File

@ -7,7 +7,7 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "dbeaver-ce"; pname = "dbeaver-ce";
version = "6.2.4"; version = "6.2.5";
desktopItem = makeDesktopItem { desktopItem = makeDesktopItem {
name = "dbeaver"; name = "dbeaver";
@ -30,7 +30,7 @@ stdenv.mkDerivation rec {
src = fetchurl { src = fetchurl {
url = "https://dbeaver.io/files/${version}/dbeaver-ce-${version}-linux.gtk.x86_64.tar.gz"; url = "https://dbeaver.io/files/${version}/dbeaver-ce-${version}-linux.gtk.x86_64.tar.gz";
sha256 = "1k3aan290kfy2b53gl8r4yxvb8jas6sms1r052m3jld3i8frqgva"; sha256 = "1bg5cq7ivf263mjr8g9qwdhp9x0gm04nqiya4fyw0k33yiab85zn";
}; };
installPhase = '' installPhase = ''

View File

@ -8,7 +8,7 @@ let
wrapperScript = writeScript "glava" '' wrapperScript = writeScript "glava" ''
#!${runtimeShell} #!${runtimeShell}
case "$1" in case "$1" in
--copy-config) --copy-config|-C)
# The binary would symlink it, which won't work in Nix because the # The binary would symlink it, which won't work in Nix because the
# garbage collector will eventually remove the original files after # garbage collector will eventually remove the original files after
# updates # updates
@ -45,6 +45,14 @@ in
]; ];
preConfigure = '' preConfigure = ''
for f in $(find -type f);do
substituteInPlace $f \
--replace /etc/xdg $out/etc/xdg
done
substituteInPlace Makefile \
--replace '$(DESTDIR)$(SHADERDIR)' '$(SHADERDIR)'
substituteInPlace Makefile \ substituteInPlace Makefile \
--replace 'unknown' 'v${version}' --replace 'unknown' 'v${version}'

View File

@ -30,14 +30,14 @@ let
license_dir = "~/.config/houdini"; license_dir = "~/.config/houdini";
in in
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
version = "17.0.352"; version = "17.5.327";
pname = "houdini-runtime"; pname = "houdini-runtime";
src = requireFile rec { src = requireFile rec {
name = "houdini-${version}-linux_x86_64_gcc6.3.tar.gz"; name = "houdini-${version}-linux_x86_64_gcc6.3.tar.gz";
sha256 = "0cl5fkgaplb0cvv7mli06ffc9j4ngpy8hl5zqabj3d645gcgafjg"; sha256 = "1byigmhmby8lgi2vmgxy9jlrrqk7jyr507zqkihq5bv8kfsanv1x";
message = '' message = ''
This nix expression requires that ${name} is already part of the store. This nix expression requires that ${name} is already part of the store.
Download it from https://sidefx.com and add it to the nix store with: Download it from https://www.sidefx.com and add it to the nix store with:
nix-prefetch-url <URL> nix-prefetch-url <URL>
@ -78,7 +78,7 @@ stdenv.mkDerivation rec {
''; '';
meta = { meta = {
description = "3D animation application software"; description = "3D animation application software";
homepage = https://sidefx.com; homepage = https://www.sidefx.com;
license = stdenv.lib.licenses.unfree; license = stdenv.lib.licenses.unfree;
platforms = stdenv.lib.platforms.linux; platforms = stdenv.lib.platforms.linux;
maintainers = [ stdenv.lib.maintainers.canndrew ]; maintainers = [ stdenv.lib.maintainers.canndrew ];

View File

@ -1,17 +1,27 @@
{ stdenv, fetchurl, pkgconfig, neon, libusb, openssl, udev, avahi, freeipmi { stdenv, fetchurl, pkgconfig, neon, libusb, openssl, udev, avahi, freeipmi
, libtool, makeWrapper, nss }: , libtool, makeWrapper, autoreconfHook, fetchpatch
}:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "nut-2.7.4"; pname = "nut";
version = "2.7.4";
src = fetchurl { src = fetchurl {
url = "http://www.networkupstools.org/source/2.7/${name}.tar.gz"; url = "https://networkupstools.org/source/2.7/${pname}-${version}.tar.gz";
sha256 = "19r5dm07sfz495ckcgbfy0pasx0zy3faa0q7bih69lsjij8q43lq"; sha256 = "19r5dm07sfz495ckcgbfy0pasx0zy3faa0q7bih69lsjij8q43lq";
}; };
buildInputs = [ neon libusb openssl udev avahi freeipmi libtool nss ]; patches = [
(fetchpatch {
# Fix build with openssl >= 1.1.0
url = "https://github.com/networkupstools/nut/commit/612c05efb3c3b243da603a3a050993281888b6e3.patch";
sha256 = "0jdbii1z5sqyv24286j5px65j7b3gp8zk3ahbph83pig6g46m3hs";
})
];
nativeBuildInputs = [ pkgconfig makeWrapper ]; buildInputs = [ neon libusb openssl udev avahi freeipmi ];
nativeBuildInputs = [ autoreconfHook libtool pkgconfig makeWrapper ];
configureFlags = configureFlags =
[ "--with-all" [ "--with-all"
@ -26,7 +36,6 @@ stdenv.mkDerivation rec {
enableParallelBuilding = true; enableParallelBuilding = true;
postInstall = '' postInstall = ''
wrapProgram $out/bin/nut-scanner --prefix LD_LIBRARY_PATH : \ wrapProgram $out/bin/nut-scanner --prefix LD_LIBRARY_PATH : \
"$out/lib:${neon}/lib:${libusb.out}/lib:${avahi}/lib:${freeipmi}/lib" "$out/lib:${neon}/lib:${libusb.out}/lib:${avahi}/lib:${freeipmi}/lib"
@ -39,7 +48,7 @@ stdenv.mkDerivation rec {
interface for monitoring and administering UPS, PDU and SCD hardware. interface for monitoring and administering UPS, PDU and SCD hardware.
It uses a layered approach to connect all of the parts. It uses a layered approach to connect all of the parts.
''; '';
homepage = http://www.networkupstools.org/; homepage = https://networkupstools.org/;
repositories.git = https://github.com/networkupstools/nut.git; repositories.git = https://github.com/networkupstools/nut.git;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = [ maintainers.pierron ]; maintainers = [ maintainers.pierron ];

View File

@ -1,5 +1,5 @@
{ cairo, cmake, fetchFromGitHub, libXdmcp, libpthreadstubs, libxcb, pcre, pkgconfig { cairo, cmake, fetchFromGitHub, libXdmcp, libpthreadstubs, libxcb, pcre, pkgconfig
, python2, stdenv, xcbproto, xcbutil, xcbutilcursor, xcbutilimage , python3, stdenv, xcbproto, xcbutil, xcbutilcursor, xcbutilimage
, xcbutilrenderutil, xcbutilwm, xcbutilxrm, makeWrapper , xcbutilrenderutil, xcbutilwm, xcbutilxrm, makeWrapper
# optional packages-- override the variables ending in 'Support' to enable or # optional packages-- override the variables ending in 'Support' to enable or
@ -24,15 +24,16 @@ assert nlSupport -> ! iwSupport && libnl != null;
assert i3Support -> ! i3GapsSupport && jsoncpp != null && i3 != null; assert i3Support -> ! i3GapsSupport && jsoncpp != null && i3 != null;
assert i3GapsSupport -> ! i3Support && jsoncpp != null && i3-gaps != null; assert i3GapsSupport -> ! i3Support && jsoncpp != null && i3-gaps != null;
stdenv.mkDerivation rec { let xcbproto-py3 = xcbproto.override { python = python3; };
in stdenv.mkDerivation rec {
pname = "polybar"; pname = "polybar";
version = "3.4.0"; version = "3.4.1";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "jaagr"; owner = pname;
repo = pname; repo = pname;
rev = version; rev = version;
sha256 = "1g3zj0788cdlm8inpl19279bw8zjcy7dzj7q4f1l2d8c8g1jhv0m"; sha256 = "1z1m6dxh2i5vsnkzaccb9j02ab05wgmcgig5d0l9w856g5jp3zmy";
fetchSubmodules = true; fetchSubmodules = true;
}; };
@ -45,12 +46,12 @@ stdenv.mkDerivation rec {
having a black belt in shell scripting. having a black belt in shell scripting.
''; '';
license = licenses.mit; license = licenses.mit;
maintainers = [ maintainers.afldcr ]; maintainers = with maintainers; [ afldcr filalex77 ];
platforms = platforms.unix; platforms = platforms.linux;
}; };
buildInputs = [ buildInputs = [
cairo libXdmcp libpthreadstubs libxcb pcre python2 xcbproto xcbutil cairo libXdmcp libpthreadstubs libxcb pcre python3 xcbproto-py3 xcbutil
xcbutilcursor xcbutilimage xcbutilrenderutil xcbutilwm xcbutilxrm xcbutilcursor xcbutilimage xcbutilrenderutil xcbutilwm xcbutilxrm
(if alsaSupport then alsaLib else null) (if alsaSupport then alsaLib else null)

View File

@ -3,8 +3,6 @@
let let
getDesktopFileName = drvName: (builtins.parseDrvName drvName).name;
# TODO: Should we move this to `lib`? Seems like its would be useful in many cases. # TODO: Should we move this to `lib`? Seems like its would be useful in many cases.
extensionOf = filePath: extensionOf = filePath:
lib.concatStringsSep "." (lib.tail (lib.splitString "." (builtins.baseNameOf filePath))); lib.concatStringsSep "." (lib.tail (lib.splitString "." (builtins.baseNameOf filePath)));
@ -15,15 +13,15 @@ let
'') icons); '') icons);
mkSweetHome3D = mkSweetHome3D =
{ name, module, version, src, license, description, desktopName, icons }: { pname, module, version, src, license, description, desktopName, icons }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
inherit name version src description; inherit pname version src description;
exec = stdenv.lib.toLower module; exec = stdenv.lib.toLower module;
sweethome3dItem = makeDesktopItem { sweethome3dItem = makeDesktopItem {
inherit exec desktopName; inherit exec desktopName;
name = getDesktopFileName name; name = pname;
icon = getDesktopFileName name; icon = pname;
comment = description; comment = description;
genericName = "Computer Aided (Interior) Design"; genericName = "Computer Aided (Interior) Design";
categories = "Application;Graphics;2DGraphics;3DGraphics;"; categories = "Application;Graphics;2DGraphics;3DGraphics;";
@ -49,7 +47,7 @@ let
mkdir -p $out/bin mkdir -p $out/bin
cp install/${module}-${version}.jar $out/share/java/. cp install/${module}-${version}.jar $out/share/java/.
${installIcons (getDesktopFileName name) icons} ${installIcons pname icons}
cp "${sweethome3dItem}/share/applications/"* $out/share/applications cp "${sweethome3dItem}/share/applications/"* $out/share/applications
@ -74,9 +72,9 @@ let
in { in {
application = mkSweetHome3D rec { application = mkSweetHome3D rec {
pname = stdenv.lib.toLower module + "-application";
version = "6.2"; version = "6.2";
module = "SweetHome3D"; module = "SweetHome3D";
name = stdenv.lib.toLower module + "-application-" + version;
description = "Design and visualize your future home"; description = "Design and visualize your future home";
license = stdenv.lib.licenses.gpl2Plus; license = stdenv.lib.licenses.gpl2Plus;
src = fetchsvn { src = fetchsvn {

View File

@ -7,20 +7,17 @@ let
m: "sweethome3d-" m: "sweethome3d-"
+ removeSuffix "libraryeditor" (toLower m) + removeSuffix "libraryeditor" (toLower m)
+ "-editor"; + "-editor";
sweetName = m: v: sweetExec m + "-" + v;
getDesktopFileName = drvName: (builtins.parseDrvName drvName).name;
mkEditorProject = mkEditorProject =
{ name, module, version, src, license, description, desktopName }: { pname, module, version, src, license, description, desktopName }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
application = sweethome3dApp; application = sweethome3dApp;
inherit name module version src description; inherit pname module version src description;
exec = sweetExec module; exec = sweetExec module;
editorItem = makeDesktopItem { editorItem = makeDesktopItem {
inherit exec desktopName; inherit exec desktopName;
name = getDesktopFileName name; name = pname;
comment = description; comment = description;
genericName = "Computer Aided (Interior) Design"; genericName = "Computer Aided (Interior) Design";
categories = "Application;Graphics;2DGraphics;3DGraphics;"; categories = "Application;Graphics;2DGraphics;3DGraphics;";
@ -66,7 +63,7 @@ in {
textures-editor = mkEditorProject rec { textures-editor = mkEditorProject rec {
version = "1.5"; version = "1.5";
module = "TexturesLibraryEditor"; module = "TexturesLibraryEditor";
name = sweetName module version; pname = module;
description = "Easily create SH3T files and edit the properties of the texture images it contain"; description = "Easily create SH3T files and edit the properties of the texture images it contain";
license = stdenv.lib.licenses.gpl2Plus; license = stdenv.lib.licenses.gpl2Plus;
src = fetchcvs { src = fetchcvs {
@ -81,7 +78,7 @@ in {
furniture-editor = mkEditorProject rec { furniture-editor = mkEditorProject rec {
version = "1.19"; version = "1.19";
module = "FurnitureLibraryEditor"; module = "FurnitureLibraryEditor";
name = sweetName module version; pname = module;
description = "Quickly create SH3F files and edit the properties of the 3D models it contain"; description = "Quickly create SH3F files and edit the properties of the 3D models it contain";
license = stdenv.lib.licenses.gpl2; license = stdenv.lib.licenses.gpl2;
src = fetchcvs { src = fetchcvs {

View File

@ -1,14 +1,17 @@
{ stdenv, fetchurl, cmake }: { stdenv, fetchFromGitHub, cmake }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
pname = "timewarrior"; pname = "timewarrior";
version = "1.1.1"; version = "1.2.0";
enableParallelBuilding = true; enableParallelBuilding = true;
src = fetchurl { src = fetchFromGitHub {
url = "https://taskwarrior.org/download/timew-${version}.tar.gz"; owner = "GothenburgBitFactory";
sha256 = "1jfcfzdwk5qqhxznj1bgy0sx3lnp3z5lqr9kch9a7iazwmi9lz8z"; repo = "timewarrior";
rev = "v${version}";
sha256 = "0ci8kb7gdp1dsv6xj30nbz8lidrmn50pbriw26wv8mdhs17rfk7w";
fetchSubmodules = true;
}; };
nativeBuildInputs = [ cmake ]; nativeBuildInputs = [ cmake ];

View File

@ -1,14 +1,14 @@
{ stdenv, fetchFromGitHub, autoreconfHook }: { stdenv, fetchFromGitHub, autoreconfHook }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
version = "1.4.17"; version = "1.4.18";
pname = "tnef"; pname = "tnef";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "verdammelt"; owner = "verdammelt";
repo = "tnef"; repo = "tnef";
rev = version; rev = version;
sha256 = "0cq2xh5wd74qn6k2nnw5rayxgqhjl3jbzf4zlc4babcwxrv32ldh"; sha256 = "104g48mcm00bgiyzas2vf86331w7bnw7h3bc11ib4lp7rz6zqfck";
}; };
doCheck = true; doCheck = true;

View File

@ -0,0 +1,28 @@
diff --git a/Cargo.lock b/Cargo.lock
index df5fef3..80f071a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2158,12 +2158,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
- "sass-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sass-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sass-sys"
-version = "0.4.13"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3410,7 +3410,7 @@ dependencies = [
"checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum sass-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cabcf7c6e55053f359911187ac401409aad2dc14338cae972dec266fee486abd"
-"checksum sass-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6e16ac97c2335bc367e2d675f54c1823558f1b19a6c67671d48b70e30ae22972"
+"checksum sass-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "304b6f9501d1da13f17404aeee85486d7383d06074906669b3ea032f81e83d22"
"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"

View File

@ -8,10 +8,11 @@ rustPlatform.buildRustPackage rec {
owner = "getzola"; owner = "getzola";
repo = pname; repo = pname;
rev = "v${version}"; rev = "v${version}";
sha256 = "0dbj2rkn4k5glnwdazsvjhah5pj9cbdb8hwlvm5q4njsmrgpyaw5"; sha256 = "13kbgxh7r6124d1fjdf0x599j1kpgixp1y9d299zb5vrd6rf5wy5";
}; };
cargoPatches = [ ./cargo-lock.patch ];
cargoSha256 = "0i0xqbpbv3md42d2853cfzkhfwlkvxahhz5dldla5x96rm1i2hr8"; cargoSha256 = "03rwf5l1l3ap03qi0xqcxsbyvpg3cqmr50j8ql6c5v55xl0ki9w8";
nativeBuildInputs = [ cmake pkgconfig ]; nativeBuildInputs = [ cmake pkgconfig ];
buildInputs = [ openssl ] buildInputs = [ openssl ]

View File

@ -150,8 +150,8 @@ let
# ++ optionals (channel == "dev") [ ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" ) ] # ++ optionals (channel == "dev") [ ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" ) ]
# ++ optional (versionRange "68" "72") ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" ) # ++ optional (versionRange "68" "72") ( githubPatch "<patch>" "0000000000000000000000000000000000000000000000000000000000000000" )
] ++ optionals (useVaapi) [ ] ++ optionals (useVaapi) [
# source: https://aur.archlinux.org/cgit/aur.git/plain/chromium-vaapi.patch?h=chromium-vaapi # source: https://aur.archlinux.org/cgit/aur.git/tree/vaapi-fix.patch?h=chromium-vaapi
./patches/chromium-vaapi.patch ./patches/vaapi-fix.patch
] ++ optional stdenv.isAarch64 (fetchpatch { ] ++ optional stdenv.isAarch64 (fetchpatch {
url = https://raw.githubusercontent.com/OSSystems/meta-browser/e4a667deaaf9a26a3a1aeb355770d1f29da549ad/recipes-browser/chromium/files/aarch64-skia-build-fix.patch; url = https://raw.githubusercontent.com/OSSystems/meta-browser/e4a667deaaf9a26a3a1aeb355770d1f29da549ad/recipes-browser/chromium/files/aarch64-skia-build-fix.patch;
postFetch = "substituteInPlace $out --replace __aarch64__ SK_CPU_ARM64"; postFetch = "substituteInPlace $out --replace __aarch64__ SK_CPU_ARM64";

View File

@ -1,117 +0,0 @@
From abc7295ca1653c85472916909f0eb76e28e79a58 Mon Sep 17 00:00:00 2001
From: Akarshan Biswas <akarshan.biswas@gmail.com>
Date: Thu, 24 Jan 2019 12:45:29 +0530
Subject: [PATCH] Enable mojo with VDA2 on Linux
---
chrome/browser/about_flags.cc | 8 ++++----
chrome/browser/flag_descriptions.cc | 9 +++++++--
chrome/browser/flag_descriptions.h | 10 ++++++++--
gpu/config/software_rendering_list.json | 3 ++-
media/media_options.gni | 9 ++++++---
media/mojo/services/gpu_mojo_media_client.cc | 4 ++--
6 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0a84c6ac1..be2aa1d8b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1714,7 +1714,7 @@ const FeatureEntry kFeatureEntries[] = {
"disable-accelerated-video-decode",
flag_descriptions::kAcceleratedVideoDecodeName,
flag_descriptions::kAcceleratedVideoDecodeDescription,
- kOsMac | kOsWin | kOsCrOS | kOsAndroid,
+ kOsMac | kOsWin | kOsCrOS | kOsAndroid | kOsLinux,
SINGLE_DISABLE_VALUE_TYPE(switches::kDisableAcceleratedVideoDecode),
},
#if defined(OS_WIN)
@@ -2345,12 +2345,12 @@ const FeatureEntry kFeatureEntries[] = {
FEATURE_VALUE_TYPE(service_manager::features::kXRSandbox)},
#endif // ENABLE_ISOLATED_XR_SERVICE
#endif // ENABLE_VR
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
{"disable-accelerated-mjpeg-decode",
flag_descriptions::kAcceleratedMjpegDecodeName,
- flag_descriptions::kAcceleratedMjpegDecodeDescription, kOsCrOS,
+ flag_descriptions::kAcceleratedMjpegDecodeDescription, kOsCrOS | kOsLinux,
SINGLE_DISABLE_VALUE_TYPE(switches::kDisableAcceleratedMjpegDecode)},
-#endif // OS_CHROMEOS
+#endif // OS_CHROMEOS // OS_LINUX
{"v8-cache-options", flag_descriptions::kV8CacheOptionsName,
flag_descriptions::kV8CacheOptionsDescription, kOsAll,
MULTI_VALUE_TYPE(kV8CacheOptionsChoices)},
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 62637e092..86f89fc6e 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3085,15 +3085,20 @@ const char kTextSuggestionsTouchBarDescription[] =
#endif
-// Chrome OS -------------------------------------------------------------------
+// Chrome OS Linux-------------------------------------------------------------------
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && !defined(OS_ANDROID))
const char kAcceleratedMjpegDecodeName[] =
"Hardware-accelerated mjpeg decode for captured frame";
const char kAcceleratedMjpegDecodeDescription[] =
"Enable hardware-accelerated mjpeg decode for captured frame where "
"available.";
+#endif
+
+// Chrome OS --------------------------------------------------
+
+#if defined(OS_CHROMEOS)
const char kAllowTouchpadThreeFingerClickName[] = "Touchpad three-finger-click";
const char kAllowTouchpadThreeFingerClickDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 5dac660bb..6cc4115da 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1846,13 +1846,19 @@ extern const char kPermissionPromptPersistenceToggleDescription[];
#endif // defined(OS_MACOSX)
-// Chrome OS ------------------------------------------------------------------
+// Chrome OS and Linux ------------------------------------------------------------------
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && !defined(OS_ANDROID))
extern const char kAcceleratedMjpegDecodeName[];
extern const char kAcceleratedMjpegDecodeDescription[];
+#endif // defined(OS_CHROMEOS) || (defined(OS_LINUX) && !defined(OS_ANDROID))
+
+// Chrome OS ------------------------------------------------------------------------
+
+#if defined(OS_CHROMEOS)
+
extern const char kAllowTouchpadThreeFingerClickName[];
extern const char kAllowTouchpadThreeFingerClickDescription[];
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
index 65f37b3f1..ae8a1718f 100644
--- a/gpu/config/software_rendering_list.json
+++ b/gpu/config/software_rendering_list.json
@@ -371,11 +371,12 @@
},
{
"id": 48,
- "description": "Accelerated video decode is unavailable on Linux",
+ "description": "Accelerated VA-API video decode is not supported on NVIDIA platforms",
"cr_bugs": [137247],
"os": {
"type": "linux"
},
+ "vendor_id": "0x10de",
"features": [
"accelerated_video_decode"
]
--
2.20.1

View File

@ -0,0 +1,54 @@
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -635,6 +635,7 @@
// |vpp_vaapi_wrapper_| for VaapiPicture to DownloadFromSurface() the VA's
// internal decoded frame.
if (buffer_allocation_mode_ != BufferAllocationMode::kNone &&
+ buffer_allocation_mode_ != BufferAllocationMode::kWrapVdpau &&
!vpp_vaapi_wrapper_) {
vpp_vaapi_wrapper_ = VaapiWrapper::Create(
VaapiWrapper::kVideoProcess, VAProfileNone,
@@ -650,7 +651,8 @@
// only used as a copy destination. Therefore, the VaapiWrapper used and
// owned by |picture| is |vpp_vaapi_wrapper_|.
std::unique_ptr<VaapiPicture> picture = vaapi_picture_factory_->Create(
- (buffer_allocation_mode_ == BufferAllocationMode::kNone)
+ ((buffer_allocation_mode_ == BufferAllocationMode::kNone) ||
+ (buffer_allocation_mode_ == BufferAllocationMode::kWrapVdpau))
? vaapi_wrapper_
: vpp_vaapi_wrapper_,
make_context_current_cb_, bind_image_cb_, buffers[i]);
@@ -1077,6 +1079,14 @@
VaapiVideoDecodeAccelerator::BufferAllocationMode
VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() {
+ // NVIDIA blobs use VDPAU
+ if (base::StartsWith(VaapiWrapper::GetVendorStringForTesting(),
+ "Splitted-Desktop Systems VDPAU",
+ base::CompareCase::SENSITIVE)) {
+ LOG(INFO) << "VA-API driver on VDPAU backend";
+ return BufferAllocationMode::kWrapVdpau;
+ }
+
// TODO(crbug.com/912295): Enable a better BufferAllocationMode for IMPORT
// |output_mode_| as well.
if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT)
@@ -1089,7 +1099,7 @@
// depends on the bitstream and sometimes it's not enough to cover the amount
// of frames needed by the client pipeline (see b/133733739).
// TODO(crbug.com/911754): Enable for VP9 Profile 2.
- if (IsGeminiLakeOrLater() &&
+ if (false && IsGeminiLakeOrLater() &&
(profile_ == VP9PROFILE_PROFILE0 || profile_ == VP8PROFILE_ANY)) {
// Add one to the reference frames for the one being currently egressed, and
// an extra allocation for both |client_| and |decoder_|, see
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.h
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.h
@@ -204,6 +204,7 @@
// Using |client_|s provided PictureBuffers and as many internally
// allocated.
kNormal,
+ kWrapVdpau,
};
// Decides the concrete buffer allocation mode, depending on the hardware

View File

@ -18,8 +18,9 @@ browser:
let let
wrapper = wrapper =
{ browserName ? browser.browserName or (builtins.parseDrvName browser.name).name { browserName ? browser.browserName or (lib.getName browser)
, name ? (browserName + "-" + (builtins.parseDrvName browser.name).version) , pname ? browserName
, version ? lib.getVersion browser
, desktopName ? # browserName with first letter capitalized , desktopName ? # browserName with first letter capitalized
(lib.toUpper (lib.substring 0 1 browserName) + lib.substring 1 (-1) browserName) (lib.toUpper (lib.substring 0 1 browserName) + lib.substring 1 (-1) browserName)
, nameSuffix ? "" , nameSuffix ? ""
@ -83,7 +84,7 @@ let
gtk_modules = [ libcanberra-gtk2 ]; gtk_modules = [ libcanberra-gtk2 ];
in stdenv.mkDerivation { in stdenv.mkDerivation {
inherit name; inherit pname version;
desktopItem = makeDesktopItem { desktopItem = makeDesktopItem {
name = browserName; name = browserName;

View File

@ -17,7 +17,7 @@ buildGoPackage rec {
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "C14 is designed for data archiving & long-term backups."; description = "C14 is designed for data archiving & long-term backups.";
homepage = https://www.online.net/en/c14; homepage = https://www.online.net/en/storage/c14-cold-storage;
license = licenses.mit; license = licenses.mit;
maintainers = with maintainers; [ apeyroux ]; maintainers = with maintainers; [ apeyroux ];
}; };

View File

@ -11,11 +11,11 @@
mkDerivation rec { mkDerivation rec {
pname = "datovka"; pname = "datovka";
version = "4.14.0"; version = "4.14.1";
src = fetchurl { src = fetchurl {
url = "https://secure.nic.cz/files/datove_schranky/${version}/${pname}-${version}.tar.xz"; url = "https://secure.nic.cz/files/datove_schranky/${version}/${pname}-${version}.tar.xz";
sha256 = "0q7zlq522wdgwxgd3jxmxvr3awclcy0mbw3qaymwzn2b8d35168r"; sha256 = "0jinxsm2zw77294vz9pjiqpgpzdwx5nijsi4nqzxna5rkmwdyxk6";
}; };
buildInputs = [ libisds qmake qtbase qtsvg libxml2 ]; buildInputs = [ libisds qmake qtbase qtsvg libxml2 ];

View File

@ -2,19 +2,18 @@
, zlib, libxml2, gtk2, libnotify, speex, ffmpeg, libX11, libsoup, udev , zlib, libxml2, gtk2, libnotify, speex, ffmpeg, libX11, libsoup, udev
, ortp, mediastreamer, sqlite, belle-sip, libosip, libexosip, bzrtp , ortp, mediastreamer, sqlite, belle-sip, libosip, libexosip, bzrtp
, mediastreamer-openh264, bctoolbox, makeWrapper, fetchFromGitHub, cmake , mediastreamer-openh264, bctoolbox, makeWrapper, fetchFromGitHub, cmake
, libmatroska, bcunit, doxygen, gdk-pixbuf, glib, cairo, pango, polarssl , libmatroska, bcunit, doxygen, gdk-pixbuf, glib, cairo, pango, mbedtls
, python, graphviz, belcard , python, graphviz, belcard, bcg729
, withGui ? true , withGui ? true
}: }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
baseName = "linphone"; pname = "linphone";
version = "3.12.0"; version = "3.12.0";
name = "${baseName}-${version}";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "BelledonneCommunications"; owner = "BelledonneCommunications";
repo = baseName; repo = pname;
rev = version; rev = version;
sha256 = "0az2ywrpx11sqfb4s4r2v726avcjf4k15bvrqj7xvhz7hdndmh0j"; sha256 = "0az2ywrpx11sqfb4s4r2v726avcjf4k15bvrqj7xvhz7hdndmh0j";
}; };
@ -27,21 +26,25 @@ stdenv.mkDerivation rec {
buildInputs = [ buildInputs = [
readline openldap cyrus_sasl libupnp zlib libxml2 gtk2 libnotify speex ffmpeg libX11 readline openldap cyrus_sasl libupnp zlib libxml2 gtk2 libnotify speex ffmpeg libX11
polarssl libsoup udev ortp mediastreamer sqlite belle-sip libosip libexosip mbedtls libsoup udev ortp mediastreamer sqlite belle-sip libosip libexosip
bctoolbox libmatroska bcunit gdk-pixbuf glib cairo pango bzrtp belcard bctoolbox libmatroska gdk-pixbuf glib cairo pango bzrtp belcard bcg729
]; ];
nativeBuildInputs = [ nativeBuildInputs = [
intltool pkgconfig makeWrapper cmake doxygen graphviz intltool pkgconfig makeWrapper cmake bcunit doxygen graphviz
(python.withPackages (ps: [ ps.pystache ps.six ])) (python.withPackages (ps: [ ps.pystache ps.six ]))
]; ];
NIX_CFLAGS_COMPILE = " -Wno-error -I${glib.dev}/include/glib-2.0 NIX_CFLAGS_COMPILE = [
-I${glib.out}/lib/glib-2.0/include -I${gtk2.dev}/include/gtk-2.0/ "-Wno-error"
-I${cairo.dev}/include/cairo -I${pango.dev}/include/pango-1.0 "-I${glib.dev}/include/glib-2.0"
-I${gtk2}/lib/gtk-2.0/include "-I${glib.out}/lib/glib-2.0/include"
-DLIBLINPHONE_GIT_VERSION=\"v${version}\" "-I${gtk2.dev}/include/gtk-2.0/"
"; "-I${cairo.dev}/include/cairo"
"-I${pango.dev}/include/pango-1.0"
"-I${gtk2}/lib/gtk-2.0/include"
"-DLIBLINPHONE_GIT_VERSION=\"v${version}\""
];
postInstall = '' postInstall = ''
for i in $(cd $out/bin && ls); do for i in $(cd $out/bin && ls); do
@ -50,8 +53,8 @@ stdenv.mkDerivation rec {
''; '';
meta = with stdenv.lib; { meta = with stdenv.lib; {
homepage = http://www.linphone.org/; homepage = https://www.linphone.org/;
description = "Open Source video SIP softphone"; description = "Open source SIP phone for voice/video calls and instant messaging";
license = licenses.gpl2Plus; license = licenses.gpl2Plus;
platforms = platforms.linux; platforms = platforms.linux;
}; };

View File

@ -3,7 +3,7 @@
set -eu -o pipefail set -eu -o pipefail
oldVersion="$(nix-instantiate --eval -E "with import ./. {}; slack-theme-black.version or (builtins.parseDrvName slack-theme-black.name).version" | tr -d '"')" oldVersion="$(nix-instantiate --eval -E "with import ./. {}; lib.getVersion slack-theme-black" | tr -d '"')"
latestSha="$(curl -L -s https://api.github.com/repos/laCour/slack-night-mode/commits\?sha\=master\&since\=${oldVersion} | jq -r '.[0].sha')" latestSha="$(curl -L -s https://api.github.com/repos/laCour/slack-night-mode/commits\?sha\=master\&since\=${oldVersion} | jq -r '.[0].sha')"
if [ ! "null" = "${latestSha}" ]; then if [ ! "null" = "${latestSha}" ]; then

View File

@ -3,7 +3,7 @@
set -eu -o pipefail set -eu -o pipefail
oldVersion=$(nix-instantiate --eval -E "with import ./. {}; zoom-us.version or (builtins.parseDrvName zoom-us.name).version" | tr -d '"') oldVersion=$(nix-instantiate --eval -E "with import ./. {}; lib.getVersion zoom-us" | tr -d '"')
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')" version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
if [ ! "${oldVersion}" = "${version}" ]; then if [ ! "${oldVersion}" = "${version}" ]; then

View File

@ -1,21 +1,22 @@
{ stdenv, buildGoModule, fetchurl { stdenv, buildGoModule, fetchurl
, go, ncurses, scdoc , go, ncurses, notmuch, scdoc
, python3, perl, w3m, dante , python3, perl, w3m, dante
}: }:
buildGoModule rec { buildGoModule rec {
pname = "aerc"; pname = "aerc";
version = "0.2.1"; version = "0.3.0";
src = fetchurl { src = fetchurl {
url = "https://git.sr.ht/~sircmpwn/aerc/archive/${version}.tar.gz"; url = "https://git.sr.ht/~sircmpwn/aerc/archive/${version}.tar.gz";
sha256 = "1ky1nl5b54lf5jnac2kb5404fplwnwypjplas8imdlsf517fw32n"; sha256 = "188jln8hmgiqn5il5m54bns0wk4grj09di8y6mmid58ibw6spma4";
}; };
nativeBuildInputs = [ nativeBuildInputs = [
go go
scdoc scdoc
python3.pkgs.wrapPython python3.pkgs.wrapPython
notmuch
]; ];
patches = [ patches = [
@ -28,6 +29,8 @@ buildGoModule rec {
buildInputs = [ python3 perl ]; buildInputs = [ python3 perl ];
GOFLAGS="-tags=notmuch";
buildPhase = " buildPhase = "
runHook preBuild runHook preBuild
# we use make instead of go build # we use make instead of go build
@ -43,12 +46,12 @@ buildGoModule rec {
postFixup = '' postFixup = ''
wrapProgram $out/bin/aerc --prefix PATH ":" \ wrapProgram $out/bin/aerc --prefix PATH ":" \
"$out/share/aerc/filters:${stdenv.lib.makeBinPath [ ncurses.dev ]}" "$out/share/aerc/filters:${stdenv.lib.makeBinPath [ ncurses ]}"
wrapProgram $out/share/aerc/filters/html --prefix PATH ":" \ wrapProgram $out/share/aerc/filters/html --prefix PATH ":" \
${stdenv.lib.makeBinPath [ w3m dante ]} ${stdenv.lib.makeBinPath [ w3m dante ]}
''; '';
modSha256 = "0fc9m1qb8innypc8cxzbqyrfkawawyaqq3gqy7lqwmyh32f300jh"; modSha256 = "0pxbv4zfhii0g41cy0ycfpkkxw6nnd4ibavic6zqw30j476jnm2x";
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "aerc is an email client for your terminal"; description = "aerc is an email client for your terminal";

View File

@ -1,18 +1,19 @@
From 7ea68a2eef026723903d72f54ca54b629881ec06 Mon Sep 17 00:00:00 2001 From 6cf3c2e42d219b9665a43ca65f321c653b0aa102 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak <me@tadeo.ca> From: Tadeo Kondrak <me@tadeo.ca>
Date: Mon, 28 Oct 2019 08:36:36 -0600 Date: Mon, 28 Oct 2019 08:36:36 -0600
Subject: [PATCH] Fix aerc breaking every time the package is rebuilt. Subject: [PATCH] Fix aerc breaking every time the package is rebuilt.
On NixOS, the SHAREDIR changes on every rebuild to the package, but aerc On NixOS, the SHAREDIR changes on every rebuild to the package, but aerc
fills it in as part of the default config. Fix this by not substituting fills it in as part of the default config and then installs that config
@SHAREDIR@ in the default config until runtime. to the users home folder. Fix this by not substituting @SHAREDIR@ in the
default config until runtime.
--- ---
Makefile | 2 +- Makefile | 2 +-
config/config.go | 3 +++ config/config.go | 8 ++++++++
2 files changed, 4 insertions(+), 1 deletion(-) 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index d3072d3..17ca0be 100644 index d1c755d..1185a96 100644
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -24,7 +24,7 @@ aerc: $(GOSRC) @@ -24,7 +24,7 @@ aerc: $(GOSRC)
@ -25,10 +26,22 @@ index d3072d3..17ca0be 100644
DOCS := \ DOCS := \
aerc.1 \ aerc.1 \
diff --git a/config/config.go b/config/config.go diff --git a/config/config.go b/config/config.go
index bfcbecf..2f4e703 100644 index 32d07fc..8ffd3e8 100644
--- a/config/config.go --- a/config/config.go
+++ b/config/config.go +++ b/config/config.go
@@ -377,6 +377,9 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) { @@ -355,6 +355,11 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
return nil, err
}
}
+ if sec, err := file.GetSection("templates"); err == nil {
+ if key, err := sec.GetKey("template-dirs"); err == nil {
+ sec.NewKey("template-dirs", strings.ReplaceAll(key.String(), "@SHAREDIR@", sharedir))
+ }
+ }
file.NameMapper = mapName
config := &AercConfig{
Bindings: BindingConfig{
@@ -423,6 +428,9 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
if err = config.LoadConfig(file); err != nil { if err = config.LoadConfig(file); err != nil {
return nil, err return nil, err
} }

View File

@ -103,6 +103,8 @@ let
git-imerge = callPackage ./git-imerge { }; git-imerge = callPackage ./git-imerge { };
git-machete = python3Packages.callPackage ./git-machete { };
git-octopus = callPackage ./git-octopus { }; git-octopus = callPackage ./git-octopus { };
git-open = callPackage ./git-open { }; git-open = callPackage ./git-open { };

View File

@ -0,0 +1,33 @@
{ lib, buildPythonApplication, fetchPypi
, installShellFiles, pbr
, flake8, mock, pycodestyle, pylint, tox }:
buildPythonApplication rec {
pname = "git-machete";
version = "2.12.1";
src = fetchPypi {
inherit pname version;
sha256 = "114kq396zq45jlibn1lp0nk4lmanj4w1bcn48gi7xzdm0y1nkzfq";
};
nativeBuildInputs = [ installShellFiles pbr ];
# TODO: Add missing check inputs (2019-11-22):
# - stestr
doCheck = false;
checkInputs = [ flake8 mock pycodestyle pylint tox ];
postInstall = ''
installShellCompletion --bash --name git-machete completion/git-machete.completion.bash
installShellCompletion --zsh --name _git-machete completion/git-machete.completion.zsh
'';
meta = with lib; {
homepage = https://github.com/VirtusLab/git-machete;
description = "Git repository organizer and rebase workflow automation tool";
license = licenses.mit;
platforms = platforms.all;
maintainers = [ maintainers.blitz ];
};
}

View File

@ -52,7 +52,7 @@ stdenv.mkDerivation rec {
homepage = https://github.com/ingydotnet/git-subrepo; homepage = https://github.com/ingydotnet/git-subrepo;
description = "Git submodule alternative"; description = "Git submodule alternative";
license = licenses.mit; license = licenses.mit;
platforms = platforms.linux; platforms = platforms.unix ++ platforms.darwin;
maintainers = [ maintainers.ryantrinkle ]; maintainers = [ maintainers.ryantrinkle ];
}; };
} }

View File

@ -3,7 +3,7 @@
set -eu -o pipefail set -eu -o pipefail
oldVersion="$(nix-instantiate --eval -E "with import ./. {}; git.version or (builtins.parseDrvName git.name).version" | tr -d '"')" oldVersion="$(nix-instantiate --eval -E "with import ./. {}; lib.getVersion git" | tr -d '"')"
latestTag="$(git ls-remote --tags --sort="v:refname" git://github.com/git/git.git | grep -v '\{\}' | grep -v '\-rc' | tail -1 | sed 's|^.*/v\(.*\)|\1|')" latestTag="$(git ls-remote --tags --sort="v:refname" git://github.com/git/git.git | grep -v '\{\}' | grep -v '\-rc' | tail -1 | sed 's|^.*/v\(.*\)|\1|')"
if [ ! "${oldVersion}" = "${latestTag}" ]; then if [ ! "${oldVersion}" = "${latestTag}" ]; then

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