about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services')
-rw-r--r--nixpkgs/nixos/modules/services/backup/znapzend.nix6
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/default.nix7
-rw-r--r--nixpkgs/nixos/modules/services/databases/openldap.nix33
-rw-r--r--nixpkgs/nixos/modules/services/desktops/deepin/dde-daemon.nix41
-rw-r--r--nixpkgs/nixos/modules/services/desktops/deepin/deepin-menu.nix29
-rw-r--r--nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix118
-rw-r--r--nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix5
-rw-r--r--nixpkgs/nixos/modules/services/logging/journalwatch.nix42
-rw-r--r--nixpkgs/nixos/modules/services/misc/emby.nix76
-rw-r--r--nixpkgs/nixos/modules/services/misc/ethminer.nix115
-rw-r--r--nixpkgs/nixos/modules/services/misc/gitea.nix15
-rw-r--r--nixpkgs/nixos/modules/services/misc/jellyfin.nix60
-rw-r--r--nixpkgs/nixos/modules/services/misc/nix-daemon.nix24
-rw-r--r--nixpkgs/nixos/modules/services/misc/nzbget.nix96
-rw-r--r--nixpkgs/nixos/modules/services/misc/packagekit.nix51
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/grafana-reporter.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/grafana.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/ejabberd.nix28
-rw-r--r--nixpkgs/nixos/modules/services/networking/hostapd.nix8
-rw-r--r--nixpkgs/nixos/modules/services/networking/softether.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/zeronet.nix13
-rw-r--r--nixpkgs/nixos/modules/services/networking/znc/default.nix4
-rw-r--r--nixpkgs/nixos/modules/services/security/sks.nix24
-rw-r--r--nixpkgs/nixos/modules/services/security/tor.nix11
-rw-r--r--nixpkgs/nixos/modules/services/system/earlyoom.nix15
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/documize.nix171
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/nginx/default.nix4
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix2
-rw-r--r--nixpkgs/nixos/modules/services/x11/window-managers/i3.nix5
29 files changed, 659 insertions, 350 deletions
diff --git a/nixpkgs/nixos/modules/services/backup/znapzend.nix b/nixpkgs/nixos/modules/services/backup/znapzend.nix
index fc8a424190f7..11b6215794ec 100644
--- a/nixpkgs/nixos/modules/services/backup/znapzend.nix
+++ b/nixpkgs/nixos/modules/services/backup/znapzend.nix
@@ -382,8 +382,10 @@ in
             | xargs -I{} ${pkgs.znapzend}/bin/znapzendzetup delete "{}"
         '' + concatStringsSep "\n" (mapAttrsToList (dataset: config: ''
           echo Importing znapzend zetup ${config} for dataset ${dataset}
-          ${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config}
-        '') files);
+          ${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config} &
+        '') files) + ''
+          wait
+        '';
 
         serviceConfig = {
           ExecStart = let
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/default.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/default.nix
index 192c893f8a16..5e46bfc4240f 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/default.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/default.nix
@@ -273,11 +273,10 @@ in {
         wantedBy = [ "kube-control-plane-online.target" ];
         after = [ "kube-scheduler.service" "kube-controller-manager.service" ];
         before = [ "kube-control-plane-online.target" ];
-        environment.KUBECONFIG = cfg.lib.mkKubeConfig "default" cfg.kubeconfig;
-        path = [ pkgs.kubectl ];
+        path = [ pkgs.curl ];
         preStart = ''
-          until kubectl get --raw=/healthz 2>/dev/null; do
-            echo kubectl get --raw=/healthz: exit status $?
+          until curl -Ssf ${cfg.apiserverAddress}/healthz do
+            echo curl -Ssf ${cfg.apiserverAddress}/healthz: exit status $?
             sleep 3
           done
         '';
diff --git a/nixpkgs/nixos/modules/services/databases/openldap.nix b/nixpkgs/nixos/modules/services/databases/openldap.nix
index c101e7375af9..c2f458c03794 100644
--- a/nixpkgs/nixos/modules/services/databases/openldap.nix
+++ b/nixpkgs/nixos/modules/services/databases/openldap.nix
@@ -18,7 +18,11 @@ let
     database ${cfg.database}
     suffix ${cfg.suffix}
     rootdn ${cfg.rootdn}
-    rootpw ${cfg.rootpw}
+    ${if (cfg.rootpw != null) then ''
+      rootpw ${cfg.rootpw}
+    '' else ''
+      include ${cfg.rootpwFile}
+    ''}
     directory ${cfg.dataDir}
     ${cfg.extraDatabaseConfig}
   '');
@@ -106,10 +110,23 @@ in
       };
 
       rootpw = mkOption {
-        type = types.str;
+        type = types.nullOr types.str;
+        default = null;
         description = ''
           Password for the root user.
           This setting will be ignored if configDir is set.
+          Using this option will store the root password in plain text in the
+          world-readable nix store. To avoid this the <literal>rootpwFile</literal> can be used.
+        '';
+      };
+
+      rootpwFile = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = ''
+          Password file for the root user.
+          The file should contain the string <literal>rootpw</literal> followed by the password.
+          e.g.: <literal>rootpw mysecurepassword</literal>
         '';
       };
 
@@ -140,9 +157,9 @@ in
             include ${pkgs.openldap.out}/etc/schema/inetorgperson.schema
             include ${pkgs.openldap.out}/etc/schema/nis.schema
 
-            database bdb 
-            suffix dc=example,dc=org 
-            rootdn cn=admin,dc=example,dc=org 
+            database bdb
+            suffix dc=example,dc=org
+            rootdn cn=admin,dc=example,dc=org
             # NOTE: change after first start
             rootpw secret
             directory /var/db/openldap
