summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2018-08-17 13:44:40 +0200
committerVladimír Čunát <vcunat@gmail.com>2018-08-17 13:45:21 +0200
commitcbabebcc2e3b884296fedf8591e04f59240b3939 (patch)
tree54f637fbb59548753ac613ec3e4f56aae97a5e6e /nixos/modules
parent7a22083e1271869294a074cbe7a971f2d8abb4f4 (diff)
parent93147d737d24f55d8da7257e24d840c9f9b1fe6c (diff)
downloadnixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar.gz
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar.bz2
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar.lz
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar.xz
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.tar.zst
nixlib-cbabebcc2e3b884296fedf8591e04f59240b3939.zip
Merge branch 'master' into staging-next
Hydra: ?compare=1473892
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/profiles/installation-device.nix3
-rw-r--r--nixos/modules/rename.nix1
-rw-r--r--nixos/modules/services/desktops/accountsservice.nix10
-rw-r--r--nixos/modules/services/desktops/geoclue2.nix39
-rw-r--r--nixos/modules/services/desktops/zeitgeist.nix26
-rw-r--r--nixos/modules/services/logging/syslog-ng.nix2
-rw-r--r--nixos/modules/services/misc/synergy.nix12
-rw-r--r--nixos/modules/services/monitoring/datadog-agent.nix236
-rw-r--r--nixos/modules/services/monitoring/dd-agent/dd-agent.nix80
-rw-r--r--nixos/modules/services/network-filesystems/samba.nix10
-rw-r--r--nixos/modules/services/networking/dhcpcd.nix2
-rw-r--r--nixos/modules/services/system/localtime.nix10
-rw-r--r--nixos/modules/services/web-servers/hydron.nix12
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix2
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix7
-rw-r--r--nixos/modules/services/x11/redshift.nix3
-rw-r--r--nixos/modules/system/boot/networkd.nix189
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix35
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix3
-rw-r--r--nixos/modules/virtualisation/virtualbox-host.nix16
21 files changed, 559 insertions, 141 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index e19853efd73c..396e91204079 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -247,6 +247,7 @@
   ./services/desktops/gnome3/tracker-miners.nix
   ./services/desktops/profile-sync-daemon.nix
   ./services/desktops/telepathy.nix
+  ./services/desktops/zeitgeist.nix
   ./services/development/bloop.nix
   ./services/development/hoogle.nix
   ./services/editors/emacs.nix
@@ -407,6 +408,7 @@
   ./services/monitoring/cadvisor.nix
   ./services/monitoring/collectd.nix
   ./services/monitoring/das_watchdog.nix
+  ./services/monitoring/datadog-agent.nix
   ./services/monitoring/dd-agent/dd-agent.nix
   ./services/monitoring/fusion-inventory.nix
   ./services/monitoring/grafana.nix
diff --git a/nixos/modules/profiles/installation-device.nix b/nixos/modules/profiles/installation-device.nix
index 57d947b52684..ff4a23a18d06 100644
--- a/nixos/modules/profiles/installation-device.nix
+++ b/nixos/modules/profiles/installation-device.nix
@@ -31,7 +31,8 @@ with lib;
     #services.rogue.enable = true;
 
     # Disable some other stuff we don't need.
-    security.sudo.enable = false;
+    security.sudo.enable = mkDefault false;
+    services.udisks2.enable = mkDefault false;
 
     # Automatically log in at the virtual consoles.
     services.mingetty.autologinUser = "root";
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 75f02ea78e64..f032f10e4557 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -256,6 +256,7 @@ with lib;
     (mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
     (mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
     (mkRemovedOptionModule [ "virtualisation" "xen" "qemu" ] "You don't need this option anymore, it will work without it.")
+    (mkRemovedOptionModule [ "boot" "zfs" "enableLegacyCrypto" ] "The corresponding package was removed from nixpkgs.")
 
     # ZSH
     (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
diff --git a/nixos/modules/services/desktops/accountsservice.nix b/nixos/modules/services/desktops/accountsservice.nix
index 2a7450669ea0..933b9da2c83c 100644
--- a/nixos/modules/services/desktops/accountsservice.nix
+++ b/nixos/modules/services/desktops/accountsservice.nix
@@ -32,15 +32,21 @@ with lib;
 
     environment.systemPackages = [ pkgs.accountsservice ];
 
+    # Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice
+    environment.pathsToLink = [ "/share/accountsservice" ];
+
     services.dbus.packages = [ pkgs.accountsservice ];
 
     systemd.packages = [ pkgs.accountsservice ];
 
-    systemd.services.accounts-daemon= {
+    systemd.services.accounts-daemon = {
 
       wantedBy = [ "graphical.target" ];
 
-    } // (mkIf (!config.users.mutableUsers) {
+      # Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice
+      environment.XDG_DATA_DIRS = "${config.system.path}/share";
+
+    } // (optionalAttrs (!config.users.mutableUsers) {
       environment.NIXOS_USERS_PURE = "true";
     });
   };
diff --git a/nixos/modules/services/desktops/geoclue2.nix b/nixos/modules/services/desktops/geoclue2.nix
index c5a000d5c6a7..dafb0af20756 100644
--- a/nixos/modules/services/desktops/geoclue2.nix
+++ b/nixos/modules/services/desktops/geoclue2.nix
@@ -4,6 +4,10 @@
 
 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; };
+in
 {
 
   ###### interface
@@ -21,21 +25,42 @@ with lib;
         '';
       };
 
+      enableDemoAgent = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to use the GeoClue demo agent. This should be
+          overridden by desktop environments that provide their own
+          agent.
+        '';
+      };
+
     };
 
   };
 
 
   ###### implementation
