Project import generated by Copybara.

GitOrigin-RevId: 135073a87b7e2c631739f4ffa016e1859b1a425e
This commit is contained in:
Default email 2020-05-29 08:06:01 +02:00
parent dbc6e1fe44
commit 4fc29cb41f
1002 changed files with 19093 additions and 10708 deletions

View file

@ -11,18 +11,26 @@ insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
# Ignore diffs/patches
[*.{diff,patch}]
end_of_line = unset
insert_final_newline = unset
trim_trailing_whitespace = unset
# see https://nixos.org/nixpkgs/manual/#chap-conventions
# Match nix/ruby/docbook files, set indent to spaces with width of two
[*.{nix,rb,xml}]
# Match nix/perl/python/ruby/shell/docbook files, set indent to spaces
[*.{nix,pl,py,rb,sh,xml}]
indent_style = space
# Match docbook files, set indent width of one
[*.xml]
indent_size = 1
# Match nix/ruby files, set indent width of two
[*.{nix,rb}]
indent_size = 2
# Match shell/python/perl scripts, set indent to spaces with width of four
[*.{sh,py,pl}]
indent_style = space
# Match perl/python/shell scripts, set indent width of four
[*.{pl,py,sh}]
indent_size = 4
# Match diffs, avoid to trim trailing whitespace
[*.{diff,patch}]
trim_trailing_whitespace = false

View file

@ -181,9 +181,15 @@
/nixos/modules/services/monitoring/prometheus/exporters.xml @WilliButz
/nixos/tests/prometheus-exporters.nix @WilliButz
# PHP
/doc/languages-frameworks/php.section.md @etu
/nixos/tests/php @etu
/pkgs/build-support/build-pecl.nix @etu
/pkgs/development/interpreters/php @etu
/pkgs/top-level/php-packages.nix @etu
# PHP interpreter, packages, extensions, tests and documentation
/doc/languages-frameworks/php.section.md @NixOS/php
/nixos/tests/php @NixOS/php
/pkgs/build-support/build-pecl.nix @NixOS/php
/pkgs/development/interpreters/php @NixOS/php
/pkgs/top-level/php-packages.nix @NixOS/php
# Podman, CRI-O modules and related
/nixos/modules/virtualisation/containers.nix @NixOS/podman
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman
/nixos/modules/virtualisation/podman.nix @NixOS/podman
/nixos/tests/podman.nix @NixOS/podman

View file

@ -42,7 +42,7 @@ $ agda -l standard-library -i . MyFile.agda
```
name: my-library
include: .
depends: standard-library
depend: standard-library
```
- Create the file `~/.agda/defaults` and add any libraries you want to use by default.

View file

@ -1023,7 +1023,8 @@ are used in `buildPythonPackage`.
- `setuptoolsBuildHook` to build a wheel using `setuptools`.
- `setuptoolsCheckHook` to run tests with `python setup.py test`.
- `venvShellHook` to source a Python 3 `venv` at the `venvDir` location. A
`venv` is created if it does not yet exist.
`venv` is created if it does not yet exist. `postVenvCreation` can be used to
to run commands only after venv is first created.
- `wheelUnpackHook` to move a wheel to the correct folder so it can be installed
with the `pipInstallHook`.
@ -1291,10 +1292,17 @@ in pkgs.mkShell rec {
zlib
];
# Run this command, only after creating the virtual environment
postVenvCreation = ''
unset SOURCE_DATE_EPOCH
pip install -r requirements.txt
'';
# Now we can execute any commands within the virtual environment.
# This is optional and can be left out to run pip manually.
postShellHook = ''
pip install -r requirements.txt
# allow pip to install wheels
unset SOURCE_DATE_EPOCH
'';
}

View file

