diff options
Diffstat (limited to 'nixos')
35 files changed, 800 insertions, 186 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 1d24553b08db..5d2ffd262e04 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/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> @@ -418,6 +432,26 @@ 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> </itemizedlist> </section> </section> diff --git a/nixos/modules/config/power-management.nix b/nixos/modules/config/power-management.nix index 64cdf50f1413..cc0ff732ffa5 100644 --- a/nixos/modules/config/power-management.nix +++ b/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/nixos/modules/config/resolvconf.nix b/nixos/modules/config/resolvconf.nix index cc202bca6c4e..cd0ed491383c 100644 --- a/nixos/modules/config/resolvconf.nix +++ b/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/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix index 5d411c73a560..5e9870bf6b1c 100644 --- a/nixos/modules/config/zram.nix +++ b/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/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 89677970dd9a..d5285cfabd78 100644 --- a/nixos/modules/module-list.nix +++ b/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 @@ -847,6 +848,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/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix index 930cc1987a33..049a315c7622 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/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/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index 168056a475e5..587b9b0234aa 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/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/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix index fdd9f0f3e5c2..565618b27a87 100644 --- a/nixos/modules/services/logging/logrotate.nix +++ b/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/nixos/modules/services/misc/bazarr.nix b/nixos/modules/services/misc/bazarr.nix new file mode 100644 index 000000000000..d3fd5b08cc84 --- /dev/null +++ b/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/nixos/modules/services/misc/docker-registry.nix b/nixos/modules/services/misc/docker-registry.nix index 89bac4f47d73..1c2e2cc53590 100644 --- a/nixos/modules/services/misc/docker-registry.nix +++ b/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/nixos/modules/services/misc/freeswitch.nix b/nixos/modules/services/misc/freeswitch.nix index 0de5ba428110..d27dbe220d3c 100644 --- a/nixos/modules/services/misc/freeswitch.nix +++ b/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/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index c0619211c2fe..0507b739d499 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/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/nixos/modules/services/networking/dnscrypt-proxy2.nix b/nixos/modules/services/networking/dnscrypt-proxy2.nix index e48eb729103b..28691e838277 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy2.nix +++ b/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/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix index 429580e5c6c4..6e3eed0c5570 100644 --- a/nixos/modules/services/networking/nsd.nix +++ b/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/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index de0f11595a94..a7dea95056a0 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/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/nixos/modules/services/networking/yggdrasil.nix b/nixos/modules/services/networking/yggdrasil.nix index ecd1406b4832..0fe9a200a1b6 100644 --- a/nixos/modules/services/networking/yggdrasil.nix +++ b/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/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix index fd28b94f7be3..e7f5aaed844e 100644 --- a/nixos/modules/services/torrent/transmission.nix +++ b/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/nixos/modules/services/web-apps/sogo.nix b/nixos/modules/services/web-apps/sogo.nix new file mode 100644 index 000000000000..5f30124dd68a --- /dev/null +++ b/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/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix index b92e34498949..2ea9537b93de 100644 --- a/nixos/modules/services/web-apps/tt-rss.nix +++ b/nixos/modules/services/web-apps/tt-rss.nix @@ -631,9 +631,12 @@ let serviceConfig = { User = "${cfg.user}"; Group = "tt_rss"; - ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon"; + ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon --quiet"; StandardOutput = "syslog"; StandardError = "syslog"; + Restart = "on-failure"; + RestartSec = "60"; + SyslogIdentifier = "tt-rss"; }; wantedBy = [ "multi-user.target" ]; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 312d2b0a21a7..8a015bb3556c 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/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/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index ea6aac9f6c92..5d3a84d71399 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/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/nixos/modules/services/x11/desktop-managers/maxx.nix b/nixos/modules/services/x11/desktop-managers/maxx.nix deleted file mode 100644 index 1c04104df41e..000000000000 --- a/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/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 2a7a19e7695a..aa6a5ec42be8 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/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/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 4224c557ed63..2f42271da872 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/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/nixos/modules/services/x11/xautolock.nix b/nixos/modules/services/x11/xautolock.nix index 3e03131ca114..5ce08fce7c43 100644 --- a/nixos/modules/services/x11/xautolock.nix +++ b/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/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 9720d90217c6..d895c58bab03 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/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/nixos/modules/virtualisation/azure-agent.nix b/nixos/modules/virtualisation/azure-agent.nix index 036b1036f92a..e85482af8392 100644 --- a/nixos/modules/virtualisation/azure-agent.nix +++ b/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/nixos/modules/virtualisation/hyperv-image.nix b/nixos/modules/virtualisation/hyperv-image.nix index be2f12b7d014..fabc9113dfc4 100644 --- a/nixos/modules/virtualisation/hyperv-image.nix +++ b/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/nixos/modules/virtualisation/vmware-image.nix b/nixos/modules/virtualisation/vmware-image.nix new file mode 100644 index 000000000000..9da9e145f7a9 --- /dev/null +++ b/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/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 0acded892c7a..af619ac99a32 100644 --- a/nixos/tests/all-tests.nix +++ b/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 {}; @@ -292,6 +293,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 {}; diff --git a/nixos/tests/bazarr.nix b/nixos/tests/bazarr.nix new file mode 100644 index 000000000000..b8cd8ef38b42 --- /dev/null +++ b/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/nixos/tests/home-assistant.nix b/nixos/tests/home-assistant.nix index 80dca43f1f3d..3365e74ba838 100644 --- a/nixos/tests/home-assistant.nix +++ b/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/nixos/tests/podman.nix b/nixos/tests/podman.nix index 283db71d9a49..9134a68ff386 100644 --- a/nixos/tests/podman.nix +++ b/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/nixos/tests/sogo.nix b/nixos/tests/sogo.nix new file mode 100644 index 000000000000..016331a9eed6 --- /dev/null +++ b/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/nixos/tests/yggdrasil.nix b/nixos/tests/yggdrasil.nix index 468fcf671274..9ceb79747339 100644 --- a/nixos/tests/yggdrasil.nix +++ b/nixos/tests/yggdrasil.nix @@ -85,6 +85,7 @@ in import ./make-test-python.nix ({ pkgs, ...} : { MulticastInterfaces = [ "eth1" ]; LinkLocalTCPPort = 43210; }; + persistentKeys = true; }; }; }; |