diff options
author | Katharina Fey <kookie@spacekookie.de> | 2020-06-04 20:34:50 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2020-06-04 20:34:50 +0200 |
commit | 8e9d8d8b70f2a5515ffa4b2dad18cf5783ab1e4e (patch) | |
tree | c2f70049be19f757f1ae6b2b80c3bfe70a47612c /nixpkgs/nixos | |
parent | 240cb27216dbb4203e2d470d78888b5cf82809ac (diff) | |
parent | 467ce5a9f45aaf96110b41eb863a56866e1c2c3c (diff) |
Merge commit '467ce5a9f45aaf96110b41eb863a56866e1c2c3c'
Diffstat (limited to 'nixpkgs/nixos')
85 files changed, 2464 insertions, 417 deletions
diff --git a/nixpkgs/nixos/doc/manual/administration/boot-problems.xml b/nixpkgs/nixos/doc/manual/administration/boot-problems.xml index de3d8ac21ae..5fa0b29e6d6 100644 --- a/nixpkgs/nixos/doc/manual/administration/boot-problems.xml +++ b/nixpkgs/nixos/doc/manual/administration/boot-problems.xml @@ -40,6 +40,17 @@ </varlistentry> <varlistentry> <term> + <literal>boot.debug1devices</literal> + </term> + <listitem> + <para> + Like <literal>boot.debug1</literal>, but runs stage1 until kernel modules are loaded and device nodes are created. + This may help with e.g. making the keyboard work. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> <literal>boot.trace</literal> </term> <listitem> diff --git a/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.xml b/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.xml index e5a887c18c7..150bea8c2d8 100644 --- a/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.xml +++ b/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.xml @@ -373,7 +373,7 @@ start_all() </varlistentry> <varlistentry> <term> - <methodname>copy_file_from_host</methodname> + <methodname>copy_from_host</methodname> </term> <listitem> <para> diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml index 1d24553b08d..e17e8ac24d1 100644 --- a/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixpkgs/nixos/doc/manual/release-notes/rl-2009.xml @@ -28,6 +28,12 @@ </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. </para> </listitem> @@ -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> @@ -386,6 +400,47 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ]; 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> @@ -418,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> diff --git a/nixpkgs/nixos/lib/test-driver/test-driver.py b/nixpkgs/nixos/lib/test-driver/test-driver.py index bf46d0df97f..e7b05968b07 100644 --- a/nixpkgs/nixos/lib/test-driver/test-driver.py +++ b/nixpkgs/nixos/lib/test-driver/test-driver.py @@ -598,11 +598,8 @@ class Machine: shutil.copytree(host_src, host_intermediate) else: shutil.copy(host_src, host_intermediate) - self.succeed("sync") self.succeed(make_command(["mkdir", "-p", vm_target.parent])) self.succeed(make_command(["cp", "-r", vm_intermediate, vm_target])) - # Make sure the cleanup is synced into VM - self.succeed("sync") def copy_from_vm(self, source: str, target_dir: str = "") -> None: """Copy a file from the VM (specified by an in-VM source path) to a path @@ -620,7 +617,6 @@ class Machine: # Copy the file to the shared directory inside VM self.succeed(make_command(["mkdir", "-p", vm_shared_temp])) self.succeed(make_command(["cp", "-r", vm_src, vm_intermediate])) - self.succeed("sync") abs_target = out_dir / target_dir / vm_src.name abs_target.parent.mkdir(exist_ok=True, parents=True) # Copy the file from the shared directory outside VM @@ -628,8 +624,6 @@ class Machine: shutil.copytree(intermediate, abs_target) else: shutil.copy(intermediate, abs_target) - # Make sure the cleanup is synced into VM - self.succeed("sync") def dump_tty_contents(self, tty: str) -> None: """Debugging: Dump the contents of the TTY<n> diff --git a/nixpkgs/nixos/modules/config/networking.nix b/nixpkgs/nixos/modules/config/networking.nix index 03944de8249..4cb7d81c997 100644 --- a/nixpkgs/nixos/modules/config/networking.nix +++ b/nixpkgs/nixos/modules/config/networking.nix @@ -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. diff --git a/nixpkgs/nixos/modules/config/power-management.nix b/nixpkgs/nixos/modules/config/power-management.nix index 64cdf50f141..cc0ff732ffa 100644 --- a/nixpkgs/nixos/modules/config/power-management.nix +++ b/nixpkgs/nixos/modules/config/power-management.nix @@ -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} ''; diff --git a/nixpkgs/nixos/modules/config/resolvconf.nix b/nixpkgs/nixos/modules/config/resolvconf.nix index cc202bca6c4..cd0ed491383 100644 --- a/nixpkgs/nixos/modules/config/resolvconf.nix +++ b/nixpkgs/nixos/modules/config/resolvconf.nix @@ -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}' diff --git a/nixpkgs/nixos/modules/config/zram.nix b/nixpkgs/nixos/modules/config/zram.nix index 5d411c73a56..5e9870bf6b1 100644 --- a/nixpkgs/nixos/modules/config/zram.nix +++ b/nixpkgs/nixos/modules/config/zram.nix @@ -91,7 +91,7 @@ in }; algorithm = mkOption { - default = "lzo"; + default = "zstd"; example = "lz4"; type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str; description = '' diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix index 901c60befb6..4187c01d70e 100644 --- a/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix +++ b/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix @@ -68,7 +68,7 @@ in default = null; example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7"; description = '' - UUID for the main NixOS partition on the SD card. + UUID for the filesystem on the main NixOS partition on the SD card. ''; }; diff --git a/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix index 842976c3574..bfd8970d2b2 100644 --- a/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix +++ b/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix @@ -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"; } diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix index d1cbd6fbfdd..ccbee0a56cf 100644 --- a/nixpkgs/nixos/modules/module-list.nix +++ b/nixpkgs/nixos/modules/module-list.nix @@ -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 @@ -461,7 +462,9 @@ ./services/misc/lidarr.nix ./services/misc/mame.nix ./services/misc/mathics.nix + ./services/misc/matrix-appservice-discord.nix ./services/misc/matrix-synapse.nix + ./services/misc/mautrix-telegram.nix ./services/misc/mbpfan.nix ./services/misc/mediatomb.nix ./services/misc/mesos-master.nix @@ -605,6 +608,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 @@ -817,6 +821,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 @@ -829,6 +834,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 @@ -848,6 +854,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 diff --git a/nixpkgs/nixos/modules/programs/chromium.nix b/nixpkgs/nixos/modules/programs/chromium.nix index 16c063ebc89..3f042913619 100644 --- a/nixpkgs/nixos/modules/programs/chromium.nix +++ b/nixpkgs/nixos/modules/programs/chromium.nix @@ -69,11 +69,24 @@ in extraOpts = mkOption { type = types.attrs; description = '' - Extra chromium policy options, see - <link xlink:href="https://www.chromium.org/administrators/policy-list-3">https://www.chromium.org/administrators/policy-list-3</link> - for a list of avalible options + Extra chromium policy options. A list of available policies + can be found in the Chrome Enterprise documentation: + <link xlink:href="https://cloud.google.com/docs/chrome-enterprise/policies/">https://cloud.google.com/docs/chrome-enterprise/policies/</link> + Make sure the selected policy is supported on Linux and your browser version. ''; default = {}; + example = literalExample '' + { + "BrowserSignin" = 0; + "SyncDisabled" = true; + "PasswordManagerEnabled" = false; + "SpellcheckEnabled" = true; + "SpellcheckLanguage" = [ + "de" + "en-US" + ]; + } + ''; }; }; }; diff --git a/nixpkgs/nixos/modules/programs/shadow.nix b/nixpkgs/nixos/modules/programs/shadow.nix index fc352795c01..386ded9d98b 100644 --- a/nixpkgs/nixos/modules/programs/shadow.nix +++ b/nixpkgs/nixos/modules/programs/shadow.nix @@ -114,8 +114,9 @@ in newgrp.source = "${pkgs.shadow.out}/bin/newgrp"; newuidmap.source = "${pkgs.shadow.out}/bin/newuidmap"; newgidmap.source = "${pkgs.shadow.out}/bin/newgidmap"; - } // (if config.users.mutableUsers then { + } // lib.optionalAttrs config.users.mutableUsers { + chsh.source = "${pkgs.shadow.out}/bin/chsh"; passwd.source = "${pkgs.shadow.out}/bin/passwd"; - } else {}); + }; }; } diff --git a/nixpkgs/nixos/modules/programs/zsh/zsh.nix b/nixpkgs/nixos/modules/programs/zsh/zsh.nix index 930cc1987a3..049a315c762 100644 --- a/nixpkgs/nixos/modules/programs/zsh/zsh.nix +++ b/nixpkgs/nixos/modules/programs/zsh/zsh.nix @@ -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} diff --git a/nixpkgs/nixos/modules/services/databases/mysql.nix b/nixpkgs/nixos/modules/services/databases/mysql.nix index 44183788d93..51885881cf7 100644 --- a/nixpkgs/nixos/modules/services/databases/mysql.nix +++ b/nixpkgs/nixos/modules/services/databases/mysql.nix @@ -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; diff --git a/nixpkgs/nixos/modules/services/databases/rethinkdb.nix b/nixpkgs/nixos/modules/services/databases/rethinkdb.nix index f18fbaf5b06..c764d6c21c6 100644 --- a/nixpkgs/nixos/modules/services/databases/rethinkdb.nix +++ b/nixpkgs/nixos/modules/services/databases/rethinkdb.nix @@ -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; diff --git a/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix b/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix index 931bac58ace..f8fb73701af 100644 --- a/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix +++ b/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix @@ -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 = [ diff --git a/nixpkgs/nixos/modules/services/hardware/udev.nix b/nixpkgs/nixos/modules/services/hardware/udev.nix index 168056a475e..587b9b0234a 100644 --- a/nixpkgs/nixos/modules/services/hardware/udev.nix +++ b/nixpkgs/nixos/modules/services/hardware/udev.nix @@ -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" diff --git a/nixpkgs/nixos/modules/services/logging/logrotate.nix b/nixpkgs/nixos/modules/services/logging/logrotate.nix index fdd9f0f3e5c..565618b27a8 100644 --- a/nixpkgs/nixos/modules/services/logging/logrotate.nix +++ b/nixpkgs/nixos/modules/services/logging/logrotate.nix @@ -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 ''; }; }; diff --git a/nixpkgs/nixos/modules/services/misc/bazarr.nix b/nixpkgs/nixos/modules/services/misc/bazarr.nix new file mode 100644 index 00000000000..d3fd5b08cc8 --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/bazarr.nix @@ -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 = {}; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/misc/docker-registry.nix b/nixpkgs/nixos/modules/services/misc/docker-registry.nix index 89bac4f47d7..1c2e2cc5359 100644 --- a/nixpkgs/nixos/modules/services/misc/docker-registry.nix +++ b/nixpkgs/nixos/modules/services/misc/docker-registry.nix @@ -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; diff --git a/nixpkgs/nixos/modules/services/misc/freeswitch.nix b/nixpkgs/nixos/modules/services/misc/freeswitch.nix index 0de5ba42811..d27dbe220d3 100644 --- a/nixpkgs/nixos/modules/services/misc/freeswitch.nix +++ b/nixpkgs/nixos/modules/services/misc/freeswitch.nix @@ -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"; }; diff --git a/nixpkgs/nixos/modules/services/misc/gitlab.nix b/nixpkgs/nixos/modules/services/misc/gitlab.nix index 730166b04d2..7b2bbf89a44 100644 --- a/nixpkgs/nixos/modules/services/misc/gitlab.nix +++ b/nixpkgs/nixos/modules/services/misc/gitlab.nix @@ -129,7 +129,7 @@ let HOME = "${cfg.statePath}/home"; UNICORN_PATH = "${cfg.statePath}/"; GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/"; - SCHEMA = "${cfg.statePath}/db/schema.rb"; + SCHEMA = "${cfg.statePath}/db/structure.sql"; GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads"; GITLAB_LOG_PATH = "${cfg.statePath}/log"; GITLAB_REDIS_CONFIG_FILE = pkgs.writeText "redis.yml" (builtins.toJSON redisConfig); diff --git a/nixpkgs/nixos/modules/services/misc/matrix-appservice-discord.nix b/nixpkgs/nixos/modules/services/misc/matrix-appservice-discord.nix new file mode 100644 index 00000000000..49c41ff637a --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/matrix-appservice-discord.nix @@ -0,0 +1,162 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + dataDir = "/var/lib/matrix-appservice-discord"; + registrationFile = "${dataDir}/discord-registration.yaml"; + appDir = "${pkgs.matrix-appservice-discord}/lib/node_modules/matrix-appservice-discord"; + cfg = config.services.matrix-appservice-discord; + # TODO: switch to configGen.json once RFC42 is implemented + settingsFile = pkgs.writeText "matrix-appservice-discord-settings.json" (builtins.toJSON cfg.settings); + +in { + options = { + services.matrix-appservice-discord = { + enable = mkEnableOption "a bridge between Matrix and Discord"; + + settings = mkOption rec { + # TODO: switch to types.config.json as prescribed by RFC42 once it's implemented + type = types.attrs; + apply = recursiveUpdate default; + default = { + database = { + filename = "${dataDir}/discord.db"; + + # TODO: remove those old config keys once the following issues are solved: + # * https://github.com/Half-Shot/matrix-appservice-discord/issues/490 + # * https://github.com/Half-Shot/matrix-appservice-discord/issues/498 + userStorePath = "${dataDir}/user-store.db"; + roomStorePath = "${dataDir}/room-store.db"; + }; + + # empty values necessary for registration file generation + # actual values defined in environmentFile + auth = { + clientID = ""; + botToken = ""; + }; + }; + example = literalExample '' + { + bridge = { + domain = "public-domain.tld"; + homeserverUrl = "http://public-domain.tld:8008"; + }; + } + ''; + description = '' + <filename>config.yaml</filename> configuration as a Nix attribute set. + </para> + + <para> + Configuration options should match those described in + <link xlink:href="https://github.com/Half-Shot/matrix-appservice-discord/blob/master/config/config.sample.yaml"> + config.sample.yaml</link>. + </para> + + <para> + <option>config.bridge.domain</option> and <option>config.bridge.homeserverUrl</option> + should be set to match the public host name of the Matrix homeserver for webhooks and avatars to work. + </para> + + <para> + Secret tokens should be specified using <option>environmentFile</option> + instead of this world-readable attribute set. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing environment variables to be passed to the matrix-appservice-discord service, + in which secret tokens can be specified securely by defining values for + <literal>APPSERVICE_DISCORD_AUTH_CLIENT_I_D</literal> and + <literal>APPSERVICE_DISCORD_AUTH_BOT_TOKEN</literal>. + ''; + }; + + url = mkOption { + type = types.str; + default = "http://localhost:${toString cfg.port}"; + description = '' + The URL where the application service is listening for HS requests. + ''; + }; + + port = mkOption { + type = types.port; + default = 9005; # from https://github.com/Half-Shot/matrix-appservice-discord/blob/master/package.json#L11 + description = '' + Port number on which the bridge should listen for internal communication with the Matrix homeserver. + ''; + }; + + localpart = mkOption { + type = with types; nullOr str; + default = null; + description = '' + The user_id localpart to assign to the AS. + ''; + }; + + serviceDependencies = mkOption { + type = with types; listOf str; + default = optional config.services.matrix-synapse.enable "matrix-synapse.service"; + description = '' + List of Systemd services to require and wait for when starting the application service, + such as the Matrix homeserver if it's running on the same host. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.matrix-appservice-discord = { + description = "A bridge between Matrix and Discord."; + + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ] ++ cfg.serviceDependencies; + after = [ "network-online.target" ] ++ cfg.serviceDependencies; + + preStart = '' + if [ ! -f '${registrationFile}' ]; then + ${pkgs.matrix-appservice-discord}/bin/matrix-appservice-discord \ + --generate-registration \ + --url=${escapeShellArg cfg.url} \ + ${optionalString (cfg.localpart != null) "--localpart=${escapeShellArg cfg.localpart}"} \ + --config='${settingsFile}' \ + --file='${registrationFile}' + fi + ''; + + serviceConfig = { + Type = "simple"; + Restart = "always"; + + ProtectSystem = "strict"; + ProtectHome = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + + DynamicUser = true; + PrivateTmp = true; + WorkingDirectory = appDir; + StateDirectory = baseNameOf dataDir; + UMask = 0027; + EnvironmentFile = cfg.environmentFile; + + ExecStart = '' + ${pkgs.matrix-appservice-discord}/bin/matrix-appservice-discord \ + --file='${registrationFile}' \ + --config='${settingsFile}' \ + --port='${toString cfg.port}' + ''; + }; + }; + }; + + meta.maintainers = with maintainers; [ pacien ]; +} diff --git a/nixpkgs/nixos/modules/services/misc/mautrix-telegram.nix b/nixpkgs/nixos/modules/services/misc/mautrix-telegram.nix new file mode 100644 index 00000000000..78a42fbb574 --- /dev/null +++ b/nixpkgs/nixos/modules/services/misc/mautrix-telegram.nix @@ -0,0 +1,163 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + dataDir = "/var/lib/mautrix-telegram"; + registrationFile = "${dataDir}/telegram-registration.yaml"; + cfg = config.services.mautrix-telegram; + # TODO: switch to configGen.json once RFC42 is implemented + settingsFile = pkgs.writeText "mautrix-telegram-settings.json" (builtins.toJSON cfg.settings); + +in { + options = { + services.mautrix-telegram = { + enable = mkEnableOption "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge"; + + settings = mkOption rec { + # TODO: switch to types.config.json as prescribed by RFC42 once it's implemented + type = types.attrs; + apply = recursiveUpdate default; + default = { + appservice = rec { + database = "sqlite:///${dataDir}/mautrix-telegram.db"; + hostname = "0.0.0.0"; + port = 8080; + address = "http://localhost:${toString port}"; + }; + + bridge = { + permissions."*" = "relaybot"; + relaybot.whitelist = [ ]; + }; + + logging = { + version = 1; + + formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s"; + + handlers.console = { + class = "logging.StreamHandler"; + formatter = "precise"; + }; + + loggers = { + mau.level = "INFO"; + telethon.level = "INFO"; + + # prevent tokens from leaking in the logs: + # https://github.com/tulir/mautrix-telegram/issues/351 + aiohttp.level = "WARNING"; + }; + + # log to console/systemd instead of file + root = { + level = "INFO"; + handlers = [ "console" ]; + }; + }; + }; + example = literalExample '' + { + homeserver = { + address = "http://localhost:8008"; + domain = "public-domain.tld"; + }; + + appservice.public = { + prefix = "/public"; + external = "https://public-appservice-address/public"; + }; + + bridge.permissions = { + "example.com" = "full"; + "@admin:example.com" = "admin"; + }; + } + ''; + description = '' + <filename>config.yaml</filename> configuration as a Nix attribute set. + Configuration options should match those described in + <link xlink:href="https://github.com/tulir/mautrix-telegram/blob/master/example-config.yaml"> + example-config.yaml</link>. + </para> + + <para> + Secret tokens should be specified using <option>environmentFile</option> + instead of this world-readable attribute set. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing environment variables to be passed to the mautrix-telegram service, + in which secret tokens can be specified securely by defining values for + <literal>MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN</literal>, + <literal>MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN</literal>, + <literal>MAUTRIX_TELEGRAM_TELEGRAM_API_ID</literal>, + <literal>MAUTRIX_TELEGRAM_TELEGRAM_API_HASH</literal> and optionally + <literal>MAUTRIX_TELEGRAM_TELEGRAM_BOT_TOKEN</literal>. + ''; + }; + + serviceDependencies = mkOption { + type = with types; listOf str; + default = optional config.services.matrix-synapse.enable "matrix-synapse.service"; + description = '' + List of Systemd services to require and wait for when starting the application service. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.mautrix-telegram = { + description = "Mautrix-Telegram, a Matrix-Telegram hybrid puppeting/relaybot bridge."; + + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ] ++ cfg.serviceDependencies; + after = [ "network-online.target" ] ++ cfg.serviceDependencies; + + preStart = '' + # generate the appservice's registration file if absent + if [ ! -f '${registrationFile}' ]; then + ${pkgs.mautrix-telegram}/bin/mautrix-telegram \ + --generate-registration \ + --base-config='${pkgs.mautrix-telegram}/example-config.yaml' \ + --config='${settingsFile}' \ + --registration='${registrationFile}' + fi + + # run automatic database init and migration scripts + ${pkgs.mautrix-telegram.alembic}/bin/alembic -x config='${settingsFile}' upgrade head + ''; + + serviceConfig = { + Type = "simple"; + Restart = "always"; + + ProtectSystem = "strict"; + ProtectHome = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + + DynamicUser = true; + PrivateTmp = true; + WorkingDirectory = pkgs.mautrix-telegram; # necessary for the database migration scripts to be found + StateDirectory = baseNameOf dataDir; + UMask = 0027; + EnvironmentFile = cfg.environmentFile; + + ExecStart = '' + ${pkgs.mautrix-telegram}/bin/mautrix-telegram \ + --config='${settingsFile}' + ''; + }; + }; + }; + + meta.maintainers = with maintainers; [ pacien vskilet ]; +} diff --git a/nixpkgs/nixos/modules/services/misc/redmine.nix b/nixpkgs/nixos/modules/services/misc/redmine.nix index 1febdba0c8f..0e71cf92569 100644 --- a/nixpkgs/nixos/modules/services/misc/redmine.nix +++ b/nixpkgs/nixos/modules/services/misc/redmine.nix @@ -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 diff --git a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix index c0619211c2f..0507b739d49 100644 --- a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix +++ b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix @@ -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 ''; }; diff --git a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix index e48eb729103..28691e83827 100644 --- a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix +++ b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix @@ -55,6 +55,7 @@ in AmbientCapabilities = "CAP_NET_BIND_SERVICE"; DynamicUser = true; ExecStart = "${pkgs.dnscrypt-proxy2}/bin/dnscrypt-proxy -config ${cfg.configFile}"; + Restart = "always"; }; }; }; diff --git a/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix b/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix index e53fb7a1578..b9333cd19a2 100644 --- a/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix +++ b/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix @@ -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 ]; diff --git a/nixpkgs/nixos/modules/services/networking/ergo.nix b/nixpkgs/nixos/modules/services/networking/ergo.nix new file mode 100644 index 00000000000..c52de30dc36 --- /dev/null +++ b/nixpkgs/nixos/modules/services/networking/ergo.nix @@ -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} = {}; + + }; +} diff --git a/nixpkgs/nixos/modules/services/networking/haproxy.nix b/nixpkgs/nixos/modules/services/networking/haproxy.nix index 4678829986c..e9d72b35499 100644 --- a/nixpkgs/nixos/modules/services/networking/haproxy.nix +++ b/nixpkgs/nixos/modules/services/networking/haproxy.nix @@ -56,6 +56,9 @@ with lib; message = "You must provide services.haproxy.config."; }]; + # configuration file indirection is needed to support reloading + environment.etc."haproxy.cfg".source = haproxyCfg; + systemd.services.haproxy = { description = "HAProxy"; after = [ "network.target" ]; @@ -64,11 +67,32 @@ with lib; User = cfg.user; Group = cfg.group; Type = "notify"; - # when running the config test, don't be quiet so we can see what goes wrong - ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}"; - ExecStart = "${pkgs.haproxy}/sbin/haproxy -Ws -f ${haproxyCfg}"; - Restart = "on-failure"; + ExecStartPre = [ + # when the master process receives USR2, it reloads itself using exec(argv[0]), + # so we create a symlink there and update it before reloading + "${pkgs.coreutils}/bin/ln -sf ${pkgs.haproxy}/sbin/haproxy /run/haproxy/haproxy" + # when running the config test, don't be quiet so we can see what goes wrong + "/run/haproxy/haproxy -c -f ${haproxyCfg}" + ]; + ExecStart = "/run/haproxy/haproxy -Ws -f /etc/haproxy.cfg -p /run/haproxy/haproxy.pid"; + # support reloading + ExecReload = [ + "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}" + "${pkgs.coreutils}/bin/ln -sf ${pkgs.haproxy}/sbin/haproxy /run/haproxy/haproxy" + "${pkgs.coreutils}/bin/kill -USR2 $MAINPID" + ]; + KillMode = "mixed"; + SuccessExitStatus = "143"; + Restart = "always"; RuntimeDirectory = "haproxy"; + # upstream hardening options + NoNewPrivileges = true; + ProtectHome = true; + ProtectSystem = "strict"; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync"; # needed in case we bind to port < 1024 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; }; diff --git a/nixpkgs/nixos/modules/services/networking/networkmanager.nix b/nixpkgs/nixos/modules/services/networking/networkmanager.nix index 6f24141b33c..cc789897b29 100644 --- a/nixpkgs/nixos/modules/services/networking/networkmanager.nix +++ b/nixpkgs/nixos/modules/services/networking/networkmanager.nix @@ -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 ]; diff --git a/nixpkgs/nixos/modules/services/networking/nsd.nix b/nixpkgs/nixos/modules/services/networking/nsd.nix index 429580e5c6c..6e3eed0c557 100644 --- a/nixpkgs/nixos/modules/services/networking/nsd.nix +++ b/nixpkgs/nixos/modules/services/networking/nsd.nix @@ -252,7 +252,7 @@ let Use imports or pkgs.lib.readFile if you don't want this data in your config file. ''; }; - + dnssec = mkEnableOption "DNSSEC"; dnssecPolicy = { @@ -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 ''; }; diff --git a/nixpkgs/nixos/modules/services/networking/v2ray.nix b/nixpkgs/nixos/modules/services/networking/v2ray.nix index a1774cdffbb..6a924a16449 100644 --- a/nixpkgs/nixos/modules/services/networking/v2ray.nix +++ b/nixpkgs/nixos/modules/services/networking/v2ray.nix @@ -58,7 +58,13 @@ with lib; cfg = config.services.v2ray; configFile = if cfg.configFile != null then cfg.configFile - else (pkgs.writeText "v2ray.json" (builtins.toJSON cfg.config)); + else pkgs.writeTextFile { + name = "v2ray.json"; + text = builtins.toJSON cfg.config; + checkPhase = '' + ${pkgs.v2ray}/bin/v2ray -test -config $out + ''; + }; in mkIf cfg.enable { assertions = [ diff --git a/nixpkgs/nixos/modules/services/networking/vsftpd.nix b/nixpkgs/nixos/modules/services/networking/vsftpd.nix index b3e20184423..c57994533c1 100644 --- a/nixpkgs/nixos/modules/services/networking/vsftpd.nix +++ b/nixpkgs/nixos/modules/services/networking/vsftpd.nix @@ -116,7 +116,8 @@ let userlist_file=${cfg.userlistFile} ''} background=YES - listen=YES + listen=NO + listen_ipv6=YES nopriv_user=vsftpd secure_chroot_dir=/var/empty ${optionalString (cfg.localRoot != null) '' diff --git a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix index de0f11595a9..a7dea95056a 100644 --- a/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixpkgs/nixos/modules/services/networking/wpa_supplicant.nix @@ -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" ''; }; diff --git a/nixpkgs/nixos/modules/services/networking/yggdrasil.nix b/nixpkgs/nixos/modules/services/networking/yggdrasil.nix index ecd1406b483..0fe9a200a1b 100644 --- a/nixpkgs/nixos/modules/services/networking/yggdrasil.nix +++ b/nixpkgs/nixos/modules/services/networking/yggdrasil.nix @@ -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 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 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 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 ]; } diff --git a/nixpkgs/nixos/modules/services/security/fprintd.nix b/nixpkgs/nixos/modules/services/security/fprintd.nix index 8ece1ca1901..cbac4ef05b8 100644 --- a/nixpkgs/nixos/modules/services/security/fprintd.nix +++ b/nixpkgs/nixos/modules/services/security/fprintd.nix @@ -29,7 +29,6 @@ in type = types.package; default = pkgs.fprintd; defaultText = "pkgs.fprintd"; - example = "pkgs.fprintd-thinkpad"; description = '' fprintd package to use. ''; diff --git a/nixpkgs/nixos/modules/services/security/usbguard.nix b/nixpkgs/nixos/modules/services/security/usbguard.nix index 4ced5acd9bd..f4118eb87fc 100644 --- a/nixpkgs/nixos/modules/services/security/usbguard.nix +++ b/nixpkgs/nixos/modules/services/security/usbguard.nix @@ -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"; }; }; }; diff --git a/nixpkgs/nixos/modules/services/system/earlyoom.nix b/nixpkgs/nixos/modules/services/system/earlyoom.nix index 39d1bf274bd..c6a001d30ee 100644 --- a/nixpkgs/nixos/modules/services/system/earlyoom.nix +++ b/nixpkgs/nixos/modules/services/system/earlyoom.nix @@ -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; }; } diff --git a/nixpkgs/nixos/modules/services/system/nscd.conf b/nixpkgs/nixos/modules/services/system/nscd.conf index 2b7523a7346..722b883ba42 100644 --- a/nixpkgs/nixos/modules/services/system/nscd.conf +++ b/nixpkgs/nixos/modules/services/system/nscd.conf @@ -24,7 +24,7 @@ negative-time-to-live netgroup 0 shared netgroup yes enable-cache hosts yes -positive-time-to-live hosts 600 +positive-time-to-live hosts 0 negative-time-to-live hosts 0 shared hosts yes diff --git a/nixpkgs/nixos/modules/services/torrent/rtorrent.nix b/nixpkgs/nixos/modules/services/torrent/rtorrent.nix new file mode 100644 index 00000000000..be57c03b172 --- /dev/null +++ b/nixpkgs/nixos/modules/services/torrent/rtorrent.nix @@ -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} -" ]; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/torrent/transmission.nix b/nixpkgs/nixos/modules/services/torrent/transmission.nix index fd28b94f7be..e7f5aaed844 100644 --- a/nixpkgs/nixos/modules/services/torrent/transmission.nix +++ b/nixpkgs/nixos/modules/services/torrent/transmission.nix @@ -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"; diff --git a/nixpkgs/nixos/modules/services/web-apps/engelsystem.nix b/nixpkgs/nixos/modules/services/web-apps/engelsystem.nix new file mode 100644 index 00000000000..899582a2030 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/engelsystem.nix @@ -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 = { }; + }; +} diff --git a/nixpkgs/nixos/modules/services/web-apps/sogo.nix b/nixpkgs/nixos/modules/services/web-apps/sogo.nix new file mode 100644 index 00000000000..5f30124dd68 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/sogo.nix @@ -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"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix index 312d2b0a21a..8a015bb3556 100644 --- a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix @@ -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 diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/cde.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/cde.nix index c1b6d3bf064..2d9504fb5f1 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/cde.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/cde.nix @@ -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; diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix index ea6aac9f6c9..5d3a84d7139 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix @@ -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 ]; diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 1690a7d51a8..3a7ab64510b 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -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 - - exec ${e.enlightenment}/bin/enlightenment_start - ''; - }]; - - security.wrappers = (import "${e.enlightenment}/e-wrappers.nix").security.wrappers; + fi + ''; + + # 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; diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix index 2224bcd5a2a..419f5055d8b 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix @@ -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 ++ diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix deleted file mode 100644 index 1c04104df41..00000000000 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix +++ /dev/null @@ -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 ]; -} diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix index 60ef0159ff1..6d48b899d23 100644 --- a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -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 diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix index 2a7a19e7695..aa6a5ec42be 100644 --- a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix +++ b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix @@ -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 ''; diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix index 4224c557ed6..2f42271da87 100644 --- a/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix @@ -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 ''} diff --git a/nixpkgs/nixos/modules/services/x11/xautolock.nix b/nixpkgs/nixos/modules/services/x11/xautolock.nix index 3e03131ca11..5ce08fce7c4 100644 --- a/nixpkgs/nixos/modules/services/x11/xautolock.nix +++ b/nixpkgs/nixos/modules/services/x11/xautolock.nix @@ -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 = '' diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix index 9720d90217c..d895c58bab0 100644 --- a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix @@ -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 diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces.nix b/nixpkgs/nixos/modules/tasks/network-interfaces.nix index 44677d417ea..a2811104944 100644 --- a/nixpkgs/nixos/modules/tasks/network-interfaces.nix +++ b/nixpkgs/nixos/modules/tasks/network-interfaces.nix @@ -283,7 +283,7 @@ let default = false; type = types.bool; description = '' - Turn on proxy_arp for this device (and proxy_ndp for ipv6). + Turn on proxy_arp for this device. This is mainly useful for creating pseudo-bridges between a real interface and a virtual network such as VPN or a virtual machine for interfaces that don't support real bridging (most wlan interfaces). @@ -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. ''; }; @@ -1055,11 +1065,11 @@ in optionalString hasBonds "options bonding max_bonds=0"; boot.kernel.sysctl = { + "net.ipv4.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces); "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6); "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6); - "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces); } // listToAttrs (flip concatMap (filter (i: i.proxyARP) interfaces) - (i: forEach [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${replaceChars ["."] ["/"] i.name}.proxy_arp" true))) + (i: [(nameValuePair "net.ipv4.conf.${replaceChars ["."] ["/"] i.name}.proxy_arp" true)])) // listToAttrs (forEach interfaces (i: let opt = i.tempAddress; diff --git a/nixpkgs/nixos/modules/virtualisation/azure-agent.nix b/nixpkgs/nixos/modules/virtualisation/azure-agent.nix index 036b1036f92..e85482af839 100644 --- a/nixpkgs/nixos/modules/virtualisation/azure-agent.nix +++ b/nixpkgs/nixos/modules/virtualisation/azure-agent.nix @@ -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 diff --git a/nixpkgs/nixos/modules/virtualisation/cri-o.nix b/nixpkgs/nixos/modules/virtualisation/cri-o.nix index 2af4214302d..f267c97b178 100644 --- a/nixpkgs/nixos/modules/virtualisation/cri-o.nix +++ b/nixpkgs/nixos/modules/virtualisation/cri-o.nix @@ -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"; diff --git a/nixpkgs/nixos/modules/virtualisation/hyperv-image.nix b/nixpkgs/nixos/modules/virtualisation/hyperv-image.nix index be2f12b7d01..fabc9113dfc 100644 --- a/nixpkgs/nixos/modules/virtualisation/hyperv-image.nix +++ b/nixpkgs/nixos/modules/virtualisation/hyperv-image.nix @@ -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; diff --git a/nixpkgs/nixos/modules/virtualisation/kvmgt.nix b/nixpkgs/nixos/modules/virtualisation/kvmgt.nix index 0902d2dc2cb..e08ad344628 100644 --- a/nixpkgs/nixos/modules/virtualisation/kvmgt.nix +++ b/nixpkgs/nixos/modules/virtualisation/kvmgt.nix @@ -9,8 +9,8 @@ let vgpuOptions = { uuid = mkOption { - type = types.str; - description = "UUID of VGPU device. You can generate one with <package>libossp_uuid</package>."; + type = with types; listOf str; + description = "UUID(s) of VGPU device. You can generate one with <package>libossp_uuid</package>."; }; }; @@ -36,7 +36,7 @@ in { and find info about device via <command>cat /sys/bus/pci/devices/*/mdev_supported_types/i915-GVTg_V5_4/description</command> ''; example = { - i915-GVTg_V5_8.uuid = "a297db4a-f4c2-11e6-90f6-d3b88d6c9525"; + i915-GVTg_V5_8.uuid = [ "a297db4a-f4c2-11e6-90f6-d3b88d6c9525" ]; }; }; }; @@ -51,31 +51,35 @@ in { boot.kernelModules = [ "kvmgt" ]; boot.kernelParams = [ "i915.enable_gvt=1" ]; - systemd.paths = mapAttrs' (name: value: - nameValuePair "kvmgt-${name}" { - description = "KVMGT VGPU ${name} path"; - wantedBy = [ "multi-user.target" ]; - pathConfig = { - PathExists = "/sys/bus/pci/devices/${cfg.device}/mdev_supported_types/${name}/create"; - }; - } - ) cfg.vgpus; - services.udev.extraRules = '' SUBSYSTEM=="vfio", OWNER="root", GROUP="kvm" ''; - systemd.services = mapAttrs' (name: value: - nameValuePair "kvmgt-${name}" { - description = "KVMGT VGPU ${name}"; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${pkgs.runtimeShell} -c 'echo ${value.uuid} > /sys/bus/pci/devices/${cfg.device}/mdev_supported_types/${name}/create'"; - ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/bus/pci/devices/${cfg.device}/${value.uuid}/remove'"; - }; - } - ) cfg.vgpus; + systemd = let + vgpus = listToAttrs (flatten (mapAttrsToList + (mdev: opt: map (id: nameValuePair "kvmgt-${id}" { inherit mdev; uuid = id; }) opt.uuid) + cfg.vgpus)); + in { + paths = mapAttrs (_: opt: + { + description = "KVMGT VGPU ${opt.uuid} path"; + wantedBy = [ "multi-user.target" ]; + pathConfig = { + PathExists = "/sys/bus/pci/devices/${cfg.device}/mdev_supported_types/${opt.mdev}/create"; + }; + }) vgpus; + + services = mapAttrs (_: opt: + { + description = "KVMGT VGPU ${opt.uuid}"; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.runtimeShell} -c 'echo ${opt.uuid} > /sys/bus/pci/devices/${cfg.device}/mdev_supported_types/${opt.mdev}/create'"; + ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/bus/pci/devices/${cfg.device}/${opt.uuid}/remove'"; + }; + }) vgpus; + }; }; meta.maintainers = with maintainers; [ gnidorah ]; diff --git a/nixpkgs/nixos/modules/virtualisation/libvirtd.nix b/nixpkgs/nixos/modules/virtualisation/libvirtd.nix index f89e5d544b2..43b5fcfa8fa 100644 --- a/nixpkgs/nixos/modules/virtualisation/libvirtd.nix +++ b/nixpkgs/nixos/modules/virtualisation/libvirtd.nix @@ -114,7 +114,7 @@ in { Specifies the action to be done to / on the guests when the host boots. The "start" option starts all guests that were running prior to shutdown regardless of their autostart settings. The "ignore" option will not - start the formally running guest on boot. However, any guest marked as + start the formerly running guest on boot. However, any guest marked as autostart will still be automatically started by libvirtd. ''; }; diff --git a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix index ac86330c098..4592ffcfe4d 100644 --- a/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix @@ -576,7 +576,7 @@ in "/tmp/xchg" = { device = "xchg"; fsType = "9p"; - options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ]; + options = [ "trans=virtio" "version=9p2000.L" ]; neededForBoot = true; }; "/tmp/shared" = diff --git a/nixpkgs/nixos/modules/virtualisation/vmware-image.nix b/nixpkgs/nixos/modules/virtualisation/vmware-image.nix new file mode 100644 index 00000000000..9da9e145f7a --- /dev/null +++ b/nixpkgs/nixos/modules/virtualisation/vmware-image.nix @@ -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; + }; +} diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix index 0acded892c7..796c626f3dd 100644 --- a/nixpkgs/nixos/tests/all-tests.nix +++ b/nixpkgs/nixos/tests/all-tests.nix @@ -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 {}; @@ -335,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 {}; diff --git a/nixpkgs/nixos/tests/bazarr.nix b/nixpkgs/nixos/tests/bazarr.nix new file mode 100644 index 00000000000..b8cd8ef38b4 --- /dev/null +++ b/nixpkgs/nixos/tests/bazarr.nix @@ -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}/") + ''; +}) diff --git a/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix b/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix new file mode 100644 index 00000000000..1dc925f4de7 --- /dev/null +++ b/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix @@ -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") + ''; +}) + diff --git a/nixpkgs/nixos/tests/dnscrypt-wrapper/public.key b/nixpkgs/nixos/tests/dnscrypt-wrapper/public.key new file mode 100644 index 00000000000..80232b97f52 --- /dev/null +++ b/nixpkgs/nixos/tests/dnscrypt-wrapper/public.key @@ -0,0 +1 @@ +A:B
;o4S
@]
\ No newline at end of file diff --git a/nixpkgs/nixos/tests/dnscrypt-wrapper/secret.key b/nixpkgs/nixos/tests/dnscrypt-wrapper/secret.key new file mode 100644 index 00000000000..01fbf8e08b7 --- /dev/null +++ b/nixpkgs/nixos/tests/dnscrypt-wrapper/secret.key @@ -0,0 +1 @@ +G>Ʃ>(J=lA:B
;o4S
@]
\ No newline at end of file diff --git a/nixpkgs/nixos/tests/engelsystem.nix b/nixpkgs/nixos/tests/engelsystem.nix new file mode 100644 index 00000000000..39c10718093 --- /dev/null +++ b/nixpkgs/nixos/tests/engelsystem.nix @@ -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)\"" + ) + ''; + }) diff --git a/nixpkgs/nixos/tests/enlightenment.nix b/nixpkgs/nixos/tests/enlightenment.nix index 5fa8d765dd1..0132b98b1cb 100644 --- a/nixpkgs/nixos/tests/enlightenment.nix +++ b/nixpkgs/nixos/tests/enlightenment.nix @@ -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.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.wait_for_text("English") # Keyboard (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 diff --git a/nixpkgs/nixos/tests/ergo.nix b/nixpkgs/nixos/tests/ergo.nix new file mode 100644 index 00000000000..8cdbbf62a95 --- /dev/null +++ b/nixpkgs/nixos/tests/ergo.nix @@ -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") + ''; +}) diff --git a/nixpkgs/nixos/tests/haproxy.nix b/nixpkgs/nixos/tests/haproxy.nix index 79f34b07faf..ffb77c052a2 100644 --- a/nixpkgs/nixos/tests/haproxy.nix +++ b/nixpkgs/nixos/tests/haproxy.nix @@ -43,5 +43,13 @@ import ./make-test-python.nix ({ pkgs, ...}: { assert "haproxy_process_pool_allocated_bytes" in machine.succeed( "curl -k http://localhost:80/metrics" ) + + with subtest("reload"): + machine.succeed("systemctl reload haproxy") + # wait some time to ensure the following request hits the reloaded haproxy + machine.sleep(5) + assert "We are all good!" in machine.succeed( + "curl -k http://localhost:80/index.txt" + ) ''; }) diff --git a/nixpkgs/nixos/tests/home-assistant.nix b/nixpkgs/nixos/tests/home-assistant.nix index 80dca43f1f3..3365e74ba83 100644 --- a/nixpkgs/nixos/tests/home-assistant.nix +++ b/nixpkgs/nixos/tests/home-assistant.nix @@ -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/" ) diff --git a/nixpkgs/nixos/tests/hostname.nix b/nixpkgs/nixos/tests/hostname.nix new file mode 100644 index 00000000000..3b87303d73e --- /dev/null +++ b/nixpkgs/nixos/tests/hostname.nix @@ -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"; +} diff --git a/nixpkgs/nixos/tests/nextcloud/basic.nix b/nixpkgs/nixos/tests/nextcloud/basic.nix index 92ac5c46e8f..9cbecf01f57 100644 --- a/nixpkgs/nixos/tests/nextcloud/basic.nix +++ b/nixpkgs/nixos/tests/nextcloud/basic.nix @@ -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") ''; }) diff --git a/nixpkgs/nixos/tests/podman.nix b/nixpkgs/nixos/tests/podman.nix index 283db71d9a4..9134a68ff38 100644 --- a/nixpkgs/nixos/tests/podman.nix +++ b/nixpkgs/nixos/tests/podman.nix @@ -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 --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 -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" + "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")) ''; } ) diff --git a/nixpkgs/nixos/tests/sogo.nix b/nixpkgs/nixos/tests/sogo.nix new file mode 100644 index 00000000000..016331a9eed --- /dev/null +++ b/nixpkgs/nixos/tests/sogo.nix @@ -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") + ''; +}) diff --git a/nixpkgs/nixos/tests/web-servers/unit-php.nix b/nixpkgs/nixos/tests/web-servers/unit-php.nix index c6327a1f825..2a0a5bdaa5d 100644 --- a/nixpkgs/nixos/tests/web-servers/unit-php.nix +++ b/nixpkgs/nixos/tests/web-servers/unit-php.nix @@ -23,7 +23,10 @@ in { "user": "testuser", "group": "testgroup", "root": "${testdir}/www", - "index": "info.php" + "index": "info.php", + "options": { + "file": "${pkgs.unit.usedPhp74}/lib/php.ini" + } } } } @@ -42,6 +45,13 @@ in { }; testScript = '' machine.wait_for_unit("unit.service") - assert "PHP Version ${pkgs.php74.version}" in machine.succeed("curl -vvv -s http://127.0.0.1:9074/") + + # Check so we get an evaluated PHP back + response = machine.succeed("curl -vvv -s http://127.0.0.1:9074/") + assert "PHP Version ${pkgs.unit.usedPhp74.version}" in response, "PHP version not detected" + + # Check so we have database and some other extensions loaded + for ext in ["json", "opcache", "pdo_mysql", "pdo_pgsql", "pdo_sqlite"]: + assert ext in response, f"Missing {ext} extension" ''; }) diff --git a/nixpkgs/nixos/tests/wireguard/basic.nix b/nixpkgs/nixos/tests/wireguard/basic.nix new file mode 100644 index 00000000000..25d706ae2e5 --- /dev/null +++ b/nixpkgs/nixos/tests/wireguard/basic.nix @@ -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") + ''; + } +) diff --git a/nixpkgs/nixos/tests/wireguard/default.nix b/nixpkgs/nixos/tests/wireguard/default.nix index e3bc31c600f..dedb321ff2e 100644 --- a/nixpkgs/nixos/tests/wireguard/default.nix +++ b/nixpkgs/nixos/tests/wireguard/default.nix @@ -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 ]; - }; - - 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; - - 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 = { - 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") - ''; - } +{ system ? builtins.currentSystem +, config ? { } +, pkgs ? import ../../.. { inherit system config; } +, kernelVersionsToTest ? [ "5.4" "latest" ] +}: + +with pkgs.lib; + +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 + +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'}"; }) + ) + ) ) diff --git a/nixpkgs/nixos/tests/wireguard/generated.nix b/nixpkgs/nixos/tests/wireguard/generated.nix index a29afd2d466..cdf15483265 100644 --- a/nixpkgs/nixos/tests/wireguard/generated.nix +++ b/nixpkgs/nixos/tests/wireguard/generated.nix @@ -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" ]; diff --git a/nixpkgs/nixos/tests/wireguard/namespaces.nix b/nixpkgs/nixos/tests/wireguard/namespaces.nix index c8a4e3bb52a..c47175ceafc 100644 --- a/nixpkgs/nixos/tests/wireguard/namespaces.nix +++ b/nixpkgs/nixos/tests/wireguard/namespaces.nix @@ -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} diff --git a/nixpkgs/nixos/tests/wireguard/wg-quick.nix b/nixpkgs/nixos/tests/wireguard/wg-quick.nix index 7354dd01a34..5472d21cd1e 100644 --- a/nixpkgs/nixos/tests/wireguard/wg-quick.nix +++ b/nixpkgs/nixos/tests/wireguard/wg-quick.nix @@ -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; diff --git a/nixpkgs/nixos/tests/yggdrasil.nix b/nixpkgs/nixos/tests/yggdrasil.nix index 468fcf67127..9ceb7974733 100644 --- a/nixpkgs/nixos/tests/yggdrasil.nix +++ b/nixpkgs/nixos/tests/yggdrasil.nix @@ -85,6 +85,7 @@ in import ./make-test-python.nix ({ pkgs, ...} : { MulticastInterfaces = [ "eth1" ]; LinkLocalTCPPort = 43210; }; + persistentKeys = true; }; }; }; |