@@ -218,6 +235,12 @@ in
   ###### implementation
 
   config = mkIf cfg.enable {
+    assertions = [
+      {
+        assertion = cfg.rootpwFile != null || cfg.rootpw != null;
+        message = "Either services.openldap.rootpw or services.openldap.rootpwFile must be set";
+      }
+    ];
 
     environment.systemPackages = [ openldap ];
 
diff --git a/nixpkgs/nixos/modules/services/desktops/deepin/dde-daemon.nix b/nixpkgs/nixos/modules/services/desktops/deepin/dde-daemon.nix
deleted file mode 100644
index 057da4e2d7f2..000000000000
--- a/nixpkgs/nixos/modules/services/desktops/deepin/dde-daemon.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-# dde-daemon
-
-{ config, pkgs, lib, ... }:
-
-{
-
-  ###### interface
-
-  options = {
-
-    services.deepin.dde-daemon = {
-
-      enable = lib.mkEnableOption
-        "A daemon for handling Deepin Desktop Environment session settings";
-
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.services.deepin.dde-daemon.enable {
-
-    environment.systemPackages = [ pkgs.deepin.dde-daemon ];
-
-    services.dbus.packages = [ pkgs.deepin.dde-daemon ];
-
-    systemd.packages = [ pkgs.deepin.dde-daemon ];
-
-    users.groups.dde-daemon = { };
-
-    users.users.dde-daemon = {
-      description = "Deepin daemon user";
-      group = "dde-daemon";
-      isSystemUser = true;
-    };
-
-  };
-
-}
diff --git a/nixpkgs/nixos/modules/services/desktops/deepin/deepin-menu.nix b/nixpkgs/nixos/modules/services/desktops/deepin/deepin-menu.nix
deleted file mode 100644
index 23fe5a741c42..000000000000
--- a/nixpkgs/nixos/modules/services/desktops/deepin/deepin-menu.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-# deepin-menu
-
-{ config, pkgs, lib, ... }:
-
-{
-
-  ###### interface
-
-  options = {
-
-    services.deepin.deepin-menu = {
-
-      enable = lib.mkEnableOption
-        "DBus service for unified menus in Deepin Desktop Environment";
-
-    };
-
-  };
-
-
-  ###### implementation
-
-  config = lib.mkIf config.services.deepin.deepin-menu.enable {
-
-    services.dbus.packages = [ pkgs.deepin.deepin-menu ];
-
-  };
-
-}
diff --git a/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix b/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix
new file mode 100644
index 000000000000..7ec326e599e5
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/desktops/deepin/deepin.nix
@@ -0,0 +1,118 @@
+# deepin
+
+{ config, pkgs, lib, ... }:
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.deepin.core.enable = lib.mkEnableOption "
+      Basic dbus and systemd services, groups and users needed by the
+      Deepin Desktop Environment.
+    ";
+
+    services.deepin.deepin-menu.enable = lib.mkEnableOption "
+      DBus service for unified menus in Deepin Desktop Environment.
+    ";
+
+    services.deepin.deepin-turbo.enable = lib.mkEnableOption "
+      Turbo service for the Deepin Desktop Environment. It is a daemon
+      that helps to launch applications faster.
+    ";
+
+  };
+
+
+  ###### implementation
+
+  config = lib.mkMerge [
+
+    (lib.mkIf config.services.deepin.core.enable {
+      environment.systemPackages = [
+        pkgs.deepin.dde-api
+        pkgs.deepin.dde-calendar
+        pkgs.deepin.dde-daemon
+        pkgs.deepin.dde-dock
+        pkgs.deepin.dde-session-ui
+        pkgs.deepin.deepin-anything
+        pkgs.deepin.deepin-image-viewer
+        pkgs.deepin.deepin-screenshot
+      ];
+
+      services.dbus.packages = [
+        pkgs.deepin.dde-api
+        pkgs.deepin.dde-calendar
+        pkgs.deepin.dde-daemon
+        pkgs.deepin.dde-dock
+        pkgs.deepin.dde-session-ui
+        pkgs.deepin.deepin-anything
+        pkgs.deepin.deepin-image-viewer
+        pkgs.deepin.deepin-screenshot
+      ];
+
+      systemd.packages = [
+        pkgs.deepin.dde-api
+        pkgs.deepin.dde-daemon
+        pkgs.deepin.deepin-anything
+      ];
+
+      boot.extraModulePackages = [ config.boot.kernelPackages.deepin-anything ];
+
+      boot.kernelModules = [ "vfs_monitor" ];
+
+      users.groups.deepin-sound-player = { };
+
+      users.users.deepin-sound-player = {
+        description = "Deepin sound player";
+        group = "deepin-sound-player";
+        isSystemUser = true;
+      };
+
+      users.groups.deepin-daemon = { };
+
+      users.users.deepin-daemon = {
+        description = "Deepin daemon user";
+        group = "deepin-daemon";
+        isSystemUser = true;
+      };
+
+      users.groups.deepin_anything_server = { };
+
+      users.users.deepin_anything_server = {
+        description = "Deepin Anything Server";
+        group = "deepin_anything_server";
+        isSystemUser = true;
+      };
+
+      security.pam.services.deepin-auth-keyboard.text = ''
+        # original at ${pkgs.deepin.dde-daemon}/etc/pam.d/deepin-auth-keyboard
+        auth	[success=2 default=ignore]	pam_lsass.so
+        auth	[success=1 default=ignore]	pam_unix.so nullok_secure try_first_pass
+        auth	requisite	pam_deny.so
+        auth	required	pam_permit.so
+      '';
+
+      environment.etc = {
+        "polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla".source = "${pkgs.deepin.dde-api}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.api.device.pkla";
+        "polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Accounts.pkla";
+        "polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla".source = "${pkgs.deepin.dde-daemon}/etc/polkit-1/localauthority/10-vendor.d/com.deepin.daemon.Grub2.pkla";
+      };
+
+      services.deepin.deepin-menu.enable = true;
+      services.deepin.deepin-turbo.enable = true;
+    })
+
+    (lib.mkIf config.services.deepin.deepin-menu.enable {
+      services.dbus.packages = [ pkgs.deepin.deepin-menu ];
+    })
+
+    (lib.mkIf config.services.deepin.deepin-turbo.enable {
+      environment.systemPackages = [ pkgs.deepin.deepin-turbo ];
+      systemd.packages = [ pkgs.deepin.deepin-turbo ];
+    })
+
+  ];
+
+}
diff --git a/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix b/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
index 4c350d8bb1c6..db60445ef773 100644
--- a/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
+++ b/nixpkgs/nixos/modules/services/desktops/gnome3/gnome-keyring.nix
@@ -37,6 +37,11 @@ with lib;
 
     security.pam.services.login.enableGnomeKeyring = true;
 
+    security.wrappers.gnome-keyring-daemon = {
+      source = "${pkgs.gnome3.gnome-keyring}/bin/gnome-keyring-daemon";
+      capabilities = "cap_ipc_lock=ep";
+    };
+
   };
 
 }
diff --git a/nixpkgs/nixos/modules/services/logging/journalwatch.nix b/nixpkgs/nixos/modules/services/logging/journalwatch.nix
index d0824df38ae3..576c646c0f58 100644
--- a/nixpkgs/nixos/modules/services/logging/journalwatch.nix
+++ b/nixpkgs/nixos/modules/services/logging/journalwatch.nix
@@ -4,6 +4,8 @@ with lib;
 let
   cfg = config.services.journalwatch;
   user = "journalwatch";
+  # for journal access
+  group = "systemd-journal";
   dataDir = "/var/lib/${user}";
 
   journalwatchConfig = pkgs.writeText "config" (''
@@ -31,6 +33,17 @@ let
 
   '') filterBlocks);
 