@ -247,12 +247,6 @@
githubId = 732652;
name = "Andreas Herrmann";
};
ahmedtd = {
email = "ahmed.taahir@gmail.com";
github = "ahmedtd";
githubId = 1017202;
name = "Taahir Ahmed";
};
ahuzik = {
email = "ales.guzik@gmail.com";
github = "alesguzik";
@ -1175,6 +1169,12 @@
githubId = 510553;
name = "Jos van Bakel";
};
caadar = {
email = "v88m@posteo.net";
github = "caadar";
githubId = 15320726;
name = "Car Cdr";
};
cab404 = {
email = "cab404@mailbox.org";
github = "cab404";
@ -1280,6 +1280,12 @@
githubId = 64804;
name = "Dennis Gosnell";
};
ccellado = {
email = "annplague@gmail.com";
github = "ccellado";
githubId = 44584960;
name = "Denis Khalmatov";
};
ceedubs = {
email = "ceedubs@gmail.com";
github = "ceedubs";
@ -3586,12 +3592,24 @@
githubId = 51518420;
name = "jitwit";
};
jk = {
email = "hello+nixpkgs@j-k.io";
github = "06kellyjac";
githubId = 9866621;
name = "Jack";
};
jlesquembre = {
email = "jl@lafuente.me";
github = "jlesquembre";
githubId = 1058504;
name = "José Luis Lafuente";
};
jloyet = {
email = "ml@fatbsd.com";
github = "fatpat";
githubId = 822436;
name = "Jérôme Loyet";
};
jluttine = {
email = "jaakko.luttinen@iki.fi";
github = "jluttine";
@ -3991,6 +4009,12 @@
githubId = 59667;
name = "Ahmed Kamal";
};
kimat = {
email = "mail@kimat.org";
github = "kimat";
githubId = 3081769;
name = "Kimat Boven";
};
kimburgess = {
email = "kim@acaprojects.com";
github = "kimburgess";
@ -4041,6 +4065,16 @@
github = "klntsky";
githubId = 18447310;
};
kloenk = {
email = "me@kloenk.de";
name = "Finn Behrens";
github = "kloenk";
githubId = 12898828;
keys = [{
longkeyid = "ed25519/0xB92445CFC9546F9D";
fingerprint = "6881 5A95 D715 D429 659B 48A4 B924 45CF C954 6F9D";
}];
};
kmcopper = {
email = "kmcopper@danwin1210.me";
name = "Kyle Copperfield";
@ -4162,6 +4196,12 @@
githubId = 10544;
name = "Giuluo Eulisse";
};
kthielen = {
email = "kthielen@gmail.com";
github = "kthielen";
githubId = 1409287;
name = "Kalani Thielen";
};
ktor = {
email = "kruszewsky@gmail.com";
github = "ktor";
@ -4695,6 +4735,12 @@
githubId = 3507;
name = "Michael Fellinger";
};
maralorn = {
email = "malte.brandy@maralorn.de";
github = "maralorn";
githubId = 1651325;
name = "Malte Brandy";
};
marcweber = {
email = "marco-oweber@gmx.de";
github = "marcweber";
@ -5546,6 +5592,12 @@
githubId = 4368690;
name = "Ratko Mladic";
};
nilp0inter = {
email = "robertomartinezp@gmail.com";
github = "nilp0inter";
githubId = 1224006;
name = "Roberto Abdelkader Martínez Pérez";
};
ninjatrappeur = {
email = "felix@alternativebit.fr";
github = "ninjatrappeur";
@ -6562,6 +6614,12 @@
githubId = 353885;
name = "Rob Vermaas";
};
robaca = {
email = "carsten@r0hrbach.de";
github = "robaca";
githubId = 580474;
name = "Carsten Rohrbach";
};
robberer = {
email = "robberer@freakmail.de";
github = "robberer";
@ -6634,6 +6692,12 @@
githubId = 1942810;
name = "Christian Ulrich";
};
rpearce = {
email = "me@robertwpearce.com";
github = "rpearce";
githubId = 592876;
name = "Robert W. Pearce";
};
rprospero = {
email = "rprospero+nix@gmail.com";
github = "rprospero";
@ -6694,6 +6758,12 @@
githubId = 889991;
name = "Ryan Artecona";
};
ryanorendorff = {
email = "12442942+ryanorendorff@users.noreply.github.com";
github = "ryanorendorff";
githubId = 12442942;
name = "Ryan Orendorff";
};
ryansydnor = {
email = "ryan.t.sydnor@gmail.com";
github = "ryansydnor";
@ -8107,6 +8177,16 @@
githubId = 6508;
name = "Vincent Demeester";
};
veehaitch = {
name = "Vincent Haupert";
email = "mail@vincent-haupert.de";
github = "veehaitch";
githubId = 15069839;
keys = [{
longkeyid = "rsa4096/0x874BD6F916FAA742";
fingerprint = "4D23 ECDF 880D CADF 5ECA 4458 874B D6F9 16FA A742";
}];
};
velovix = {
email = "xaviosx@gmail.com";
github = "velovix";
@ -8283,6 +8363,12 @@
githubId = 6016963;
name = "Patrick Winter";
};
wishfort36 = {
email = "42300264+wishfort36@users.noreply.github.com";
github = "wishfort36";
githubId = 42300264;
name = "wishfort36";
};
wizeman = {
email = "rcorreia@wizy.org";
github = "wizeman";
@ -8301,6 +8387,12 @@
githubId = 54934;
name = "Wout Mertens";
};
wnklmnn = {
email = "pascal@wnklmnn.de";
github = "wnklmnn";
githubId = 9423014;
name = "Pascal Winkelmann";
};
woffs = {
email = "github@woffs.de";
github = "woffs";

View file

@ -26,6 +26,12 @@
<listitem>
<para>GNOME desktop environment was upgraded to 3.36, see its <link xlink:href="https://help.gnome.org/misc/release-notes/3.36/">release notes</link>.</para>
</listitem>
<listitem>
<para>
<package>maxx</package> package removed along with <varname>services.xserver.desktopManager.maxx</varname> module.
Please migrate to <package>cdesktopenv</package> and <varname>services.xserver.desktopManager.cde</varname> module.
</para>
</listitem>
<listitem>
<para>
We now distribute a GNOME ISO.
@ -122,8 +128,16 @@ services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" ''
<itemizedlist>
<listitem>
<para>
The go-modules builder now uses vendorSha256 instead of modSha256 to pin
fetched version data. This is currently a warning, but will be removed in the next release.
<literal>buildGoModule</literal> now internally creates a vendor directory
in the source tree for downloaded modules instead of using go's <link
xlink:href="https://golang.org/cmd/go/#hdr-Module_proxy_protocol">module
proxy protocol</link>. This storage format is simpler and therefore less
likekly to break with future versions of go. As a result
<literal>buildGoModule</literal> switched from
<literal>modSha256</literal> to the <literal>vendorSha256</literal>
attribute to pin fetched version data. <literal>buildGoModule</literal>
still accepts <literal>modSha256</literal> with a warning, but support will
be removed in the next release.
</para>
</listitem>
<listitem>
@ -381,6 +395,52 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
will have changed.
</para>
</listitem>
<listitem>
<para>
The rkt module has been removed, it was archived by upstream.
</para>
</listitem>
<listitem>
<para>
The <link xlink:href="https://bazaar.canonical.com">Bazaar</link> VCS is
unmaintained and, as consequence of the Python 2 EOL, the packages
<literal>bazaar</literal> and <literal>bazaarTools</literal> were
removed. Breezy, the backward compatible fork of Bazaar (see the
<link xlink:href="https://www.jelmer.uk/breezy-intro.html">announcement</link>),
was packaged as <literal>breezy</literal> and can be used instead.
</para>
<para>
Regarding Nixpkgs, <literal>fetchbzr</literal>,
<literal>nix-prefetch-bzr</literal> and Bazaar support in Hydra will
continue to work through Breezy.
</para>
</listitem>
<listitem>
<para>
In addition to the hostname, the fully qualified domain name (FQDN),
which consists of <literal>${cfg.hostName}</literal> and
<literal>${cfg.domain}</literal> is now added to
<literal>/etc/hosts</literal>, to allow local FQDN resolution, as used by the
<literal>hostname --fqdn</literal> command and other applications that
try to determine the FQDN. These new entries take precedence over entries
from the DNS which could cause regressions in some very specific setups.
Additionally the hostname is now resolved to <literal>127.0.0.2</literal>
instead of <literal>127.0.1.1</literal> to be consistent with what
<literal>nss-myhostname</literal> (from systemd) returns.
The old behaviour can e.g. be restored by using
<literal>networking.hosts = lib.mkForce { "127.0.1.1" = [ config.networking.hostName ]; };</literal>.
</para>
</listitem>
<listitem>
<para>
The hostname (<literal>networking.hostName</literal>) must now be a valid
DNS label (see RFC 1035) and as such must not contain the domain part.
This means that the hostname must start with a letter, end with a letter
or digit, and have as interior characters only letters, digits, and
hyphen. The maximum length is 63 characters. Additionally it is
recommended to only use lower-case characters.
</para>
</listitem>
</itemizedlist>
</section>
@ -413,6 +473,34 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
The default output of <literal>buildGoPackage</literal> is now <literal>$out</literal> instead of <literal>$bin</literal>.
</para>
</listitem>
<listitem>
<para>
Default algorithm for ZRAM swap was changed to <literal>zstd</literal>.
</para>
</listitem>
<listitem>
<para>
The scripted networking system now uses <literal>.link</literal> files in
<literal>/etc/systemd/network</literal> to configure mac address and link MTU,
instead of the sometimes buggy <literal>network-link-*</literal> units, which
have been removed.
Bringing the interface up has been moved to the beginning of the
<literal>network-addresses-*</literal> unit.
Note this doesn't require <command>systemd-networkd</command> - it's udev that
parses <literal>.link</literal> files.
Extra care needs to be taken in the presence of <link xlink:href="https://wiki.debian.org/NetworkInterfaceNames#THE_.22PERSISTENT_NAMES.22_SCHEME">legacy udev rules</link>
to rename interfaces, as MAC Address and MTU defined in these options can only match on the original link name.
In such cases, you most likely want to create a <literal>10-*.link</literal> file through <xref linkend="opt-systemd.network.links"/> and set both name and MAC Address / MTU there.
</para>
</listitem>
<listitem>
<para>
Grafana received a major update to version 7.x. A plugin is now needed for
image rendering support, and plugins must now be signed by default. More
information can be found
<link xlink:href="https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v7-0">in the Grafana documentation</link>.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View file

@ -8,9 +8,6 @@ let
cfg = config.networking;
localhostMapped4 = cfg.hosts ? "127.0.0.1" && elem "localhost" cfg.hosts."127.0.0.1";
localhostMapped6 = cfg.hosts ? "::1" && elem "localhost" cfg.hosts."::1";
localhostMultiple = any (elem "localhost") (attrValues (removeAttrs cfg.hosts [ "127.0.0.1" "::1" ]));
in
@ -147,12 +144,6 @@ in
config = {
assertions = [{
assertion = localhostMapped4;
message = ''`networking.hosts` doesn't map "127.0.0.1" to "localhost"'';
} {
assertion = !cfg.enableIPv6 || localhostMapped6;
message = ''`networking.hosts` doesn't map "::1" to "localhost"'';
} {
assertion = !localhostMultiple;
message = ''
`networking.hosts` maps "localhost" to something other than "127.0.0.1"
@ -161,22 +152,34 @@ in
'';
}];
networking.hosts = {
"127.0.0.1" = [ "localhost" ];
} // optionalAttrs (cfg.hostName != "") {
"127.0.1.1" = [ cfg.hostName ];
# These entries are required for "hostname -f" and to resolve both the
# hostname and FQDN correctly:
networking.hosts = let
hostnames = # Note: The FQDN (canonical hostname) has to come first:
optional (cfg.hostName != "" && cfg.domain != null) "${cfg.hostName}.${cfg.domain}"
++ optional (cfg.hostName != "") cfg.hostName; # Then the hostname (without the domain)
in {
"127.0.0.2" = hostnames;
} // optionalAttrs cfg.enableIPv6 {
"::1" = [ "localhost" ];
"::1" = hostnames;
};
networking.hostFiles = let
# Note: localhostHosts has to appear first in /etc/hosts so that 127.0.0.1
# resolves back to "localhost" (as some applications assume) instead of
# the FQDN! By default "networking.hosts" also contains entries for the
# FQDN so that e.g. "hostname -f" works correctly.
localhostHosts = pkgs.writeText "localhost-hosts" ''
127.0.0.1 localhost
${optionalString cfg.enableIPv6 "::1 localhost"}
'';
stringHosts =
let
oneToString = set: ip: ip + " " + concatStringsSep " " set.${ip} + "\n";
allToString = set: concatMapStrings (oneToString set) (attrNames set);
in pkgs.writeText "string-hosts" (allToString (filterAttrs (_: v: v != []) cfg.hosts));
extraHosts = pkgs.writeText "extra-hosts" cfg.extraHosts;
in mkBefore [ stringHosts extraHosts ];
in mkBefore [ localhostHosts stringHosts extraHosts ];
environment.etc =
{ # /etc/services: TCP/UDP port assignments.

View file

@ -94,7 +94,7 @@ in
after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
script =
''
${config.systemd.package}/bin/systemctl try-restart post-resume.target
/run/current-system/systemd/bin/systemctl try-restart post-resume.target
${cfg.resumeCommands}
${cfg.powerUpCommands}
'';

View file

@ -21,7 +21,7 @@ let
'' + optionalString config.services.nscd.enable ''
# Invalidate the nscd cache whenever resolv.conf is
# regenerated.
libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service 2> /dev/null'
libc_restart='/run/current-system/systemd/bin/systemctl try-restart --no-block nscd.service 2> /dev/null'
'' + optionalString (length resolvconfOptions > 0) ''
# Options as described in resolv.conf(5)
resolv_conf_options='${concatStringsSep " " resolvconfOptions}'

View file

@ -91,7 +91,7 @@ in
};
algorithm = mkOption {
default = "lzo";
default = "zstd";
example = "lz4";
type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str;
description = ''

View file

@ -1,6 +1,6 @@
{
x86_64-linux = "/nix/store/8928ygfyf9iassfrnj76v55s6zid58ja-nix-2.3.4";
i686-linux = "/nix/store/b5cx3nmba9ahx3wk5ybxa67k40pdpdxn-nix-2.3.4";
aarch64-linux = "/nix/store/p6j4mis6agdjlk4j0cyg7yh58wpm3kif-nix-2.3.4";
x86_64-darwin = "/nix/store/aizhr07dljmlbf17wfrj40x3s0b5iv3d-nix-2.3.4";
x86_64-linux = "/nix/store/xb0nl3z356n0sfrhswfli2g19a19slys-nix-2.3.5";
i686-linux = "/nix/store/k8kdd4yy1yap6lai5idyhmzcwsjh1fik-nix-2.3.5";
aarch64-linux = "/nix/store/dr86cbipxqjcb8pf2k0v8wvw0h0adfpz-nix-2.3.5";
x86_64-darwin = "/nix/store/n6dqdndkv9kac66kdr988kaiyavl44x8-nix-2.3.5";
}

View file

@ -415,6 +415,7 @@
./services/misc/apache-kafka.nix
./services/misc/autofs.nix
./services/misc/autorandr.nix
./services/misc/bazarr.nix
./services/misc/beanstalkd.nix
./services/misc/bees.nix
./services/misc/bepasty.nix
@ -605,6 +606,7 @@
./services/networking/dnsmasq.nix
./services/networking/ejabberd.nix
./services/networking/epmd.nix
./services/networking/ergo.nix
./services/networking/eternal-terminal.nix
./services/networking/fakeroute.nix
./services/networking/ferm.nix
@ -816,6 +818,7 @@
./services/torrent/magnetico.nix
./services/torrent/opentracker.nix
./services/torrent/peerflix.nix
./services/torrent/rtorrent.nix
./services/torrent/transmission.nix
./services/ttys/agetty.nix
./services/ttys/gpm.nix
@ -828,6 +831,7 @@
./services/web-apps/cryptpad.nix
./services/web-apps/documize.nix
./services/web-apps/dokuwiki.nix
./services/web-apps/engelsystem.nix
./services/web-apps/frab.nix
./services/web-apps/gerrit.nix
./services/web-apps/gotify-server.nix
@ -847,6 +851,7 @@
./services/web-apps/matomo.nix
./services/web-apps/moinmoin.nix
./services/web-apps/restya-board.nix
./services/web-apps/sogo.nix
./services/web-apps/tt-rss.nix
./services/web-apps/trac.nix
./services/web-apps/trilium.nix
@ -1002,7 +1007,6 @@
./virtualisation/podman.nix
./virtualisation/qemu-guest-agent.nix
./virtualisation/railcar.nix
./virtualisation/rkt.nix
./virtualisation/virtualbox-guest.nix
./virtualisation/virtualbox-host.nix
./virtualisation/vmware-guest.nix

View file

@ -135,6 +135,13 @@ in
type = types.bool;
};
enableBashCompletion = mkOption {
default = false;
description = ''
Enable compatibility with bash's programmable completion system.
'';
type = types.bool;
};
enableGlobalCompInit = mkOption {
default = cfg.enableCompletion;
@ -239,6 +246,11 @@ in
autoload -U compinit && compinit
''}
${optionalString cfg.enableBashCompletion ''
# Enable compatibility with bash's completion system.
autoload -U bashcompinit && bashcompinit
''}
# Setup custom interactive shell init stuff.
${cfge.interactiveShellInit}

View file

@ -48,6 +48,7 @@ with lib;
systemd-logind API). Instead of using the module you can now
simply add the brightnessctl package to environment.systemPackages.
'')
(mkRemovedOptionModule [ "virtualisation" "rkt" ] "The rkt module has been removed, it was archived by upstream")
(mkRemovedOptionModule ["services" "prey" ] ''
prey-bash-client is deprecated upstream

View file

@ -32,13 +32,7 @@ in
services.mysql = {
enable = mkOption {
type = types.bool;
default = false;
description = "
Whether to enable the MySQL server.
";
};
enable = mkEnableOption "MySQL server";
package = mkOption {
type = types.package;

View file

@ -11,12 +11,11 @@ let
port ${toString cfg.port}
${condOption "bind" cfg.bind}
${condOption "unixsocket" cfg.unixSocket}
daemonize yes
daemonize no
supervised systemd
loglevel ${cfg.logLevel}
logfile ${cfg.logfile}
syslog-enabled ${redisBool cfg.syslog}
pidfile /run/redis/redis.pid
databases ${toString cfg.databases}
${concatMapStrings (d: "save ${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}\n") cfg.save}
dbfilename dump.rdb

View file

@ -15,10 +15,7 @@ in
services.rethinkdb = {
enable = mkOption {
default = false;
description = "Whether to enable the RethinkDB server.";
};
enable = mkEnableOption "RethinkDB server";
#package = mkOption {
# default = pkgs.rethinkdb;

View file

@ -41,7 +41,6 @@
pkgs.deepin.dde-session-ui
pkgs.deepin.deepin-anything
pkgs.deepin.deepin-image-viewer
pkgs.deepin.deepin-screenshot
];
services.dbus.packages = [
@ -55,7 +54,6 @@
pkgs.deepin.dde-session-ui
pkgs.deepin.deepin-anything
pkgs.deepin.deepin-image-viewer
pkgs.deepin.deepin-screenshot
];
systemd.packages = [

View file

@ -83,6 +83,10 @@ let
run_progs=$(grep -v '^[[:space:]]*#' $out/* | grep 'RUN+="/' |
sed -e 's/.*RUN+="\([^ "]*\)[ "].*/\1/' | uniq)
for i in $import_progs $run_progs; do
# if the path refers to /run/current-system/systemd, replace with config.systemd.package
if [[ $i == /run/current-system/systemd* ]]; then
i="${config.systemd.package}/''${i#/run/current-system/systemd/}"
fi
if [[ ! -x $i ]]; then
echo "FAIL"
echo "$i is called in udev rules but is not executable or does not exist"

View file

@ -5,26 +5,85 @@ with lib;
let
cfg = config.services.logrotate;
configFile = pkgs.writeText "logrotate.conf"
cfg.config;
pathOptions = {
options = {
path = mkOption {
type = types.str;
description = "The path to log files to be rotated";
};
user = mkOption {
type = types.str;
description = "The user account to use for rotation";
};
group = mkOption {
type = types.str;
description = "The group to use for rotation";
};
frequency = mkOption {
type = types.enum [
"daily" "weekly" "monthly" "yearly"
];
default = "daily";
description = "How often to rotate the logs";
};
keep = mkOption {
type = types.int;
default = 20;
description = "How many rotations to keep";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra logrotate config options for this path";
};
};
};
pathConfig = options: ''
"${options.path}" {
su ${options.user} ${options.group}
${options.frequency}
missingok
notifempty
rotate ${toString options.keep}
${options.extraConfig}
}
'';
configFile = pkgs.writeText "logrotate.conf" (
(concatStringsSep "\n" ((map pathConfig cfg.paths) ++ [cfg.extraConfig]))
);
in
{
imports = [
(mkRenamedOptionModule [ "services" "logrotate" "config" ] [ "services" "logrotate" "extraConfig" ])
];
options = {
services.logrotate = {
enable = mkOption {
type = lib.types.bool;
default = false;
description = ''
Enable the logrotate cron job
'';
enable = mkEnableOption "the logrotate systemd service";
paths = mkOption {
type = types.listOf (types.submodule pathOptions);
default = [];
description = "List of attribute sets with paths to rotate";
example = {
"/var/log/myapp/*.log" = {
user = "myuser";
group = "mygroup";
rotate = "weekly";
keep = 5;
};
};
};
config = mkOption {
extraConfig = mkOption {
default = "";
type = types.lines;
description = ''
The contents of the logrotate config file
Extra contents to add to the logrotate config file.
See https://linux.die.net/man/8/logrotate
'';
};
};

View file

@ -0,0 +1,76 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.bazarr;
in
{
options = {
services.bazarr = {
enable = mkEnableOption "bazarr, a subtitle manager for Sonarr and Radarr";
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Open ports in the firewall for the bazarr web interface.";
};
listenPort = mkOption {
type = types.port;
default = 6767;
description = "Port on which the bazarr web interface should listen";
};
user = mkOption {
type = types.str;
default = "bazarr";
description = "User account under which bazarr runs.";
};
group = mkOption {
type = types.str;
default = "bazarr";
description = "Group under which bazarr runs.";
};
};
};
config = mkIf cfg.enable {
systemd.services.bazarr = {
description = "bazarr";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = rec {
Type = "simple";
User = cfg.user;
Group = cfg.group;
StateDirectory = "bazarr";
SyslogIdentifier = "bazarr";
ExecStart = pkgs.writeShellScript "start-bazarr" ''
${pkgs.bazarr}/bin/bazarr \
--config '/var/lib/${StateDirectory}' \
--port ${toString cfg.listenPort} \
--no-update True
'';
Restart = "on-failure";
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.listenPort ];
};
users.users = mkIf (cfg.user == "bazarr") {
bazarr = {
group = cfg.group;
home = "/var/lib/${config.systemd.services.bazarr.serviceConfig.StateDirectory}";
};
};
users.groups = mkIf (cfg.group == "bazarr") {
bazarr = {};
};
};
}

View file

@ -138,7 +138,7 @@ in {
script = ''
${pkgs.docker-distribution}/bin/registry garbage-collect ${configFile}
${pkgs.systemd}/bin/systemctl restart docker-registry.service
/run/current-system/systemd/bin/systemctl restart docker-registry.service
'';
startAt = optional cfg.enableGarbageCollect cfg.garbageCollectDates;

View file

@ -78,7 +78,7 @@ in {
wantedBy = [ "multi-user.target" ];
restartTriggers = [ configDirectory ];
serviceConfig = {
ExecStart = "${pkgs.systemd}/bin/systemctl try-reload-or-restart freeswitch.service";
ExecStart = "/run/current-system/systemd/bin/systemctl try-reload-or-restart freeswitch.service";
RemainAfterExit = true;
Type = "oneshot";
};

View file

@ -26,7 +26,7 @@ let
scm_mercurial_command: ${pkgs.mercurial}/bin/hg
scm_git_command: ${pkgs.gitAndTools.git}/bin/git
scm_cvs_command: ${pkgs.cvs}/bin/cvs
scm_bazaar_command: ${pkgs.bazaar}/bin/bzr
scm_bazaar_command: ${pkgs.breezy}/bin/bzr
scm_darcs_command: ${pkgs.darcs}/bin/darcs
${cfg.extraConfig}
@ -297,7 +297,7 @@ in
environment.SCHEMA = "${cfg.stateDir}/cache/schema.db";
path = with pkgs; [
imagemagick
bazaar
breezy
cvs
darcs
gitAndTools.git

View file

@ -63,10 +63,6 @@ let
${cfg.extraConfig}
'';
phpExtensions = with pkgs.phpPackages; [
{ pkg = apcu; name = "apcu"; }
];
in {
options = {
services.zoneminder = with lib; {
@ -289,11 +285,9 @@ in {
phpfpm = lib.mkIf useNginx {
pools.zoneminder = {
inherit user group;
phpPackage = pkgs.php.withExtensions ({ enabled, all }: enabled ++ [ all.apcu ]);
phpOptions = ''
date.timezone = "${config.time.timeZone}"
${lib.concatStringsSep "\n" (map (e:
"extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)}
'';
settings = lib.mapAttrs (name: lib.mkDefault) {
"listen.owner" = user;

View file

@ -81,7 +81,7 @@ let
# anything ever again ("couldn't resolve ..., giving up on
# it"), so we silently lose time synchronisation. This also
# applies to openntpd.
${config.systemd.package}/bin/systemctl try-reload-or-restart ntpd.service openntpd.service chronyd.service || true
/run/current-system/systemd/bin/systemctl try-reload-or-restart ntpd.service openntpd.service chronyd.service || true
fi
${cfg.runHook}
@ -217,7 +217,7 @@ in
powerManagement.resumeCommands = mkIf config.systemd.services.dhcpcd.enable
''
# Tell dhcpcd to rebind its interfaces if it's running.
${config.systemd.package}/bin/systemctl reload dhcpcd.service
/run/current-system/systemd/bin/systemctl reload dhcpcd.service
'';
};

View file

@ -55,6 +55,7 @@ in
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
DynamicUser = true;
ExecStart = "${pkgs.dnscrypt-proxy2}/bin/dnscrypt-proxy -config ${cfg.configFile}";
Restart = "always";
};
};
};

View file

@ -5,12 +5,20 @@ let
cfg = config.services.dnscrypt-wrapper;
dataDir = "/var/lib/dnscrypt-wrapper";
mkPath = path: default:
if path != null
then toString path
else default;
publicKey = mkPath cfg.providerKey.public "${dataDir}/public.key";
secretKey = mkPath cfg.providerKey.secret "${dataDir}/secret.key";
daemonArgs = with cfg; [
"--listen-address=${address}:${toString port}"
"--resolver-address=${upstream.address}:${toString upstream.port}"
"--provider-name=${providerName}"
"--provider-publickey-file=public.key"
"--provider-secretkey-file=secret.key"
"--provider-publickey-file=${publicKey}"
"--provider-secretkey-file=${secretKey}"
"--provider-cert-file=${providerName}.crt"
"--crypt-secretkey-file=${providerName}.key"
];
@ -24,17 +32,19 @@ let
dnscrypt-wrapper --gen-cert-file \
--crypt-secretkey-file=${cfg.providerName}.key \
--provider-cert-file=${cfg.providerName}.crt \
--provider-publickey-file=public.key \
--provider-secretkey-file=secret.key \
--provider-publickey-file=${publicKey} \
--provider-secretkey-file=${secretKey} \
--cert-file-expire-days=${toString cfg.keys.expiration}
}
cd ${dataDir}
# generate provider keypair (first run only)
if [ ! -f public.key ] || [ ! -f secret.key ]; then
dnscrypt-wrapper --gen-provider-keypair
fi
${optionalString (cfg.providerKey.public == null || cfg.providerKey.secret == null) ''
if [ ! -f ${publicKey} ] || [ ! -f ${secretKey} ]; then
dnscrypt-wrapper --gen-provider-keypair
fi
''}
# generate new keys for rotation
if [ ! -f ${cfg.providerName}.key ] || [ ! -f ${cfg.providerName}.crt ]; then
@ -64,6 +74,47 @@ let
fi
'';
# This is the fork of the original dnscrypt-proxy maintained by Dyne.org.
# dnscrypt-proxy2 doesn't provide the `--test` feature that is needed to
# correctly implement key rotation of dnscrypt-wrapper ephemeral keys.
dnscrypt-proxy1 = pkgs.callPackage
({ stdenv, fetchFromGitHub, autoreconfHook
, pkgconfig, libsodium, ldns, openssl, systemd }:
stdenv.mkDerivation rec {
pname = "dnscrypt-proxy";
version = "2019-08-20";
src = fetchFromGitHub {
owner = "dyne";
repo = "dnscrypt-proxy";
rev = "07ac3825b5069adc28e2547c16b1d983a8ed8d80";
sha256 = "0c4mq741q4rpmdn09agwmxap32kf0vgfz7pkhcdc5h54chc3g3xy";
};
configureFlags = optional stdenv.isLinux "--with-systemd";
nativeBuildInputs = [ autoreconfHook pkgconfig ];
# <ldns/ldns.h> depends on <openssl/ssl.h>
buildInputs = [ libsodium openssl.dev ldns ] ++ optional stdenv.isLinux systemd;
postInstall = ''
# Previous versions required libtool files to load plugins; they are
# now strictly optional.
rm $out/lib/dnscrypt-proxy/*.la
'';
meta = {
description = "A tool for securing communications between a client and a DNS resolver";
homepage = "https://github.com/dyne/dnscrypt-proxy";
license = licenses.isc;
maintainers = with maintainers; [ rnhmjoj ];
platforms = platforms.linux;
};
}) { };
in {
@ -98,6 +149,26 @@ in {
'';
};
providerKey.public = mkOption {
type = types.nullOr types.path;
default = null;
example = "/etc/secrets/public.key";
description = ''
The filepath to the provider public key. If not given a new
provider key pair will be generated on the first run.
'';
};
providerKey.secret = mkOption {
type = types.nullOr types.path;
default = null;
example = "/etc/secrets/secret.key";
description = ''
The filepath to the provider secret key. If not given a new
provider key pair will be generated on the first run.
'';
};
upstream.address = mkOption {
type = types.str;
default = "127.0.0.1";
@ -179,7 +250,7 @@ in {
requires = [ "dnscrypt-wrapper.service" ];
description = "Rotates DNSCrypt wrapper keys if soon to expire";
path = with pkgs; [ dnscrypt-wrapper dnscrypt-proxy gawk ];
path = with pkgs; [ dnscrypt-wrapper dnscrypt-proxy1 gawk ];
script = rotateKeys;
serviceConfig.User = "dnscrypt-wrapper";
};
@ -196,6 +267,13 @@ in {
};
};
assertions = with cfg; [
{ assertion = (providerKey.public == null && providerKey.secret == null) ||
(providerKey.secret != null && providerKey.public != null);
message = "The secret and public provider key must be set together.";
}
];
};
meta.maintainers = with lib.maintainers; [ rnhmjoj ];

View file

@ -0,0 +1,141 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.ergo;
inherit (lib) mkEnableOption mkIf mkOption optionalString types;
configFile = pkgs.writeText "ergo.conf" (''
ergo {
directory = "${cfg.dataDir}"
node {
mining = false
}
wallet.secretStorage.secretDir = "${cfg.dataDir}/wallet/keystore"
}
scorex {
network {
bindAddress = "${cfg.listen.ip}:${toString cfg.listen.port}"
}
'' + optionalString (cfg.api.keyHash != null) ''
restApi {
apiKeyHash = "${cfg.api.keyHash}"
bindAddress = "${cfg.api.listen.ip}:${toString cfg.api.listen.port}"
}
'' + ''
}
'');
in {
options = {
services.ergo = {
enable = mkEnableOption "Ergo service";
dataDir = mkOption {
type = types.path;
default = "/var/lib/ergo";
description = "The data directory for the Ergo node.";
};
listen = {
ip = mkOption {
type = types.str;
default = "0.0.0.0";
description = "IP address on which the Ergo node should listen.";
};
port = mkOption {
type = types.port;
default = 9006;
description = "Listen port for the Ergo node.";
};
};
api = {
keyHash = mkOption {
type = types.nullOr types.str;
default = null;
example = "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf";
description = "Hex-encoded Blake2b256 hash of an API key as a 64-chars long Base16 string.";
};
listen = {
ip = mkOption {
type = types.str;
default = "0.0.0.0";
description = "IP address that the Ergo node API should listen on if <option>api.keyHash</option> is defined.";
};
port = mkOption {
type = types.port;
default = 9052;
description = "Listen port for the API endpoint if <option>api.keyHash</option> is defined.";
};
};
};
testnet = mkOption {
type = types.bool;
default = false;
description = "Connect to testnet network instead of the default mainnet.";
};
user = mkOption {
type = types.str;
default = "ergo";
description = "The user as which to run the Ergo node.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run the Ergo node.";
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Open ports in the firewall for the Ergo node as well as the API.";
};
};
};
config = mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 '${cfg.user}' '${cfg.group}' - -"
];
systemd.services.ergo = {
description = "ergo server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
ExecStart = ''${pkgs.ergo}/bin/ergo \
${optionalString (!cfg.testnet)
"--mainnet"} \
-c ${configFile}'';
};
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.listen.port ] ++ [ cfg.api.listen.port ];
};
users.users.${cfg.user} = {
name = cfg.user;
group = cfg.group;
description = "Ergo daemon user";
home = cfg.dataDir;
isSystemUser = true;
};
users.groups.${cfg.group} = {};
};
}

View file

@ -449,6 +449,13 @@ in {
systemd.services.ModemManager.aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
# override unit as recommended by upstream - see https://github.com/NixOS/nixpkgs/issues/88089
# TODO: keep an eye on modem-manager releases as this will eventually be added to the upstream unit
systemd.services.ModemManager.serviceConfig.ExecStart = [
""
"${pkgs.modemmanager}/sbin/ModemManager --filter-policy=STRICT"
];
systemd.services.NetworkManager-dispatcher = {
wantedBy = [ "network.target" ];
restartTriggers = [ configFile ];

View file

@ -970,7 +970,7 @@ in
script = signZones;
postStop = ''
${pkgs.systemd}/bin/systemctl kill -s SIGHUP nsd.service
/run/current-system/systemd/bin/systemctl kill -s SIGHUP nsd.service
'';
};

View file

@ -253,12 +253,12 @@ in {
};
powerManagement.resumeCommands = ''
${config.systemd.package}/bin/systemctl try-restart wpa_supplicant
/run/current-system/systemd/bin/systemctl try-restart wpa_supplicant
'';
# Restart wpa_supplicant when a wlan device appears or disappears.
services.udev.extraRules = ''
ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service"
ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="/run/current-system/systemd/bin/systemctl try-restart wpa_supplicant.service"
'';
};

View file

@ -1,55 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
let
keysPath = "/var/lib/yggdrasil/keys.json";
cfg = config.services.yggdrasil;
configProvided = (cfg.config != {});
configAsFile = (if configProvided then
toString (pkgs.writeTextFile {
name = "yggdrasil-conf";
text = builtins.toJSON cfg.config;
})
else null);
configFileProvided = (cfg.configFile != null);
generateConfig = (
if configProvided && configFileProvided then
"${pkgs.jq}/bin/jq -s add ${configAsFile} ${cfg.configFile}"
else if configProvided then
"cat ${configAsFile}"
else if configFileProvided then
"cat ${cfg.configFile}"
else
"${cfg.package}/bin/yggdrasil -genconf"
);
configProvided = cfg.config != { };
configFileProvided = cfg.configFile != null;
in {
options = with types; {
services.yggdrasil = {
enable = mkEnableOption "the yggdrasil system service";
configFile = mkOption {
type = nullOr str;
default = null;
example = "/run/keys/yggdrasil.conf";
description = ''
A file which contains JSON configuration for yggdrasil.
You do not have to supply a complete configuration, as
yggdrasil will use default values for anything which is
omitted. If the encryption and signing keys are omitted,
yggdrasil will generate new ones each time the service is
started, resulting in a random IPv6 address on the yggdrasil
network each time.
If both this option and <option>config</option> are
supplied, they will be combined, with values from
<option>config</option> taking precedence.
You can use the command <code>nix-shell -p yggdrasil --run
"yggdrasil -genconf -json"</code> to generate a default
JSON configuration.
'';
};
config = mkOption {
type = attrs;
default = {};
@ -66,16 +28,21 @@ in {
Configuration for yggdrasil, as a Nix attribute set.
Warning: this is stored in the WORLD-READABLE Nix store!
Therefore, it is not appropriate for private keys. If you
do not specify the keys, yggdrasil will generate a new set
each time the service is started, creating a random IPv6
address on the yggdrasil network each time.
Therefore, it is not appropriate for private keys. If you
wish to specify the keys, use <option>configFile</option>.
If you wish to specify the keys, use
<option>configFile</option>. If both
<option>configFile</option> and <option>config</option> are
supplied, they will be combined, with values from
<option>config</option> taking precedence.
If the <option>persistentKeys</option> is enabled then the
keys that are generated during activation will override
those in <option>config</option> or
<option>configFile</option>.
If no keys are specified then ephemeral keys are generated
and the Yggdrasil interface will have a random IPv6 address
each time the service is started, this is the default.
If both <option>configFile</option> and <option>config</option>
are supplied, they will be combined, with values from
<option>configFile</option> taking precedence.
You can use the command <code>nix-shell -p yggdrasil --run
"yggdrasil -genconf"</code> to generate default
@ -83,12 +50,21 @@ in {
'';
};
configFile = mkOption {
type = nullOr path;
default = null;
example = "/run/keys/yggdrasil.conf";
description = ''
A file which contains JSON configuration for yggdrasil.
See the <option>config</option> option for more information.
'';
};
group = mkOption {
type = types.str;
default = "root";
example = "wheel";
description =
"Group to grant acces to the Yggdrasil control socket.";
description = "Group to grant acces to the Yggdrasil control socket.";
};
openMulticastPort = mkOption {
@ -126,37 +102,64 @@ in {
defaultText = "pkgs.yggdrasil";
description = "Yggdrasil package to use.";
};
persistentKeys = mkEnableOption ''
If enabled then keys will be generated once and Yggdrasil
will retain the same IPv6 address when the service is
restarted. Keys are stored at ${keysPath}.
'';
};
};
config = mkIf cfg.enable {
assertions = [
{ assertion = config.networking.enableIPv6;
message = "networking.enableIPv6 must be true for yggdrasil to work";
}
];
config = mkIf cfg.enable (let binYggdrasil = cfg.package + "/bin/yggdrasil";
in {
assertions = [{
assertion = config.networking.enableIPv6;
message = "networking.enableIPv6 must be true for yggdrasil to work";
}];
system.activationScripts.yggdrasil = mkIf cfg.persistentKeys ''
if [ ! -e ${keysPath} ]
then
mkdir -p ${builtins.dirOf keysPath}
${binYggdrasil} -genconf -json \
| ${pkgs.jq}/bin/jq \
'to_entries|map(select(.key|endswith("Key")))|from_entries' \
> ${keysPath}
chmod 600 ${keysPath}
fi
'';
systemd.services.yggdrasil = {
description = "Yggdrasil Network Service";
path = [ cfg.package ] ++ optional (configProvided && configFileProvided) pkgs.jq;
bindsTo = [ "network-online.target" ];
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
${generateConfig} | yggdrasil -normaliseconf -useconf > /run/yggdrasil/yggdrasil.conf
'';
preStart =
(if configProvided || configFileProvided || cfg.persistentKeys then
"echo "
+ (lib.optionalString configProvided
"'${builtins.toJSON cfg.config}'")
+ (lib.optionalString configFileProvided "$(cat ${cfg.configFile})")
+ (lib.optionalString cfg.persistentKeys "$(cat ${keysPath})")
+ " | ${pkgs.jq}/bin/jq -s add | ${binYggdrasil} -normaliseconf -useconf"
else
"${binYggdrasil} -genconf") + " > /run/yggdrasil/yggdrasil.conf";
serviceConfig = {
ExecStart = "${cfg.package}/bin/yggdrasil -useconffile /run/yggdrasil/yggdrasil.conf";
ExecStart =
"${binYggdrasil} -useconffile /run/yggdrasil/yggdrasil.conf";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Restart = "always";
Group = cfg.group;
RuntimeDirectory = "yggdrasil";
RuntimeDirectoryMode = "0750";
BindReadOnlyPaths = mkIf configFileProvided
[ "${cfg.configFile}" ];
BindReadOnlyPaths = lib.optional configFileProvided cfg.configFile
++ lib.optional cfg.persistentKeys keysPath;
# TODO: as of yggdrasil 0.3.8 and systemd 243, yggdrasil fails
# to set up the network adapter when DynamicUser is set. See
@ -191,6 +194,6 @@ in {
# Make yggdrasilctl available on the command line.
environment.systemPackages = [ cfg.package ];
};
meta.maintainers = with lib.maintainers; [ gazally ];
});
meta.maintainers = with lib.maintainers; [ gazally ehmry ];
}

View file

@ -29,7 +29,6 @@ in
type = types.package;
default = pkgs.fprintd;
defaultText = "pkgs.fprintd";
example = "pkgs.fprintd-thinkpad";
description = ''
fprintd package to use.
'';

View file

@ -207,6 +207,29 @@ in {
Type = "simple";
ExecStart = ''${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}'';
Restart = "on-failure";
AmbientCapabilities = "";
CapabilityBoundingSet = "CAP_CHOWN CAP_FOWNER";
DeviceAllow = "/dev/null rw";
DevicePolicy = "strict";
IPAddressDeny = "any";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectKernelModules = true;
ProtectSystem = true;
ReadOnlyPaths = "-/";
ReadWritePaths = "-/dev/shm -${dirOf cfg.auditFilePath} -/tmp -${dirOf cfg.ruleFile}";
RestrictAddressFamilies = "AF_UNIX AF_NETLINK";
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
UMask = "0077";
};
};
};

View file

@ -67,9 +67,19 @@ in
notificationsCommand = mkOption {
type = types.nullOr types.str;
default = null;
example = "sudo -u example_user DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send";
description = ''
Command used to send notifications.
This option is deprecated and ignored by earlyoom since 1.6.
Use <option>services.earlyoom.enableNotifications</option> instead.
'';
};
enableNotifications = mkOption {
type = types.bool;
default = false;
description = ''
Send notifications about killed processes via the system d-bus.
To actually see the notifications in your GUI session, you need to have
<literal>systembus-notify</literal> running as your user.
See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
'';
@ -87,9 +97,13 @@ in
message = "Both options in conjunction do not make sense"; }
];
warnings = optional (ecfg.notificationsCommand != null)
"`services.earlyoom.notificationsCommand` is deprecated and ignored by earlyoom since 1.6.";
systemd.services.earlyoom = {
description = "Early OOM Daemon for Linux";
wantedBy = [ "multi-user.target" ];
path = optional ecfg.enableNotifications pkgs.dbus;
serviceConfig = {
StandardOutput = "null";
StandardError = "syslog";
@ -100,10 +114,11 @@ in
${optionalString ecfg.useKernelOOMKiller "-k"} \
${optionalString ecfg.ignoreOOMScoreAdjust "-i"} \
${optionalString ecfg.enableDebugInfo "-d"} \
${optionalString (ecfg.notificationsCommand != null)
"-N ${escapeShellArg ecfg.notificationsCommand}"}
${optionalString ecfg.enableNotifications "-n"}
'';
};
};
environment.systemPackages = optional ecfg.enableNotifications pkgs.systembus-notify;
};
}

View file

@ -0,0 +1,209 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.rtorrent;
in {
options.services.rtorrent = {
enable = mkEnableOption "rtorrent";
dataDir = mkOption {
type = types.str;
default = "/var/lib/rtorrent";
description = ''
The directory where rtorrent stores its data files.
'';
};
downloadDir = mkOption {
type = types.str;
default = "${cfg.dataDir}/download";
description = ''
Where to put downloaded files.
'';
};
user = mkOption {
type = types.str;
default = "rtorrent";
description = ''
User account under which rtorrent runs.
'';
};
group = mkOption {
type = types.str;
default = "rtorrent";
description = ''
Group under which rtorrent runs.
'';
};
package = mkOption {
type = types.package;
default = pkgs.rtorrent;
defaultText = "pkgs.rtorrent";
description = ''
The rtorrent package to use.
'';
};
port = mkOption {
type = types.port;
default = 50000;
description = ''
The rtorrent port.
'';
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Whether to open the firewall for the port in <option>services.rtorrent.port</option>.
'';
};
rpcSocket = mkOption {
type = types.str;
readOnly = true;
default = "/run/rtorrent/rpc.sock";
description = ''
RPC socket path.
'';
};
configText = mkOption {
type = types.lines;
default = "";
description = ''
The content of <filename>rtorrent.rc</filename>. The <link xlink:href="https://rtorrent-docs.readthedocs.io/en/latest/cookbook.html#modernized-configuration-template">modernized configuration template</link> with the values specified in this module will be prepended using mkBefore. You can use mkForce to overwrite the config completly.
'';
};
};
config = mkIf cfg.enable {
users.groups = mkIf (cfg.group == "rtorrent") {
rtorrent = {};
};
users.users = mkIf (cfg.user == "rtorrent") {
rtorrent = {
group = cfg.group;
shell = pkgs.bashInteractive;
home = cfg.dataDir;
description = "rtorrent Daemon user";
isSystemUser = true;
};
};
networking.firewall.allowedTCPPorts = mkIf (cfg.openFirewall) [ cfg.port ];
services.rtorrent.configText = mkBefore ''
# Instance layout (base paths)
method.insert = cfg.basedir, private|const|string, (cat,"${cfg.dataDir}/")
method.insert = cfg.watch, private|const|string, (cat,(cfg.basedir),"watch/")
method.insert = cfg.logs, private|const|string, (cat,(cfg.basedir),"log/")
method.insert = cfg.logfile, private|const|string, (cat,(cfg.logs),(system.time),".log")
method.insert = cfg.rpcsock, private|const|string, (cat,"${cfg.rpcSocket}")
# Create instance directories
execute.throw = sh, -c, (cat, "mkdir -p ", (cfg.basedir), "/session ", (cfg.watch), " ", (cfg.logs))
# Listening port for incoming peer traffic (fixed; you can also randomize it)
network.port_range.set = ${toString cfg.port}-${toString cfg.port}
network.port_random.set = no
# Tracker-less torrent and UDP tracker support
# (conservative settings for 'private' trackers, change for 'public')
dht.mode.set = disable
protocol.pex.set = no
trackers.use_udp.set = no
# Peer settings
throttle.max_uploads.set = 100
throttle.max_uploads.global.set = 250
throttle.min_peers.normal.set = 20
throttle.max_peers.normal.set = 60
throttle.min_peers.seed.set = 30
throttle.max_peers.seed.set = 80
trackers.numwant.set = 80
protocol.encryption.set = allow_incoming,try_outgoing,enable_retry
# Limits for file handle resources, this is optimized for
# an `ulimit` of 1024 (a common default). You MUST leave
# a ceiling of handles reserved for rTorrent's internal needs!
network.http.max_open.set = 50
network.max_open_files.set = 600
network.max_open_sockets.set = 3000
# Memory resource usage (increase if you have a large number of items loaded,
# and/or the available resources to spend)
pieces.memory.max.set = 1800M
network.xmlrpc.size_limit.set = 4M
# Basic operational settings (no need to change these)
session.path.set = (cat, (cfg.basedir), "session/")
directory.default.set = "${cfg.downloadDir}"
log.execute = (cat, (cfg.logs), "execute.log")
##log.xmlrpc = (cat, (cfg.logs), "xmlrpc.log")
execute.nothrow = sh, -c, (cat, "echo >", (session.path), "rtorrent.pid", " ", (system.pid))
# Other operational settings (check & adapt)
encoding.add = utf8
system.umask.set = 0027
system.cwd.set = (cfg.basedir)
network.http.dns_cache_timeout.set = 25
schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))
# Watch directories (add more as you like, but use unique schedule names)
#schedule2 = watch_start, 10, 10, ((load.start, (cat, (cfg.watch), "start/*.torrent")))
#schedule2 = watch_load, 11, 10, ((load.normal, (cat, (cfg.watch), "load/*.torrent")))
# Logging:
# Levels = critical error warn notice info debug
# Groups = connection_* dht_* peer_* rpc_* storage_* thread_* tracker_* torrent_*
print = (cat, "Logging to ", (cfg.logfile))
log.open_file = "log", (cfg.logfile)
log.add_output = "info", "log"
##log.add_output = "tracker_debug", "log"
# XMLRPC
scgi_local = (cfg.rpcsock)
schedule = scgi_group,0,0,"execute.nothrow=chown,\":rtorrent\",(cfg.rpcsock)"
schedule = scgi_permission,0,0,"execute.nothrow=chmod,\"g+w,o=\",(cfg.rpcsock)"
'';
systemd = {
services = {
rtorrent = let
rtorrentConfigFile = pkgs.writeText "rtorrent.rc" cfg.configText;
in {
description = "rTorrent system service";
after = [ "network.target" ];
path = [ cfg.package pkgs.bash ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Type = "simple";
Restart = "on-failure";
WorkingDirectory = cfg.dataDir;
ExecStartPre=''${pkgs.bash}/bin/bash -c "if test -e ${cfg.dataDir}/session/rtorrent.lock && test -z $(${pkgs.procps}/bin/pidof rtorrent); then rm -f ${cfg.dataDir}/session/rtorrent.lock; fi"'';
ExecStart="${cfg.package}/bin/rtorrent -n -o system.daemon.set=true -o import=${rtorrentConfigFile}";
RuntimeDirectory = "rtorrent";
RuntimeDirectoryMode = 755;
};
};
};
tmpfiles.rules = [ "d '${cfg.dataDir}' 0750 ${cfg.user} ${cfg.group} -" ];
};
};
}

View file

@ -11,7 +11,7 @@ let
downloadDir = "${homeDir}/Downloads";
incompleteDir = "${homeDir}/.incomplete";
settingsDir = "${homeDir}/.config/transmission-daemon";
settingsDir = "${homeDir}/config";
settingsFile = pkgs.writeText "settings.json" (builtins.toJSON fullSettings);
# for users in group "transmission" to have access to torrents
@ -20,12 +20,6 @@ let
preStart = pkgs.writeScript "transmission-pre-start" ''
#!${pkgs.runtimeShell}
set -ex
for DIR in "${homeDir}" "${settingsDir}" "${fullSettings.download-dir}" "${fullSettings.incomplete-dir}"; do
mkdir -p "$DIR"
done
chmod 755 "${homeDir}"
chmod 700 "${settingsDir}"
chmod ${downloadDirPermissions} "${fullSettings.download-dir}" "${fullSettings.incomplete-dir}"
cp -f ${settingsFile} ${settingsDir}/settings.json
'';
in
@ -110,6 +104,13 @@ in
};
config = mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '${homeDir}' 0770 '${cfg.user}' '${cfg.group}' - -"
"d '${settingsDir}' 0700 '${cfg.user}' '${cfg.group}' - -"
"d '${fullSettings.download-dir}' '${downloadDirPermissions}' '${cfg.user}' '${cfg.group}' - -"
"d '${fullSettings.incomplete-dir}' '${downloadDirPermissions}' '${cfg.user}' '${cfg.group}' - -"
];
systemd.services.transmission = {
description = "Transmission BitTorrent Service";
after = [ "network.target" ] ++ optional apparmor "apparmor.service";

View file

@ -0,0 +1,186 @@
{ config, lib, pkgs, utils, ... }:
let
inherit (lib) mkDefault mkEnableOption mkIf mkOption types literalExample;
cfg = config.services.engelsystem;
in {
options = {
services.engelsystem = {
enable = mkOption {
default = false;
example = true;
description = ''
Whether to enable engelsystem, an online tool for coordinating helpers
and shifts on large events.
'';
type = lib.types.bool;
};
domain = mkOption {
type = types.str;
example = "engelsystem.example.com";
description = "Domain to serve on.";
};
package = mkOption {
type = types.package;
example = literalExample "pkgs.engelsystem";
description = "Engelsystem package used for the service.";
default = pkgs.engelsystem;
};
createDatabase = mkOption {
type = types.bool;
default = true;
description = ''
Whether to create a local database automatically.
This will override every database setting in <option>services.engelsystem.config</option>.
'';
};
};
services.engelsystem.config = mkOption {
type = types.attrs;
default = {
database = {
host = "localhost";
database = "engelsystem";
username = "engelsystem";
};
};
example = {
maintenance = false;
database = {
host = "database.example.com";
database = "engelsystem";
username = "engelsystem";
password._secret = "/var/keys/engelsystem/database";
};
email = {
driver = "smtp";
host = "smtp.example.com";
port = 587;
from.address = "engelsystem@example.com";
from.name = "example engelsystem";
encryption = "tls";
username = "engelsystem@example.com";
password._secret = "/var/keys/engelsystem/mail";
};
autoarrive = true;
min_password_length = 6;
default_locale = "de_DE";
};
description = ''
Options to be added to config.php, as a nix attribute set. Options containing secret data
should be set to an attribute set containing the attribute _secret - a string pointing to a
file containing the value the option should be set to. See the example to get a better
picture of this: in the resulting config.php file, the email.password key will be set to
the contents of the /var/keys/engelsystem/mail file.
See https://engelsystem.de/doc/admin/configuration/ for available options.
Note that the admin user login credentials cannot be set here - they always default to
admin:asdfasdf. Log in and change them immediately.
'';
};
};
config = mkIf cfg.enable {
# create database
services.mysql = mkIf cfg.createDatabase {
enable = true;
package = mkDefault pkgs.mysql;
ensureUsers = [{
name = "engelsystem";
ensurePermissions = { "engelsystem.*" = "ALL PRIVILEGES"; };
}];
ensureDatabases = [ "engelsystem" ];
};
environment.etc."engelsystem/config.php".source =
pkgs.writeText "config.php" ''
<?php
return json_decode(file_get_contents("/var/lib/engelsystem/config.json"), true);
'';
services.phpfpm.pools.engelsystem = {
user = "engelsystem";
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
};
services.nginx = {
enable = true;
virtualHosts."${cfg.domain}".locations = {
"/" = {
root = "${cfg.package}/share/engelsystem/public";
extraConfig = ''
index index.php;
try_files $uri $uri/ /index.php?$args;
autoindex off;
'';
};
"~ \\.php$" = {
root = "${cfg.package}/share/engelsystem/public";
extraConfig = ''
fastcgi_pass unix:${config.services.phpfpm.pools.engelsystem.socket};
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include ${config.services.nginx.package}/conf/fastcgi_params;
include ${config.services.nginx.package}/conf/fastcgi.conf;
'';
};
};
};
systemd.services."engelsystem-init" = {
wantedBy = [ "multi-user.target" ];
serviceConfig = { Type = "oneshot"; };
script =
let
genConfigScript = pkgs.writeScript "engelsystem-gen-config.sh"
(utils.genJqSecretsReplacementSnippet cfg.config "config.json");
in ''
umask 077
mkdir -p /var/lib/engelsystem/storage/app
mkdir -p /var/lib/engelsystem/storage/cache/views
cd /var/lib/engelsystem
${genConfigScript}
chmod 400 config.json
chown -R engelsystem .
'';
};
systemd.services."engelsystem-migrate" = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
User = "engelsystem";
Group = "engelsystem";
};
script = ''
${cfg.package}/bin/migrate
'';
after = [ "engelsystem-init.service" "mysql.service" ];
};
systemd.services."phpfpm-engelsystem".after =
[ "engelsystem-migrate.service" ];
users.users.engelsystem = {
isSystemUser = true;
createHome = true;
home = "/var/lib/engelsystem/storage";
group = "engelsystem";
};
users.groups.engelsystem = { };
};
}

View file

@ -0,0 +1,272 @@
{ config, pkgs, lib, ... }: with lib; let
cfg = config.services.sogo;
preStart = pkgs.writeShellScriptBin "sogo-prestart" ''
touch /etc/sogo/sogo.conf
chown sogo:sogo /etc/sogo/sogo.conf
chmod 640 /etc/sogo/sogo.conf
${if (cfg.configReplaces != {}) then ''
# Insert secrets
${concatStringsSep "\n" (mapAttrsToList (k: v: ''export ${k}="$(cat "${v}" | tr -d '\n')"'') cfg.configReplaces)}
${pkgs.perl}/bin/perl -p ${concatStringsSep " " (mapAttrsToList (k: v: '' -e 's/${k}/''${ENV{"${k}"}}/g;' '') cfg.configReplaces)} /etc/sogo/sogo.conf.raw > /etc/sogo/sogo.conf
'' else ''
cp /etc/sogo/sogo.conf.raw /etc/sogo/sogo.conf
''}
'';
in {
options.services.sogo = with types; {
enable = mkEnableOption "SOGo groupware";
vhostName = mkOption {
description = "Name of the nginx vhost";
type = str;
default = "sogo";
};
timezone = mkOption {
description = "Timezone of your SOGo instance";
type = str;
example = "America/Montreal";
};
language = mkOption {
description = "Language of SOGo";
type = str;
default = "English";
};
ealarmsCredFile = mkOption {
description = "Optional path to a credentials file for email alarms";
type = nullOr str;
default = null;
};
configReplaces = mkOption {
description = ''
Replacement-filepath mapping for sogo.conf.
Every key is replaced with the contents of the file specified as value.
In the example, every occurence of LDAP_BINDPW will be replaced with the text of the
specified file.
'';
type = attrsOf str;
default = {};
example = {
LDAP_BINDPW = "/var/lib/secrets/sogo/ldappw";
};
};
extraConfig = mkOption {
description = "Extra sogo.conf configuration lines";
type = lines;
default = "";
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.sogo ];
environment.etc."sogo/sogo.conf.raw".text = ''
{
// Mandatory parameters
SOGoTimeZone = "${cfg.timezone}";
SOGoLanguage = "${cfg.language}";
// Paths
WOSendMail = "/run/wrappers/bin/sendmail";
SOGoMailSpoolPath = "/var/lib/sogo/spool";
SOGoZipPath = "${pkgs.zip}/bin/zip";
// Enable CSRF protection
SOGoXSRFValidationEnabled = YES;
// Remove dates from log (jornald does that)
NGLogDefaultLogEventFormatterClass = "NGLogEventFormatter";
// Extra config
${cfg.extraConfig}
}
'';
systemd.services.sogo = {
description = "SOGo groupware";
after = [ "postgresql.service" "mysql.service" "memcached.service" "openldap.service" "dovecot2.service" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
environment.LDAPTLS_CACERT = "/etc/ssl/certs/ca-certificates.crt";
serviceConfig = {
Type = "forking";
ExecStartPre = "+" + preStart + "/bin/sogo-prestart";
ExecStart = "${pkgs.sogo}/bin/sogod -WOLogFile - -WOPidFile /run/sogo/sogo.pid";
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
RuntimeDirectory = "sogo";
StateDirectory = "sogo/spool";
User = "sogo";
Group = "sogo";
CapabilityBoundingSet = "";
NoNewPrivileges = true;
LockPersonality = true;
RestrictRealtime = true;
PrivateMounts = true;
PrivateUsers = true;
MemoryDenyWriteExecute = true;
SystemCallFilter = "@basic-io @file-system @network-io @system-service @timer";
SystemCallArchitectures = "native";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
};
};
systemd.services.sogo-tmpwatch = {
description = "SOGo tmpwatch";
startAt = [ "hourly" ];
script = ''
SOGOSPOOL=/var/lib/sogo/spool
find "$SOGOSPOOL" -type f -user sogo -atime +23 -delete > /dev/null
find "$SOGOSPOOL" -mindepth 1 -type d -user sogo -empty -delete > /dev/null
'';
serviceConfig = {
Type = "oneshot";
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
StateDirectory = "sogo/spool";
User = "sogo";
Group = "sogo";
CapabilityBoundingSet = "";
NoNewPrivileges = true;
LockPersonality = true;
RestrictRealtime = true;
PrivateMounts = true;
PrivateUsers = true;
PrivateNetwork = true;
SystemCallFilter = "@basic-io @file-system @system-service";
SystemCallArchitectures = "native";
RestrictAddressFamilies = "";
};
};
systemd.services.sogo-ealarms = {
description = "SOGo email alarms";
after = [ "postgresql.service" "mysqld.service" "memcached.service" "openldap.service" "dovecot2.service" "sogo.service" ];
restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
startAt = [ "minutely" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.sogo}/bin/sogo-ealarms-notify${optionalString (cfg.ealarmsCredFile != null) " -p ${cfg.ealarmsCredFile}"}";
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
StateDirectory = "sogo/spool";
User = "sogo";
Group = "sogo";
CapabilityBoundingSet = "";
NoNewPrivileges = true;
LockPersonality = true;
RestrictRealtime = true;
PrivateMounts = true;
PrivateUsers = true;
MemoryDenyWriteExecute = true;
SystemCallFilter = "@basic-io @file-system @network-io @system-service";
SystemCallArchitectures = "native";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
};
};
# nginx vhost
services.nginx.virtualHosts."${cfg.vhostName}" = {
locations."/".extraConfig = ''
rewrite ^ https://$server_name/SOGo;
allow all;
'';
# For iOS 7
locations."/principals/".extraConfig = ''
rewrite ^ https://$server_name/SOGo/dav;
allow all;
'';
locations."^~/SOGo".extraConfig = ''
proxy_pass http://127.0.0.1:20000;
proxy_redirect http://127.0.0.1:20000 default;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host 127.0.0.1;
proxy_set_header x-webobjects-server-port $server_port;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $scheme://$host;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
client_max_body_size 50m;
client_body_buffer_size 128k;
break;
'';
locations."/SOGo.woa/WebServerResources/".extraConfig = ''
alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
allow all;
'';
locations."/SOGo/WebServerResources/".extraConfig = ''
alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
allow all;
'';
locations."~ ^/SOGo/so/ControlPanel/Products/([^/]*)/Resources/(.*)$".extraConfig = ''
alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
'';
locations."~ ^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\\.(jpg|png|gif|css|js)$".extraConfig = ''
alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
'';
};
# User and group
users.groups.sogo = {};
users.users.sogo = {
group = "sogo";
isSystemUser = true;
description = "SOGo service user";
};
};
}

View file

@ -631,9 +631,12 @@ let
serviceConfig = {
User = "${cfg.user}";
Group = "tt_rss";
ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon";
ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon --quiet";
StandardOutput = "syslog";
StandardError = "syslog";
Restart = "on-failure";
RestartSec = "60";
SyslogIdentifier = "tt-rss";
};
wantedBy = [ "multi-user.target" ];

View file

@ -756,9 +756,9 @@ in
serviceConfig.Type = "oneshot";
serviceConfig.TimeoutSec = 60;
script = ''
if ${pkgs.systemd}/bin/systemctl -q is-active nginx.service ; then
if /run/current-system/systemd/bin/systemctl -q is-active nginx.service ; then
${execCommand} -t && \
${pkgs.systemd}/bin/systemctl reload nginx.service
/run/current-system/systemd/bin/systemctl reload nginx.service
fi
'';
serviceConfig.RemainAfterExit = true;
@ -772,7 +772,7 @@ in
webroot = vhostConfig.acmeRoot;
extraDomains = genAttrs vhostConfig.serverAliases (alias: null);
postRun = ''
systemctl reload nginx
/run/current-system/systemd/bin/systemctl reload nginx
'';
}; }) acmeEnabledVhosts;
in

View file

@ -79,7 +79,25 @@ in {
};
instance = mkOption {
type = types.attrs;
type = with lib.types; let
valueType = nullOr (oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
(mkOptionType {
name = "function";
description = "function";
check = x: isFunction x;
merge = mergeOneOption;
})
]) // {
description = "Json value or lambda";
emptyValue.value = {};
};
in valueType;
default = {
type = "normal";
};

View file

@ -8,9 +8,26 @@ let
in {
options.services.xserver.desktopManager.cde = {
enable = mkEnableOption "Common Desktop Environment";
extraPackages = mkOption {
type = with types; listOf package;
default = with pkgs.xorg; [
xclock bitmap xlsfonts xfd xrefresh xload xwininfo xdpyinfo xwd xwud
];
example = literalExample ''
with pkgs.xorg; [
xclock bitmap xlsfonts xfd xrefresh xload xwininfo xdpyinfo xwd xwud
]
'';
description = ''
Extra packages to be installed system wide.
'';
};
};
config = mkIf (xcfg.enable && cfg.enable) {
environment.systemPackages = cfg.extraPackages;
services.rpcbind.enable = true;
services.xinetd.enable = true;

View file

@ -19,7 +19,7 @@ in
# E.g., if Plasma 5 is enabled, it supersedes xterm.
imports = [
./none.nix ./xterm.nix ./xfce.nix ./plasma5.nix ./lumina.nix
./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ./maxx.nix
./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix
./mate.nix ./pantheon.nix ./surf-display.nix ./cde.nix
];

View file

@ -32,15 +32,14 @@ in
config = mkIf cfg.enable {
environment.systemPackages = [
e.efl e.enlightenment
e.terminology e.econnman
pkgs.xorg.xauth # used by kdesu
pkgs.gtk2 # To get GTK's themes.
pkgs.tango-icon-theme
pkgs.gnome-icon-theme
pkgs.xorg.xcursorthemes
environment.systemPackages = with pkgs; [
enlightenment.econnman
enlightenment.efl
enlightenment.enlightenment
enlightenment.ephoto
enlightenment.rage
enlightenment.terminology
xorg.xcursorthemes
];
environment.pathsToLink = [
@ -50,11 +49,10 @@ in
"/share/locale"
];
services.xserver.desktopManager.session = [
{ name = "Enlightenment";
start = ''
export XDG_MENU_PREFIX=e-
services.xserver.displayManager.sessionPackages = [ pkgs.enlightenment.enlightenment ];
services.xserver.displayManager.sessionCommands = ''
if test "$XDG_CURRENT_DESKTOP" = "Enlightenment"; then
export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"
# make available for D-BUS user services
@ -62,12 +60,15 @@ in
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
fi
'';
exec ${e.enlightenment}/bin/enlightenment_start
'';
}];
security.wrappers = (import "${e.enlightenment}/e-wrappers.nix").security.wrappers;
# Wrappers for programs installed by enlightenment that should be setuid
security.wrappers = {
enlightenment_ckpasswd.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_ckpasswd";
enlightenment_sys.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_sys";
enlightenment_system.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_system";
};
environment.etc."X11/xkb".source = xcfg.xkbDir;

View file

@ -23,12 +23,9 @@ in
config = mkIf cfg.enable {
services.xserver.desktopManager.session = singleton {
name = "lumina";
start = ''
exec ${pkgs.lumina.lumina}/bin/start-lumina-desktop
'';
};
services.xserver.displayManager.sessionPackages = [
pkgs.lumina.lumina
];
environment.systemPackages =
pkgs.lumina.preRequisitePackages ++

View file

@ -1,31 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
xcfg = config.services.xserver;
cfg = xcfg.desktopManager.maxx;
in {
options.services.xserver.desktopManager.maxx = {
enable = mkEnableOption "MaXX desktop environment";
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.maxx ];
# there is hardcoded path in binaries
system.activationScripts.setup-maxx = ''
mkdir -p /opt
ln -sfn ${pkgs.maxx}/opt/MaXX /opt
'';
services.xserver.desktopManager.session = [
{ name = "MaXX";
start = ''
exec ${pkgs.maxx}/opt/MaXX/etc/skel/Xsession.dt
'';
}];
};
meta.maintainers = [ maintainers.gnidorah ];
}

View file

@ -158,6 +158,19 @@ in
example = "vlc";
description = "Phonon audio backend to install.";
};
supportDDC = mkOption {
type = types.bool;
default = false;
description = ''
Support setting monitor brightness via DDC.
</para>
<para>
This is not needed for controlling brightness of the internal monitor
of a laptop and as it is considered experimental by upstream, it is
disabled by default.
'';
};
};
};
@ -184,6 +197,12 @@ in
};
};
# DDC support
boot.kernelModules = lib.optional cfg.supportDDC "i2c_dev";
services.udev.extraRules = lib.optionalString cfg.supportDDC ''
KERNEL=="i2c-[0-9]*", TAG+="uaccess"
'';
environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications;
[
frameworkintegration

View file

@ -39,7 +39,8 @@ let
${optionalString cfg.startDbusSession ''
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
exec ${pkgs.dbus.dbus-launch} --exit-with-session "$0" "$@"
/run/current-system/systemd/bin/systemctl --user start dbus.socket
export `/run/current-system/systemd/bin/systemctl --user show-environment | grep '^DBUS_SESSION_BUS_ADDRESS'`
fi
''}
@ -59,7 +60,7 @@ let
#
# Also tell systemd about the dbus session bus address.
# This is required by user units using the session bus.
${config.systemd.package}/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
/run/current-system/systemd/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
# Load X defaults. This should probably be safe on wayland too.
${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft}
@ -88,7 +89,7 @@ let
fi
# Start systemd user services for graphical sessions
${config.systemd.package}/bin/systemctl --user start graphical-session.target
/run/current-system/systemd/bin/systemctl --user start graphical-session.target
# Allow the user to setup a custom session type.
if test -x ~/.xsession; then
@ -393,7 +394,7 @@ in
test -n "$waitPID" && wait "$waitPID"
${config.systemd.package}/bin/systemctl --user stop graphical-session.target
/run/current-system/systemd/bin/systemctl --user stop graphical-session.target
exit 0
'';

View file

@ -30,8 +30,8 @@ let
cfgFile = pkgs.writeText "sddm.conf" ''
[General]
HaltCommand=${pkgs.systemd}/bin/systemctl poweroff
RebootCommand=${pkgs.systemd}/bin/systemctl reboot
HaltCommand=/run/current-system/systemd/bin/systemctl poweroff
RebootCommand=/run/current-system/systemd/bin/systemctl reboot
${optionalString cfg.autoNumlock ''
Numlock=on
''}

View file

@ -66,7 +66,7 @@ in
killer = mkOption {
default = null; # default according to `man xautolock` is none
example = "${pkgs.systemd}/bin/systemctl suspend";
example = "/run/current-system/systemd/bin/systemctl suspend";
type = types.nullOr types.str;
description = ''

View file

@ -268,9 +268,10 @@ in {
mkdir -p -m 0755 /run/binfmt
${lib.concatStringsSep "\n" (lib.mapAttrsToList activationSnippet config.boot.binfmt.registrations)}
'';
systemd.additionalUpstreamSystemUnits = lib.mkIf (config.boot.binfmt.registrations != {})
[ "proc-sys-fs-binfmt_misc.automount"
"proc-sys-fs-binfmt_misc.mount"
];
systemd.additionalUpstreamSystemUnits = lib.mkIf (config.boot.binfmt.registrations != {}) [
"proc-sys-fs-binfmt_misc.automount"
"proc-sys-fs-binfmt_misc.mount"
"systemd-binfmt.service"
];
};
}

View file

@ -164,7 +164,6 @@ let
"systemd-timedated.service"
"systemd-localed.service"
"systemd-hostnamed.service"
"systemd-binfmt.service"
"systemd-exit.service"
"systemd-update-done.service"
] ++ optionals config.services.journald.enableHttpGateway [
@ -1056,7 +1055,6 @@ in
systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.mount" ];
systemd.services.systemd-importd.environment = proxy_env;
# Don't bother with certain units in containers.

View file

@ -433,7 +433,16 @@ in
services.zfs.zed.settings = {
ZED_EMAIL_PROG = mkDefault "${pkgs.mailutils}/bin/mail";
PATH = lib.makeBinPath [ packages.zfsUser pkgs.utillinux pkgs.gawk pkgs.gnused pkgs.gnugrep pkgs.coreutils pkgs.curl ];
PATH = lib.makeBinPath [
packages.zfsUser
pkgs.coreutils
pkgs.curl
pkgs.gawk
pkgs.gnugrep
pkgs.gnused
pkgs.nettools
pkgs.utillinux
];
};
environment.etc = genAttrs

View file

@ -54,7 +54,16 @@ let
};
normalConfig = {
systemd.network.links = let
createNetworkLink = i: nameValuePair "40-${i.name}" {
matchConfig.OriginalName = i.name;
linkConfig = optionalAttrs (i.macAddress != null) {
MACAddress = i.macAddress;
} // optionalAttrs (i.mtu != null) {
MTUBytes = toString i.mtu;
};
};
in listToAttrs (map createNetworkLink interfaces);
systemd.services =
let
@ -164,7 +173,6 @@ let
{ description = "Address configuration of ${i.name}";
wantedBy = [
"network-setup.service"
"network-link-${i.name}.service"
"network.target"
];
# order before network-setup because the routes that are configured
@ -183,6 +191,8 @@ let
state="/run/nixos/network/addresses/${i.name}"
mkdir -p $(dirname "$state")
ip link set "${i.name}" up
${flip concatMapStrings ips (ip:
let
cidr = "${ip.address}/${toString ip.prefixLength}";
@ -237,38 +247,6 @@ let
'';
};
createNetworkLink = i:
let
deviceDependency = if (config.boot.isContainer || i.name == "lo")
then []
else [ (subsystemDevice i.name) ];
in
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = deviceDependency;
after = [ "network-pre.target" ] ++ deviceDependency;
path = [ pkgs.iproute ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script =
''
echo "Configuring link..."
'' + optionalString (i.macAddress != null) ''
echo "setting MAC address to ${i.macAddress}..."
ip link set "${i.name}" address "${i.macAddress}"
'' + optionalString (i.mtu != null) ''
echo "setting MTU to ${toString i.mtu}..."
ip link set "${i.name}" mtu "${toString i.mtu}"
'' + ''
echo -n "bringing up interface... "
ip link set "${i.name}" up && echo "done" || (echo "failed"; exit 1)
'';
};
createTunDevice = i: nameValuePair "${i.name}-netdev"
{ description = "Virtual Network Interface ${i.name}";
bindsTo = [ "dev-net-tun.device" ];
@ -298,7 +276,7 @@ let
bindsTo = deps ++ optional v.rstp "mstpd.service";
partOf = [ "network-setup.service" ] ++ optional v.rstp "mstpd.service";
after = [ "network-pre.target" ] ++ deps ++ optional v.rstp "mstpd.service"
++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
++ map (i: "network-addresses-${i}.service") v.interfaces;
before = [ "network-setup.service" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
@ -327,7 +305,7 @@ let
# if `libvirtd.service` is not running, do not use `virsh` which would try activate it via 'libvirtd.socket' and thus start it out-of-order.
# `libvirtd.service` will set up bridge interfaces when it will start normally.
#
if ${pkgs.systemd}/bin/systemctl --quiet is-active 'libvirtd.service'; then
if /run/current-system/systemd/bin/systemctl --quiet is-active 'libvirtd.service'; then
for uri in qemu:///system lxc:///; do
for dom in $(${pkgs.libvirt}/bin/virsh -c $uri list --name); do
${pkgs.libvirt}/bin/virsh -c $uri dumpxml "$dom" | \
@ -375,7 +353,7 @@ let
createVswitchDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = concatLists (map deviceDependency (attrNames (filterAttrs (_: config: config.type != "internal") v.interfaces)));
internalConfigs = concatMap (i: ["network-link-${i}.service" "network-addresses-${i}.service"]) (attrNames (filterAttrs (_: config: config.type == "internal") v.interfaces));
internalConfigs = map (i: "network-addresses-${i}.service") (attrNames (filterAttrs (_: config: config.type == "internal") v.interfaces));
ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules;
in
{ description = "Open vSwitch Interface ${n}";
@ -427,7 +405,7 @@ let
bindsTo = deps;
partOf = [ "network-setup.service" ];
after = [ "network-pre.target" ] ++ deps
++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
++ map (i: "network-addresses-${i}.service") v.interfaces;
before = [ "network-setup.service" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
@ -540,7 +518,6 @@ let
});
in listToAttrs (
map createNetworkLink interfaces ++
map configureAddrs interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges

View file

@ -376,10 +376,20 @@ in
networking.hostName = mkOption {
default = "nixos";
type = types.str;
# Only allow hostnames without the domain name part (i.e. no FQDNs, see
# e.g. "man 5 hostname") and require valid DNS labels (recommended
# syntax). Note: We also allow underscores for compatibility/legacy
# reasons (as undocumented feature):
type = types.strMatching
"^[[:alpha:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$";
description = ''
The name of the machine. Leave it empty if you want to obtain
it from a DHCP server (if using DHCP).
The name of the machine. Leave it empty if you want to obtain it from a
DHCP server (if using DHCP). The hostname must be a valid DNS label (see
RFC 1035 section 2.3.1: "Preferred name syntax") and as such must not
contain the domain part. This means that the hostname must start with a
letter, end with a letter or digit, and have as interior characters only
letters, digits, and hyphen. The maximum length is 63 characters.
Additionally it is recommended to only use lower-case characters.
'';
};

View file

@ -48,7 +48,7 @@ let
provisionedHook = pkgs.writeScript "provisioned-hook" ''
#!${pkgs.runtimeShell}
${config.systemd.package}/bin/systemctl start provisioned.target
/run/current-system/systemd/bin/systemctl start provisioned.target
'';
in

View file

@ -5,6 +5,8 @@ with lib;
let
cfg = config.virtualisation.cri-o;
crioPackage = (pkgs.cri-o.override { inherit (cfg) extraPackages; });
# Copy configuration files to avoid having the entire sources in the system closure
copyFile = filePath: pkgs.runCommandNoCC (builtins.unsafeDiscardStringContext (builtins.baseNameOf filePath)) {} ''
cp ${filePath} $out
@ -23,55 +25,90 @@ in
enable = mkEnableOption "Container Runtime Interface for OCI (CRI-O)";
storageDriver = mkOption {
type = types.enum ["btrfs" "overlay" "vfs"];
type = types.enum [ "btrfs" "overlay" "vfs" ];
default = "overlay";
description = "Storage driver to be used";
};
logLevel = mkOption {
type = types.enum ["trace" "debug" "info" "warn" "error" "fatal"];
type = types.enum [ "trace" "debug" "info" "warn" "error" "fatal" ];
default = "info";
description = "Log level to be used";
};
pauseImage = mkOption {
type = types.str;
default = "k8s.gcr.io/pause:3.1";
description = "Pause image for pod sandboxes to be used";
type = types.nullOr types.str;
default = null;
description = "Override the default pause image for pod sandboxes";
example = [ "k8s.gcr.io/pause:3.2" ];
};
pauseCommand = mkOption {
type = types.str;
default = "/pause";
description = "Pause command to be executed";
type = types.nullOr types.str;
default = null;
description = "Override the default pause command";
example = [ "/pause" ];
};
runtime = mkOption {
type = types.nullOr types.str;
default = null;
description = "Override the default runtime";
example = [ "crun" ];
};
extraPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = lib.literalExample ''
[
pkgs.gvisor
]
'';
description = ''
Extra packages to be installed in the CRI-O wrapper.
'';
};
package = lib.mkOption {
type = types.package;
default = crioPackage;
internal = true;
description = ''
The final CRI-O package (including extra packages).
'';
};
};
config = mkIf cfg.enable {
environment.systemPackages = with pkgs;
[ cri-o cri-tools conmon iptables runc utillinux ];
environment.systemPackages = [ cfg.package pkgs.cri-tools ];
environment.etc."crictl.yaml".source = copyFile "${pkgs.cri-o.src}/crictl.yaml";
environment.etc."crictl.yaml".source = copyFile "${pkgs.cri-o-unwrapped.src}/crictl.yaml";
environment.etc."crio/crio.conf".text = ''
[crio]
storage_driver = "${cfg.storageDriver}"
[crio.image]
pause_image = "${cfg.pauseImage}"
pause_command = "${cfg.pauseCommand}"
${optionalString (cfg.pauseImage != null) ''pause_image = "${cfg.pauseImage}"''}
${optionalString (cfg.pauseCommand != null) ''pause_command = "${cfg.pauseCommand}"''}
[crio.network]
plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
network_dir = "/etc/cni/net.d/"
[crio.runtime]
conmon = "${pkgs.conmon}/bin/conmon"
cgroup_manager = "systemd"
log_level = "${cfg.logLevel}"
manage_network_ns_lifecycle = true
manage_ns_lifecycle = true
${optionalString (cfg.runtime != null) ''
default_runtime = "${cfg.runtime}"
[crio.runtime.runtimes]
[crio.runtime.runtimes.${cfg.runtime}]
''}
'';
environment.etc."cni/net.d/10-crio-bridge.conf".source = copyFile "${pkgs.cri-o.src}/contrib/cni/10-crio-bridge.conf";
environment.etc."cni/net.d/10-crio-bridge.conf".source = copyFile "${pkgs.cri-o-unwrapped.src}/contrib/cni/10-crio-bridge.conf";
# Enable common /etc/containers configuration
virtualisation.containers.enable = true;
@ -81,10 +118,10 @@ in
documentation = [ "https://github.com/cri-o/cri-o" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [ pkgs.utillinux pkgs.runc pkgs.iptables ];
path = [ cfg.package ];
serviceConfig = {
Type = "notify";
ExecStart = "${pkgs.cri-o}/bin/crio";
ExecStart = "${cfg.package}/bin/crio";
ExecReload = "/bin/kill -s HUP $MAINPID";
TasksMax = "infinity";
LimitNOFILE = "1048576";

View file

@ -37,6 +37,7 @@ in {
name = cfg.vmDerivationName;
postVM = ''
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -o subformat=dynamic -O vhdx $diskImage $out/${cfg.vmFileName}
rm $diskImage
'';
format = "raw";
diskSize = cfg.baseImageSize;

View file

@ -1,64 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.rkt;
in
{
options.virtualisation.rkt = {
enable = mkEnableOption "rkt metadata service";
gc = {
automatic = mkOption {
default = true;
type = types.bool;
description = "Automatically run the garbage collector at a specific time.";
};
dates = mkOption {
default = "03:15";
type = types.str;
description = ''
Specification (in the format described by
<citerefentry><refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum></citerefentry>) of the time at
which the garbage collector will run.
'';
};
options = mkOption {
default = "--grace-period=24h";
type = types.str;
description = ''
Options given to <filename>rkt gc</filename> when the
garbage collector is run automatically.
'';
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.rkt ];
systemd.services.rkt = {
description = "rkt metadata service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.rkt}/bin/rkt metadata-service";
};
};
systemd.services.rkt-gc = {
description = "rkt garbage collection";
startAt = optionalString cfg.gc.automatic cfg.gc.dates;
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.rkt}/bin/rkt gc ${cfg.gc.options}";
};
};
users.groups.rkt = {};
};
}

View file

@ -0,0 +1,90 @@
{ config, pkgs, lib, ... }:
with lib;
let
boolToStr = value: if value then "on" else "off";
cfg = config.vmware;
subformats = [
"monolithicSparse"
"monolithicFlat"
"twoGbMaxExtentSparse"
"twoGbMaxExtentFlat"
"streamOptimized"
];
in {
options = {
vmware = {
baseImageSize = mkOption {
type = types.int;
default = 2048;
description = ''
The size of the VMWare base image in MiB.
'';
};
vmDerivationName = mkOption {
type = types.str;
default = "nixos-vmware-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}";
description = ''
The name of the derivation for the VMWare appliance.
'';
};
vmFileName = mkOption {
type = types.str;
default = "nixos-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.vmdk";
description = ''
The file name of the VMWare appliance.
'';
};
vmSubformat = mkOption {
type = types.enum subformats;
default = "monolithicSparse";
description = "Specifies which VMDK subformat to use.";
};
vmCompat6 = mkOption {
type = types.bool;
default = false;
example = true;
description = "Create a VMDK version 6 image (instead of version 4).";
};
};
};
config = {
system.build.vmwareImage = import ../../lib/make-disk-image.nix {
name = cfg.vmDerivationName;
postVM = ''
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -o compat6=${boolToStr cfg.vmCompat6},subformat=${cfg.vmSubformat} -O vmdk $diskImage $out/${cfg.vmFileName}
rm $diskImage
'';
format = "raw";
diskSize = cfg.baseImageSize;
partitionTableType = "efi";
inherit config lib pkgs;
};
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/ESP";
fsType = "vfat";
};
boot.growPartition = true;
boot.loader.grub = {
version = 2;
device = "nodev";
efiSupport = true;
efiInstallAsRemovable = true;
};
virtualisation.vmware.guest.enable = true;
};
}

View file

@ -27,6 +27,7 @@ in
atd = handleTest ./atd.nix {};
avahi = handleTest ./avahi.nix {};
babeld = handleTest ./babeld.nix {};
bazarr = handleTest ./bazarr.nix {};
bcachefs = handleTestOn ["x86_64-linux"] ./bcachefs.nix {}; # linux-4.18.2018.10.12 is unsupported on aarch64
beanstalkd = handleTest ./beanstalkd.nix {};
bees = handleTest ./bees.nix {};
@ -69,6 +70,7 @@ in
deluge = handleTest ./deluge.nix {};
dhparams = handleTest ./dhparams.nix {};
dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
dnscrypt-wrapper = handleTestOn ["x86_64-linux"] ./dnscrypt-wrapper {};
doas = handleTest ./doas.nix {};
docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
@ -86,8 +88,10 @@ in
ecryptfs = handleTest ./ecryptfs.nix {};
ejabberd = handleTest ./xmpp/ejabberd.nix {};
elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
engelsystem = handleTest ./engelsystem.nix {};
enlightenment = handleTest ./enlightenment.nix {};
env = handleTest ./env.nix {};
ergo = handleTest ./ergo.nix {};
etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {};
etcd-cluster = handleTestOn ["x86_64-linux"] ./etcd-cluster.nix {};
fancontrol = handleTest ./fancontrol.nix {};
@ -132,6 +136,7 @@ in
hitch = handleTest ./hitch {};
hocker-fetchdocker = handleTest ./hocker-fetchdocker {};
home-assistant = handleTest ./home-assistant.nix {};
hostname = handleTest ./hostname.nix {};
hound = handleTest ./hound.nix {};
hydra = handleTest ./hydra {};
hydra-db-migration = handleTest ./hydra/db-migration.nix {};
@ -292,6 +297,7 @@ in
slurm = handleTest ./slurm.nix {};
smokeping = handleTest ./smokeping.nix {};
snapper = handleTest ./snapper.nix {};
sogo = handleTest ./sogo.nix {};
solr = handleTest ./solr.nix {};
spacecookie = handleTest ./spacecookie.nix {};
spike = handleTest ./spike.nix {};
@ -304,6 +310,7 @@ in
syncthing-relay = handleTest ./syncthing-relay.nix {};
systemd = handleTest ./systemd.nix {};
systemd-analyze = handleTest ./systemd-analyze.nix {};
systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {};
systemd-boot = handleTestOn ["x86_64-linux"] ./systemd-boot.nix {};
systemd-confinement = handleTest ./systemd-confinement.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
@ -334,10 +341,7 @@ in
vault = handleTest ./vault.nix {};
victoriametrics = handleTest ./victoriametrics.nix {};
virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
wg-quick = handleTest ./wireguard/wg-quick.nix {};
wireguard = handleTest ./wireguard {};
wireguard-generated = handleTest ./wireguard/generated.nix {};
wireguard-namespaces = handleTest ./wireguard/namespaces.nix {};
wordpress = handleTest ./wordpress.nix {};
xandikos = handleTest ./xandikos.nix {};
xautolock = handleTest ./xautolock.nix {};
@ -348,6 +352,7 @@ in
yabar = handleTest ./yabar.nix {};
yggdrasil = handleTest ./yggdrasil.nix {};
zfs = handleTest ./zfs.nix {};
zsh-history = handleTest ./zsh-history.nix {};
zoneminder = handleTest ./zoneminder.nix {};
zookeeper = handleTest ./zookeeper.nix {};
zsh-history = handleTest ./zsh-history.nix {};
}

View file

@ -0,0 +1,26 @@
import ./make-test-python.nix ({ lib, ... }:
with lib;
let
port = 42069;
in
{
name = "bazarr";
meta.maintainers = with maintainers; [ xwvvvvwx ];
nodes.machine =
{ pkgs, ... }:
{
services.bazarr = {
enable = true;
listenPort = port;
};
};
testScript = ''
machine.wait_for_unit("bazarr.service")
machine.wait_for_open_port("${toString port}")
machine.succeed("curl --fail http://localhost:${toString port}/")
'';
})

View file

@ -0,0 +1,71 @@
import ../make-test-python.nix ({ pkgs, ... }: {
name = "dnscrypt-wrapper";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ rnhmjoj ];
};
nodes = {
server = { lib, ... }:
{ services.dnscrypt-wrapper = with builtins;
{ enable = true;
address = "192.168.1.1";
keys.expiration = 5; # days
keys.checkInterval = 2; # min
# The keypair was generated by the command:
# dnscrypt-wrapper --gen-provider-keypair \
# --provider-name=2.dnscrypt-cert.server \
# --ext-address=192.168.1.1:5353
providerKey.public = toFile "public.key" (readFile ./public.key);
providerKey.secret = toFile "secret.key" (readFile ./secret.key);
};
services.tinydns.enable = true;
services.tinydns.data = ''
..:192.168.1.1:a
+it.works:1.2.3.4
'';
networking.firewall.allowedUDPPorts = [ 5353 ];
networking.firewall.allowedTCPPorts = [ 5353 ];
networking.interfaces.eth1.ipv4.addresses = lib.mkForce
[ { address = "192.168.1.1"; prefixLength = 24; } ];
};
client = { lib, ... }:
{ services.dnscrypt-proxy2.enable = true;
services.dnscrypt-proxy2.settings = {
server_names = [ "server" ];
static.server.stamp = "sdns://AQAAAAAAAAAAEDE5Mi4xNjguMS4xOjUzNTMgFEHYOv0SCKSuqR5CDYa7-58cCBuXO2_5uTSVU9wNQF0WMi5kbnNjcnlwdC1jZXJ0LnNlcnZlcg";
};
networking.nameservers = [ "127.0.0.1" ];
networking.interfaces.eth1.ipv4.addresses = lib.mkForce
[ { address = "192.168.1.2"; prefixLength = 24; } ];
};
};
testScript = ''
start_all()
with subtest("The server can generate the ephemeral keypair"):
server.wait_for_unit("dnscrypt-wrapper")
server.wait_for_file("/var/lib/dnscrypt-wrapper/2.dnscrypt-cert.server.key")
server.wait_for_file("/var/lib/dnscrypt-wrapper/2.dnscrypt-cert.server.crt")
with subtest("The client can connect to the server"):
server.wait_for_unit("tinydns")
client.wait_for_unit("dnscrypt-proxy2")
assert "1.2.3.4" in client.succeed(
"host it.works"
), "The IP address of 'it.works' does not match 1.2.3.4"
with subtest("The server rotates the ephemeral keys"):
# advance time by a little less than 5 days
server.succeed("date -s \"$(date --date '4 days 6 hours')\"")
client.succeed("date -s \"$(date --date '4 days 6 hours')\"")
server.wait_for_file("/var/lib/dnscrypt-wrapper/oldkeys")
with subtest("The client can still connect to the server"):
server.wait_for_unit("dnscrypt-wrapper")
client.succeed("host it.works")
'';
})

View file

@ -0,0 +1 @@
A<>:<3A><08><><EFBFBD>B <0A><><EFBFBD><EFBFBD><1B>;o<><6F>4<EFBFBD>S<EFBFBD> @]

View file

@ -0,0 +1 @@
G½>ֶ©» ל>׀א¥(ׂ²‡¼J•«÷=<3D><EFBFBD>ֱ<EFBFBD>A״:₪®©B †»<E280A0><C2BB>—;oש¹4•S<E280A2> @]

View file

@ -0,0 +1,41 @@
import ./make-test-python.nix (
{ pkgs, lib, ... }:
{
name = "engelsystem";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ talyz ];
};
nodes.engelsystem =
{ ... }:
{
services.engelsystem = {
enable = true;
domain = "engelsystem";
createDatabase = true;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
environment.systemPackages = with pkgs; [
xmlstarlet
libxml2
];
};
testScript = ''
engelsystem.start()
engelsystem.wait_for_unit("phpfpm-engelsystem.service")
engelsystem.wait_until_succeeds("curl engelsystem/login -sS -f")
engelsystem.succeed(
"curl engelsystem/login -sS -f -c cookie | xmllint -html -xmlout - >login"
)
engelsystem.succeed(
"xml sel -T -t -m \"html/head/meta[@name='csrf-token']\" -v @content login >token"
)
engelsystem.succeed(
"curl engelsystem/login -sS -f -b cookie -F 'login=admin' -F 'password=asdfasdf' -F '_token=<token' -L | xmllint -html -xmlout - >news"
)
engelsystem.succeed(
"test 'News - Engelsystem' = \"$(xml sel -T -t -c html/head/title news)\""
)
'';
})

View file

@ -41,28 +41,24 @@ import ./make-test-python.nix ({ pkgs, ...} :
with subtest("First time wizard"):
machine.wait_for_text("Default") # Language
machine.succeed("xdotool mousemove 512 185 click 1") # Default Language
machine.screenshot("wizard1")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.screenshot("wizard2")
machine.wait_for_text("English") # Keyboard (default)
machine.screenshot("wizard2")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.wait_for_text("Standard") # Profile (default)
machine.screenshot("wizard3")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.wait_for_text("Title") # Sizing (default)
machine.wait_for_text("Standard") # Profile (default)
machine.screenshot("wizard4")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.wait_for_text("clicked") # Windows Phocus
machine.succeed("xdotool mousemove 512 370 click 1") # Click
machine.wait_for_text("Title") # Sizing (default)
machine.screenshot("wizard5")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.wait_for_text("bindings") # Mouse Modifiers (default)
machine.wait_for_text("clicked") # Windows Focus
machine.succeed("xdotool mousemove 512 370 click 1") # Click
machine.screenshot("wizard6")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
@ -74,7 +70,7 @@ import ./make-test-python.nix ({ pkgs, ...} :
machine.screenshot("wizard8")
machine.succeed("xdotool mousemove 512 740 click 1") # Next
machine.wait_for_text("Compositing") # Compositing (default)
machine.wait_for_text("OpenGL") # Compositing (default)
machine.screenshot("wizard9")
machine.succeed("xdotool mousemove 512 740 click 1") # Next

View file

@ -0,0 +1,18 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "ergo";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ mmahut ];
};
nodes = {
machine = { ... }: {
services.ergo.enable = true;
services.ergo.api.keyHash = "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf";
};
};
testScript = ''
start_all()
machine.wait_for_unit("ergo.service")
'';
})

View file

@ -76,7 +76,7 @@ in {
hass.succeed("test -f ${configDir}/ui-lovelace.yaml")
with subtest("Check that Home Assistant's web interface and API can be reached"):
hass.wait_for_open_port(8123)
hass.succeed("curl --fail http://localhost:8123/states")
hass.succeed("curl --fail http://localhost:8123/lovelace")
assert "API running" in hass.succeed(
"curl --fail -H 'x-ha-access: ${apiPassword}' http://localhost:8123/api/"
)

View file

@ -0,0 +1,66 @@
{ system ? builtins.currentSystem,
config ? {},
pkgs ? import ../.. { inherit system config; }
}:
with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
let
makeHostNameTest = hostName: domain:
let
fqdn = hostName + (optionalString (domain != null) ".${domain}");
in
makeTest {
name = "hostname-${fqdn}";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ primeos blitz ];
};
machine = { lib, ... }: {
networking.hostName = hostName;
networking.domain = domain;
environment.systemPackages = with pkgs; [
inetutils
];
};
testScript = ''
start_all()
machine = ${hostName}
machine.wait_for_unit("network-online.target")
# The FQDN, domain name, and hostname detection should work as expected:
assert "${fqdn}" == machine.succeed("hostname --fqdn").strip()
assert "${optionalString (domain != null) domain}" == machine.succeed("dnsdomainname").strip()
assert (
"${hostName}"
== machine.succeed(
'hostnamectl status | grep "Static hostname" | cut -d: -f2'
).strip()
)
# 127.0.0.1 and ::1 should resolve back to "localhost":
assert (
"localhost" == machine.succeed("getent hosts 127.0.0.1 | awk '{print $2}'").strip()
)
assert "localhost" == machine.succeed("getent hosts ::1 | awk '{print $2}'").strip()
# 127.0.0.2 should resolve back to the FQDN and hostname:
fqdn_and_host_name = "${optionalString (domain != null) "${hostName}.${domain} "}${hostName}"
assert (
fqdn_and_host_name
== machine.succeed("getent hosts 127.0.0.2 | awk '{print $2,$3}'").strip()
)
'';
};
in
{
noExplicitDomain = makeHostNameTest "ahost" null;
explicitDomain = makeHostNameTest "ahost" "adomain";
}

View file

@ -9,7 +9,22 @@ in {
nodes = {
# The only thing the client needs to do is download a file.
client = { ... }: {};
client = { ... }: {
services.davfs2.enable = true;
system.activationScripts.davfs2-secrets = ''
echo "http://nextcloud/remote.php/webdav/ ${adminuser} ${adminpass}" > /tmp/davfs2-secrets
chmod 600 /tmp/davfs2-secrets
'';
fileSystems = pkgs.lib.mkVMOverride {
"/mnt/dav" = {
device = "http://nextcloud/remote.php/webdav/";
fsType = "davfs";
options = let
davfs2Conf = (pkgs.writeText "davfs2.conf" "secrets /tmp/davfs2-secrets");
in [ "conf=${davfs2Conf}" "x-systemd.automount" "noauto"];
};
};
};
nextcloud = { config, pkgs, ... }: {
networking.firewall.allowedTCPPorts = [ 80 ];
@ -60,5 +75,6 @@ in {
client.succeed(
"${withRcloneEnv} ${diffSharedFile}"
)
assert "hi" in client.succeed("cat /mnt/dav/test-shared-file")
'';
})

View file

@ -38,23 +38,45 @@ import ./make-test-python.nix (
start_all()
with subtest("Run container as root"):
with subtest("Run container as root with runc"):
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
podman.succeed(
"podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
"podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
podman.succeed("podman ps | grep sleeping")
podman.succeed("podman stop sleeping")
podman.succeed("podman rm sleeping")
with subtest("Run container rootless"):
with subtest("Run container as root with crun"):
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
podman.succeed(
"podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
podman.succeed("podman ps | grep sleeping")
podman.succeed("podman stop sleeping")
podman.succeed("podman rm sleeping")
with subtest("Run container rootless with runc"):
podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
podman.succeed(
su_cmd(
"podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
"podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
)
podman.succeed(su_cmd("podman ps | grep sleeping"))
podman.succeed(su_cmd("podman stop sleeping"))
podman.succeed(su_cmd("podman rm sleeping"))
with subtest("Run container rootless with crun"):
podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
podman.succeed(
su_cmd(
"podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
)
podman.succeed(su_cmd("podman ps | grep sleeping"))
podman.succeed(su_cmd("podman stop sleeping"))
podman.succeed(su_cmd("podman rm sleeping"))
'';
}
)

View file

@ -0,0 +1,58 @@
import ./make-test-python.nix ({ pkgs, ... }: {
name = "sogo";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ajs124 das_j ];
};
nodes = {
sogo = { config, pkgs, ... }: {
services.nginx.enable = true;
services.mysql = {
enable = true;
package = pkgs.mysql;
ensureDatabases = [ "sogo" ];
ensureUsers = [{
name = "sogo";
ensurePermissions = {
"sogo.*" = "ALL PRIVILEGES";
};
}];
};
services.sogo = {
enable = true;
timezone = "Europe/Berlin";
extraConfig = ''
WOWorkersCount = 1;
SOGoUserSources = (
{
type = sql;
userPasswordAlgorithm = md5;
viewURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_users";
canAuthenticate = YES;
id = users;
}
);
SOGoProfileURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_user_profile";
OCSFolderInfoURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_folder_info";
OCSSessionsFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_sessions_folder";
OCSEMailAlarmsFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_alarms_folder";
OCSStoreURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_store";
OCSAclURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_acl";
OCSCacheFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_cache_folder";
'';
};
};
};
testScript = ''
start_all()
sogo.wait_for_unit("multi-user.target")
sogo.wait_for_open_port(20000)
sogo.wait_for_open_port(80)
sogo.succeed("curl -sSfL http://sogo/SOGo")
'';
})

View file

@ -0,0 +1,24 @@
# Teach the kernel how to run armv7l and aarch64-linux binaries,
# and run GNU Hello for these architectures.
import ./make-test-python.nix ({ pkgs, ... }: {
name = "systemd-binfmt";
machine = {
boot.binfmt.emulatedSystems = [
"armv7l-linux"
"aarch64-linux"
];
};
testScript = let
helloArmv7l = pkgs.pkgsCross.armv7l-hf-multiplatform.hello;
helloAarch64 = pkgs.pkgsCross.aarch64-multiplatform.hello;
in ''
machine.start()
assert "world" in machine.succeed(
"${helloArmv7l}/bin/hello"
)
assert "world" in machine.succeed(
"${helloAarch64}/bin/hello"
)
'';
})

View file

@ -0,0 +1,74 @@
{ kernelPackages ? null }:
import ../make-test-python.nix ({ pkgs, lib, ...} :
let
wg-snakeoil-keys = import ./snakeoil-keys.nix;
peer = (import ./make-peer.nix) { inherit lib; };
in
{
name = "wireguard";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 ];
};
nodes = {
peer0 = peer {
ip4 = "192.168.0.1";
ip6 = "fd00::1";
extraConfig = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.firewall.allowedUDPPorts = [ 23542 ];
networking.wireguard.interfaces.wg0 = {
ips = [ "10.23.42.1/32" "fc00::1/128" ];
listenPort = 23542;
inherit (wg-snakeoil-keys.peer0) privateKey;
peers = lib.singleton {
allowedIPs = [ "10.23.42.2/32" "fc00::2/128" ];
inherit (wg-snakeoil-keys.peer1) publicKey;
};
};
};
};
peer1 = peer {
ip4 = "192.168.0.2";
ip6 = "fd00::2";
extraConfig = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wireguard.interfaces.wg0 = {
ips = [ "10.23.42.2/32" "fc00::2/128" ];
listenPort = 23542;
allowedIPsAsRoutes = false;
inherit (wg-snakeoil-keys.peer1) privateKey;
peers = lib.singleton {
allowedIPs = [ "0.0.0.0/0" "::/0" ];
endpoint = "192.168.0.1:23542";
persistentKeepalive = 25;
inherit (wg-snakeoil-keys.peer0) publicKey;
};
postSetup = let inherit (pkgs) iproute; in ''
${iproute}/bin/ip route replace 10.23.42.1/32 dev wg0
${iproute}/bin/ip route replace fc00::1/128 dev wg0
'';
};
};
};
};
testScript = ''
start_all()
peer0.wait_for_unit("wireguard-wg0.service")
peer1.wait_for_unit("wireguard-wg0.service")
peer1.succeed("ping -c5 fc00::1")
peer1.succeed("ping -c5 10.23.42.1")
'';
}
)

View file

@ -1,71 +1,27 @@
import ../make-test-python.nix ({ pkgs, lib, ...} :
let
wg-snakeoil-keys = import ./snakeoil-keys.nix;
peer = (import ./make-peer.nix) { inherit lib; };
in
{
name = "wireguard";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 ];
};
{ system ? builtins.currentSystem
, config ? { }
, pkgs ? import ../../.. { inherit system config; }
, kernelVersionsToTest ? [ "5.4" "latest" ]
}:
nodes = {
peer0 = peer {
ip4 = "192.168.0.1";
ip6 = "fd00::1";
extraConfig = {
networking.firewall.allowedUDPPorts = [ 23542 ];
networking.wireguard.interfaces.wg0 = {
ips = [ "10.23.42.1/32" "fc00::1/128" ];
listenPort = 23542;
with pkgs.lib;
inherit (wg-snakeoil-keys.peer0) privateKey;
let
tests = let callTest = p: flip (import p) { inherit system pkgs; }; in {
basic = callTest ./basic.nix;
namespaces = callTest ./namespaces.nix;
wg-quick = callTest ./wg-quick.nix;
generated = callTest ./generated.nix;
};
in
peers = lib.singleton {
allowedIPs = [ "10.23.42.2/32" "fc00::2/128" ];
inherit (wg-snakeoil-keys.peer1) publicKey;
};
};
};
};
peer1 = peer {
ip4 = "192.168.0.2";
ip6 = "fd00::2";
extraConfig = {
networking.wireguard.interfaces.wg0 = {
ips = [ "10.23.42.2/32" "fc00::2/128" ];
listenPort = 23542;
allowedIPsAsRoutes = false;
inherit (wg-snakeoil-keys.peer1) privateKey;
peers = lib.singleton {
allowedIPs = [ "0.0.0.0/0" "::/0" ];
endpoint = "192.168.0.1:23542";
persistentKeepalive = 25;
inherit (wg-snakeoil-keys.peer0) publicKey;
};
postSetup = let inherit (pkgs) iproute; in ''
${iproute}/bin/ip route replace 10.23.42.1/32 dev wg0
${iproute}/bin/ip route replace fc00::1/128 dev wg0
'';
};
};
};
};
testScript = ''
start_all()
peer0.wait_for_unit("wireguard-wg0.service")
peer1.wait_for_unit("wireguard-wg0.service")
peer1.succeed("ping -c5 fc00::1")
peer1.succeed("ping -c5 10.23.42.1")
'';
}
listToAttrs (
flip concatMap kernelVersionsToTest (version:
let
v' = replaceStrings [ "." ] [ "_" ] version;
in
flip mapAttrsToList tests (name: test:
nameValuePair "wireguard-${name}-linux-${v'}" (test { kernelPackages = pkgs."linuxPackages_${v'}"; })
)
)
)

View file

@ -1,4 +1,5 @@
import ../make-test-python.nix ({ pkgs, ...} : {
{ kernelPackages ? null }:
import ../make-test-python.nix ({ pkgs, lib, ... } : {
name = "wireguard-generated";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ ma27 grahamc ];
@ -6,6 +7,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
nodes = {
peer1 = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.firewall.allowedUDPPorts = [ 12345 ];
networking.wireguard.interfaces.wg0 = {
ips = [ "10.10.10.1/24" ];
@ -17,6 +19,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
};
peer2 = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.firewall.allowedUDPPorts = [ 12345 ];
networking.wireguard.interfaces.wg0 = {
ips = [ "10.10.10.2/24" ];

View file

@ -1,3 +1,5 @@
{ kernelPackages ? null }:
let
listenPort = 12345;
socketNamespace = "foo";
@ -13,7 +15,7 @@ let
in
import ../make-test-python.nix ({ pkgs, ...} : {
import ../make-test-python.nix ({ pkgs, lib, ... } : {
name = "wireguard-with-namespaces";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ asymmetric ];
@ -23,6 +25,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
# interface should be created in the socketNamespace
# and not moved from there
peer0 = pkgs.lib.attrsets.recursiveUpdate node {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wireguard.interfaces.wg0 = {
preSetup = ''
ip netns add ${socketNamespace}
@ -33,6 +36,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
# interface should be created in the init namespace
# and moved to the interfaceNamespace
peer1 = pkgs.lib.attrsets.recursiveUpdate node {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wireguard.interfaces.wg0 = {
preSetup = ''
ip netns add ${interfaceNamespace}
@ -43,6 +47,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
# interface should be created in the socketNamespace
# and moved to the interfaceNamespace
peer2 = pkgs.lib.attrsets.recursiveUpdate node {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wireguard.interfaces.wg0 = {
preSetup = ''
ip netns add ${socketNamespace}
@ -54,6 +59,7 @@ import ../make-test-python.nix ({ pkgs, ...} : {
# interface should be created in the socketNamespace
# and moved to the init namespace
peer3 = pkgs.lib.attrsets.recursiveUpdate node {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wireguard.interfaces.wg0 = {
preSetup = ''
ip netns add ${socketNamespace}

View file

@ -1,3 +1,5 @@
{ kernelPackages ? null }:
import ../make-test-python.nix ({ pkgs, lib, ... }:
let
wg-snakeoil-keys = import ./snakeoil-keys.nix;
@ -14,6 +16,7 @@ import ../make-test-python.nix ({ pkgs, lib, ... }:
ip4 = "192.168.0.1";
ip6 = "fd00::1";
extraConfig = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.firewall.allowedUDPPorts = [ 23542 ];
networking.wg-quick.interfaces.wg0 = {
address = [ "10.23.42.1/32" "fc00::1/128" ];
@ -34,6 +37,7 @@ import ../make-test-python.nix ({ pkgs, lib, ... }:
ip4 = "192.168.0.2";
ip6 = "fd00::2";
extraConfig = {
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
networking.wg-quick.interfaces.wg0 = {
address = [ "10.23.42.2/32" "fc00::2/128" ];
inherit (wg-snakeoil-keys.peer1) privateKey;

View file

@ -85,6 +85,7 @@ in import ./make-test-python.nix ({ pkgs, ...} : {
MulticastInterfaces = [ "eth1" ];
LinkLocalTCPPort = 43210;
};
persistentKeys = true;
};
};
};

View file

@ -0,0 +1,23 @@
import ./make-test-python.nix ({ lib, ...}:
{
name = "zoneminder";
meta.maintainers = with lib.maintainers; [ danielfullmer ];
machine = { ... }:
{
services.zoneminder = {
enable = true;
database.createLocally = true;
database.username = "zoneminder";
};
time.timeZone = "America/New_York";
};
testScript = ''
machine.wait_for_unit("zoneminder.service")
machine.wait_for_unit("nginx.service")
machine.wait_for_open_port(8095)
machine.succeed("curl --fail http://localhost:8095/")
'';
})

View file

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

View file

@ -0,0 +1,28 @@
{ stdenv, fetchFromGitHub, libX11, cairo, lv2, pkgconfig, libsndfile }:
stdenv.mkDerivation rec {
pname = "BJumblr";
version = "0.2";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = "v${version}";
sha256 = "14z8113zkwykbhm1a8h2xs972dgifvlfij92b08jckyc7cbz84ys";
};
nativeBuildInputs = [ pkgconfig ];
buildInputs = [
libX11 cairo lv2 libsndfile
];
installFlags = [ "PREFIX=$(out)" ];
meta = with stdenv.lib; {
homepage = "https://github.com/sjaehn/BJumblr";
description = "Pattern-controlled audio stream / sample re-sequencer LV2 plugin";
maintainers = [ maintainers.magnetophon ];
platforms = platforms.linux;
license = licenses.gpl3;
};
}

View file

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "BSEQuencer";
version = "1.4.0";
version = "1.4.2";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = "${version}";
sha256 = "1zz1cirmx4wm4im4gjdp691f2042c8d1i8np1ns71f6kqdj9ps3k";
sha256 = "1fz0p0ba00b7k7a8q9mxwj01jwl8xwh9a2npn00pbbdrg9zv4fdr";
};
nativeBuildInputs = [ pkgconfig ];

View file

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "BShapr";
version = "0.8";
version = "0.9";
src = fetchFromGitHub {
owner = "sjaehn";
repo = pname;
rev = "v${version}";
sha256 = "0jlq5rjicc4fxlpk869dg0l5bwwz8k9aj2wfk9v89b0qw8l8kaxl";
sha256 = "04zd3a178i2nivg5rjailzqvc5mlnilmhj1ziygmbhshbrywplri";
};
nativeBuildInputs = [ pkgconfig ];

View file

@ -6,11 +6,11 @@
stdenv.mkDerivation rec {
pname = "denemo";
version = "2.3.0";
version = "2.4.0";
src = fetchurl {
url = "https://ftp.gnu.org/gnu/denemo/denemo-${version}.tar.gz";
sha256 = "1blkcl3slbsq9jlhwcf2m9v9g38a0sjfhh9advgi2qr1gxri08by";
sha256 = "145kq0zfgdadykl3i6na221i4s5wzdrcqq48amzyfarnrqk2rmpd";
};
buildInputs = [

View file

@ -7,13 +7,13 @@
stdenv.mkDerivation rec {
pname = "ft2-clone";
version = "1.23";
version = "1.24";
src = fetchFromGitHub {
owner = "8bitbubsy";
repo = "ft2-clone";
rev = "v${version}";
sha256 = "03prdifc2nz7smmzdy19flp33m927vb7j5bhdc46gak753pikw7d";
sha256 = "0wb7xsc2m9f4q5zsf5ai6h6c0558lkziv30b5a8ic64wp0layr6k";
};
nativeBuildInputs = [ cmake ];

View file

@ -0,0 +1,69 @@
{ stdenv
, fetchurl
, unzip
, makeDesktopItem
, imagemagick
, SDL
, isStereo ? false
}:
with stdenv.lib;
let
pname = "goattracker" + optionalString isStereo "-stereo";
desktopItem = makeDesktopItem {
type = "Application";
name = pname;
desktopName = "GoatTracker 2" + optionalString isStereo " Stereo";
genericName = "Music Tracker";
exec = if isStereo
then "gt2stereo"
else "goattrk2";
icon = "goattracker";
categories = "AudioVideo;AudioVideoEditing;";
extraEntries = "Keywords=tracker;music;";
};
in stdenv.mkDerivation rec {
inherit pname;
version = if isStereo
then "2.76" # stereo
else "2.75"; # normal
src = fetchurl {
url = "mirror://sourceforge/goattracker2/GoatTracker_${version}${optionalString isStereo "_Stereo"}.zip";
sha256 = if isStereo
then "12cz3780x5k047jqdv69n6rjgbfiwv67z850kfl4i37lxja432l7" # stereo
else "1km97nl7qvk6qc5l5j69wncbm76hf86j47sgzgr968423g0bxxlk"; # normal
};
sourceRoot = (if isStereo then "gt2stereo/trunk" else "goattrk2") + "/src";
nativeBuildInputs = [ unzip imagemagick ];
buildInputs = [ SDL ];
# PREFIX gets treated as BINDIR.
makeFlags = [ "PREFIX=$(out)/bin/" ];
# The zip contains some build artifacts.
prePatch = "make clean";
# The destination does not get created automatically.
preBuild = "mkdir -p $out/bin";
# Other files get installed during the build phase.
installPhase = ''
convert goattrk2.bmp goattracker.png
install -Dm644 goattracker.png $out/share/icons/hicolor/32x32/apps/goattracker.png
${desktopItem.buildCommand}
'';
meta = {
description = "A crossplatform music editor for creating Commodore 64 music. Uses reSID library by Dag Lem and supports alternatively HardSID & CatWeasel devices"
+ optionalString isStereo " - Stereo version";
homepage = "https://cadaver.github.io/tools.html";
downloadPage = "https://sourceforge.net/projects/goattracker2/";
license = licenses.gpl2Plus;
maintainers = with maintainers; [ fgaz ];
platforms = platforms.all;
};
}

View file

@ -1,4 +1,4 @@
{ stdenv, fetchurl, gettext, intltool, pkgconfig, python2
{ stdenv, fetchurl, fetchpatch, faust, gettext, intltool, pkgconfig, python2
, avahi, bluez, boost, eigen, fftw, glib, glib-networking
, glibmm, gsettings-desktop-schemas, gtkmm2, libjack2
, ladspaH, libav, libsndfile, lilv, lrdf, lv2, serd, sord, sratom
@ -19,7 +19,15 @@ stdenv.mkDerivation rec {
sha256 = "1nn80m1qagfhvv69za60f0w6ck87vmk77qmqarj7fbr8avwg63s9";
};
nativeBuildInputs = [ gettext intltool wrapGAppsHook pkgconfig python2 wafHook ];
patches = [
(fetchpatch {
url = "https://git.archlinux.org/svntogit/community.git/plain/trunk/guitarix-0.39.0-fix_faust_and_lv2_plugins.patch?id=8579b4dfe85e04303ad2d9771ed699f04ea7b7cf";
stripLen = 1;
sha256 = "0pgkhi4v4vrzjnig0ggmz207q4x5iyk2n6rjj8s5lv15fia7qzp4";
})
];
nativeBuildInputs = [ faust gettext intltool wrapGAppsHook pkgconfig python2 wafHook ];
buildInputs = [
avahi bluez boost eigen fftw glib glibmm glib-networking.out
@ -28,11 +36,16 @@ stdenv.mkDerivation rec {
zita-resampler curl
];
postPatch = ''
# Fix build with lv2 1.18: https://github.com/brummer10/guitarix/commit/c0334c72
find . -type f -exec fgrep -q LV2UI_Descriptor {} \; \
-exec sed -i {} -e 's/const struct _\?LV2UI_Descriptor/const LV2UI_Descriptor/' \;
'';
wafConfigureFlags = [
"--shared-lib"
"--no-desktop-update"
"--enable-nls"
"--no-faust" # todo: find out why --faust doesn't work
"--install-roboto-font"
"--includeresampler"
"--convolver-ffmpeg"

View file

@ -9,11 +9,11 @@
stdenv.mkDerivation rec {
pname = "kid3";
version = "3.8.2";
version = "3.8.3";
src = fetchurl {
url = "mirror://sourceforge/project/kid3/kid3/${version}/${pname}-${version}.tar.gz";
sha256 = "051y77swpi9isx275gwzl4fn3igd2dmixbszv9m3h0h9lqhcjrvr";
sha256 = "0i0c4bmsm36jj1v535kil47ig0ig70ykrzcw2f56spr25xns06ka";
};
nativeBuildInputs = [ wrapQtAppsHook ];

View file

@ -26,6 +26,10 @@ let
mopidy-mpd = callPackage ./mpd.nix { };
mopidy-mpris = callPackage ./mpris.nix { };
mopidy-somafm = callPackage ./somafm.nix { };
mopidy-spotify-tunigo = callPackage ./spotify-tunigo.nix { };
mopidy-youtube = callPackage ./youtube.nix { };

View file

@ -1,19 +1,20 @@
{ stdenv, fetchurl, pythonPackages, mopidy }:
{ stdenv, python3Packages, mopidy }:
pythonPackages.buildPythonApplication rec {
python3Packages.buildPythonApplication rec {
pname = "mopidy-gmusic";
version = "3.0.0";
version = "4.0.0";
src = fetchurl {
url = "https://github.com/mopidy/mopidy-gmusic/archive/v${version}.tar.gz";
sha256 = "0a2s4xrrhnkv85rx4w5bj6ih9xm34jy0q71fdvbzmi827g9dw5sz";
src = python3Packages.fetchPypi {
inherit version;
pname = "Mopidy-GMusic";
sha256 = "14yswmlfs659rs3k595606m77lw9c6pjykb5pikqw21sb97haxl3";
};
propagatedBuildInputs = [
mopidy
pythonPackages.requests
pythonPackages.gmusicapi
pythonPackages.cachetools
python3Packages.requests
python3Packages.gmusicapi
python3Packages.cachetools
];
doCheck = false;

View file

@ -2,11 +2,11 @@
python3Packages.buildPythonApplication rec {
pname = "Mopidy-Iris";
version = "3.47.0";
version = "3.49.0";
src = python3Packages.fetchPypi {
inherit pname version;
sha256 = "1lvq5qsnn2djwkgbadzr7rr6ik2xh8yyj0p3y3hck9pl96ms7lfv";
sha256 = "0zddm7286iwx437gjz47m4g28s8gdcxnm2hmly9w1dzi08aa4fas";
};
propagatedBuildInputs = [

View file

@ -0,0 +1,27 @@
{ stdenv, python3Packages, mopidy }:
python3Packages.buildPythonApplication rec {
pname = "mopidy-mpris";
version = "3.0.1";
src = python3Packages.fetchPypi {
inherit version;
pname = "Mopidy-MPRIS";
sha256 = "0qk46aq5r92qgkldzl41x09naww1gv92l4c4hknyl7yymyvm9lr2";
};
propagatedBuildInputs = [
mopidy
python3Packages.pydbus
];
doCheck = false;
meta = with stdenv.lib; {
homepage = https://www.mopidy.com/;
description = "Mopidy extension for controlling Mopidy through D-Bus using the MPRIS specification";
license = licenses.asl20;
maintainers = [ maintainers.nickhu ];
};
}

View file

@ -0,0 +1,26 @@
{ stdenv, python3Packages, mopidy }:
python3Packages.buildPythonApplication rec {
pname = "mopidy-somafm";
version = "2.0.0";
src = python3Packages.fetchPypi {
inherit version;
pname = "Mopidy-SomaFM";
sha256 = "1j88rrliys8hqvnb35k1xqw88bvrllcb4rb53lgh82byhscsxlf3";
};
propagatedBuildInputs = [
mopidy
];
doCheck = false;
meta = with stdenv.lib; {
homepage = https://www.mopidy.com/;
description = "Mopidy extension for playing music from SomaFM";
license = licenses.mit;
maintainers = [ maintainers.nickhu ];
};
}

View file

@ -1,17 +1,23 @@
{ stdenv, fetchFromGitHub, pythonPackages, mopidy }:
{ stdenv, python3Packages, mopidy }:
pythonPackages.buildPythonApplication rec {
python3Packages.buildPythonApplication rec {
pname = "mopidy-youtube";
version = "2.0.2";
version = "3.0";
src = fetchFromGitHub {
owner = "mopidy";
repo = "mopidy-youtube";
rev = "v${version}";
sha256 = "06r3ikyg2ch5n7fbn3sgj04hk6icpfpk1r856qch41995k3bbfg7";
src = python3Packages.fetchPypi {
inherit version;
pname = "Mopidy-YouTube";
sha256 = "0x1q9rfnjx65n6hi8s5rw5ff4xv55h63zy52fwm8aksdnzppr7gd";
};
propagatedBuildInputs = with pythonPackages; [ mopidy pafy ];
patchPhase = "sed s/bs4/beautifulsoup4/ -i setup.cfg";
propagatedBuildInputs = [
mopidy
python3Packages.beautifulsoup4
python3Packages.cachetools
python3Packages.youtube-dl
];
doCheck = false;

View file

@ -7,13 +7,13 @@
stdenv.mkDerivation rec {
pname = "pt2-clone";
version = "1.12";
version = "1.16";
src = fetchFromGitHub {
owner = "8bitbubsy";
repo = "pt2-clone";
rev = "v${version}";
sha256 = "1y7kv889rm3nvaigcda4bglvwm799f3gp0zrivkvrg1lrlygs89f";
sha256 = "0rbjphhyca71j22lbyx53w3n2mkdw7xflks2knfaziwdkqcfcvp2";
};
nativeBuildInputs = [ cmake ];

View file

@ -5,11 +5,11 @@
stdenv.mkDerivation rec {
pname = "qtractor";
version = "0.9.13";
version = "0.9.14";
src = fetchurl {
url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.gz";
sha256 = "1hwxdjlzsf1z6xl82s4bdfxa2bfisklrfx361zbzskmg9iymw1gy";
sha256 = "1gh268gdpj7nw19xfh7k2l3aban4yrs1lmx33qswrnngs2izj1fk";
};
nativeBuildInputs = [

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