about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2019-05-24 18:25:09 +0000
committerAlyssa Ross <hi@alyssa.is>2019-05-24 18:25:09 +0000
commitcb026a2bd22d2656d88a7883e44caa31402d7646 (patch)
tree804c389adfe6dc6deb38dfd90167b03b4f828bce /nixpkgs/nixos
parent5781972383d0382dc9353ac720a5d751ca17cd05 (diff)
parent650a295621b27c4ebe0fa64a63fd25323e64deb3 (diff)
downloadnixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar.gz
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar.bz2
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar.lz
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar.xz
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.tar.zst
nixlib-cb026a2bd22d2656d88a7883e44caa31402d7646.zip
Merge commit '650a295621b27c4ebe0fa64a63fd25323e64deb3'
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml7
-rw-r--r--nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml4
-rw-r--r--nixpkgs/nixos/maintainers/option-usages.nix2
-rw-r--r--nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix2
-rw-r--r--nixpkgs/nixos/modules/config/fonts/fontconfig.nix2
-rw-r--r--nixpkgs/nixos/modules/config/sysctl.nix2
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix4
-rw-r--r--nixpkgs/nixos/modules/misc/ids.nix4
-rw-r--r--nixpkgs/nixos/modules/module-list.nix1
-rw-r--r--nixpkgs/nixos/modules/programs/bash/bash.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/fish.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/ssmtp.nix2
-rw-r--r--nixpkgs/nixos/modules/programs/zsh/zsh.nix2
-rw-r--r--nixpkgs/nixos/modules/rename.nix1
-rw-r--r--nixpkgs/nixos/modules/services/backup/znapzend.nix4
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/addons/dns.nix8
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/apiserver.nix8
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/kubelet.nix6
-rw-r--r--nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix2
-rw-r--r--nixpkgs/nixos/modules/services/continuous-integration/buildkite-agent.nix2
-rw-r--r--nixpkgs/nixos/modules/services/continuous-integration/jenkins/default.nix2
-rw-r--r--nixpkgs/nixos/modules/services/databases/cassandra.nix22
-rw-r--r--nixpkgs/nixos/modules/services/databases/cockroachdb.nix4
-rw-r--r--nixpkgs/nixos/modules/services/databases/foundationdb.nix12
-rw-r--r--nixpkgs/nixos/modules/services/databases/pgmanage.nix4
-rw-r--r--nixpkgs/nixos/modules/services/databases/postgresql.nix91
-rw-r--r--nixpkgs/nixos/modules/services/desktops/geoclue2.nix188
-rw-r--r--nixpkgs/nixos/modules/services/games/factorio.nix44
-rw-r--r--nixpkgs/nixos/modules/services/games/minecraft-server.nix4
-rw-r--r--nixpkgs/nixos/modules/services/logging/logcheck.nix2
-rw-r--r--nixpkgs/nixos/modules/services/mail/dovecot.nix12
-rw-r--r--nixpkgs/nixos/modules/services/misc/bepasty.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/errbot.nix2
-rw-r--r--nixpkgs/nixos/modules/services/misc/home-assistant.nix35
-rw-r--r--nixpkgs/nixos/modules/services/misc/taskserver/default.nix4
-rw-r--r--nixpkgs/nixos/modules/services/misc/zoneminder.nix2
-rw-r--r--nixpkgs/nixos/modules/services/monitoring/graphite.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/flannel.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/i2pd.nix8
-rw-r--r--nixpkgs/nixos/modules/services/networking/mxisd.nix10
-rw-r--r--nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/syncthing.nix260
-rw-r--r--nixpkgs/nixos/modules/services/networking/xinetd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/search/kibana.nix2
-rw-r--r--nixpkgs/nixos/modules/services/security/fprintd.nix12
-rw-r--r--nixpkgs/nixos/modules/services/security/oauth2_proxy.nix8
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/miniflux.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/restya-board.nix12
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-servers/winstone.nix129
-rw-r--r--nixpkgs/nixos/modules/services/x11/colord.nix1
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix21
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix11
-rw-r--r--nixpkgs/nixos/modules/virtualisation/docker-containers.nix6
-rw-r--r--nixpkgs/nixos/modules/virtualisation/google-compute-image.nix2
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix3
-rw-r--r--nixpkgs/nixos/tests/redmine.nix53
-rw-r--r--nixpkgs/nixos/tests/syncthing-init.nix30
-rw-r--r--nixpkgs/nixos/tests/tinydns.nix26
-rw-r--r--nixpkgs/nixos/tests/upnp.nix4
62 files changed, 823 insertions, 292 deletions
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
index e9c6cd7e9acb..8ff1681d3b4a 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-1903.xml
@@ -3,7 +3,7 @@
          xmlns:xi="http://www.w3.org/2001/XInclude"
          version="5.0"
          xml:id="sec-release-19.03">
- <title>Release 19.03 (“Koi”, 2019/03/??)</title>
+ <title>Release 19.03 (“Koi”, 2019/04/11)</title>
 
  <section xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
@@ -20,6 +20,11 @@
   <itemizedlist>
    <listitem>
     <para>
+     End of support is planned for end of October 2019, handing over to 19.09.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
      The default Python 3 interpreter is now CPython 3.7 instead of CPython
      3.6.
     </para>
diff --git a/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml b/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
index ead8f3abd8b2..b78c3e08b799 100644
--- a/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixpkgs/nixos/doc/manual/release-notes/rl-1909.xml
@@ -19,7 +19,9 @@
 
   <itemizedlist>
    <listitem>
-    <para />
+    <para>
+     End of support is planned for end of April 2020, handing over to 20.03.
+    </para>
    </listitem>
   </itemizedlist>
  </section>
diff --git a/nixpkgs/nixos/maintainers/option-usages.nix b/nixpkgs/nixos/maintainers/option-usages.nix
index 242c2a4dd442..a67a0ab960e5 100644
--- a/nixpkgs/nixos/maintainers/option-usages.nix
+++ b/nixpkgs/nixos/maintainers/option-usages.nix
@@ -145,7 +145,7 @@ let
   displayOptionsGraph =
      let
        checkList =
-         if !(isNull testOption) then [ testOption ]
+         if testOption != null then [ testOption ]
          else testOptions;
        checkAll = checkList == [];
      in
diff --git a/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix b/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix
index 2c18244621af..04fa8b9559a9 100644
--- a/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix
+++ b/nixpkgs/nixos/modules/config/fonts/fontconfig-penultimate.nix
@@ -31,7 +31,7 @@ let
   # use latest when no version is passed
   makeCacheConf = { version ? null }:
     let
-      fcPackage = if builtins.isNull version
+      fcPackage = if version == null
                   then "fontconfig"
                   else "fontconfig_${version}";
       makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
diff --git a/nixpkgs/nixos/modules/config/fonts/fontconfig.nix b/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
index d79c43c0b5b9..724158f73821 100644
--- a/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixpkgs/nixos/modules/config/fonts/fontconfig.nix
@@ -46,7 +46,7 @@ let cfg = config.fonts.fontconfig;
     # use latest when no version is passed
     makeCacheConf = { version ? null }:
       let
-        fcPackage = if builtins.isNull version
+        fcPackage = if version == null
                     then "fontconfig"
                     else "fontconfig_${version}";
         makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
diff --git a/nixpkgs/nixos/modules/config/sysctl.nix b/nixpkgs/nixos/modules/config/sysctl.nix
index 74bff602a477..0c6a7e2431aa 100644
--- a/nixpkgs/nixos/modules/config/sysctl.nix
+++ b/nixpkgs/nixos/modules/config/sysctl.nix
@@ -8,7 +8,7 @@ let
     name = "sysctl option value";
     check = val:
       let
-        checkType = x: isBool x || isString x || isInt x || isNull x;
+        checkType = x: isBool x || isString x || isInt x || x == null;
       in
         checkType val || (val._type or "" == "override" && checkType val.content);
     merge = loc: defs: mergeOneOption loc (filterOverrides defs);
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
index fd780be20825..d5c92cfc1d9e 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -198,7 +198,7 @@ let
     fi
 
     ${ # When there is a theme configured, use it, otherwise use the background image.
-    if (!isNull config.isoImage.grubTheme) then ''
+    if config.isoImage.grubTheme != null then ''
       # Sets theme.
       set theme=(hd0)/EFI/boot/grub-theme/theme.txt
       # Load theme fonts
@@ -622,7 +622,7 @@ in
         { source = "${pkgs.memtest86plus}/memtest.bin";
           target = "/boot/memtest.bin";
         }
-      ] ++ optionals (!isNull config.isoImage.grubTheme) [
+      ] ++ optionals (config.isoImage.grubTheme != null) [
         { source = config.isoImage.grubTheme;
           target = "/EFI/boot/grub-theme";
         }
diff --git a/nixpkgs/nixos/modules/misc/ids.nix b/nixpkgs/nixos/modules/misc/ids.nix
index 96ad4e904a49..aabf961f90c3 100644
--- a/nixpkgs/nixos/modules/misc/ids.nix
+++ b/nixpkgs/nixos/modules/misc/ids.nix
@@ -265,7 +265,7 @@
       syncthing = 237;
       caddy = 239;
       taskd = 240;
-      factorio = 241;
+      # factorio = 241; # DynamicUser = true
       # emby = 242; # unusued, removed 2019-05-01
       graylog = 243;
       sniproxy = 244;
@@ -567,7 +567,7 @@
       syncthing = 237;
       caddy = 239;
       taskd = 240;
-      factorio = 241;
+      # factorio = 241; # unused
       # emby = 242; # unused, removed 2019-05-01
       sniproxy = 244;
       nzbget = 245;
diff --git a/nixpkgs/nixos/modules/module-list.nix b/nixpkgs/nixos/modules/module-list.nix
index 089919d1d550..df9b0096393c 100644
--- a/nixpkgs/nixos/modules/module-list.nix
+++ b/nixpkgs/nixos/modules/module-list.nix
@@ -794,7 +794,6 @@
   ./services/web-servers/traefik.nix
   ./services/web-servers/uwsgi.nix
   ./services/web-servers/varnish/default.nix
-  ./services/web-servers/winstone.nix
   ./services/web-servers/zope2.nix
   ./services/x11/colord.nix
   ./services/x11/compton.nix
diff --git a/nixpkgs/nixos/modules/programs/bash/bash.nix b/nixpkgs/nixos/modules/programs/bash/bash.nix
index 27b5f9e4b642..a7e57b8608d7 100644
--- a/nixpkgs/nixos/modules/programs/bash/bash.nix
+++ b/nixpkgs/nixos/modules/programs/bash/bash.nix
@@ -34,7 +34,7 @@ let
 
   bashAliases = concatStringsSep "\n" (
     mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}")
-      (filterAttrs (k: v: !isNull v) cfg.shellAliases)
+      (filterAttrs (k: v: v != null) cfg.shellAliases)
   );
 
 in