+  # can't use joinSymlinks directly, because when we point $XDG_CONFIG_HOME
+  # to the /nix/store path, we still need the subdirectory "journalwatch" inside that
+  # to match journalwatch's expectations
+  journalwatchConfigDir = pkgs.runCommand "journalwatch-config"
+    { preferLocalBuild = true; allowSubstitutes = false; }
+    ''
+      mkdir -p $out/journalwatch
+      ln -sf ${journalwatchConfig} $out/journalwatch/config
+      ln -sf ${journalwatchPatterns} $out/journalwatch/patterns
+    '';
+
 
 in {
   options = {
@@ -199,33 +212,38 @@ in {
 
     users.users.${user} = {
       isSystemUser = true;
-      createHome = true;
       home = dataDir;
-      # for journal access
-      group = "systemd-journal";
+      group = group;
     };
 
+    systemd.tmpfiles.rules = [
+      # present since NixOS 19.09: remove old stateful symlink join directory,
+      # which has been replaced with the journalwatchConfigDir store path
+      "R ${dataDir}/config"
+    ];
+
     systemd.services.journalwatch = {
+
       environment = {
+        # journalwatch stores the last processed timpestamp here
+        # the share subdirectory is historic now that config home lives in /nix/store,
+        # but moving this in a backwards-compatible way is much more work than what's justified
+        # for cleaning that up.
         XDG_DATA_HOME = "${dataDir}/share";
-        XDG_CONFIG_HOME = "${dataDir}/config";
+        XDG_CONFIG_HOME = journalwatchConfigDir;
       };
       serviceConfig = {
         User = user;
+        Group = group;
         Type = "oneshot";
-        PermissionsStartOnly = true;
+        # requires a relative directory name to create beneath /var/lib
+        StateDirectory = user;
+        StateDirectoryMode = 0750;
         ExecStart = "${pkgs.python3Packages.journalwatch}/bin/journalwatch mail";
         # lowest CPU and IO priority, but both still in best-effort class to prevent starvation
         Nice=19;
         IOSchedulingPriority=7;
       };
-      preStart = ''
-        chown -R ${user}:systemd-journal ${dataDir}
-        chmod -R u+rwX,go-w ${dataDir}
-        mkdir -p ${dataDir}/config/journalwatch
-        ln -sf ${journalwatchConfig} ${dataDir}/config/journalwatch/config
-        ln -sf ${journalwatchPatterns} ${dataDir}/config/journalwatch/patterns
-      '';
     };
 
     systemd.timers.journalwatch = {
diff --git a/nixpkgs/nixos/modules/services/misc/emby.nix b/nixpkgs/nixos/modules/services/misc/emby.nix
deleted file mode 100644
index 0ad4a3f7376f..000000000000
--- a/nixpkgs/nixos/modules/services/misc/emby.nix
+++ /dev/null
@@ -1,76 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-with lib;
-
-let
-  cfg = config.services.emby;
-in
-{
-  options = {
-    services.emby = {
-      enable = mkEnableOption "Emby Media Server";
-
-      user = mkOption {
-        type = types.str;
-        default = "emby";
-        description = "User account under which Emby runs.";
-      };
-
-      group = mkOption {
-        type = types.str;
-        default = "emby";
-        description = "Group under which emby runs.";
-      };
-
-      dataDir = mkOption {
-        type = types.path;
-        default = "/var/lib/emby/ProgramData-Server";
-        description = "Location where Emby stores its data.";
-      };
-    };
-  };
-
-  config = mkIf cfg.enable {
-    systemd.services.emby = {
-      description = "Emby Media Server";
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
-      preStart = ''
-        if [ -d ${cfg.dataDir} ]
-        then
-            for plugin in ${cfg.dataDir}/plugins/*
-            do
-                echo "Correcting permissions of plugin: $plugin"
-                chmod u+w $plugin
-            done
-        else
-            echo "Creating initial Emby data directory in ${cfg.dataDir}"
-            mkdir -p ${cfg.dataDir}
-            chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
-        fi
-      '';
-
-      serviceConfig = {
-        Type = "simple";
-        User = cfg.user;
-        Group = cfg.group;
-        PermissionsStartOnly = "true";
-        ExecStart = "${pkgs.emby}/bin/emby -programdata ${cfg.dataDir}";
-        Restart = "on-failure";
-      };
-    };
-
-    users.users = mkIf (cfg.user == "emby") {
-      emby = {
-        group = cfg.group;
-        uid = config.ids.uids.emby;
-      };
-    };
-
-    users.groups = mkIf (cfg.group == "emby") {
-      emby = {
-        gid = config.ids.gids.emby;
-      };
-    };
-  };
-}
diff --git a/nixpkgs/nixos/modules/services/misc/ethminer.nix b/nixpkgs/nixos/modules/services/misc/ethminer.nix
new file mode 100644
index 000000000000..2958cf214473
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/ethminer.nix
@@ -0,0 +1,115 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.ethminer;
+  poolUrl = escapeShellArg "stratum1+tcp://${cfg.wallet}@${cfg.pool}:${toString cfg.stratumPort}/${cfg.rig}/${cfg.registerMail}";
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.ethminer = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable ethminer ether mining.";
+      };
+
+      recheckInterval = mkOption {
+        type = types.int;
+        default = 2000;
+        description = "Interval in milliseconds between farm rechecks.";
+      };
+
+      toolkit = mkOption {
+        type = types.enum [ "cuda" "opencl" ];
+        default = "cuda";
+        description = "Cuda or opencl toolkit.";
+      };
+
+      apiPort = mkOption {
+        type = types.int;
+        default = -3333;
+        description = "Ethminer api port. minus sign puts api in read-only mode.";
+      };
+
+      wallet = mkOption {
+        type = types.str;
+        example = "0x0123456789abcdef0123456789abcdef01234567";
+        description = "Ethereum wallet address.";
+      };
+
+      pool = mkOption {
+        type = types.str;
+        example = "eth-us-east1.nanopool.org";
+        description = "Mining pool address.";
+      };
+
+      stratumPort = mkOption {
+        type = types.port;
+        default = 9999;
+        description = "Stratum protocol tcp port.";
+      };
+
+      rig = mkOption {
+        type = types.str;
+        default = "mining-rig-name";
+        description = "Mining rig name.";
+      };
+
+      registerMail = mkOption {
+        type = types.str;
+        example = "email%40example.org";
+        description = "Url encoded email address to register with pool.";
+      };
+
+      maxPower = mkOption {
+        type = types.int;
+        default = 115;
+        description = "Miner max watt usage.";
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.ethminer = {
+      path = [ pkgs.cudatoolkit ];
+      description = "ethminer ethereum mining service";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+
+      serviceConfig = {
+        DynamicUser = true;
+        ExecStartPost = optional (cfg.toolkit == "cuda") "+${getBin config.boot.kernelPackages.nvidia_x11}/bin/nvidia-smi -pl ${toString cfg.maxPower}";
+      };
+
+      environment = {
+        LD_LIBRARY_PATH = "${config.boot.kernelPackages.nvidia_x11}/lib";
+      };
+
+      script = ''
+        ${pkgs.ethminer}/bin/.ethminer-wrapped \
+          --farm-recheck ${toString cfg.recheckInterval} \
+          --report-hashrate \
+          --${cfg.toolkit} \
+          --api-port ${toString cfg.apiPort} \
+          --pool ${poolUrl}
+      '';
+
+    };
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/misc/gitea.nix b/nixpkgs/nixos/modules/services/misc/gitea.nix
index be4d38719785..6fd4183bd6b4 100644
--- a/nixpkgs/nixos/modules/services/misc/gitea.nix
+++ b/nixpkgs/nixos/modules/services/misc/gitea.nix
@@ -8,6 +8,7 @@ let
   pg = config.services.postgresql;
   useMysql = cfg.database.type == "mysql";
   usePostgresql = cfg.database.type == "postgres";
+  useSqlite = cfg.database.type == "sqlite3";
   configFile = pkgs.writeText "app.ini" ''
     APP_NAME = ${cfg.appName}
     RUN_USER = ${cfg.user}
@@ -15,11 +16,15 @@ let
 
     [database]
     DB_TYPE = ${cfg.database.type}
-    HOST = ${if cfg.database.socket != null then cfg.database.socket else cfg.database.host + ":" + toString cfg.database.port}
-    NAME = ${cfg.database.name}
-    USER = ${cfg.database.user}
-    PASSWD = #dbpass#
-    PATH = ${cfg.database.path}
+    ${optionalString (usePostgresql || useMysql) ''
+      HOST = ${if cfg.database.socket != null then cfg.database.socket else cfg.database.host + ":" + toString cfg.database.port}
+      NAME = ${cfg.database.name}
+      USER = ${cfg.database.user}
+      PASSWD = #dbpass#
+    ''}
+    ${optionalString useSqlite ''
+      PATH = ${cfg.database.path}
+    ''}
     ${optionalString usePostgresql ''
       SSL_MODE = disable
     ''}
diff --git a/nixpkgs/nixos/modules/services/misc/jellyfin.nix b/nixpkgs/nixos/modules/services/misc/jellyfin.nix
new file mode 100644
index 000000000000..7f38dd0ff233
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/jellyfin.nix
@@ -0,0 +1,60 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.jellyfin;
+in
+{
+  options = {
+    services.jellyfin = {
+      enable = mkEnableOption "Jellyfin Media Server";
+
+      user = mkOption {
+        type = types.str;
+        default = "jellyfin";
+        description = "User account under which Jellyfin runs.";
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "jellyfin";
+        description = "Group under which jellyfin runs.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.jellyfin = {
+      description = "Jellyfin Media Server";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = rec {
+        User = cfg.user;
+        Group = cfg.group;
+        StateDirectory = "jellyfin";
+        CacheDirectory = "jellyfin";
+        ExecStart = "${pkgs.jellyfin}/bin/jellyfin --datadir '/var/lib/${StateDirectory}' --cachedir '/var/cache/${CacheDirectory}'";
+        Restart = "on-failure";
+      };
+    };
+
+    users.users = mkIf (cfg.user == "jellyfin") {
+      jellyfin.group = cfg.group;
+    };
+
+    users.groups = mkIf (cfg.group == "jellyfin") {
+      jellyfin = {};
+    };
+
+    assertions = [
+      {
+        assertion = !config.services.emby.enable;
+        message = "Emby and Jellyfin are incompatible, you cannot enable both";
+      }
+    ];
+  };
+
+  meta.maintainers = with lib.maintainers; [ minijackson ];
+}
diff --git a/nixpkgs/nixos/modules/services/misc/nix-daemon.nix b/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
index 665215822af8..8db3c44246f3 100644
--- a/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
@@ -60,6 +60,7 @@ let
         ${optionalString (isNix20 && !cfg.distributedBuilds) ''
           builders =
         ''}
+        system-features = ${toString cfg.systemFeatures}
         $extraOptions
         END
       '' + optionalString cfg.checkConfig (
@@ -360,6 +361,14 @@ in
         '';
       };
 
+      systemFeatures = mkOption {
+        type = types.listOf types.str;
+        example = [ "kvm" "big-parallel" "gccarch-skylake" ];
+        description = ''
+          The supported features of a machine
+        '';
+      };
+
       checkConfig = mkOption {
         type = types.bool;
         default = true;
@@ -478,6 +487,21 @@ in
           /nix/var/nix/gcroots/tmp
       '';
 
+    nix.systemFeatures = mkDefault (
+      [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
+      optionals (pkgs.stdenv.isx86_64 && pkgs.hostPlatform.platform ? gcc.arch) (
+        # a x86_64 builder can run code for `platform.gcc.arch` and minor architectures:
+        [ "gccarch-${pkgs.hostPlatform.platform.gcc.arch}" ] ++ {
+          "sandybridge"    = [ "gccarch-westmere" ];
+          "ivybridge"      = [ "gccarch-westmere" "gccarch-sandybridge" ];
+          "haswell"        = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" ];
+          "broadwell"      = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" ];
+          "skylake"        = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" ];
+          "skylake-avx512" = [ "gccarch-westmere" "gccarch-sandybridge" "gccarch-ivybridge" "gccarch-haswell" "gccarch-broadwell" "gccarch-skylake" ];
+        }.${pkgs.hostPlatform.platform.gcc.arch} or []
+      )
+    );
+
   };
 
 }
diff --git a/nixpkgs/nixos/modules/services/misc/nzbget.nix b/nixpkgs/nixos/modules/services/misc/nzbget.nix
index 6ab98751c57b..eb7b4c05d82d 100644
--- a/nixpkgs/nixos/modules/services/misc/nzbget.nix
+++ b/nixpkgs/nixos/modules/services/misc/nzbget.nix
@@ -4,32 +4,34 @@ with lib;
 
 let
   cfg = config.services.nzbget;
-  dataDir = builtins.dirOf cfg.configFile;
-in {
-  options = {
-    services.nzbget = {
-      enable = mkEnableOption "NZBGet";
+  pkg = pkgs.nzbget;
+  stateDir = "/var/lib/nzbget";
+  configFile = "${stateDir}/nzbget.conf";
+  configOpts = concatStringsSep " " (mapAttrsToList (name: value: "-o ${name}=${value}") nixosOpts);
 
-      package = mkOption {
-        type = types.package;
-        default = pkgs.nzbget;
-        defaultText = "pkgs.nzbget";
-        description = "The NZBGet package to use";
-      };
+  nixosOpts = {
+    # allows nzbget to run as a "simple" service
+    OutputMode = "loggable";
+    # use journald for logging
+    WriteLog = "none";
+    ErrorTarget = "screen";
+    WarningTarget = "screen";
+    InfoTarget = "screen";
+    DetailTarget = "screen";
+    # required paths
+    ConfigTemplate = "${pkg}/share/nzbget/nzbget.conf";
+    WebDir = "${pkg}/share/nzbget/webui";
+    # nixos handles package updates
+    UpdateCheck = "none";
+  };
 
-      dataDir = mkOption {
-        type = types.str;
-        default = "/var/lib/nzbget";
-        description = "The directory where NZBGet stores its configuration files.";
-      };
+in
+{
+  # interface
 
-      openFirewall = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Open ports in the firewall for the NZBGet web interface
-        '';
-      };
+  options = {
+    services.nzbget = {
+      enable = mkEnableOption "NZBGet";
 
       user = mkOption {
         type = types.str;
@@ -42,15 +44,11 @@ in {
         default = "nzbget";
         description = "Group under which NZBGet runs";
       };
-
-      configFile = mkOption {
-        type = types.str;
-        default = "/var/lib/nzbget/nzbget.conf";
-        description = "Path for NZBGet's config file. (If this doesn't exist, the default config template is copied here.)";
-      };
     };
   };
 
+  # implementation
+
   config = mkIf cfg.enable {
     systemd.services.nzbget = {
       description = "NZBGet Daemon";
@@ -61,50 +59,26 @@ in {
         p7zip
       ];
       preStart = ''
-        cfgtemplate=${cfg.package}/share/nzbget/nzbget.conf
-        if [ ! -f ${cfg.configFile} ]; then
-          echo "${cfg.configFile} not found. Copying default config $cfgtemplate to ${cfg.configFile}"
-          install -m 0700 $cfgtemplate ${cfg.configFile}
-          echo "Setting temporary \$MAINDIR variable in default config required in order to allow nzbget to complete initial start"
-          echo "Remember to change this to a proper value once NZBGet startup has been completed"
-          sed -i -e 's/MainDir=.*/MainDir=\/tmp/g' ${cfg.configFile}
+        if [ ! -f ${configFile} ]; then
+          ${pkgs.coreutils}/bin/install -m 0700 ${pkg}/share/nzbget/nzbget.conf ${configFile}
         fi
       '';
 
-      script = ''
-        args="--daemon --configfile ${cfg.configFile}"
-        # The script in preStart (above) copies nzbget's config template to datadir on first run, containing paths that point to the nzbget derivation installed at the time.
-        # These paths break when nzbget is upgraded & the original derivation is garbage collected. If such broken paths are found in the config file, override them to point to
-        # the currently installed nzbget derivation.
-        cfgfallback () {
-          local hit=`grep -Po "(?<=^$1=).*+" "${cfg.configFile}" | sed 's/[ \t]*$//'` # Strip trailing whitespace
-          ( test $hit && test -e $hit ) || {
-            echo "In ${cfg.configFile}, valid $1 not found; falling back to $1=$2"
-            args+=" -o $1=$2"
-          }
-        }
-        cfgfallback ConfigTemplate ${cfg.package}/share/nzbget/nzbget.conf
-        cfgfallback WebDir ${cfg.package}/share/nzbget/webui
-        ${cfg.package}/bin/nzbget $args
-      '';
-
       serviceConfig = {
-        StateDirectory = dataDir;
-        StateDirectoryMode = "0700";
-        Type = "forking";
+        StateDirectory = "nzbget";
+        StateDirectoryMode = "0750";
         User = cfg.user;
         Group = cfg.group;
-        PermissionsStartOnly = "true";
+        UMask = "0002";
         Restart = "on-failure";
+        ExecStart = "${pkg}/bin/nzbget --server --configfile ${stateDir}/nzbget.conf ${configOpts}";
+        ExecStop = "${pkg}/bin/nzbget --quit";
       };
     };
 
-    networking.firewall = mkIf cfg.openFirewall {
-      allowedTCPPorts = [ 8989 ];
-    };
-
     users.users = mkIf (cfg.user == "nzbget") {
       nzbget = {
+        home = stateDir;
         group = cfg.group;
         uid = config.ids.uids.nzbget;
       };
diff --git a/nixpkgs/nixos/modules/services/misc/packagekit.nix b/nixpkgs/nixos/modules/services/misc/packagekit.nix
index bce21e8acff3..325c4e84e0d8 100644
--- a/nixpkgs/nixos/modules/services/misc/packagekit.nix
+++ b/nixpkgs/nixos/modules/services/misc/packagekit.nix
@@ -7,18 +7,19 @@ let
   cfg = config.services.packagekit;
 
   packagekitConf = ''
-[Daemon]
-KeepCache=false
-    '';
+    [Daemon]
+    DefaultBackend=${cfg.backend}
+    KeepCache=false
+  '';
 
   vendorConf = ''
-[PackagesNotFound]
-DefaultUrl=https://github.com/NixOS/nixpkgs
-CodecUrl=https://github.com/NixOS/nixpkgs
-HardwareUrl=https://github.com/NixOS/nixpkgs
-FontUrl=https://github.com/NixOS/nixpkgs
-MimeUrl=https://github.com/NixOS/nixpkgs
-      '';
+    [PackagesNotFound]
+    DefaultUrl=https://github.com/NixOS/nixpkgs
+    CodecUrl=https://github.com/NixOS/nixpkgs
+    HardwareUrl=https://github.com/NixOS/nixpkgs
+    FontUrl=https://github.com/NixOS/nixpkgs
+    MimeUrl=https://github.com/NixOS/nixpkgs
+  '';
 
 in
 
@@ -33,26 +34,32 @@ in
           installing software. Software utilizing PackageKit can install
           software regardless of the package manager.
         '';
-    };
 
+      # TODO: integrate with PolicyKit if the nix backend matures to the point
+      # where it will require elevated permissions
+      backend = mkOption {
+        type = types.enum [ "test_nop" ];
+        default = "test_nop";
+        description = ''
+          PackageKit supports multiple different backends and <literal>auto</literal> which
+          should do the right thing.
+          </para>
+          <para>
+          On NixOS however, we do not have a backend compatible with nix 2.0
+          (refer to <link xlink:href="https://github.com/NixOS/nix/issues/233">this issue</link> so we have to force
+          it to <literal>test_nop</literal> for now.
+        '';
+      };
+    };
   };
 
   config = mkIf cfg.enable {
 
-    services.dbus.packages = [ pkgs.packagekit ];
+    services.dbus.packages = with pkgs; [ packagekit ];
 
-    systemd.services.packagekit = {
-      description = "PackageKit Daemon";
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig.ExecStart = "${pkgs.packagekit}/libexec/packagekitd";
-      serviceConfig.User = "root";
-      serviceConfig.BusName = "org.freedesktop.PackageKit";
-      serviceConfig.Type = "dbus";
-    };
+    systemd.packages = with pkgs; [ packagekit ];
 
     environment.etc."PackageKit/PackageKit.conf".text = packagekitConf;
     environment.etc."PackageKit/Vendor.conf".text = vendorConf;
-
   };
-
 }
diff --git a/nixpkgs/nixos/modules/services/monitoring/grafana-reporter.nix b/nixpkgs/nixos/modules/services/monitoring/grafana-reporter.nix
index 149026d20188..827cf6322cfd 100644
--- a/nixpkgs/nixos/modules/services/monitoring/grafana-reporter.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/grafana-reporter.nix
@@ -52,7 +52,7 @@ in {
       wantedBy = ["multi-user.target"];
       after = ["network.target"];
       serviceConfig = let
-        args = lib.concatSepString " " [
+        args = lib.concatStringsSep " " [
           "-proto ${cfg.grafana.protocol}://"
           "-ip ${cfg.grafana.addr}:${toString cfg.grafana.port}"
           "-port :${toString cfg.port}"
diff --git a/nixpkgs/nixos/modules/services/monitoring/grafana.nix b/nixpkgs/nixos/modules/services/monitoring/grafana.nix
index 85879cfe0b33..5d3f2e6ac28f 100644
--- a/nixpkgs/nixos/modules/services/monitoring/grafana.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/grafana.nix
@@ -177,7 +177,7 @@ let
       folder = mkOption {
         type = types.str;
         default = "";
-        description = "Add dashboards to the speciied folder";
+        description = "Add dashboards to the specified folder";
       };
       type = mkOption {
         type = types.str;
diff --git a/nixpkgs/nixos/modules/services/networking/ejabberd.nix b/nixpkgs/nixos/modules/services/networking/ejabberd.nix
index ef5e2cee6f20..6a38f85c48a2 100644
--- a/nixpkgs/nixos/modules/services/networking/ejabberd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ejabberd.nix
@@ -11,7 +11,7 @@ let
     ${cfg.ctlConfig}
   '';
 
-  ectl = ''${cfg.package}/bin/ejabberdctl ${if cfg.configFile == null then "" else "--config ${cfg.configFile}"} --ctl-config "${ctlcfg}" --spool "${cfg.spoolDir}" --logs "${cfg.logsDir}"'';
+  ectl = ''${cfg.package}/bin/ejabberdctl ${optionalString (cfg.configFile != null) "--config ${cfg.configFile}"} --ctl-config "${ctlcfg}" --spool "${cfg.spoolDir}" --logs "${cfg.logsDir}"'';
 
   dumps = lib.escapeShellArgs cfg.loadDumps;
 
@@ -111,28 +111,17 @@ in {
       description = "ejabberd server";
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" ];
-      path = [ pkgs.findutils pkgs.coreutils pkgs.runit ] ++ lib.optional cfg.imagemagick pkgs.imagemagick;
+      path = [ pkgs.findutils pkgs.coreutils ] ++ lib.optional cfg.imagemagick pkgs.imagemagick;
 
       serviceConfig = {
-        ExecStart = ''${ectl} foreground'';
-        # FIXME: runit is used for `chpst` -- can we get rid of this?
-        ExecStop = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} stop'';
-        ExecReload = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} reload_config'';
         User = cfg.user;
         Group = cfg.group;
-        PermissionsStartOnly = true;
+        ExecStart = "${ectl} foreground";
+        ExecStop = "${ectl} stop";
+        ExecReload = "${ectl} reload_config";
       };
 
       preStart = ''
-        mkdir -p -m750 "${cfg.logsDir}"
-        chown "${cfg.user}:${cfg.group}" "${cfg.logsDir}"
-
-        mkdir -p -m750 "/var/lock/ejabberdctl"
-        chown "${cfg.user}:${cfg.group}" "/var/lock/ejabberdctl"
-
-        mkdir -p -m750 "${cfg.spoolDir}"
-        chown -R "${cfg.user}:${cfg.group}" "${cfg.spoolDir}"
-
         if [ -z "$(ls -A '${cfg.spoolDir}')" ]; then
           touch "${cfg.spoolDir}/.firstRun"
         fi
@@ -149,13 +138,18 @@ in {
           for src in ${dumps}; do
             find "$src" -type f | while read dump; do
               echo "Loading configuration dump at $dump"
-              chpst -u "${cfg.user}:${cfg.group}" ${ectl} load "$dump"
+              ${ectl} load "$dump"
             done
           done
         fi
       '';
     };
 
+    systemd.tmpfiles.rules = [
+      "d '${cfg.logsDir}' 0750 ${cfg.user} ${cfg.group} -"
+      "d '${cfg.spoolDir}' 0700 ${cfg.user} ${cfg.group} -"
+    ];
+
     security.pam.services.ejabberd = {};
 
   };
diff --git a/nixpkgs/nixos/modules/services/networking/hostapd.nix b/nixpkgs/nixos/modules/services/networking/hostapd.nix
index 3fbc08e90607..7add48308f80 100644
--- a/nixpkgs/nixos/modules/services/networking/hostapd.nix
+++ b/nixpkgs/nixos/modules/services/networking/hostapd.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
 
 # TODO:
 #
@@ -12,6 +12,8 @@ let
 
   cfg = config.services.hostapd;
 
+  escapedInterface = utils.escapeSystemdPath cfg.interface;
+
   configFile = pkgs.writeText "hostapd.conf" ''
     interface=${cfg.interface}
     driver=${cfg.driver}
@@ -157,8 +159,8 @@ in
       { description = "hostapd wireless AP";
 
         path = [ pkgs.hostapd ];
-        after = [ "sys-subsystem-net-devices-${cfg.interface}.device" ];
-        bindsTo = [ "sys-subsystem-net-devices-${cfg.interface}.device" ];
+        after = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
+        bindsTo = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
         requiredBy = [ "network-link-${cfg.interface}.service" ];
 
         serviceConfig =
diff --git a/nixpkgs/nixos/modules/services/networking/softether.nix b/nixpkgs/nixos/modules/services/networking/softether.nix
index 65df93a00da9..0046dcd366fa 100644
--- a/nixpkgs/nixos/modules/services/networking/softether.nix
+++ b/nixpkgs/nixos/modules/services/networking/softether.nix
@@ -70,6 +70,8 @@ in
 
       systemd.services."softether-init" = {
         description = "SoftEther VPN services initial task";
+        after = [ "keys.target" ];
+        wants = [ "keys.target" ];
         wantedBy = [ "network.target" ];
         serviceConfig = {
           Type = "oneshot";
diff --git a/nixpkgs/nixos/modules/services/networking/zeronet.nix b/nixpkgs/nixos/modules/services/networking/zeronet.nix
index 8b60799891ca..611a51c74ce2 100644
--- a/nixpkgs/nixos/modules/services/networking/zeronet.nix
+++ b/nixpkgs/nixos/modules/services/networking/zeronet.nix
@@ -5,13 +5,15 @@ let
 
   zConfFile = pkgs.writeTextFile {
     name = "zeronet.conf";
-    
+
     text = ''
       [global]
       data_dir = ${cfg.dataDir}
       log_dir = ${cfg.logDir}
     '' + lib.optionalString (cfg.port != null) ''
       ui_port = ${toString cfg.port}
+    '' + lib.optionalString (cfg.fileserverPort != null) ''
+      fileserver_port = ${toString cfg.fileserverPort}
     '' + lib.optionalString (cfg.torAlways) ''
       tor = always
     '' + cfg.extraConfig;
@@ -41,6 +43,15 @@ in with lib; {
       description = "Optional zeronet web UI port.";
     };
 
+    fileserverPort = mkOption {
+      # Not optional: when absent zeronet tries to write one to the
+      # read-only config file and crashes
+      type = types.int;
+      default = 12261;
+      example = 12261;
+      description = "Zeronet fileserver port.";
+    };
+
     tor = mkOption {
       type = types.bool;
       default = false;
diff --git a/nixpkgs/nixos/modules/services/networking/znc/default.nix b/nixpkgs/nixos/modules/services/networking/znc/default.nix
index 1ad8855b86db..46bff6954cdd 100644
--- a/nixpkgs/nixos/modules/services/networking/znc/default.nix
+++ b/nixpkgs/nixos/modules/services/networking/znc/default.nix
@@ -47,11 +47,11 @@ let
           #     Baz=baz
           #     Qux=qux
           #   </Foo>
-          set = concatMap (subname: [
+          set = concatMap (subname: optionals (value.${subname} != null) ([
               "<${name} ${subname}>"
             ] ++ map (line: "\t${line}") (toLines value.${subname}) ++ [
               "</${name}>"
-            ]) (filter (v: v != null) (attrNames value));
+            ])) (filter (v: v != null) (attrNames value));
 
         }.${builtins.typeOf value};
 
diff --git a/nixpkgs/nixos/modules/services/security/sks.nix b/nixpkgs/nixos/modules/services/security/sks.nix
index 8136a5c763a9..1b7a2ad13980 100644
--- a/nixpkgs/nixos/modules/services/security/sks.nix
+++ b/nixpkgs/nixos/modules/services/security/sks.nix
@@ -116,20 +116,22 @@ in {
           ${lib.optionalString (cfg.webroot != null)
             "ln -sfT \"${cfg.webroot}\" web"}
           mkdir -p dump
-          # Check that both database configs are symlinks before overwriting them
-          if [ -e KDB/DB_CONFIG ] && [ ! -L KBD/DB_CONFIG ]; then
-            echo "KDB/DB_CONFIG exists but is not a symlink." >&2
-            exit 1
-          fi
-          if [ -e PTree/DB_CONFIG ] && [ ! -L PTree/DB_CONFIG ]; then
-            echo "PTree/DB_CONFIG exists but is not a symlink." >&2
-            exit 1
-          fi
-          ln -sf ${dbConfig} KDB/DB_CONFIG
-          ln -sf ${dbConfig} PTree/DB_CONFIG
           ${sksPkg}/bin/sks build dump/*.gpg -n 10 -cache 100 || true #*/
           ${sksPkg}/bin/sks cleandb || true
           ${sksPkg}/bin/sks pbuild -cache 20 -ptree_cache 70 || true
+          # Check that both database configs are symlinks before overwriting them
+          # TODO: The initial build will be without DB_CONFIG, but this will
+          # hopefully not cause any significant problems. It might be better to
+          # create both directories manually but we have to check that this does
+          # not affect the initial build of the DB.
+          for CONFIG_FILE in KDB/DB_CONFIG PTree/DB_CONFIG; do
+            if [ -e $CONFIG_FILE ] && [ ! -L $CONFIG_FILE ]; then
+              echo "$CONFIG_FILE exists but is not a symlink." >&2
+              echo "Please remove $PWD/$CONFIG_FILE manually to continue." >&2
+              exit 1
+            fi
+            ln -sf ${dbConfig} $CONFIG_FILE
+          done
         '';
         serviceConfig = {
           WorkingDirectory = "~";
diff --git a/nixpkgs/nixos/modules/services/security/tor.nix b/nixpkgs/nixos/modules/services/security/tor.nix
index 61b751bb518b..6f4852c3ba1a 100644
--- a/nixpkgs/nixos/modules/services/security/tor.nix
+++ b/nixpkgs/nixos/modules/services/security/tor.nix
@@ -81,7 +81,7 @@ let
 
     ${optionalString (elem cfg.relay.role ["bridge" "private-bridge"]) ''
       BridgeRelay 1
-      ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
+      ServerTransportPlugin ${concatStringsSep "," cfg.relay.bridgeTransports} exec ${obfs4}/bin/obfs4proxy managed
       ExtORPort auto
       ${optionalString (cfg.relay.role == "private-bridge") ''
         ExtraInfoStatistics 0
@@ -355,7 +355,7 @@ in
                 <para>
                   Regular bridge. Works like a regular relay, but
                   doesn't list you in the public relay directory and
-                  hides your Tor node behind obfsproxy.
+                  hides your Tor node behind obfs4proxy.
                 </para>
 
                 <para>
@@ -424,6 +424,13 @@ in
           '';
         };
 
+        bridgeTransports = mkOption {
+          type = types.listOf types.str;
+          default = ["obfs4"];
+          example = ["obfs2" "obfs3" "obfs4" "scramblesuit"];
+          description = "List of pluggable transports";
+        };
+
         nickname = mkOption {
           type = types.str;
           default = "anonymous";
diff --git a/nixpkgs/nixos/modules/services/system/earlyoom.nix b/nixpkgs/nixos/modules/services/system/earlyoom.nix
index daa46838bfa8..39d1bf274bd2 100644
--- a/nixpkgs/nixos/modules/services/system/earlyoom.nix
+++ b/nixpkgs/nixos/modules/services/system/earlyoom.nix
@@ -63,6 +63,17 @@ in
           Enable debugging messages.
         '';
       };
+
+      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.
+
+          See <link xlink:href="https://github.com/rfjakob/earlyoom#notifications">README</link> for details.
+        '';
+      };
     };
   };
 
@@ -88,7 +99,9 @@ in
           -s ${toString ecfg.freeSwapThreshold} \
           ${optionalString ecfg.useKernelOOMKiller "-k"} \
           ${optionalString ecfg.ignoreOOMScoreAdjust "-i"} \
-          ${optionalString ecfg.enableDebugInfo "-d"}
+          ${optionalString ecfg.enableDebugInfo "-d"} \
+          ${optionalString (ecfg.notificationsCommand != null)
+            "-N ${escapeShellArg ecfg.notificationsCommand}"}
         '';
       };
     };
diff --git a/nixpkgs/nixos/modules/services/web-apps/documize.nix b/nixpkgs/nixos/modules/services/web-apps/documize.nix
index 206617b0e5ac..37359869cb64 100644
--- a/nixpkgs/nixos/modules/services/web-apps/documize.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/documize.nix
@@ -3,65 +3,136 @@
 with lib;
 
 let
-
   cfg = config.services.documize;
 
-in
+  mkParams = optional: concatMapStrings (name: let
+    predicate = optional -> cfg.${name} != null;
+    template = " -${name} '${toString cfg.${name}}'";
+  in optionalString predicate template);
 
-  {
-    options.services.documize = {
-      enable = mkEnableOption "Documize Wiki";
+in {
+  options.services.documize = {
+    enable = mkEnableOption "Documize Wiki";
 
-      offline = mkEnableOption "Documize offline mode";
+    package = mkOption {
+      type = types.package;
+      default = pkgs.documize-community;
+      description = ''
+        Which package to use for documize.
+      '';
+    };
 
-      package = mkOption {
-        default = pkgs.documize-community;
-        type = types.package;
-        description = ''
-          Which package to use for documize.
-        '';
-      };
+    salt = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "3edIYV6c8B28b19fh";
+      description = ''
+        The salt string used to encode JWT tokens, if not set a random value will be generated.
+      '';
+    };
 
-      db = mkOption {
-        type = types.str;
-        example = "host=localhost port=5432 sslmode=disable user=admin password=secret dbname=documize";
-        description = ''
-          The DB connection string to use for the database.
-        '';
-      };
+    cert = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        The <filename>cert.pem</filename> file used for https.
+      '';
+    };
 
-      dbtype = mkOption {
-        type = types.enum [ "postgresql" "percona" "mariadb" "mysql" ];
-        description = ''
-          Which database to use for storage.
-        '';
-      };
+    key = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        The <filename>key.pem</filename> file used for https.
+      '';
+    };
 
-      port = mkOption {
-        type = types.port;
-        example = 3000;
-        description = ''
-          Which TCP port to serve.
-        '';
-      };
+    port = mkOption {
+      type = types.port;
+      default = 5001;
+      description = ''
+        The http/https port number.
+      '';
+    };
+
+    forcesslport = mkOption {
+      type = types.nullOr types.port;
+      default = null;
+      description = ''
+        Redirect given http port number to TLS.
+      '';
+    };
+
+    offline = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Set <literal>true</literal> for offline mode.
+      '';
+      apply = v: if true == v then 1 else 0;
+    };
+
+    dbtype = mkOption {
+      type = types.enum [ "mysql" "percona" "mariadb" "postgresql" "sqlserver" ];
+      default = "postgresql";
+      description = ''
+        Specify the database provider:
+        <simplelist type='inline'>
+          <member><literal>mysql</literal></member>
+          <member><literal>percona</literal></member>
+          <member><literal>mariadb</literal></member>
+          <member><literal>postgresql</literal></member>
+          <member><literal>sqlserver</literal></member>
+        </simplelist>
+      '';
     };
 
-    config = mkIf cfg.enable {
-      systemd.services.documize-server = {
-        wantedBy = [ "multi-user.target" ];
-
-        script = ''
-          ${cfg.package}/bin/documize \
-            -db "${cfg.db}" \
-            -dbtype ${cfg.dbtype} \
-            -port ${toString cfg.port} \
-            -offline ${if cfg.offline then "1" else "0"}
-        '';
-
-        serviceConfig = {
-          Restart = "always";
-          DynamicUser = "yes";
-        };
+    db = mkOption {
+      type = types.str;
+      description = ''
+        Database specific connection string for example:
+        <itemizedlist>
+        <listitem><para>MySQL/Percona/MariaDB:
+          <literal>user:password@tcp(host:3306)/documize</literal>
+        </para></listitem>
+        <listitem><para>MySQLv8+:
+          <literal>user:password@tcp(host:3306)/documize?allowNativePasswords=true</literal>
+        </para></listitem>
+        <listitem><para>PostgreSQL:
+          <literal>host=localhost port=5432 dbname=documize user=admin password=secret sslmode=disable</literal>
+        </para></listitem>
+        <listitem><para>MSSQL:
+          <literal>sqlserver://username:password@localhost:1433?database=Documize</literal> or
+          <literal>sqlserver://sa@localhost/SQLExpress?database=Documize</literal>
+        </para></listitem>
+        </itemizedlist>
+      '';
+    };
+
+    location = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        reserved
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.documize-server = {
+      description = "Documize Wiki";
+      documentation = [ https://documize.com/ ];
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        ExecStart = concatStringsSep " " [
+          "${cfg.package}/bin/documize"
+          (mkParams false [ "db" "dbtype" "port" ])
+          (mkParams true [ "offline" "location" "forcesslport" "key" "cert" "salt" ])
+        ];
+        Restart = "always";
+        DynamicUser = "yes";
       };
     };
-  }
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
index 3a154ab75ba9..c486d6c8613b 100644
--- a/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/nginx/default.nix
@@ -16,11 +16,11 @@ let
     } // (optionalAttrs vhostConfig.enableACME {
       sslCertificate = "${acmeDirectory}/${serverName}/fullchain.pem";
       sslCertificateKey = "${acmeDirectory}/${serverName}/key.pem";
-      sslTrustedCertificate = "${acmeDirectory}/${serverName}/full.pem";
+      sslTrustedCertificate = "${acmeDirectory}/${serverName}/fullchain.pem";
     }) // (optionalAttrs (vhostConfig.useACMEHost != null) {
       sslCertificate = "${acmeDirectory}/${vhostConfig.useACMEHost}/fullchain.pem";
       sslCertificateKey = "${acmeDirectory}/${vhostConfig.useACMEHost}/key.pem";
-      sslTrustedCertificate = "${acmeDirectory}/${vhostConfig.useACMEHost}/full.pem";
+      sslTrustedCertificate = "${acmeDirectory}/${vhostConfig.useACMEHost}/fullchain.pem";
     })
   ) cfg.virtualHosts;
   enableIPv6 = config.networking.enableIPv6;
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 9bf03a494701..7b65f1b85c69 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -18,7 +18,7 @@ let
   nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" { preferLocalBuild = true; }
     ''
      mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
-     cp -rf ${pkgs.gnome3.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
+     cp -rf ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
 
      ${concatMapStrings (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n") cfg.extraGSettingsOverridePackages}
 
diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix b/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix
index c9b0669e7ba5..0ef55d5f2c03 100644
--- a/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix
+++ b/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix
@@ -60,12 +60,15 @@ in
         ${cfg.extraSessionCommands}
 
         ${cfg.package}/bin/i3 ${optionalString (cfg.configFile != null)
-          "-c \"${cfg.configFile}\""
+          "-c /etc/i3/config"
         } &
         waitPID=$!
       '';
     }];
     environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages;
+    environment.etc."i3/config" = mkIf (cfg.configFile != null) {
+      source = cfg.configFile;
+    };
   };
 
   imports = [