-
   config = mkIf config.services.geoclue2.enable {
 
-    environment.systemPackages = [ pkgs.geoclue2 ];
-
-    services.dbus.packages = [ pkgs.geoclue2 ];
-
-    systemd.packages = [ pkgs.geoclue2 ];
-
+    environment.systemPackages = [ package ];
+
+    services.dbus.packages = [ package ];
+
+    systemd.packages = [ package ];
+  
+    # 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 { 
+      "geoclue-agent" = {
+        description = "Geoclue agent";
+        script = "${package}/libexec/geoclue-2.0/demos/agent";
+        # this should really be `partOf = [ "geoclue.service" ]`, but
+        # we can't be part of a system service, and the agent should
+        # be okay with the main service coming and going
+        wantedBy = [ "default.target" ];
+      };
+    };
   };
 
 }
diff --git a/nixos/modules/services/desktops/zeitgeist.nix b/nixos/modules/services/desktops/zeitgeist.nix
new file mode 100644
index 000000000000..20c82ccdd56c
--- /dev/null
+++ b/nixos/modules/services/desktops/zeitgeist.nix
@@ -0,0 +1,26 @@
+# Zeitgeist
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+
+  options = {
+    services.zeitgeist = {
+      enable = mkEnableOption "zeitgeist";
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.services.zeitgeist.enable {
+
+    environment.systemPackages = [ pkgs.zeitgeist ];
+
+    services.dbus.packages = [ pkgs.zeitgeist ];
+
+    systemd.packages = [ pkgs.zeitgeist ];
+  };
+}
diff --git a/nixos/modules/services/logging/syslog-ng.nix b/nixos/modules/services/logging/syslog-ng.nix
index 21be286a6e98..65e103ac2ba5 100644
--- a/nixos/modules/services/logging/syslog-ng.nix
+++ b/nixos/modules/services/logging/syslog-ng.nix
@@ -85,9 +85,11 @@ in {
       after = [ "multi-user.target" ]; # makes sure hostname etc is set
       serviceConfig = {
         Type = "notify";
+        PIDFile = pidFile;
         StandardOutput = "null";
         Restart = "on-failure";
         ExecStart = "${cfg.package}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}";
+        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
       };
     };
   };
diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix
index 7e8eadbe5f37..b89cb41ac3ad 100644
--- a/nixos/modules/services/misc/synergy.nix
+++ b/nixos/modules/services/misc/synergy.nix
@@ -83,20 +83,20 @@ in
 
   config = mkMerge [
     (mkIf cfgC.enable {
-      systemd.services."synergy-client" = {
-        after = [ "network.target" ];
+      systemd.user.services."synergy-client" = {
+        after = [ "network.target" "graphical-session.target" ];
         description = "Synergy client";
-        wantedBy = optional cfgC.autoStart "multi-user.target";
+        wantedBy = optional cfgC.autoStart "graphical-session.target";
         path = [ pkgs.synergy ];
         serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
         serviceConfig.Restart = "on-failure";
       };
     })
     (mkIf cfgS.enable {
-      systemd.services."synergy-server" = {
-        after = [ "network.target" ];
+      systemd.user.services."synergy-server" = {
+        after = [ "network.target" "graphical-session.target" ];
         description = "Synergy server";
-        wantedBy = optional cfgS.autoStart "multi-user.target";
+        wantedBy = optional cfgS.autoStart "graphical-session.target";
         path = [ pkgs.synergy ];
         serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }'';
         serviceConfig.Restart = "on-failure";
diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix
new file mode 100644
index 000000000000..f8ee34ebdf88
--- /dev/null
+++ b/nixos/modules/services/monitoring/datadog-agent.nix
@@ -0,0 +1,236 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.datadog-agent;
+
+  ddConf = {
+    dd_url              = "https://app.datadoghq.com";
+    skip_ssl_validation = "no";
+    api_key             = "";
+    confd_path          = "/etc/datadog-agent/conf.d";
+    additional_checksd  = "/etc/datadog-agent/checks.d";
+    use_dogstatsd       = "yes";
+  }
+  // optionalAttrs (cfg.logLevel != null) { log_level = cfg.logLevel; }
+  // optionalAttrs (cfg.hostname != null) { inherit (cfg) hostname; }
+  // optionalAttrs (cfg.tags != null ) { tags = concatStringsSep ", " cfg.tags; }
+  // cfg.extraConfig;
+
+  # Generate Datadog configuration files for each configured checks.
+  # This works because check configurations have predictable paths,
+  # and because JSON is a valid subset of YAML.
+  makeCheckConfigs = entries: mapAttrsToList (name: conf: {
+    source = pkgs.writeText "${name}-check-conf.yaml" (builtins.toJSON conf);
+    target = "datadog-agent/conf.d/${name}.d/conf.yaml";
+  }) entries;
+
+  defaultChecks = {
+    disk = cfg.diskCheck;
+    network = cfg.networkCheck;
+  };
+
+  # Assemble all check configurations and the top-level agent
+  # configuration.
+  etcfiles = with pkgs; with builtins; [{
+    source = writeText "datadog.yaml" (toJSON ddConf);
+    target = "datadog-agent/datadog.yaml";
+  }] ++ makeCheckConfigs (cfg.checks // defaultChecks);
+
+  # Apply the configured extraIntegrations to the provided agent
+  # package. See the documentation of `dd-agent/integrations-core.nix`
+  # for detailed information on this.
+  datadogPkg = cfg.package.overrideAttrs(_: {
+    python = (pkgs.datadog-integrations-core cfg.extraIntegrations).python;
+  });
+in {
+  options.services.datadog-agent = {
+    enable = mkOption {
+      description = ''
+        Whether to enable the datadog-agent v6 monitoring service
+      '';
+      default = false;
+      type = types.bool;
+    };
+
+    package = mkOption {
+      default = pkgs.datadog-agent;
+      defaultText = "pkgs.datadog-agent";
+      description = ''
+        Which DataDog v6 agent package to use. Note that the provided
+        package is expected to have an overridable `python`-attribute
+        which configures the Python environment with the Datadog
+        checks.
+      '';
+      type = types.package;
+    };
+
+    apiKeyFile = mkOption {
+      description = ''
+        Path to a file containing the Datadog API key to associate the
+        agent with your account.
+      '';
+      example = "/run/keys/datadog_api_key";
+      type = types.path;
+    };
+
+    tags = mkOption {
+      description = "The tags to mark this Datadog agent";
+      example = [ "test" "service" ];
+      default = null;
+      type = types.nullOr (types.listOf types.str);
+    };
+
+    hostname = mkOption {
+      description = "The hostname to show in the Datadog dashboard (optional)";
+      default = null;
+      example = "mymachine.mydomain";
+      type = types.uniq (types.nullOr types.string);
+    };
+
+    logLevel = mkOption {
+      description = "Logging verbosity.";
+      default = null;
+      type = types.nullOr (types.enum ["DEBUG" "INFO" "WARN" "ERROR"]);
+    };
+
+    extraIntegrations = mkOption {
+      default = {};
+      type    = types.attrs;
+
+      description = ''
+        Extra integrations from the Datadog core-integrations
+        repository that should be built and included.
+
+        By default the included integrations are disk, mongo, network,
+        nginx and postgres.
+
+        To include additional integrations the name of the derivation
+        and a function to filter its dependencies from the Python
+        package set must be provided.
+      '';
+
+      example = {
+        ntp = (pythonPackages: [ pythonPackages.ntplib ]);
+      };
+    };
+
+    extraConfig = mkOption {
+      default = {};
+      type = types.attrs;
+      description = ''
+        Extra configuration options that will be merged into the
+        main config file <filename>datadog.yaml</filename>.
+      '';
+     };
+
+    checks = mkOption {
+      description = ''
+        Configuration for all Datadog checks. Keys of this attribute
+        set will be used as the name of the check to create the
+        appropriate configuration in `conf.d/$check.d/conf.yaml`.
+
+        The configuration is converted into JSON from the plain Nix
+        language configuration, meaning that you should write
+        configuration adhering to Datadog's documentation - but in Nix
+        language.
+
+        Refer to the implementation of this module (specifically the
+        definition of `defaultChecks`) for an example.
+
+        Note: The 'disk' and 'network' check are configured in
+        separate options because they exist by default. Attempting to
+        override their configuration here will have no effect.
+      '';
+
+      example = {
+        http_check = {
+          init_config = null; # sic!
+          instances = [
+            {
+              name = "some-service";
+              url = "http://localhost:1337/healthz";
+              tags = [ "some-service" ];
+            }
+          ];
+        };
+      };
+
+      default = {};
+
+      # sic! The structure of the values is up to the check, so we can
+      # not usefully constrain the type further.
+      type = with types; attrsOf attrs;
+    };
+
+    diskCheck = mkOption {
+      description = "Disk check config";
+      type = types.attrs;
+      default = {
+        init_config = {};
+        instances = [ { use-mount = "no"; } ];
+      };
+    };
+
+    networkCheck = mkOption {
+      description = "Network check config";
+      type = types.attrs;
+      default = {
+        init_config = {};
+        # Network check only supports one configured instance
+        instances = [ { collect_connection_state = false;
+          excluded_interfaces = [ "lo" "lo0" ]; } ];
+      };
+    };
+  };
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ datadogPkg pkgs.sysstat pkgs.procps ];
+
+    users.extraUsers.datadog = {
+      description = "Datadog Agent User";
+      uid = config.ids.uids.datadog;
+      group = "datadog";
+      home = "/var/log/datadog/";
+      createHome = true;
+    };
+
+    users.extraGroups.datadog.gid = config.ids.gids.datadog;
+
+    systemd.services = let
+      makeService = attrs: recursiveUpdate {
+        path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "datadog";
+          Group = "datadog";
+          Restart = "always";
+          RestartSec = 2;
+          PrivateTmp = true;
+        };
+        restartTriggers = [ datadogPkg ] ++ map (etc: etc.source) etcfiles;
+      } attrs;
+    in {
+      datadog-agent = makeService {
+        description = "Datadog agent monitor";
+        preStart = ''
+          chown -R datadog: /etc/datadog-agent
+          rm -f /etc/datadog-agent/auth_token
+        '';
+        script = ''
+          export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile})
+          exec ${datadogPkg}/bin/agent start -c /etc/datadog-agent/datadog.yaml
+        '';
+        serviceConfig.PermissionsStartOnly = true;
+      };
+
+      dd-jmxfetch = lib.mkIf (lib.hasAttr "jmx" cfg.checks) (makeService {
+        description = "Datadog JMX Fetcher";
+        path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ];
+        serviceConfig.ExecStart = "${datadogPkg}/bin/dd-jmxfetch";
+      });
+    };
+
+    environment.etc = etcfiles;
+  };
+}
diff --git a/nixos/modules/services/monitoring/dd-agent/dd-agent.nix b/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
index cf65b6c28cf2..abc8d65d58f2 100644
--- a/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
+++ b/nixos/modules/services/monitoring/dd-agent/dd-agent.nix
@@ -114,13 +114,22 @@ let
 in {
   options.services.dd-agent = {
     enable = mkOption {
-      description = "Whether to enable the dd-agent montioring service";
+      description = ''
+        Whether to enable the dd-agent v5 monitoring service.
+        For datadog-agent v6, see <option>services.datadog-agent.enable</option>.
+      '';
       default = false;
       type = types.bool;
     };
 
     api_key = mkOption {
-      description = "The Datadog API key to associate the agent with your account";
+      description = ''
+        The Datadog API key to associate the agent with your account.
+
+        Warning: this key is stored in cleartext within the world-readable
+        Nix store! Consider using the new v6
+        <option>services.datadog-agent</option> module instead.
+      '';
       example = "ae0aa6a8f08efa988ba0a17578f009ab";
       type = types.str;
     };
@@ -188,48 +197,41 @@ in {
 
     users.groups.datadog.gid = config.ids.gids.datadog;
 
-    systemd.services.dd-agent = {
-      description = "Datadog agent monitor";
-      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps pkgs.gohai ];
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig = {
-        ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
-        User = "datadog";
-        Group = "datadog";
-        Restart = "always";
-        RestartSec = 2;
+    systemd.services = let
+      makeService = attrs: recursiveUpdate {
+        path = [ pkgs.dd-agent pkgs.python pkgs.sysstat pkgs.procps pkgs.gohai ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "datadog";
+          Group = "datadog";
+          Restart = "always";
+          RestartSec = 2;
+          PrivateTmp = true;
+        };
+        restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ];
+      } attrs;
+    in {
+      dd-agent = makeService {
+        description = "Datadog agent monitor";
+        serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
       };
-      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ];
-    };
 
-    systemd.services.dogstatsd = {
-      description = "Datadog statsd";
-      path = [ pkgs."dd-agent" pkgs.python pkgs.procps ];
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig = {
-        ExecStart = "${pkgs.dd-agent}/bin/dogstatsd start";
-        User = "datadog";
-        Group = "datadog";
-        Type = "forking";
-        PIDFile = "/tmp/dogstatsd.pid";
-        Restart = "always";
-        RestartSec = 2;
+      dogstatsd = makeService {
+        description = "Datadog statsd";
+        environment.TMPDIR = "/run/dogstatsd";
+        serviceConfig = {
+          ExecStart = "${pkgs.dd-agent}/bin/dogstatsd start";
+          Type = "forking";
+          PIDFile = "/run/dogstatsd/dogstatsd.pid";
+          RuntimeDirectory = "dogstatsd";
+        };
       };
-      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig processConfig ];
-    };
 
-    systemd.services.dd-jmxfetch = lib.mkIf (cfg.jmxConfig != null) {
-      description = "Datadog JMX Fetcher";
-      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ];
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig = {
-        ExecStart = "${pkgs.dd-agent}/bin/dd-jmxfetch";
-        User = "datadog";
-        Group = "datadog";
-        Restart = "always";
-        RestartSec = 2;
+      dd-jmxfetch = lib.mkIf (cfg.jmxConfig != null) {
+        description = "Datadog JMX Fetcher";
+        path = [ pkgs.dd-agent pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ];
+        serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-jmxfetch";
       };
-      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig jmxConfig ];
     };
 
     environment.etc = etcfiles;
diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index b23266e8d43a..10dc58311212 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -214,12 +214,10 @@ in
             }
           ];
         # Always provide a smb.conf to shut up programs like smbclient and smbspool.