diff --git a/nixpkgs/nixos/modules/programs/fish.nix b/nixpkgs/nixos/modules/programs/fish.nix
index 622d2f96fe41..87f6816e4ac0 100644
--- a/nixpkgs/nixos/modules/programs/fish.nix
+++ b/nixpkgs/nixos/modules/programs/fish.nix
@@ -10,7 +10,7 @@ let
 
   fishAliases = concatStringsSep "\n" (
     mapAttrsFlatten (k: v: "alias ${k} ${escapeShellArg v}")
-      (filterAttrs (k: v: !isNull v) cfg.shellAliases)
+      (filterAttrs (k: v: v != null) cfg.shellAliases)
   );
 
 in
diff --git a/nixpkgs/nixos/modules/programs/ssmtp.nix b/nixpkgs/nixos/modules/programs/ssmtp.nix
index 44756171b74c..0e060e3f5226 100644
--- a/nixpkgs/nixos/modules/programs/ssmtp.nix
+++ b/nixpkgs/nixos/modules/programs/ssmtp.nix
@@ -148,7 +148,7 @@ in
         UseSTARTTLS=${yesNo cfg.useSTARTTLS}
         #Debug=YES
         ${optionalString (cfg.authUser != "")       "AuthUser=${cfg.authUser}"}
-        ${optionalString (!isNull cfg.authPassFile) "AuthPassFile=${cfg.authPassFile}"}
+        ${optionalString (cfg.authPassFile != null) "AuthPassFile=${cfg.authPassFile}"}
       '';
 
     environment.systemPackages = [pkgs.ssmtp];
diff --git a/nixpkgs/nixos/modules/programs/zsh/zsh.nix b/nixpkgs/nixos/modules/programs/zsh/zsh.nix
index b7117e5f90d7..bdb37eae23ef 100644
--- a/nixpkgs/nixos/modules/programs/zsh/zsh.nix
+++ b/nixpkgs/nixos/modules/programs/zsh/zsh.nix
@@ -12,7 +12,7 @@ let
 
   zshAliases = concatStringsSep "\n" (
     mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}")
-      (filterAttrs (k: v: !isNull v) cfg.shellAliases)
+      (filterAttrs (k: v: v != null) cfg.shellAliases)
   );
 
 in
diff --git a/nixpkgs/nixos/modules/rename.nix b/nixpkgs/nixos/modules/rename.nix
index aa3d120c97f1..b2c030fb7791 100644
--- a/nixpkgs/nixos/modules/rename.nix
+++ b/nixpkgs/nixos/modules/rename.nix
@@ -210,6 +210,7 @@ with lib;
     (mkRemovedOptionModule [ "virtualisation" "xen" "qemu" ] "You don't need this option anymore, it will work without it.")
     (mkRemovedOptionModule [ "services" "logstash" "enableWeb" ] "The web interface was removed from logstash")
     (mkRemovedOptionModule [ "boot" "zfs" "enableLegacyCrypto" ] "The corresponding package was removed from nixpkgs.")