-        environment.etc = singleton
-          { source =
-              if cfg.enable then configFile
-              else pkgs.writeText "smb-dummy.conf" "# Samba is disabled.";
-            target = "samba/smb.conf";
-          };
+        environment.etc."samba/smb.conf".source = mkOptionDefault (
+          if cfg.enable then configFile
+          else pkgs.writeText "smb-dummy.conf" "# Samba is disabled."
+        );
       }
 
       (mkIf cfg.enable {
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index de0aa1a2c2c3..019c8fd9ec48 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -161,8 +161,8 @@ in
       { description = "DHCP Client";
 
         wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target";
-        after = [ "network.target" ];
         wants = [ "network.target" ];
+        before = [ "network.target" ];
 
         # Stopping dhcpcd during a reconfiguration is undesirable
         # because it brings down the network interfaces configured by
diff --git a/nixos/modules/services/system/localtime.nix b/nixos/modules/services/system/localtime.nix
index b9355bbb9441..c7e897c96448 100644
--- a/nixos/modules/services/system/localtime.nix
+++ b/nixos/modules/services/system/localtime.nix
@@ -22,14 +22,8 @@ in {
   config = mkIf cfg.enable {
     services.geoclue2.enable = true;
 
-    security.polkit.extraConfig = ''
-     polkit.addRule(function(action, subject) {
-       if (action.id == "org.freedesktop.timedate1.set-timezone"
-           && subject.user == "localtimed") {
-         return polkit.Result.YES;
-       }
-     });
-    '';
+    # so polkit will pick up the rules
+    environment.systemPackages = [ pkgs.localtime ];
 
     users.users = [{
       name = "localtimed";
diff --git a/nixos/modules/services/web-servers/hydron.nix b/nixos/modules/services/web-servers/hydron.nix
index c49efaede160..ed63230bc784 100644
--- a/nixos/modules/services/web-servers/hydron.nix
+++ b/nixos/modules/services/web-servers/hydron.nix
@@ -16,10 +16,10 @@ in with lib; {
 
     interval = mkOption {
       type = types.str;
-      default = "hourly";
+      default = "weekly";
       example = "06:00";
       description = ''
-        How often we run hydron import and possibly fetch tags. Runs by default every hour.
+        How often we run hydron import and possibly fetch tags. Runs by default every week.
 
         The format is described in
         <citerefentry><refentrytitle>systemd.time</refentrytitle>
@@ -137,9 +137,13 @@ in with lib; {
 
     systemd.timers.hydron-fetch = {
       description = "Automatically import paths into hydron and possibly fetch tags";
-      after = [ "network.target" ];
+      after = [ "network.target" "hydron.service" ];
       wantedBy = [ "timers.target" ];
-      timerConfig.OnCalendar = cfg.interval;
+      
+      timerConfig = {
+        Persistent = true;
+        OnCalendar = cfg.interval;
+      };
     };
 
     users = {
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index ee9b11928ae1..c339d24b098a 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -97,6 +97,8 @@ in {
     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;
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index 6be15d8cdf46..dc82f7086c82 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -15,7 +15,7 @@ let
 
   inherit (pkgs) lightdm writeScript writeText;
 
-  # lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup
+  # lightdm runs with clearenv(), but we need a few things in the environment for X to startup
   xserverWrapper = writeScript "xserver-wrapper"
     ''
       #! ${pkgs.bash}/bin/bash
@@ -209,9 +209,12 @@ in
     services.dbus.enable = true;
     services.dbus.packages = [ lightdm ];
 
-    # lightdm uses the accounts daemon to rember language/window-manager per user
+    # lightdm uses the accounts daemon to remember language/window-manager per user
     services.accounts-daemon.enable = true;
 
+    # Enable the accounts daemon to find lightdm's dbus interface
+    environment.systemPackages = [ lightdm ];
+
     security.pam.services.lightdm = {
       allowNullPassword = true;
       startSession = true;
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index 30d853841ea4..b7dd7debcb63 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -116,6 +116,9 @@ in {
       }
     ];
 
+    # needed so that .desktop files are installed, which geoclue cares about
+    environment.systemPackages = [ cfg.package ];
+
     services.geoclue2.enable = mkIf (cfg.provider == "geoclue2") true;
 
     systemd.user.services.redshift = 
diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix
index ce770d067608..a3b7d7ba07ad 100644
--- a/nixos/modules/system/boot/networkd.nix
+++ b/nixos/modules/system/boot/networkd.nix
@@ -11,17 +11,29 @@ let
   checkLink = checkUnitConfig "Link" [
     (assertOnlyFields [
       "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
-      "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
+      "MTUBytes" "BitsPerSecond" "Duplex" "AutoNegotiation" "WakeOnLan" "Port"
+      "TCPSegmentationOffload" "TCP6SegmentationOffload" "GenericSegmentationOffload"
+      "GenericReceiveOffload" "LargeReceiveOffload" "RxChannels" "TxChannels"
+      "OtherChannels" "CombinedChannels"
     ])
-    (assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
+    (assertValueOneOf "MACAddressPolicy" ["persistent" "random" "none"])
     (assertMacAddress "MACAddress")
-    (assertValueOneOf "NamePolicy" [
-      "kernel" "database" "onboard" "slot" "path" "mac"
-    ])
     (assertByteFormat "MTUBytes")
     (assertByteFormat "BitsPerSecond")
     (assertValueOneOf "Duplex" ["half" "full"])
-    (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
+    (assertValueOneOf "AutoNegotiation" boolValues)
+    (assertValueOneOf "WakeOnLan" ["phy" "unicast" "multicast" "broadcast" "arp" "magic" "secureon" "off"])
+    (assertValueOneOf "Port" ["tp" "aui" "bnc" "mii" "fibre"])
+    (assertValueOneOf "TCPSegmentationOffload" boolValues)
+    (assertValueOneOf "TCP6SegmentationOffload" boolValues)
+    (assertValueOneOf "GenericSegmentationOffload" boolValues)
+    (assertValueOneOf "UDPSegmentationOffload" boolValues)
+    (assertValueOneOf "GenericReceiveOffload" boolValues)
+    (assertValueOneOf "LargeReceiveOffload" boolValues)
+    (range "RxChannels" 1 4294967295)
+    (range "TxChannels" 1 4294967295)
+    (range "OtherChannels" 1 4294967295)
+    (range "CombinedChannels" 1 4294967295)
   ];
 
   checkNetdev = checkUnitConfig "Netdev" [
@@ -31,16 +43,21 @@ let
     (assertHasField "Name")
     (assertHasField "Kind")
     (assertValueOneOf "Kind" [
-      "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
-      "gre" "sit" "vti" "veth" "tun" "tap" "dummy"
+      "bond" "bridge" "dummy" "gre" "gretap" "ip6gre" "ip6tnl" "ip6gretap" "ipip"
+      "ipvlan" "macvlan" "macvtap" "sit" "tap" "tun" "veth" "vlan" "vti" "vti6"
+      "vxlan" "geneve" "vrf" "vcan" "vxcan" "wireguard" "netdevsim"
     ])
     (assertByteFormat "MTUBytes")
     (assertMacAddress "MACAddress")
   ];
 
   checkVlan = checkUnitConfig "VLAN" [
-    (assertOnlyFields ["Id"])
+    (assertOnlyFields ["Id" "GVRP" "MVRP" "LooseBinding" "ReorderHeader"])
     (assertRange "Id" 0 4094)
+    (assertValueOneOf "GVRP" boolValues)
+    (assertValueOneOf "MVRP" boolValues)
+    (assertValueOneOf "LooseBinding" boolValues)
+    (assertValueOneOf "ReorderHeader" boolValues)
   ];
 
   checkMacvlan = checkUnitConfig "MACVLAN" [
@@ -49,15 +66,41 @@ let
   ];
 
   checkVxlan = checkUnitConfig "VXLAN" [
-    (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
+    (assertOnlyFields [
+      "Id" "Remote" "Local" "TOS" "TTL" "MacLearning" "FDBAgeingSec"
+      "MaximumFDBEntries" "ReduceARPProxy" "L2MissNotification"
+      "L3MissNotification" "RouteShortCircuit" "UDPChecksum"
+      "UDP6ZeroChecksumTx" "UDP6ZeroChecksumRx" "RemoteChecksumTx"
+      "RemoteChecksumRx" "GroupPolicyExtension" "DestinationPort" "PortRange"
+      "FlowLabel"
+    ])
     (assertRange "TTL" 0 255)
     (assertValueOneOf "MacLearning" boolValues)
+    (assertValueOneOf "ReduceARPProxy" boolValues)
+    (assertValueOneOf "L2MissNotification" boolValues)
+    (assertValueOneOf "L3MissNotification" boolValues)
+    (assertValueOneOf "RouteShortCircuit" boolValues)
+    (assertValueOneOf "UDPChecksum" boolValues)
+    (assertValueOneOf "UDP6ZeroChecksumTx" boolValues)
+    (assertValueOneOf "UDP6ZeroChecksumRx" boolValues)
+    (assertValueOneOf "RemoteChecksumTx" boolValues)
+    (assertValueOneOf "RemoteChecksumRx" boolValues)
+    (assertValueOneOf "GroupPolicyExtension" boolValues)
+    (assertRange "FlowLabel" 0 1048575)
   ];
 
   checkTunnel = checkUnitConfig "Tunnel" [
-    (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
+    (assertOnlyFields [
+      "Local" "Remote" "TOS" "TTL" "DiscoverPathMTU" "IPv6FlowLabel" "CopyDSCP"
+      "EncapsulationLimit" "Key" "InputKey" "OutputKey" "Mode" "Independent"
+      "AllowLocalRemote"
+    ])
     (assertRange "TTL" 0 255)
     (assertValueOneOf "DiscoverPathMTU" boolValues)
+    (assertValueOneOf "CopyDSCP" boolValues)
+    (assertValueOneOf "Mode" ["ip6ip6" "ipip6" "any"])
+    (assertValueOneOf "Independent" boolValues)
+    (assertValueOneOf "AllowLocalRemote" boolValues)
   ];
 
   checkPeer = checkUnitConfig "Peer" [
@@ -66,10 +109,11 @@ let
   ];
 
   tunTapChecks = [
-    (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
+    (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "VNetHeader" "User" "Group"])
     (assertValueOneOf "OneQueue" boolValues)
     (assertValueOneOf "MultiQueue" boolValues)
     (assertValueOneOf "PacketInfo" boolValues)
+    (assertValueOneOf "VNetHeader" boolValues)
   ];
 
   checkTun = checkUnitConfig "Tun" tunTapChecks;
@@ -79,67 +123,121 @@ let
   checkBond = checkUnitConfig "Bond" [
     (assertOnlyFields [
       "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
-      "UpDelaySec" "DownDelaySec" "GratuitousARP"
+      "UpDelaySec" "DownDelaySec" "LearnPacketIntervalSec" "AdSelect"
+      "FailOverMACPolicy" "ARPValidate" "ARPIntervalSec" "ARPIPTargets"
+      "ARPAllTargets" "PrimaryReselectPolicy" "ResendIGMP" "PacketsPerSlave"
+      "GratuitousARP" "AllSlavesActive" "MinLinks"
     ])
     (assertValueOneOf "Mode" [
       "balance-rr" "active-backup" "balance-xor"
       "broadcast" "802.3ad" "balance-tlb" "balance-alb"
     ])
     (assertValueOneOf "TransmitHashPolicy" [
-      "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
+      "layer2" "layer3+4" "layer2+3" "encap2+3" "encap3+4"
     ])
     (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
+    (assertValueOneOf "AdSelect" ["stable" "bandwidth" "count"])
+    (assertValueOneOf "FailOverMACPolicy" ["none" "active" "follow"])
+    (assertValueOneOf "ARPValidate" ["none" "active" "backup" "all"])
+    (assertValueOneOf "ARPAllTargets" ["any" "all"])
+    (assertValueOneOf "PrimaryReselectPolicy" ["always" "better" "failure"])
+    (assertRange "ResendIGMP" 0 255)
+    (assertRange "PacketsPerSlave" 0 65535)
+    (assertRange "GratuitousARP" 0 255)
+    (assertValueOneOf "AllSlavesActive" boolValues)
   ];
 
   checkNetwork = checkUnitConfig "Network" [
     (assertOnlyFields [
-      "Description" "DHCP" "DHCPServer" "IPForward" "IPMasquerade" "IPv4LL" "IPv4LLRoute"
-      "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond" "IPv6PrivacyExtensions"
+      "Description" "DHCP" "DHCPServer" "LinkLocalAddressing" "IPv4LLRoute"
+      "IPv6Token" "LLMNR" "MulticastDNS" "DNSOverTLS" "DNSSEC"
+      "DNSSECNegativeTrustAnchors" "LLDP" "EmitLLDP" "BindCarrier" "Address"
+      "Gateway" "DNS" "Domains" "NTP" "IPForward" "IPMasquerade"
+      "IPv6PrivacyExtensions" "IPv6AcceptRA" "IPv6DuplicateAddressDetection"
+      "IPv6HopLimit" "IPv4ProxyARP" "IPv6ProxyNDP" "IPv6ProxyNDPAddress"
+      "IPv6PrefixDelegation" "IPv6MTUBytes" "Bridge" "Bond" "VRF" "VLAN"
+      "IPVLAN" "MACVLAN" "VXLAN" "Tunnel" "ActiveSlave" "PrimarySlave"
+      "ConfigureWithoutCarrier"
     ])
-    (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
+    # Note: For DHCP the values both, none, v4, v6 are deprecated
+    (assertValueOneOf "DHCP" ["yes" "no" "ipv4" "ipv6" "both" "none" "v4" "v6"])
     (assertValueOneOf "DHCPServer" boolValues)
+    (assertValueOneOf "LinkLocalAddressing" ["yes" "no" "ipv4" "ipv6"])
+    (assertValueOneOf "IPv4LLRoute" boolValues)
+    (assertValueOneOf "LLMNR" ["yes" "resolve" "no"])
+    (assertValueOneOf "MulticastDNS" ["yes" "resolve" "no"])
+    (assertValueOneOf "DNSOverTLS" ["opportunistic" "no"])
+    (assertValueOneOf "DNSSEC" ["yes" "allow-downgrade" "no"])
+    (assertValueOneOf "LLDP" ["yes" "routers-only" "no"])
+    (assertValueOneOf "EmitLLDP" ["yes" "no" "nearest-bridge" "non-tpmr-bridge" "customer-bridge"])
     (assertValueOneOf "IPForward" ["yes" "no" "ipv4" "ipv6"])
     (assertValueOneOf "IPMasquerade" boolValues)
-    (assertValueOneOf "IPv4LL" boolValues)
-    (assertValueOneOf "IPv4LLRoute" boolValues)
-    (assertValueOneOf "LLMNR" boolValues)
-    (assertValueOneOf "MulticastDNS" boolValues)
     (assertValueOneOf "IPv6PrivacyExtensions" ["yes" "no" "prefer-public" "kernel"])
+    (assertValueOneOf "IPv6AcceptRA" boolValues)
+    (assertValueOneOf "IPv4ProxyARP" boolValues)
+    (assertValueOneOf "IPv6ProxyNDP" boolValues)
+    (assertValueOneOf "IPv6PrefixDelegation" boolValues)
+    (assertValueOneOf "ActiveSlave" boolValues)
+    (assertValueOneOf "PrimarySlave" boolValues)
+    (assertValueOneOf "ConfigureWithoutCarrier" boolValues)
   ];
 
   checkAddress = checkUnitConfig "Address" [
-    (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
+    (assertOnlyFields [
+      "Address" "Peer" "Broadcast" "Label" "PreferredLifetime" "Scope"
+      "HomeAddress" "DuplicateAddressDetection" "ManageTemporaryAddress"
+      "PrefixRoute" "AutoJoin"
+    ])
     (assertHasField "Address")
+    (assertValueOneOf "PreferredLifetime" ["forever" "infinity" "0" 0])
+    (assertValueOneOf "HomeAddress" boolValues)
+    (assertValueOneOf "DuplicateAddressDetection" boolValues)
+    (assertValueOneOf "ManageTemporaryAddress" boolValues)
+    (assertValueOneOf "PrefixRoute" boolValues)
+    (assertValueOneOf "AutoJoin" boolValues)
   ];
 
   checkRoute = checkUnitConfig "Route" [
-    (assertOnlyFields ["Gateway" "Destination" "Metric"])
+    (assertOnlyFields [
+      "Gateway" "GatewayOnlink" "Destination" "Source" "Metric"
+      "IPv6Preference" "Scope" "PreferredSource" "Table" "Protocol" "Type"
+      "InitialCongestionWindow" "InitialAdvertisedReceiveWindow" "QuickAck"
+      "MTUBytes"
+    ])
     (assertHasField "Gateway")
   ];
 
   checkDhcp = checkUnitConfig "DHCP" [
     (assertOnlyFields [
-      "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
-      "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
-      "RouteMetric"
+      "UseDNS" "UseNTP" "UseMTU" "Anonymize" "SendHostname" "UseHostname"
+      "Hostname" "UseDomains" "UseRoutes" "UseTimezone" "CriticalConnection"
+      "ClientIdentifier" "VendorClassIdentifier" "UserClass" "DUIDType"
+      "DUIDRawData" "IAID" "RequestBroadcast" "RouteMetric" "RouteTable"
+      "ListenPort" "RapidCommit"
     ])
     (assertValueOneOf "UseDNS" boolValues)
+    (assertValueOneOf "UseNTP" boolValues)
     (assertValueOneOf "UseMTU" boolValues)
+    (assertValueOneOf "Anonymize" boolValues)
     (assertValueOneOf "SendHostname" boolValues)
     (assertValueOneOf "UseHostname" boolValues)
-    (assertValueOneOf "UseDomains" boolValues)
+    (assertValueOneOf "UseDomains" ["yes" "no" "route"])
     (assertValueOneOf "UseRoutes" boolValues)
-    (assertValueOneOf "CriticalConnections" boolValues)
+    (assertValueOneOf "UseTimezone" boolValues)
+    (assertValueOneOf "CriticalConnection" boolValues)
     (assertValueOneOf "RequestBroadcast" boolValues)
+    (assertRange "RouteTable" 0 4294967295)
+    (assertValueOneOf "RapidCommit" boolValues)
   ];
 
   checkDhcpServer = checkUnitConfig "DHCPServer" [
     (assertOnlyFields [
       "PoolOffset" "PoolSize" "DefaultLeaseTimeSec" "MaxLeaseTimeSec"
-      "EmitDNS" "DNS" "EmitNTP" "NTP" "EmitTimezone" "Timezone"
+      "EmitDNS" "DNS" "EmitNTP" "NTP" "EmitRouter" "EmitTimezone" "Timezone"
     ])
     (assertValueOneOf "EmitDNS" boolValues)
     (assertValueOneOf "EmitNTP" boolValues)
+    (assertValueOneOf "EmitRouter" boolValues)
     (assertValueOneOf "EmitTimezone" boolValues)
   ];
 
@@ -461,6 +559,36 @@ let
       '';
     };
 
+    bridge = mkOption {
+      default = [ ];
+      type = types.listOf types.str;
+      description = ''
+        A list of bridge interfaces to be added to the network section of the
+        unit.  See <citerefentry><refentrytitle>systemd.network</refentrytitle>
+        <manvolnum>5</manvolnum></citerefentry> for details.
+      '';
+    };
+
+    bond = mkOption {
+      default = [ ];
+      type = types.listOf types.str;
+      description = ''
+        A list of bond interfaces to be added to the network section of the
+        unit.  See <citerefentry><refentrytitle>systemd.network</refentrytitle>
+        <manvolnum>5</manvolnum></citerefentry> for details.
+      '';
+    };
+
+    vrf = mkOption {
+      default = [ ];
+      type = types.listOf types.str;
+      description = ''
+        A list of vrf interfaces to be added to the network section of the
+        unit.  See <citerefentry><refentrytitle>systemd.network</refentrytitle>
+        <manvolnum>5</manvolnum></citerefentry> for details.
+      '';
+    };
+
     vlan = mkOption {
       default = [ ];
       type = types.listOf types.str;
@@ -619,6 +747,9 @@ let
           ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
           ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
           ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
+          ${concatStringsSep "\n" (map (s: "Bridge=${s}") def.bridge)}
+          ${concatStringsSep "\n" (map (s: "Bond=${s}") def.bond)}
+          ${concatStringsSep "\n" (map (s: "VRF=${s}") def.vrf)}
           ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
           ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
           ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 7120856387ef..2b3b09d725c7 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -23,12 +23,8 @@ let
 
   kernel = config.boot.kernelPackages;
 
-  packages = if config.boot.zfs.enableLegacyCrypto then {
-    spl = kernel.splLegacyCrypto;
-    zfs = kernel.zfsLegacyCrypto;
-    zfsUser = pkgs.zfsLegacyCrypto;
-  } else if config.boot.zfs.enableUnstable then {
-    spl = kernel.splUnstable;
+  packages = if config.boot.zfs.enableUnstable then {
+    spl = null;
     zfs = kernel.zfsUnstable;
     zfsUser = pkgs.zfsUnstable;
   } else {
@@ -117,27 +113,6 @@ in
           '';
       };
 
-      enableLegacyCrypto = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Enabling this option will allow you to continue to use the old format for
-          encrypted datasets. With the inclusion of stability patches the format of
-          encrypted datasets has changed. They can still be accessed and mounted but
-          in read-only mode mounted. It is highly recommended to convert them to
-          the new format.
-
-          This option is only for convenience to people that cannot convert their
-          datasets to the new format yet and it will be removed in due time.
-
-          For migration strategies from old format to this new one, check the Wiki:
-          https://nixos.wiki/wiki/NixOS_on_ZFS#Encrypted_Dataset_Format_Change
-
-          See https://github.com/zfsonlinux/zfs/pull/6864 for more details about
-          the stability patches.
-          '';
-      };
-
       extraPools = mkOption {
         type = types.listOf types.str;
         default = [];
@@ -350,12 +325,12 @@ in
       virtualisation.lxd.zfsSupport = true;
 
       boot = {
-        kernelModules = [ "spl" "zfs" ] ;
-        extraModulePackages = with packages; [ spl zfs ];
+        kernelModules = [ "zfs" ] ++ optional (!cfgZfs.enableUnstable) "spl";
+        extraModulePackages = with packages; [ zfs ] ++ optional (!cfgZfs.enableUnstable) spl;
       };
 
       boot.initrd = mkIf inInitrd {
-        kernelModules = [ "spl" "zfs" ];
+        kernelModules = [ "zfs" ] ++ optional (!cfgZfs.enableUnstable) "spl";
         extraUtilsCommands =
           ''
             copy_bin_and_libs ${packages.zfsUser}/sbin/zfs
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index 0abf7b11703c..4e9c87222d0a 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -156,9 +156,6 @@ let
             --partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F \
             --hybrid 2 \
             --recompute-chs /dev/vda
-          . /sys/class/block/vda2/uevent
-          mknod /dev/vda2 b $MAJOR $MINOR
-          . /sys/class/block/vda/uevent
           ${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
           export MTOOLS_SKIP_CHECK=1
           ${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix
index b69860a199a2..60779579402c 100644
--- a/nixos/modules/virtualisation/virtualbox-host.nix
+++ b/nixos/modules/virtualisation/virtualbox-host.nix
@@ -6,7 +6,8 @@ let
   cfg = config.virtualisation.virtualbox.host;
 
   virtualbox = cfg.package.override {
-    inherit (cfg) enableExtensionPack enableHardening headless;
+    inherit (cfg) enableHardening headless;
+    extensionPack = if cfg.enableExtensionPack then pkgs.virtualboxExtpack else null;
   };
 
   kernelModules = config.boot.kernelPackages.virtualbox.override {
@@ -28,6 +29,17 @@ in
       '';
     };
 
+    enableExtensionPack = mkEnableOption "VirtualBox extension pack" // {
+      description = ''
+        Whether to install the Oracle Extension Pack for VirtualBox.
+
+        <important><para>
+          You must set <literal>nixpkgs.config.allowUnfree = true</literal> in
+          order to use this.  This requires you accept the VirtualBox PUEL.
+        </para></important>
+      '';
+    };
+
     package = mkOption {
       type = types.package;
       default = pkgs.virtualbox;
@@ -45,8 +57,6 @@ in
       '';
     };
 
-    enableExtensionPack = mkEnableOption "VirtualBox extension pack";
-
     enableHardening = mkOption {
       type = types.bool;
       default = true;