+    (mkRemovedOptionModule [ "services" "winstone" ] "The corresponding package was removed from nixpkgs.")
 
     # ZSH
     (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
diff --git a/nixpkgs/nixos/modules/services/backup/znapzend.nix b/nixpkgs/nixos/modules/services/backup/znapzend.nix
index 9c4c5545e35e..9c7f84655727 100644
--- a/nixpkgs/nixos/modules/services/backup/znapzend.nix
+++ b/nixpkgs/nixos/modules/services/backup/znapzend.nix
@@ -248,7 +248,7 @@ let
   cfg = config.services.znapzend;
 
   onOff = b: if b then "on" else "off";
-  nullOff = b: if isNull b then "off" else toString b;
+  nullOff = b: if b == null then "off" else toString b;
   stripSlashes = replaceStrings [ "/" ] [ "." ];
 
   attrsToFile = config: concatStringsSep "\n" (builtins.attrValues (
@@ -256,7 +256,7 @@ let
 
   mkDestAttrs = dst: with dst;
     mapAttrs' (n: v: nameValuePair "dst_${label}${n}" v) ({
-      "" = optionalString (! isNull host) "${host}:" + dataset;
+      "" = optionalString (host != null) "${host}:" + dataset;
       _plan = plan;
     } // optionalAttrs (presend != null) {
       _precmd = presend;
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/addons/dns.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/addons/dns.nix
index 4368159ea6e3..ee0ac632ecf0 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/addons/dns.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/addons/dns.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  version = "1.3.1";
+  version = "1.5.0";
   cfg = config.services.kubernetes.addons.dns;
   ports = {
     dns = 10053;
@@ -55,9 +55,9 @@ in {
       type = types.attrs;
       default = {
         imageName = "coredns/coredns";
-        imageDigest = "sha256:02382353821b12c21b062c59184e227e001079bb13ebd01f9d3270ba0fcbf1e4";
+        imageDigest = "sha256:e83beb5e43f8513fa735e77ffc5859640baea30a882a11cc75c4c3244a737d3c";
         finalImageTag = version;
-        sha256 = "0vbylgyxv2jm2mnzk6f28jbsj305zsxmx3jr6ngjq461czcl5fi5";
+        sha256 = "15sbmhrxjxidj0j0cccn1qxpg6al175w43m6ngspl0mc132zqc9q";
       };
     };
   };
@@ -160,7 +160,7 @@ in {
               fallthrough in-addr.arpa ip6.arpa
             }
             prometheus :${toString ports.metrics}
-            proxy . /etc/resolv.conf
+            forward . /etc/resolv.conf
             cache 30
             loop
             reload
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/apiserver.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/apiserver.nix
index 0c04648355b4..f293dd79f42a 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/apiserver.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/apiserver.nix
@@ -184,6 +184,12 @@ in
       type = bool;
     };
 
+    preferredAddressTypes = mkOption {
+      description = "List of the preferred NodeAddressTypes to use for kubelet connections.";
+      type = nullOr str;
+      default = null;
+    };
+
     proxyClientCertFile = mkOption {
       description = "Client certificate to use for connections to proxy.";
       default = null;
@@ -349,6 +355,8 @@ in
                 "--kubelet-client-certificate=${cfg.kubeletClientCertFile}"} \
               ${optionalString (cfg.kubeletClientKeyFile != null)
                 "--kubelet-client-key=${cfg.kubeletClientKeyFile}"} \
+              ${optionalString (cfg.preferredAddressTypes != null)
+                "--kubelet-preferred-address-types=${cfg.preferredAddressTypes}"} \
               ${optionalString (cfg.proxyClientCertFile != null)
                 "--proxy-client-cert-file=${cfg.proxyClientCertFile}"} \
               ${optionalString (cfg.proxyClientKeyFile != null)
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/kubelet.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/kubelet.nix
index 2a4a0624555d..ccc8a16e788a 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/kubelet.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/kubelet.nix
@@ -7,9 +7,9 @@ let
   cfg = top.kubelet;
 
   cniConfig =
-    if cfg.cni.config != [] && !(isNull cfg.cni.configDir) then
+    if cfg.cni.config != [] && cfg.cni.configDir != null then
       throw "Verbatim CNI-config and CNI configDir cannot both be set."
-    else if !(isNull cfg.cni.configDir) then
+    else if cfg.cni.configDir != null then
       cfg.cni.configDir
     else
       (pkgs.buildEnv {
@@ -373,7 +373,7 @@ in
       boot.kernelModules = ["br_netfilter"];
 
       services.kubernetes.kubelet.hostname = with config.networking;
-        mkDefault (hostName + optionalString (!isNull domain) ".${domain}");
+        mkDefault (hostName + optionalString (domain != null) ".${domain}");
 
       services.kubernetes.pki.certs = with top.lib; {
         kubelet = mkCert {
diff --git a/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix b/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
index 32eacad9025f..e68660e8bdd4 100644
--- a/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
+++ b/nixpkgs/nixos/modules/services/cluster/kubernetes/pki.nix
@@ -285,7 +285,7 @@ in
         };
       };
 
-      environment.etc.${cfg.etcClusterAdminKubeconfig}.source = mkIf (!isNull cfg.etcClusterAdminKubeconfig)
+      environment.etc.${cfg.etcClusterAdminKubeconfig}.source = mkIf (cfg.etcClusterAdminKubeconfig != null)
         (top.lib.mkKubeConfig "cluster-admin" clusterAdminKubeconfig);
 
       environment.systemPackages = mkIf (top.kubelet.enable || top.proxy.enable) [
diff --git a/nixpkgs/nixos/modules/services/continuous-integration/buildkite-agent.nix b/nixpkgs/nixos/modules/services/continuous-integration/buildkite-agent.nix
index 2136778aff47..12cc3d2b1ccc 100644
--- a/nixpkgs/nixos/modules/services/continuous-integration/buildkite-agent.nix
+++ b/nixpkgs/nixos/modules/services/continuous-integration/buildkite-agent.nix
@@ -236,7 +236,7 @@ in
       };
 
     assertions = [
-      { assertion = cfg.hooksPath == hooksDir || all isNull (attrValues cfg.hooks);
+      { assertion = cfg.hooksPath == hooksDir || all (v: v == null) (attrValues cfg.hooks);
         message = ''
           Options `services.buildkite-agent.hooksPath' and
           `services.buildkite-agent.hooks.<name>' are mutually exclusive.
diff --git a/nixpkgs/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixpkgs/nixos/modules/services/continuous-integration/jenkins/default.nix
index 1eca45fbd570..ec6a36413fe7 100644
--- a/nixpkgs/nixos/modules/services/continuous-integration/jenkins/default.nix
+++ b/nixpkgs/nixos/modules/services/continuous-integration/jenkins/default.nix
@@ -189,7 +189,7 @@ in {
 
       preStart =
         let replacePlugins =
-              if isNull cfg.plugins
+              if cfg.plugins == null
               then ""
               else
                 let pluginCmds = lib.attrsets.mapAttrsToList
diff --git a/nixpkgs/nixos/modules/services/databases/cassandra.nix b/nixpkgs/nixos/modules/services/databases/cassandra.nix
index d741ee48c48f..688938868020 100644
--- a/nixpkgs/nixos/modules/services/databases/cassandra.nix
+++ b/nixpkgs/nixos/modules/services/databases/cassandra.nix
@@ -22,11 +22,11 @@ let
              else {})
     );
   cassandraConfigWithAddresses = cassandraConfig //
-    ( if isNull cfg.listenAddress
+    ( if cfg.listenAddress == null
         then { listen_interface = cfg.listenInterface; }
         else { listen_address = cfg.listenAddress; }
     ) // (
-      if isNull cfg.rpcAddress
+      if cfg.rpcAddress == null
         then { rpc_interface = cfg.rpcInterface; }
         else { rpc_address = cfg.rpcAddress; }
     );
@@ -219,19 +219,13 @@ in {
   config = mkIf cfg.enable {
     assertions =
       [ { assertion =
-            ((isNull cfg.listenAddress)
-             || (isNull cfg.listenInterface)
-            ) && !((isNull cfg.listenAddress)
-                   && (isNull cfg.listenInterface)
-                  );
+          (cfg.listenAddress == null || cfg.listenInterface == null)
+          && !(cfg.listenAddress == null && cfg.listenInterface == null);
           message = "You have to set either listenAddress or listenInterface";
         }
         { assertion =
-            ((isNull cfg.rpcAddress)
-             || (isNull cfg.rpcInterface)
-            ) && !((isNull cfg.rpcAddress)
-                   && (isNull cfg.rpcInterface)
-                  );
+          (cfg.rpcAddress == null || cfg.rpcInterface == null)
+          && !(cfg.rpcAddress == null && cfg.rpcInterface == null);
           message = "You have to set either rpcAddress or rpcInterface";
         }
       ];
@@ -276,7 +270,7 @@ in {
           };
       };
     systemd.timers.cassandra-full-repair =
-      mkIf (!isNull cfg.fullRepairInterval) {
+      mkIf (cfg.fullRepairInterval != null) {
         description = "Schedule full repairs on Cassandra";
         wantedBy = [ "timers.target" ];
         timerConfig =
@@ -300,7 +294,7 @@ in {
           };
       };
     systemd.timers.cassandra-incremental-repair =
-      mkIf (!isNull cfg.incrementalRepairInterval) {
+      mkIf (cfg.incrementalRepairInterval != null) {
         description = "Schedule incremental repairs on Cassandra";
         wantedBy = [ "timers.target" ];
         timerConfig =
diff --git a/nixpkgs/nixos/modules/services/databases/cockroachdb.nix b/nixpkgs/nixos/modules/services/databases/cockroachdb.nix
index e977751b21ef..268fdcc819fd 100644
--- a/nixpkgs/nixos/modules/services/databases/cockroachdb.nix
+++ b/nixpkgs/nixos/modules/services/databases/cockroachdb.nix
@@ -7,7 +7,7 @@ let
   crdb = cfg.package;
 
   escape    = builtins.replaceStrings ["%"] ["%%"];
-  ifNotNull = v: s: optionalString (!isNull v) s;
+  ifNotNull = v: s: optionalString (v != null) s;
 
   startupCommand = lib.concatStringsSep " "
     [ # Basic startup
@@ -164,7 +164,7 @@ in
 
   config = mkIf config.services.cockroachdb.enable {
     assertions = [
-      { assertion = !cfg.insecure -> !(isNull cfg.certsDir);
+      { assertion = !cfg.insecure -> cfg.certsDir != null;
         message = "CockroachDB must have a set of SSL certificates (.certsDir), or run in Insecure Mode (.insecure = true)";
       }
     ];
diff --git a/nixpkgs/nixos/modules/services/databases/foundationdb.nix b/nixpkgs/nixos/modules/services/databases/foundationdb.nix
index 169ed37b348e..490c5e9d005a 100644
--- a/nixpkgs/nixos/modules/services/databases/foundationdb.nix
+++ b/nixpkgs/nixos/modules/services/databases/foundationdb.nix
@@ -35,7 +35,10 @@ let
     ${optionalString (cfg.class != null) "class = ${cfg.class}"}
     memory         = ${cfg.memory}
     storage_memory = ${cfg.storageMemory}
+
+    ${optionalString (lib.versionAtLeast cfg.package.version "6.1") ''
     trace_format   = ${cfg.traceFormat}
+    ''}
 
     ${optionalString (cfg.tls != null) ''
       tls_plugin           = ${pkg}/libexec/plugins/FDBLibTLS.so
@@ -327,6 +330,15 @@ in
   };
 
   config = mkIf cfg.enable {
+    assertions = [
+      { assertion = lib.versionOlder cfg.package.version "6.1" -> cfg.traceFormat == "xml";
+        message = ''
+          Versions of FoundationDB before 6.1 do not support configurable trace formats (only XML is supported).
+          This option has no effect for version '' + cfg.package.version + '', and enabling it is an error.
+        '';
+      }
+    ];
+
     environment.systemPackages = [ pkg ];
 
     users.users = optionalAttrs (cfg.user == "foundationdb") (singleton
diff --git a/nixpkgs/nixos/modules/services/databases/pgmanage.nix b/nixpkgs/nixos/modules/services/databases/pgmanage.nix
index 1a34c7f5ecee..1050c2dd481a 100644
--- a/nixpkgs/nixos/modules/services/databases/pgmanage.nix
+++ b/nixpkgs/nixos/modules/services/databases/pgmanage.nix
@@ -16,7 +16,7 @@ let
 
       super_only = ${builtins.toJSON cfg.superOnly}
 
-      ${optionalString (!isNull cfg.loginGroup) "login_group = ${cfg.loginGroup}"}
+      ${optionalString (cfg.loginGroup != null) "login_group = ${cfg.loginGroup}"}
 
       login_timeout = ${toString cfg.loginTimeout}
 
@@ -24,7 +24,7 @@ let
 
       sql_root = ${cfg.sqlRoot}
 
-      ${optionalString (!isNull cfg.tls) ''
+      ${optionalString (cfg.tls != null) ''
       tls_cert = ${cfg.tls.cert}
       tls_key = ${cfg.tls.key}
       ''}
diff --git a/nixpkgs/nixos/modules/services/databases/postgresql.nix b/nixpkgs/nixos/modules/services/databases/postgresql.nix
index 87b236dd5fd1..5661edbee2db 100644
--- a/nixpkgs/nixos/modules/services/databases/postgresql.nix
+++ b/nixpkgs/nixos/modules/services/databases/postgresql.nix
@@ -105,6 +105,80 @@ in
         '';
       };
 
+      ensureDatabases = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          Ensures that the specified databases exist.
+          This option will never delete existing databases, especially not when the value of this
+          option is changed. This means that databases created once through this option or
+          otherwise have to be removed manually.
+        '';
+        example = [
+          "gitea"
+          "nextcloud"
+        ];
+      };
+
+      ensureUsers = mkOption {
+        type = types.listOf (types.submodule {
+          options = {
+            name = mkOption {
+              type = types.str;
+              description = ''
+                Name of the user to ensure.
+              '';
+            };
+            ensurePermissions = mkOption {
+              type = types.attrsOf types.str;
+              default = {};
+              description = ''
+                Permissions to ensure for the user, specified as an attribute set.
+                The attribute names specify the database and tables to grant the permissions for.
+                The attribute values specify the permissions to grant. You may specify one or
+                multiple comma-separated SQL privileges here.
+
+                For more information on how to specify the target
+                and on which privileges exist, see the
+                <link xlink:href="https://www.postgresql.org/docs/current/sql-grant.html">GRANT syntax</link>.
+                The attributes are used as <code>GRANT ''${attrName} ON ''${attrValue}</code>.
+              '';
+              example = literalExample ''
+                {
+                  "DATABASE nextcloud" = "ALL PRIVILEGES";
+                  "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
+                }
+              '';
+            };
+          };
+        });
+        default = [];
+        description = ''
+          Ensures that the specified users exist and have at least the ensured permissions.
+          The PostgreSQL users will be identified using peer authentication. This authenticates the Unix user with the
+          same name only, and that without the need for a password.
+          This option will never delete existing users or remove permissions, especially not when the value of this
+          option is changed. This means that users created and permissions assigned once through this option or
+          otherwise have to be removed manually.
+        '';
+        example = literalExample ''
+          [
+            {
+              name = "nextcloud";
+              ensurePermissions = {
+                "DATABASE nextcloud" = "ALL PRIVILEGES";
+              };
+            }
+            {
+              name = "superuser";
+              ensurePermissions = {
+                "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
+              };
+            }
+          ]
+        '';
+      };
+
       enableTCPIP = mkOption {
         type = types.bool;
         default = false;
@@ -256,17 +330,30 @@ in
         # Wait for PostgreSQL to be ready to accept connections.
         postStart =
           ''
-            while ! ${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql --port=${toString cfg.port} -d postgres -c "" 2> /dev/null; do
+            PSQL="${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql --port=${toString cfg.port}"
+
+            while ! $PSQL -d postgres -c "" 2> /dev/null; do
                 if ! kill -0 "$MAINPID"; then exit 1; fi
                 sleep 0.1
             done
 
             if test -e "${cfg.dataDir}/.first_startup"; then
               ${optionalString (cfg.initialScript != null) ''
-                ${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql -f "${cfg.initialScript}" --port=${toString cfg.port} -d postgres
+                $PSQL -f "${cfg.initialScript}" -d postgres
               ''}
               rm -f "${cfg.dataDir}/.first_startup"
             fi
+          '' + optionalString (cfg.ensureDatabases != []) ''
+            ${concatMapStrings (database: ''
+              $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${database}'" | grep -q 1 || $PSQL -tAc "CREATE DATABASE ${database}"
+            '') cfg.ensureDatabases}
+          '' + ''
+            ${concatMapStrings (user: ''
+              $PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname='${user.name}'" | grep -q 1 || $PSQL -tAc "CREATE USER ${user.name}"
+              ${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
+                $PSQL -tAc "GRANT ${permission} ON ${database} TO ${user.name}"
+              '') user.ensurePermissions)}
+            '') cfg.ensureUsers}
           '';
 
         unitConfig.RequiresMountsFor = "${cfg.dataDir}";
diff --git a/nixpkgs/nixos/modules/services/desktops/geoclue2.nix b/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
index 840aa5294ed0..a16dbc04a5f7 100644
--- a/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
+++ b/nixpkgs/nixos/modules/services/desktops/geoclue2.nix
@@ -7,6 +7,56 @@ with lib;
 let
   # the demo agent isn't built by default, but we need it here
   package = pkgs.geoclue2.override { withDemoAgent = config.services.geoclue2.enableDemoAgent; };
+
+  cfg = config.services.geoclue2;
+
+  defaultWhitelist = [ "gnome-shell" "io.elementary.desktop.agent-geoclue2" ];
+
+  appConfigModule = types.submodule ({ name, ... }: {
+    options = {
+      desktopID = mkOption {
+        type = types.str;
+        description = "Desktop ID of the application.";
+      };
+
+      isAllowed = mkOption {
+        type = types.bool;
+        default = null;
+        description = ''
+          Whether the application will be allowed access to location information.
+        '';
+      };
+
+      isSystem = mkOption {
+        type = types.bool;
+        default = null;
+        description = ''
+          Whether the application is a system component or not.
+        '';
+      };
+
+      users = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = ''
+          List of UIDs of all users for which this application is allowed location
+          info access, Defaults to an empty string to allow it for all users.
+        '';
+      };
+    };
+
+    config.desktopID = mkDefault name;
+  });
+
+  appConfigToINICompatible = _: { desktopID, isAllowed, isSystem, users, ... }: {
+    name = desktopID;
+    value = {
+      allowed = isAllowed;
+      system = isSystem;
+      users = concatStringsSep ";" users;
+    };
+  };
+
 in
 {
 
@@ -35,23 +85,117 @@ in
         '';
       };
 
+      enableNmea = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to fetch location from NMEA sources on local network.
+        '';
+      };
+
+      enable3G = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable 3G source.
+        '';
+      };
+
+      enableCDMA = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable CDMA source.
+        '';
+      };
+
+      enableModemGPS = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable Modem-GPS source.
+        '';
+      };
+
+      enableWifi = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable WiFi source.
+        '';
+      };
+
+      geoProviderUrl = mkOption {
+        type = types.str;
+        default = "https://location.services.mozilla.com/v1/geolocate?key=geoclue";
+        example = "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_KEY";
+        description = ''
+          The url to the wifi GeoLocation Service.
+        '';
+      };
+
+      submitData = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to submit data to a GeoLocation Service.
+        '';
+      };
+
+      submissionUrl = mkOption {
+        type = types.str;
+        default = "https://location.services.mozilla.com/v1/submit?key=geoclue";
+        description = ''
+          The url to submit data to a GeoLocation Service.
+        '';
+      };
+
+      submissionNick = mkOption {
+        type = types.str;
+        default = "geoclue";
+        description = ''
+          A nickname to submit network data with.
+          Must be 2-32 characters long.
+        '';
+      };
+
+      appConfig = mkOption {
+        type = types.loaOf appConfigModule;
+        default = {};
+        example = literalExample ''
+          "com.github.app" = {
+            isAllowed = true;
+            isSystem = true;
+            users = [ "300" ];
+          };
+        '';
+        description = ''
+          Specify extra settings per application.
+        '';
+      };
+
     };
 
   };
 
 
   ###### implementation
-  config = mkIf config.services.geoclue2.enable {
+  config = mkIf cfg.enable {
 
     environment.systemPackages = [ package ];
 
     services.dbus.packages = [ package ];
 
     systemd.packages = [ package ];
-  
+
+    # restart geoclue service when the configuration changes
+    systemd.services."geoclue".restartTriggers = [
+      config.environment.etc."geoclue/geoclue.conf".source
+    ];
+
     # this needs to run as a user service, since it's associated with the
     # user who is making the requests
-    systemd.user.services = mkIf config.services.geoclue2.enableDemoAgent { 
+    systemd.user.services = mkIf cfg.enableDemoAgent {
       "geoclue-agent" = {
         description = "Geoclue agent";
         script = "${package}/libexec/geoclue-2.0/demos/agent";
@@ -62,7 +206,41 @@ in
       };
     };
 
-    environment.etc."geoclue/geoclue.conf".source = "${package}/etc/geoclue/geoclue.conf";
-  };
+    services.geoclue2.appConfig."epiphany" = {
+      isAllowed = true;
+      isSystem = false;
+    };
 
+    services.geoclue2.appConfig."firefox" = {
+      isAllowed = true;
+      isSystem = false;
+    };
+
+    environment.etc."geoclue/geoclue.conf".text =
+      generators.toINI {} ({
+        agent = {
+          whitelist = concatStringsSep ";"
+            (optional cfg.enableDemoAgent "geoclue-demo-agent" ++ defaultWhitelist);
+        };
+        network-nmea = {
+          enable = cfg.enableNmea;
+        };
+        "3g" = {
+          enable = cfg.enable3G;
+        };
+        cdma = {
+          enable = cfg.enableCDMA;
+        };
+        modem-gps = {
+          enable = cfg.enableModemGPS;
+        };
+        wifi = {
+          enable = cfg.enableWifi;
+          url = cfg.geoProviderUrl;
+          submit-data = boolToString cfg.submitData;
+          submission-url = cfg.submissionUrl;
+          submission-nick = cfg.submissionNick;
+        };
+      } // mapAttrs' appConfigToINICompatible cfg.appConfig);
+  };
 }
diff --git a/nixpkgs/nixos/modules/services/games/factorio.nix b/nixpkgs/nixos/modules/services/games/factorio.nix
index 3f6bf9de8931..d04673a6c8b8 100644
--- a/nixpkgs/nixos/modules/services/games/factorio.nix
+++ b/nixpkgs/nixos/modules/services/games/factorio.nix
@@ -6,7 +6,7 @@ let
   cfg = config.services.factorio;
   factorio = pkgs.factorio-headless;
   name = "Factorio";
-  stateDir = cfg.stateDir;
+  stateDir = "/var/lib/${cfg.stateDirName}";
   mkSavePath = name: "${stateDir}/saves/${name}.zip";
   configFile = pkgs.writeText "factorio.conf" ''
     use-system-read-write-data-directories=true
@@ -80,11 +80,11 @@ in
           customizations.
         '';
       };
-      stateDir = mkOption {
-        type = types.path;
-        default = "/var/lib/factorio";
+      stateDirName = mkOption {
+        type = types.string;
+        default = "factorio";
         description = ''
-          The server's data directory.
+          Name of the directory under /var/lib holding the server's data.
 
           The configuration and map will be stored here.
         '';
@@ -176,20 +176,6 @@ in
   };
 
   config = mkIf cfg.enable {
-    users = {
-      users.factorio = {
-        uid             = config.ids.uids.factorio;
-        description     = "Factorio server user";
-        group           = "factorio";
-        home            = stateDir;
-        createHome      = true;
-      };
-
-      groups.factorio = {
-        gid = config.ids.gids.factorio;
-      };
-    };
-
     systemd.services.factorio = {
       description   = "Factorio headless server";
       wantedBy      = [ "multi-user.target" ];
@@ -205,12 +191,10 @@ in
       ];
 
       serviceConfig = {
-        User = "factorio";
-        Group = "factorio";
         Restart = "always";
         KillSignal = "SIGINT";
-        WorkingDirectory = stateDir;
-        PrivateTmp = true;
+        DynamicUser = true;
+        StateDirectory = cfg.stateDirName;
         UMask = "0007";
         ExecStart = toString [
           "${factorio}/bin/factorio"
@@ -220,6 +204,20 @@ in
           "--server-settings=${serverSettingsFile}"
           (optionalString (cfg.mods != []) "--mod-directory=${modDir}")
         ];
+
+        # Sandboxing
+        NoNewPrivileges = true;
+        PrivateTmp = true;
+        PrivateDevices = true;
+        ProtectSystem = "strict";
+        ProtectHome = true;
+        ProtectControlGroups = true;
+        ProtectKernelModules = true;
+        ProtectKernelTunables = true;
+        RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
+        RestrictRealtime = true;
+        RestrictNamespaces = true;
+        MemoryDenyWriteExecute = true;
       };
     };
 
diff --git a/nixpkgs/nixos/modules/services/games/minecraft-server.nix b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
index 7d26d1501650..39a68f4b5536 100644
--- a/nixpkgs/nixos/modules/services/games/minecraft-server.nix
+++ b/nixpkgs/nixos/modules/services/games/minecraft-server.nix
@@ -215,8 +215,8 @@ in {
     networking.firewall = mkIf cfg.openFirewall (if cfg.declarative then {
       allowedUDPPorts = [ serverPort ];
       allowedTCPPorts = [ serverPort ]
-        ++ optional (! isNull queryPort) queryPort
-        ++ optional (! isNull rconPort) rconPort;
+        ++ optional (queryPort != null) queryPort
+        ++ optional (rconPort != null) rconPort;
     } else {
       allowedUDPPorts = [ defaultServerPort ];
       allowedTCPPorts = [ defaultServerPort ];
diff --git a/nixpkgs/nixos/modules/services/logging/logcheck.nix b/nixpkgs/nixos/modules/services/logging/logcheck.nix
index 9c64160e92bc..f139190a1709 100644
--- a/nixpkgs/nixos/modules/services/logging/logcheck.nix
+++ b/nixpkgs/nixos/modules/services/logging/logcheck.nix
@@ -227,7 +227,7 @@ in
     '';
 
     services.cron.systemCronJobs =
-        let withTime = name: {timeArgs, ...}: ! (builtins.isNull timeArgs);
+        let withTime = name: {timeArgs, ...}: timeArgs != null;
             mkCron = name: {user, cmdline, timeArgs, ...}: ''
               ${timeArgs} ${user} ${cmdline}
             '';
diff --git a/nixpkgs/nixos/modules/services/mail/dovecot.nix b/nixpkgs/nixos/modules/services/mail/dovecot.nix
index 30ad7d82fb80..139011dca23a 100644
--- a/nixpkgs/nixos/modules/services/mail/dovecot.nix
+++ b/nixpkgs/nixos/modules/services/mail/dovecot.nix
@@ -16,13 +16,13 @@ let
       sendmail_path = /run/wrappers/bin/sendmail
     ''
 
-    (if isNull cfg.sslServerCert then ''
+    (if cfg.sslServerCert == null then ''
       ssl = no
       disable_plaintext_auth = no
     '' else ''
       ssl_cert = <${cfg.sslServerCert}
       ssl_key = <${cfg.sslServerKey}
-      ${optionalString (!(isNull cfg.sslCACert)) ("ssl_ca = <" + cfg.sslCACert)}
+      ${optionalString (cfg.sslCACert != null) ("ssl_ca = <" + cfg.sslCACert)}
       ssl_dh = <${config.security.dhparams.params.dovecot2.path}
       disable_plaintext_auth = yes
     '')
@@ -298,7 +298,7 @@ in
   config = mkIf cfg.enable {
     security.pam.services.dovecot2 = mkIf cfg.enablePAM {};
 
-    security.dhparams = mkIf (! isNull cfg.sslServerCert) {
+    security.dhparams = mkIf (cfg.sslServerCert != null) {
       enable = true;
       params.dovecot2 = {};
     };
@@ -384,14 +384,14 @@ in
       { assertion = intersectLists cfg.protocols [ "pop3" "imap" ] != [];
         message = "dovecot needs at least one of the IMAP or POP3 listeners enabled";
       }
-      { assertion = isNull cfg.sslServerCert == isNull cfg.sslServerKey
-          && (!(isNull cfg.sslCACert) -> !(isNull cfg.sslServerCert || isNull cfg.sslServerKey));
+      { assertion = (cfg.sslServerCert == null) == (cfg.sslServerKey == null)
+          && (cfg.sslCACert != null -> !(cfg.sslServerCert == null || cfg.sslServerKey == null));
         message = "dovecot needs both sslServerCert and sslServerKey defined for working crypto";
       }
       { assertion = cfg.showPAMFailure -> cfg.enablePAM;
         message = "dovecot is configured with showPAMFailure while enablePAM is disabled";
       }
-      { assertion = (cfg.sieveScripts != {}) -> ((cfg.mailUser != null) && (cfg.mailGroup != null));
+      { assertion = cfg.sieveScripts != {} -> (cfg.mailUser != null && cfg.mailGroup != null);
         message = "dovecot requires mailUser and mailGroup to be set when sieveScripts is set";
       }
     ];
diff --git a/nixpkgs/nixos/modules/services/misc/bepasty.nix b/nixpkgs/nixos/modules/services/misc/bepasty.nix
index 006feca42b32..87d360681445 100644
--- a/nixpkgs/nixos/modules/services/misc/bepasty.nix
+++ b/nixpkgs/nixos/modules/services/misc/bepasty.nix
@@ -143,7 +143,7 @@ in
           serviceConfig = {
             Type = "simple";
             PrivateTmp = true;
-            ExecStartPre = assert !isNull server.secretKeyFile; pkgs.writeScript "bepasty-server.${name}-init" ''
+            ExecStartPre = assert server.secretKeyFile != null; pkgs.writeScript "bepasty-server.${name}-init" ''
               #!/bin/sh
               mkdir -p "${server.workDir}"
               mkdir -p "${server.dataDir}"
diff --git a/nixpkgs/nixos/modules/services/misc/errbot.nix b/nixpkgs/nixos/modules/services/misc/errbot.nix
index ac6ba2181de2..256adce2f02e 100644
--- a/nixpkgs/nixos/modules/services/misc/errbot.nix
+++ b/nixpkgs/nixos/modules/services/misc/errbot.nix
@@ -81,7 +81,7 @@ in {
 
     systemd.services = mapAttrs' (name: instanceCfg: nameValuePair "errbot-${name}" (
     let
-      dataDir = if !isNull instanceCfg.dataDir then instanceCfg.dataDir else
+      dataDir = if instanceCfg.dataDir != null then instanceCfg.dataDir else
         "/var/lib/errbot/${name}";
     in {
       after = [ "network-online.target" ];
diff --git a/nixpkgs/nixos/modules/services/misc/home-assistant.nix b/nixpkgs/nixos/modules/services/misc/home-assistant.nix
index 7f8d31bcf0b8..f1b351246740 100644
--- a/nixpkgs/nixos/modules/services/misc/home-assistant.nix
+++ b/nixpkgs/nixos/modules/services/misc/home-assistant.nix
@@ -21,32 +21,23 @@ let
 
   availableComponents = cfg.package.availableComponents;
 
-  # Given component "parentConfig.platform", returns whether config.parentConfig
-  # is a list containing a set with set.platform == "platform".
+  usedPlatforms = config:
+    if isAttrs config then
+      optional (config ? platform) config.platform
+      ++ concatMap usedPlatforms (attrValues config)
+    else if isList config then
+      concatMap usedPlatforms config
+    else [ ];
+
+  # Given a component "platform", looks up whether it is used in the config
+  # as `platform = "platform";`.
   #
-  # For example, the component sensor.luftdaten is used as follows:
+  # For example, the component mqtt.sensor is used as follows:
   # config.sensor = [ {
-  #   platform = "luftdaten";
+  #   platform = "mqtt";
   #   ...
   # } ];
-  #
-  # Beginning with 0.87 Home Assistant is migrating their components to the
-  # scheme "platform.subComponent", e.g. "hue.light" instead of "light.hue".
-  # See https://developers.home-assistant.io/blog/2019/02/19/the-great-migration.html.
-  # Hence, we also check whether we find an entry in the config when interpreting
-  # the first part of the path as the component.
-  useComponentPlatform = component:
-    let
-      path = splitString "." component;
-      # old: platform is the last part of path
-      parentConfig = attrByPath (init path) null cfg.config;
-      platform = last path;
-      # new: platform is the first part of the path
-      parentConfig' = attrByPath (tail path) null cfg.config;
-      platform' = head path;
-    in
-      (isList parentConfig && any (item: item.platform or null == platform) parentConfig)
-      || (isList parentConfig' && any (item: item.platform or null == platform') parentConfig');
+  useComponentPlatform = component: elem component (usedPlatforms cfg.config);
 
   # Returns whether component is used in config
   useComponent = component:
diff --git a/nixpkgs/nixos/modules/services/misc/taskserver/default.nix b/nixpkgs/nixos/modules/services/misc/taskserver/default.nix
index 483bc99ad946..07dbee69db0c 100644
--- a/nixpkgs/nixos/modules/services/misc/taskserver/default.nix
+++ b/nixpkgs/nixos/modules/services/misc/taskserver/default.nix
@@ -48,7 +48,7 @@ let
     type = types.nullOr types.int;
     default = null;
     example = 365;
-    apply = val: if isNull val then -1 else val;
+    apply = val: if val == null then -1 else val;
     description = mkAutoDesc ''
       The expiration time of ${desc} in days or <literal>null</literal> for no
       expiration time.
@@ -82,7 +82,7 @@ let
          then attrByPath newPath (notFound newPath) cfg.pki.manual
          else findPkiDefinitions newPath val;
     in flatten (mapAttrsToList mkSublist attrs);
-  in all isNull (findPkiDefinitions [] manualPkiOptions);
+  in all (x: x == null) (findPkiDefinitions [] manualPkiOptions);
 
   orgOptions = { ... }: {
     options.users = mkOption {
diff --git a/nixpkgs/nixos/modules/services/misc/zoneminder.nix b/nixpkgs/nixos/modules/services/misc/zoneminder.nix
index 2bd2f3c7cc08..01720ba432ed 100644
--- a/nixpkgs/nixos/modules/services/misc/zoneminder.nix
+++ b/nixpkgs/nixos/modules/services/misc/zoneminder.nix
@@ -17,7 +17,7 @@ let
   defaultDir = "/var/lib/${user}";
   home = if useCustomDir then cfg.storageDir else defaultDir;
 
-  useCustomDir = !(builtins.isNull cfg.storageDir);
+  useCustomDir = cfg.storageDir != null;
 
   socket = "/run/phpfpm/${dirName}.sock";
 
diff --git a/nixpkgs/nixos/modules/services/monitoring/graphite.nix b/nixpkgs/nixos/modules/services/monitoring/graphite.nix
index 2365142af40e..d6473220c140 100644
--- a/nixpkgs/nixos/modules/services/monitoring/graphite.nix
+++ b/nixpkgs/nixos/modules/services/monitoring/graphite.nix
@@ -19,13 +19,13 @@ let
 
   graphiteLocalSettings = pkgs.writeText "graphite_local_settings.py" (
     "STATIC_ROOT = '${staticDir}'\n" +
-    optionalString (! isNull config.time.timeZone) "TIME_ZONE = '${config.time.timeZone}'\n"
+    optionalString (config.time.timeZone != null) "TIME_ZONE = '${config.time.timeZone}'\n"
     + cfg.web.extraConfig
   );
 
   graphiteApiConfig = pkgs.writeText "graphite-api.yaml" ''
     search_index: ${dataDir}/index
-    ${optionalString (!isNull config.time.timeZone) ''time_zone: ${config.time.timeZone}''}
+    ${optionalString (config.time.timeZone != null) ''time_zone: ${config.time.timeZone}''}
     ${optionalString (cfg.api.finders != []) ''finders:''}
     ${concatMapStringsSep "\n" (f: "  - " + f.moduleName) cfg.api.finders}
     ${optionalString (cfg.api.functions != []) ''functions:''}
diff --git a/nixpkgs/nixos/modules/services/networking/flannel.nix b/nixpkgs/nixos/modules/services/networking/flannel.nix
index c1f778ac139a..dd2f6454e954 100644
--- a/nixpkgs/nixos/modules/services/networking/flannel.nix
+++ b/nixpkgs/nixos/modules/services/networking/flannel.nix
@@ -92,7 +92,7 @@ in {
         Needed when running with Kubernetes as backend as this cannot be auto-detected";
       '';
       type = types.nullOr types.str;
-      default = with config.networking; (hostName + optionalString (!isNull domain) ".${domain}");
+      default = with config.networking; (hostName + optionalString (domain != null) ".${domain}");
       example = "node1.example.com";
     };
 
diff --git a/nixpkgs/nixos/modules/services/networking/i2pd.nix b/nixpkgs/nixos/modules/services/networking/i2pd.nix
index 40478b85b75e..f2be417738ee 100644
--- a/nixpkgs/nixos/modules/services/networking/i2pd.nix
+++ b/nixpkgs/nixos/modules/services/networking/i2pd.nix
@@ -12,9 +12,9 @@ let
   boolOpt = k: v: k + " = " + boolToString v;
   intOpt = k: v: k + " = " + toString v;
   lstOpt = k: xs: k + " = " + concatStringsSep "," xs;
-  optionalNullString = o: s: optional (! isNull s) (strOpt o s);
-  optionalNullBool = o: b: optional (! isNull b) (boolOpt o b);
-  optionalNullInt = o: i: optional (! isNull i) (intOpt o i);
+  optionalNullString = o: s: optional (s != null) (strOpt o s);
+  optionalNullBool = o: b: optional (b != null) (boolOpt o b);
+  optionalNullInt = o: i: optional (i != null) (intOpt o i);
   optionalEmptyList = o: l: optional ([] != l) (lstOpt o l);
 
   mkEnableTrueOption = name: mkEnableOption name // { default = true; };
@@ -225,7 +225,7 @@ let
   i2pdSh = pkgs.writeScriptBin "i2pd" ''
     #!/bin/sh
     exec ${pkgs.i2pd}/bin/i2pd \
-      ${if isNull cfg.address then "" else "--host="+cfg.address} \
+      ${if cfg.address == null then "" else "--host="+cfg.address} \
       --service \
       --conf=${i2pdConf} \
       --tunconf=${tunnelConf}
diff --git a/nixpkgs/nixos/modules/services/networking/mxisd.nix b/nixpkgs/nixos/modules/services/networking/mxisd.nix
index 0b9824f29fd7..02e89f441b34 100644
--- a/nixpkgs/nixos/modules/services/networking/mxisd.nix
+++ b/nixpkgs/nixos/modules/services/networking/mxisd.nix
@@ -103,20 +103,12 @@ in {
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
 
-      # mxisd / spring.boot needs the configuration to be named "application.yaml"
-      preStart = ''
-        config=${cfg.dataDir}/application.yaml
-        cp ${configFile} $config
-        chmod 444 $config
-      '';
-
       serviceConfig = {
         Type = "simple";
         User = "mxisd";
         Group = "mxisd";
-        ExecStart = "${cfg.package}/bin/mxisd --spring.config.location=${cfg.dataDir}/ --spring.profiles.active=systemd --java.security.egd=file:/dev/./urandom";
+        ExecStart = "${cfg.package}/bin/mxisd -c ${configFile}";
         WorkingDirectory = cfg.dataDir;
-        SuccessExitStatus = 143;
         Restart = "on-failure";
       };
     };
diff --git a/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix b/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
index 5e74a96664f0..95a174122d04 100644
--- a/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
+++ b/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
@@ -56,7 +56,7 @@ rec {
   };
 
   documentDefault = description : strongswanDefault :
-    if isNull strongswanDefault
+    if strongswanDefault == null
     then description
     else description + ''
       </para><para>
diff --git a/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix b/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix
index fb87e81f3215..193ad27f035a 100644
--- a/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix
+++ b/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix
@@ -45,10 +45,10 @@ rec {
     filterEmptySets (
       (mapParamsRecursive (path: name: param:
         let value = attrByPath path null cfg;
-        in optionalAttrs (!isNull value) (param.render name value)
+        in optionalAttrs (value != null) (param.render name value)
       ) ps));
 
-  filterEmptySets = set : filterAttrs (n: v: !(isNull v)) (mapAttrs (name: value:
+  filterEmptySets = set : filterAttrs (n: v: (v != null)) (mapAttrs (name: value:
     if isAttrs value
     then let value' = filterEmptySets value;
          in if value' == {}
diff --git a/nixpkgs/nixos/modules/services/networking/syncthing.nix b/nixpkgs/nixos/modules/services/networking/syncthing.nix
index 114a64dfb175..89dae7bb3f86 100644
--- a/nixpkgs/nixos/modules/services/networking/syncthing.nix
+++ b/nixpkgs/nixos/modules/services/networking/syncthing.nix
@@ -5,6 +5,57 @@ with lib;
 let
   cfg = config.services.syncthing;
   defaultUser = "syncthing";
+
+  devices = mapAttrsToList (name: device: {
+    deviceID = device.id;
+    inherit (device) name addresses introducer;
+  }) cfg.declarative.devices;
+
+  folders = mapAttrsToList ( _: folder: {
+    inherit (folder) path id label type;
+    devices = map (device: { deviceId = cfg.declarative.devices.${device}.id; }) folder.devices;
+    rescanIntervalS = folder.rescanInterval;
+    fsWatcherEnabled = folder.watch;
+    fsWatcherDelayS = folder.watchDelay;
+    ignorePerms = folder.ignorePerms;
+  }) cfg.declarative.folders;
+
+  # get the api key by parsing the config.xml
+  getApiKey = pkgs.writers.writeDash "getAPIKey" ''
+    ${pkgs.libxml2}/bin/xmllint \
+      --xpath 'string(configuration/gui/apikey)'\
+      ${cfg.configDir}/config.xml
+  '';
+
+  updateConfig = pkgs.writers.writeDash "merge-syncthing-config" ''
+    set -efu
+    # wait for syncthing port to open
+    until ${pkgs.curl}/bin/curl -Ss ${cfg.guiAddress} -o /dev/null; do
+      sleep 1
+    done
+
+    API_KEY=$(${getApiKey})
+    OLD_CFG=$(${pkgs.curl}/bin/curl -Ss \
+      -H "X-API-Key: $API_KEY" \
+      ${cfg.guiAddress}/rest/system/config)
+
+    # generate the new config by merging with the nixos config options
+    NEW_CFG=$(echo "$OLD_CFG" | ${pkgs.jq}/bin/jq -s '.[] as $in | $in * {
+      "devices": (${builtins.toJSON devices}${optionalString (! cfg.declarative.overrideDevices) " + $in.devices"}),
+      "folders": (${builtins.toJSON folders}${optionalString (! cfg.declarative.overrideFolders) " + $in.folders"})
+    }')
+
+    # POST the new config to syncthing
+    echo "$NEW_CFG" | ${pkgs.curl}/bin/curl -Ss \
+      -H "X-API-Key: $API_KEY" \
+      ${cfg.guiAddress}/rest/system/config -d @-
+
+    # restart syncthing after sending the new config
+    ${pkgs.curl}/bin/curl -Ss \
+      -H "X-API-Key: $API_KEY" \
+      -X POST \
+      ${cfg.guiAddress}/rest/system/restart
+  '';
 in {
   ###### interface
   options = {
@@ -16,6 +67,187 @@ in {
         available on http://127.0.0.1:8384/.
       '';
 
+      declarative = {
+        cert = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = ''
+            Path to users cert.pem file, will be copied into the syncthing's
+            <literal>configDir</literal>
+          '';
+        };
+
+        key = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = ''
+            Path to users key.pem file, will be copied into the syncthing's
+            <literal>configDir</literal>
+          '';
+        };
+
+        overrideDevices = mkOption {
+          type = types.bool;
+          default = true;
+          description = ''
+            Whether to delete the devices which are not configured via the
+            <literal>declarative.devices</literal> option.
+            If set to false, devices added via the webinterface will
+            persist but will have to be deleted manually.
+          '';
+        };
+
+        devices = mkOption {
+          default = {};
+          description = ''
+            Peers/devices which syncthing should communicate with.
+          '';
+          example = [
+            {
+              name = "bigbox";
+              id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
+              addresses = [ "tcp://192.168.0.10:51820" ];
+            }
+          ];
+          type = types.attrsOf (types.submodule ({ config, ... }: {
+            options = {
+
+              name = mkOption {
+                type = types.str;
+                default = config._module.args.name;
+                description = ''
+                  Name of the device
+                '';
+              };
+
+              addresses = mkOption {
+                type = types.listOf types.str;
+                default = [];
+                description = ''
+                  The addresses used to connect to the device.
+                  If this is let empty, dynamic configuration is attempted
+                '';
+              };
+
+              id = mkOption {
+                type = types.str;
+                description = ''
+                  The id of the other peer, this is mandatory. It's documented at
+                  https://docs.syncthing.net/dev/device-ids.html
+                '';
+              };
+
+              introducer = mkOption {
+                type = types.bool;
+                default = false;
+                description = ''
+                  If the device should act as an introducer and be allowed
+                  to add folders on this computer.
+                '';
+              };
+
+            };
+          }));
+        };
+
+        overrideFolders = mkOption {
+          type = types.bool;
+          default = true;
+          description = ''
+            Whether to delete the folders which are not configured via the
+            <literal>declarative.folders</literal> option.
+            If set to false, folders added via the webinterface will persist
+            but will have to be deleted manually.
+          '';
+        };
+
+        folders = mkOption {
+          default = {};
+          description = ''
+            folders which should be shared by syncthing.
+          '';
+          type = types.attrsOf (types.submodule ({ config, ... }: {
+            options = {
+
+              path = mkOption {
+                type = types.str;
+                default = config._module.args.name;
+                description = ''
+                  The path to the folder which should be shared.
+                '';
+              };
+
+              id = mkOption {
+                type = types.str;
+                default = config._module.args.name;
+                description = ''
+                  The id of the folder. Must be the same on all devices.
+                '';
+              };
+
+              label = mkOption {
+                type = types.str;
+                default = config._module.args.name;
+                description = ''
+                  The label of the folder.
+                '';
+              };
+
+              devices = mkOption {
+                type = types.listOf types.str;
+                default = [];
+                description = ''
+                  The devices this folder should be shared with. Must be defined
+                  in the <literal>declarative.devices</literal> attribute.
+                '';
+              };
+
+              rescanInterval = mkOption {
+                type = types.int;
+                default = 3600;
+                description = ''
+                  How often the folders should be rescaned for changes.
+                '';
+              };
+
+              type = mkOption {
+                type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
+                default = "sendreceive";
+                description = ''
+                  Whether to send only changes from this folder, only receive them
+                  or propagate both.
+                '';
+              };
+
+              watch = mkOption {
+                type = types.bool;
+                default = true;
+                description = ''
+                  Whether the folder should be watched for changes by inotify.
+                '';
+              };
+
+              watchDelay = mkOption {
+                type = types.int;
+                default = 10;
+                description = ''
+                  The delay after an inotify event is triggered.
+                '';
+              };
+
+              ignorePerms = mkOption {
+                type = types.bool;
+                default = true;
+                description = ''
+                  Whether to propagate permission changes.
+                '';
+              };
+
+            };
+          }));
+        };
+      };
+
       guiAddress = mkOption {
         type = types.str;
         default = "127.0.0.1:8384";
@@ -151,6 +383,23 @@ in {
           RestartForceExitStatus="3 4";
           User = cfg.user;
           Group = cfg.group;
+          ExecStartPre = mkIf (cfg.declarative.cert != null || cfg.declarative.key != null)
+            "+${pkgs.writers.writeBash "syncthing-copy-keys" ''
+              mkdir -p ${cfg.configDir}
+              chown ${cfg.user}:${cfg.group} ${cfg.configDir}
+              chmod 700 ${cfg.configDir}
+              ${optionalString (cfg.declarative.cert != null) ''
+                cp ${toString cfg.declarative.cert} ${cfg.configDir}/cert.pem
+                chown ${cfg.user}:${cfg.group} ${cfg.configDir}/cert.pem
+                chmod 400 ${cfg.configDir}/cert.pem
+              ''}
+              ${optionalString (cfg.declarative.key != null) ''
+                cp ${toString cfg.declarative.key} ${cfg.configDir}/key.pem
+                chown ${cfg.user}:${cfg.group} ${cfg.configDir}/key.pem
+                chmod 400 ${cfg.configDir}/key.pem
+              ''}
+            ''}"
+          ;
           ExecStart = ''
             ${cfg.package}/bin/syncthing \
               -no-browser \
@@ -159,6 +408,17 @@ in {
           '';
         };
       };
+      syncthing-init = {
+        after = [ "syncthing.service" ];
+        wantedBy = [ "multi-user.target" ];
+
+        serviceConfig = {
+          User = cfg.user;
+          RemainAfterExit = true;
+          Type = "oneshot";
+          ExecStart = updateConfig;
+        };
+      };
 
       syncthing-resume = {
         wantedBy = [ "suspend.target" ];
diff --git a/nixpkgs/nixos/modules/services/networking/xinetd.nix b/nixpkgs/nixos/modules/services/networking/xinetd.nix
index 002245027804..2d7cd5cebb48 100644
--- a/nixpkgs/nixos/modules/services/networking/xinetd.nix
+++ b/nixpkgs/nixos/modules/services/networking/xinetd.nix
@@ -146,7 +146,7 @@ in
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       path = [ pkgs.xinetd ];
-      script = "xinetd -syslog daemon -dontfork -stayalive -f ${configFile}";
+      script = "exec xinetd -syslog daemon -dontfork -stayalive -f ${configFile}";
     };
   };
 }
diff --git a/nixpkgs/nixos/modules/services/search/kibana.nix b/nixpkgs/nixos/modules/services/search/kibana.nix
index 2a6e8250850c..c096af731ad4 100644
--- a/nixpkgs/nixos/modules/services/search/kibana.nix
+++ b/nixpkgs/nixos/modules/services/search/kibana.nix
@@ -129,7 +129,7 @@ in {
 
           This defaults to the singleton list [ca] when the <option>ca</option> option is defined.
         '';
-        default = if isNull cfg.elasticsearch.ca then [] else [ca];
+        default = if cfg.elasticsearch.ca == null then [] else [ca];
         type = types.listOf types.path;
       };
 
diff --git a/nixpkgs/nixos/modules/services/security/fprintd.nix b/nixpkgs/nixos/modules/services/security/fprintd.nix
index 9ed7f2a2efd9..8ece1ca19013 100644
--- a/nixpkgs/nixos/modules/services/security/fprintd.nix
+++ b/nixpkgs/nixos/modules/services/security/fprintd.nix
@@ -25,6 +25,16 @@ in
         '';
       };
 
+      package = mkOption {
+        type = types.package;
+        default = pkgs.fprintd;
+        defaultText = "pkgs.fprintd";
+        example = "pkgs.fprintd-thinkpad";
+        description = ''
+          fprintd package to use.
+        '';
+      };
+
     };
 
   };
@@ -38,7 +48,7 @@ in
 
     environment.systemPackages = [ pkgs.fprintd ];
 
-    systemd.packages = [ pkgs.fprintd ];
+    systemd.packages = [ cfg.package ];
 
   };
 
diff --git a/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix b/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
index 0c5fe8c0ef5f..61f203ef9e7d 100644
--- a/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
+++ b/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
@@ -58,11 +58,11 @@ let
       httponly = cookie.httpOnly;
     };
     set-xauthrequest = setXauthrequest;
-  } // lib.optionalAttrs (!isNull cfg.email.addresses) {
+  } // lib.optionalAttrs (cfg.email.addresses != null) {
     authenticated-emails-file = authenticatedEmailsFile;
   } // lib.optionalAttrs (cfg.passBasicAuth) {
     basic-auth-password = cfg.basicAuthPassword;
-  } // lib.optionalAttrs (!isNull cfg.htpasswd.file) {
+  } // lib.optionalAttrs (cfg.htpasswd.file != null) {
     display-htpasswd-file = cfg.htpasswd.displayForm;
   } // lib.optionalAttrs tls.enable {
     tls-cert = tls.certificate;
@@ -71,7 +71,7 @@ let
   } // (getProviderOptions cfg cfg.provider) // cfg.extraConfig;
 
   mapConfig = key: attr:
-  if (!isNull attr && attr != []) then (
+  if attr != null && attr != [] then (
     if isDerivation attr then mapConfig key (toString attr) else
     if (builtins.typeOf attr) == "set" then concatStringsSep " "
       (mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else
@@ -538,7 +538,7 @@ in
 
   config = mkIf cfg.enable {
 
-    services.oauth2_proxy = mkIf (!isNull cfg.keyFile) {
+    services.oauth2_proxy = mkIf (cfg.keyFile != null) {
       clientID = mkDefault null;
       clientSecret = mkDefault null;
       cookie.secret = mkDefault null;
diff --git a/nixpkgs/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix b/nixpkgs/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
index 644aad82df2c..910e1d937bf3 100644
--- a/nixpkgs/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
@@ -215,7 +215,7 @@ in {
 
     # /etc/icingaweb2
     environment.etc = let
-      doModule = name: optionalAttrs (cfg.modules."${name}".enable) (nameValuePair "icingaweb2/enabledModules/${name}" { source = "${pkgs.icingaweb2}/modules/${name}"; });
+      doModule = name: optionalAttrs (cfg.modules."${name}".enable) { "icingaweb2/enabledModules/${name}".source = "${pkgs.icingaweb2}/modules/${name}"; };
     in {}
       # Module packages
       // (mapAttrs' (k: v: nameValuePair "icingaweb2/enabledModules/${k}" { source = v; }) cfg.modulePackages)
diff --git a/nixpkgs/nixos/modules/services/web-apps/miniflux.nix b/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
index 1d60004e574d..304712d0efc3 100644
--- a/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/miniflux.nix
@@ -85,7 +85,7 @@ in
         DynamicUser = true;
         RuntimeDirectory = "miniflux";
         RuntimeDirectoryMode = "0700";
-        EnvironmentFile = if isNull cfg.adminCredentialsFile
+        EnvironmentFile = if cfg.adminCredentialsFile == null
         then defaultCredentials
         else cfg.adminCredentialsFile;
       };
diff --git a/nixpkgs/nixos/modules/services/web-apps/restya-board.nix b/nixpkgs/nixos/modules/services/web-apps/restya-board.nix
index 15fd943a0826..2e5e0ea6622d 100644
--- a/nixpkgs/nixos/modules/services/web-apps/restya-board.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/restya-board.nix
@@ -184,7 +184,7 @@ in
         phpOptions = ''
           date.timezone = "CET"
 
-          ${optionalString (!isNull cfg.email.server) ''
+          ${optionalString (cfg.email.server != null) ''
             SMTP = ${cfg.email.server}
             smtp_port = ${toString cfg.email.port}
             auth_username = ${cfg.email.login}
@@ -282,7 +282,7 @@ in
 
         sed -i "s@^php@${config.services.phpfpm.phpPackage}/bin/php@" "${runDir}/server/php/shell/"*.sh
 
-        ${if (isNull cfg.database.host) then ''
+        ${if (cfg.database.host == null) then ''
           sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', 'localhost');/g" "${runDir}/server/php/config.inc.php"
           sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', 'restya');/g" "${runDir}/server/php/config.inc.php"
         '' else ''
@@ -311,7 +311,7 @@ in
         chown -R "${cfg.user}"."${cfg.group}" "${cfg.dataDir}/media"
         chown -R "${cfg.user}"."${cfg.group}" "${cfg.dataDir}/client/img"
 
-        ${optionalString (isNull cfg.database.host) ''
+        ${optionalString (cfg.database.host == null) ''
           if ! [ -e "${cfg.dataDir}/.db-initialized" ]; then
             ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \
               ${config.services.postgresql.package}/bin/psql -U ${config.services.postgresql.superUser} \
@@ -367,14 +367,14 @@ in
     };
     users.groups.restya-board = {};
 
-    services.postgresql.enable = mkIf (isNull cfg.database.host) true;
+    services.postgresql.enable = mkIf (cfg.database.host == null) true;
 
-    services.postgresql.identMap = optionalString (isNull cfg.database.host)
+    services.postgresql.identMap = optionalString (cfg.database.host == null)
       ''
         restya-board-users restya-board restya_board
       '';
 
-    services.postgresql.authentication = optionalString (isNull cfg.database.host)
+    services.postgresql.authentication = optionalString (cfg.database.host == null)
       ''
         local restya_board all ident map=restya-board-users
       '';
diff --git a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
index 8f00f81b078c..a8fb11f114ec 100644
--- a/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -690,7 +690,7 @@ in
 
         ; Don't advertise PHP
         expose_php = off
-      '' + optionalString (!isNull config.time.timeZone) ''
+      '' + optionalString (config.time.timeZone != null) ''
 
         ; Apparently PHP doesn't use $TZ.
         date.timezone = "${config.time.timeZone}"
diff --git a/nixpkgs/nixos/modules/services/web-servers/winstone.nix b/nixpkgs/nixos/modules/services/web-servers/winstone.nix
deleted file mode 100644
index 064ead5ce4bb..000000000000
--- a/nixpkgs/nixos/modules/services/web-servers/winstone.nix
+++ /dev/null
@@ -1,129 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
-  cfg = config.services.winstone;
-
-  winstoneOpts = { name, ... }: {
-    options = {
-      name = mkOption {
-        default = name;
-        internal = true;
-      };
-
-      serviceName = mkOption {
-        type = types.str;
-        description = ''
-          The name of the systemd service. By default, it is
-          derived from the winstone instance name.
-        '';
-      };
-
-      warFile = mkOption {
-        type = types.str;
-        description = ''
-          The WAR file that Winstone should serve.
-        '';
-      };
-
-      javaPackage = mkOption {
-        type = types.package;
-        default = pkgs.jre;
-        defaultText = "pkgs.jre";
-        description = ''
-          Which Java derivation to use for running Winstone.
-        '';
-      };
-
-      user = mkOption {
-        type = types.str;
-        description = ''
-          The user that should run this Winstone process and
-          own the working directory.
-        '';
-      };
-
-      group = mkOption {
-        type = types.str;
-        description = ''
-          The group that will own the working directory.
-        '';
-      };
-
-      workDir = mkOption {
-        type = types.str;
-        description = ''
-          The working directory for this Winstone instance. Will
-          contain extracted webapps etc. The directory will be
-          created if it doesn't exist.
-        '';
-      };
-
-      extraJavaOptions = mkOption {
-        type = types.listOf types.str;
-        default = [];
-        description = ''
-          Extra command line options given to the java process running
-          Winstone.
-        '';
-      };
-
-      extraOptions = mkOption {
-        type = types.listOf types.str;
-        default = [];
-        description = ''
-          Extra command line options given to the Winstone process.
-        '';
-      };
-    };
-
-    config = {
-      workDir = mkDefault "/run/winstone/${name}";
-      serviceName = mkDefault "winstone-${name}";
-    };
-  };
-
-  mkService = cfg: let
-    opts = concatStringsSep " " (cfg.extraOptions ++ [
-      "--warfile ${cfg.warFile}"
-    ]);
-
-    javaOpts = concatStringsSep " " (cfg.extraJavaOptions ++ [
-      "-Djava.io.tmpdir=${cfg.workDir}"
-      "-jar ${pkgs.winstone}/lib/winstone.jar"
-    ]);
-  in {
-    wantedBy = [ "multi-user.target" ];
-    description = "winstone service for ${cfg.name}";
-    preStart = ''
-      mkdir -p "${cfg.workDir}"
-      chown ${cfg.user}:${cfg.group} "${cfg.workDir}"
-    '';
-    serviceConfig = {
-      ExecStart = "${cfg.javaPackage}/bin/java ${javaOpts} ${opts}";
-      User = cfg.user;
-      PermissionsStartOnly = true;
-    };
-  };
-
-in {
-
-  options = {
-    services.winstone = mkOption {
-      default = {};
-      type = with types; attrsOf (submodule winstoneOpts);
-      description = ''
-        Defines independent Winstone services, each serving one WAR-file.
-      '';
-    };
-  };
-
-  config = mkIf (cfg != {}) {
-
-    systemd.services = mapAttrs' (n: c: nameValuePair c.serviceName (mkService c)) cfg;
-
-  };
-
-}
diff --git a/nixpkgs/nixos/modules/services/x11/colord.nix b/nixpkgs/nixos/modules/services/x11/colord.nix
index 17568df091d4..cf113ad2af8c 100644
--- a/nixpkgs/nixos/modules/services/x11/colord.nix
+++ b/nixpkgs/nixos/modules/services/x11/colord.nix
@@ -29,6 +29,7 @@ in {
     environment.etc."tmpfiles.d/colord.conf".source = "${pkgs.colord}/lib/tmpfiles.d/colord.conf";
 
     users.users.colord = {
+      isSystemUser = true;
       home = "/var/lib/colord";
       group = "colord";
     };
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 7b65f1b85c69..ef6820d33260 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -120,9 +120,6 @@ in {
     security.polkit.enable = true;
     services.udisks2.enable = true;
     services.accounts-daemon.enable = true;
-    services.geoclue2.enable = mkDefault true;
-    # GNOME should have its own geoclue agent
-    services.geoclue2.enableDemoAgent = false;
     services.dleyna-renderer.enable = mkDefault true;
     services.dleyna-server.enable = mkDefault true;
     services.gnome3.at-spi2-core.enable = true;
@@ -191,6 +188,24 @@ in {
       '') cfg.sessionPath}
     '';
 
+
+    services.geoclue2.enable = mkDefault true;
+    # GNOME should have its own geoclue agent
+    services.geoclue2.enableDemoAgent = false;
+
+    services.geoclue2.appConfig."gnome-datetime-panel" = {
+      isAllowed = true;
+      isSystem = true;
+    };
+    services.geoclue2.appConfig."gnome-color-panel" = {
+      isAllowed = true;
+      isSystem = true;
+    };
+    services.geoclue2.appConfig."org.gnome.Shell" = {
+      isAllowed = true;
+      isSystem = true;
+    };
+
     environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
 
     # Override default mimeapps
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
index e1eeb32aa1a0..9a0f77a856a7 100644
--- a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -118,9 +118,6 @@ in
       (mkIf config.services.printing.enable  ([pkgs.system-config-printer]) )
     ];
     services.pantheon.contractor.enable = mkDefault true;
-    services.geoclue2.enable = mkDefault true;
-    # pantheon has pantheon-agent-geoclue2
-    services.geoclue2.enableDemoAgent = false;
     services.gnome3.at-spi2-core.enable = true;
     services.gnome3.evince.enable = mkDefault true;
     services.gnome3.evolution-data-server.enable = true;
@@ -140,6 +137,14 @@ in
     services.xserver.updateDbusEnvironment = true;
     services.zeitgeist.enable = mkDefault true;
 
+    services.geoclue2.enable = mkDefault true;
+    # pantheon has pantheon-agent-geoclue2
+    services.geoclue2.enableDemoAgent = false;
+    services.geoclue2.appConfig."io.elementary.desktop.agent-geoclue2" = {
+      isAllowed = true;
+      isSystem = true;
+    };
+
     networking.networkmanager.enable = mkDefault true;
     networking.networkmanager.basePackages =
       { inherit (pkgs) networkmanager modemmanager wpa_supplicant;
diff --git a/nixpkgs/nixos/modules/virtualisation/docker-containers.nix b/nixpkgs/nixos/modules/virtualisation/docker-containers.nix
index c1f0ba303e32..3e882a1383ff 100644
--- a/nixpkgs/nixos/modules/virtualisation/docker-containers.nix
+++ b/nixpkgs/nixos/modules/virtualisation/docker-containers.nix
@@ -174,13 +174,13 @@ let
         "--rm"
         "--name=%n"
         "--log-driver=${container.log-driver}"
-      ] ++ optional (! isNull container.entrypoint)
+      ] ++ optional (container.entrypoint != null)
         "--entrypoint=${escapeShellArg container.entrypoint}"
         ++ (mapAttrsToList (k: v: "-e ${escapeShellArg k}=${escapeShellArg v}") container.environment)
         ++ map (p: "-p ${escapeShellArg p}") container.ports
-        ++ optional (! isNull container.user) "-u ${escapeShellArg container.user}"
+        ++ optional (container.user != null) "-u ${escapeShellArg container.user}"
         ++ map (v: "-v ${escapeShellArg v}") container.volumes
-        ++ optional (! isNull container.workdir) "-w ${escapeShellArg container.workdir}"
+        ++ optional (container.workdir != null) "-w ${escapeShellArg container.workdir}"
         ++ map escapeShellArg container.extraDockerOptions
         ++ [container.image]
         ++ map escapeShellArg container.cmd
diff --git a/nixpkgs/nixos/modules/virtualisation/google-compute-image.nix b/nixpkgs/nixos/modules/virtualisation/google-compute-image.nix
index 0d2d25d30752..d172ae38fdcf 100644
--- a/nixpkgs/nixos/modules/virtualisation/google-compute-image.nix
+++ b/nixpkgs/nixos/modules/virtualisation/google-compute-image.nix
@@ -51,7 +51,7 @@ in
         popd
       '';
       format = "raw";
-      configFile = if isNull cfg.configFile then defaultConfigFile else cfg.configFile;
+      configFile = if cfg.configFile == null then defaultConfigFile else cfg.configFile;
       inherit (cfg) diskSize;
       inherit config lib pkgs;
     };
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index d495b2fa6333..5be7c4292e5f 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -151,6 +151,7 @@ in
   mumble = handleTest ./mumble.nix {};
   munin = handleTest ./munin.nix {};
   mutableUsers = handleTest ./mutable-users.nix {};
+  mxisd = handleTest ./mxisd.nix {};
   mysql = handleTest ./mysql.nix {};
   mysqlBackup = handleTest ./mysql-backup.nix {};
   mysqlReplication = handleTest ./mysql-replication.nix {};
@@ -230,12 +231,14 @@ in
   strongswan-swanctl = handleTest ./strongswan-swanctl.nix {};
   sudo = handleTest ./sudo.nix {};
   switchTest = handleTest ./switch-test.nix {};
+  syncthing-init = handleTest ./syncthing-init.nix {};
   syncthing-relay = handleTest ./syncthing-relay.nix {};
   systemd = handleTest ./systemd.nix {};
   systemd-confinement = handleTest ./systemd-confinement.nix {};
   pdns-recursor = handleTest ./pdns-recursor.nix {};
   taskserver = handleTest ./taskserver.nix {};
   telegraf = handleTest ./telegraf.nix {};
+  tinydns = handleTest ./tinydns.nix {};
   tomcat = handleTest ./tomcat.nix {};
   tor = handleTest ./tor.nix {};
   transmission = handleTest ./transmission.nix {};
diff --git a/nixpkgs/nixos/tests/redmine.nix b/nixpkgs/nixos/tests/redmine.nix
index ea72a0121d11..cbdb5c8d2954 100644
--- a/nixpkgs/nixos/tests/redmine.nix
+++ b/nixpkgs/nixos/tests/redmine.nix
@@ -7,7 +7,7 @@ with import ../lib/testing.nix { inherit system pkgs; };
 with pkgs.lib;
 
 let
-  redmineTest = package: makeTest {
+  mysqlTest = package: makeTest {
     machine =
       { config, pkgs, ... }:
       { services.mysql.enable = true;
@@ -21,6 +21,7 @@ let
 
         services.redmine.enable = true;
         services.redmine.package = package;
+        services.redmine.database.type = "mysql2";
         services.redmine.database.socket = "/run/mysqld/mysqld.sock";
         services.redmine.plugins = {
           redmine_env_auth = pkgs.fetchurl {
@@ -38,7 +39,44 @@ let
 
     testScript = ''
       startAll;
+      $machine->waitForUnit('redmine.service');
+      $machine->waitForOpenPort('3000');
+      $machine->succeed("curl --fail http://localhost:3000/");
+    '';
+  };
+
+  pgsqlTest = package: makeTest {
+    machine =
+      { config, pkgs, ... }:
+      { services.postgresql.enable = true;
+        services.postgresql.ensureDatabases = [ "redmine" ];
+        services.postgresql.ensureUsers = [
+          { name = "redmine";
+            ensurePermissions = { "DATABASE redmine" = "ALL PRIVILEGES"; };
+          }
+        ];
+
+        services.redmine.enable = true;
+        services.redmine.package = package;
+        services.redmine.database.type = "postgresql";
+        services.redmine.database.host = "";
+        services.redmine.database.port = 5432;
+        services.redmine.plugins = {
+          redmine_env_auth = pkgs.fetchurl {
+            url = https://github.com/Intera/redmine_env_auth/archive/0.7.zip;
+            sha256 = "1xb8lyarc7mpi86yflnlgyllh9hfwb9z304f19dx409gqpia99sc";
+          };
+        };
+        services.redmine.themes = {
+          dkuk-redmine_alex_skin = pkgs.fetchurl {
+            url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
+            sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
+          };
+        };
+      };
 
+    testScript = ''
+      startAll;
       $machine->waitForUnit('redmine.service');
       $machine->waitForOpenPort('3000');
       $machine->succeed("curl --fail http://localhost:3000/");
@@ -46,13 +84,18 @@ let
   };
 in
 {
-  redmine_3 = redmineTest pkgs.redmine // {
-    name = "redmine_3";
+  v3-mysql = mysqlTest pkgs.redmine // {
+    name = "v3-mysql";
+    meta.maintainers = [ maintainers.aanderse ];
+  };
+
+  v4-mysql = mysqlTest pkgs.redmine_4 // {
+    name = "v4-mysql";
     meta.maintainers = [ maintainers.aanderse ];
   };
 
-  redmine_4 = redmineTest pkgs.redmine_4 // {
-    name = "redmine_4";
+  v4-pgsql = pgsqlTest pkgs.redmine_4 // {
+    name = "v4-pgsql";
     meta.maintainers = [ maintainers.aanderse ];
   };
 }
diff --git a/nixpkgs/nixos/tests/syncthing-init.nix b/nixpkgs/nixos/tests/syncthing-init.nix
new file mode 100644
index 000000000000..811a466ff941
--- /dev/null
+++ b/nixpkgs/nixos/tests/syncthing-init.nix
@@ -0,0 +1,30 @@
+import ./make-test.nix ({ lib, pkgs, ... }: let
+
+  testId = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
+
+in {
+  name = "syncthing-init";
+  meta.maintainers = with pkgs.stdenv.lib.maintainers; [ lassulus ];
+
+  machine = {
+    services.syncthing = {
+      enable = true;
+      declarative = {
+        devices.testDevice = {
+          id = testId;
+        };
+        folders.testFolder = {
+          path = "/tmp/test";
+          devices = [ "testDevice" ];
+        };
+      };
+    };
+  };
+
+  testScript = ''
+    $machine->waitForUnit("syncthing-init.service");
+    $machine->succeed("cat /var/lib/syncthing/config.xml") =~ /${testId}/ or die;
+    $machine->succeed("cat /var/lib/syncthing/config.xml") =~ /testFolder/ or die;
+  '';
+})
+
diff --git a/nixpkgs/nixos/tests/tinydns.nix b/nixpkgs/nixos/tests/tinydns.nix
new file mode 100644
index 000000000000..cb7ee0c5fb5e
--- /dev/null
+++ b/nixpkgs/nixos/tests/tinydns.nix
@@ -0,0 +1,26 @@
+import ./make-test.nix ({ lib, ...} : {
+  name = "tinydns";
+  meta = {
+    maintainers = with lib.maintainers; [ basvandijk ];
+  };
+  nodes = {
+    nameserver = { config, lib, ... } : let
+      ip = (lib.head config.networking.interfaces.eth1.ipv4.addresses).address;
+    in {
+      networking.nameservers = [ ip ];
+      services.tinydns = {
+        enable = true;
+        inherit ip;
+        data = ''
+          .foo.bar:${ip}
+          +.bla.foo.bar:1.2.3.4:300
+        '';
+      };
+    };
+  };
+  testScript = ''
+    $nameserver->start;
+    $nameserver->waitForUnit("tinydns.service");
+    $nameserver->succeed("host bla.foo.bar | grep '1\.2\.3\.4'");
+  '';
+})
diff --git a/nixpkgs/nixos/tests/upnp.nix b/nixpkgs/nixos/tests/upnp.nix
index 3f2dd13fb560..98344aee3efa 100644
--- a/nixpkgs/nixos/tests/upnp.nix
+++ b/nixpkgs/nixos/tests/upnp.nix
@@ -47,7 +47,7 @@ in
 
       client1 =
         { pkgs, nodes, ... }:
-        { environment.systemPackages = [ pkgs.miniupnpc pkgs.netcat ];
+        { environment.systemPackages = [ pkgs.miniupnpc_2 pkgs.netcat ];
           virtualisation.vlans = [ 2 ];
           networking.defaultGateway = internalRouterAddress;
           networking.interfaces.eth1.ipv4.addresses = [
@@ -63,7 +63,7 @@ in
 
       client2 =
         { pkgs, ... }:
-        { environment.systemPackages = [ pkgs.miniupnpc ];
+        { environment.systemPackages = [ pkgs.miniupnpc_2 ];
           virtualisation.vlans = [ 1 ];
           networking.interfaces.eth1.ipv4.addresses = [
             { address = externalClient2Address; prefixLength = 24; }