summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/fonts/fontconfig-ultimate.nix203
-rw-r--r--nixos/modules/config/fonts/fontconfig.nix353
-rw-r--r--nixos/modules/config/ldap.nix12
-rw-r--r--nixos/modules/config/nsswitch.nix2
-rw-r--r--nixos/modules/config/pulseaudio.nix2
-rw-r--r--nixos/modules/config/zram.nix2
-rw-r--r--nixos/modules/hardware/video/amdgpu.nix9
-rw-r--r--nixos/modules/hardware/video/bumblebee.nix1
-rw-r--r--nixos/modules/hardware/video/webcam/facetimehd.nix1
-rw-r--r--nixos/modules/i18n/input-method/default.xml2
-rw-r--r--nixos/modules/installer/tools/nixos-install.sh48
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh6
-rw-r--r--nixos/modules/installer/tools/tools.nix2
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/misc/nixpkgs.nix5
-rw-r--r--nixos/modules/module-list.nix9
-rw-r--r--nixos/modules/programs/shadow.nix5
-rw-r--r--nixos/modules/rename.nix33
-rw-r--r--nixos/modules/security/grsecurity.nix4
-rw-r--r--nixos/modules/security/pam.nix9
-rw-r--r--nixos/modules/services/backup/crashplan.nix2
-rw-r--r--nixos/modules/services/continuous-integration/buildkite-agent.nix12
-rw-r--r--nixos/modules/services/continuous-integration/gocd-agent/default.nix37
-rw-r--r--nixos/modules/services/continuous-integration/hydra/default.nix9
-rw-r--r--nixos/modules/services/databases/cassandra.nix449
-rw-r--r--nixos/modules/services/databases/redis.nix5
-rw-r--r--nixos/modules/services/hardware/tlp.nix4
-rw-r--r--nixos/modules/services/hardware/udev.nix5
-rw-r--r--nixos/modules/services/misc/autofs.nix9
-rw-r--r--nixos/modules/services/misc/gitlab.nix51
-rw-r--r--nixos/modules/services/misc/gitlab.xml12
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix2
-rw-r--r--nixos/modules/services/monitoring/graphite.nix10
-rw-r--r--nixos/modules/services/network-filesystems/openafs-client/default.nix2
-rw-r--r--nixos/modules/services/networking/cjdns.nix2
-rw-r--r--nixos/modules/services/networking/ejabberd.nix29
-rw-r--r--nixos/modules/services/networking/fan.nix2
-rw-r--r--nixos/modules/services/networking/ferm.nix63
-rw-r--r--nixos/modules/services/networking/gdomap.nix32
-rw-r--r--nixos/modules/services/networking/networkmanager.nix12
-rw-r--r--nixos/modules/services/networking/strongswan.nix2
-rw-r--r--nixos/modules/services/networking/unifi.nix31
-rw-r--r--nixos/modules/services/printing/cupsd.nix6
-rw-r--r--nixos/modules/services/torrent/transmission.nix2
-rw-r--r--nixos/modules/services/web-apps/mattermost.nix228
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix2
-rw-r--r--nixos/modules/services/web-servers/nginx/location-options.nix21
-rw-r--r--nixos/modules/services/web-servers/phpfpm/default.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/enlightenment.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix2
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix6
-rw-r--r--nixos/modules/services/x11/redshift.nix7
-rw-r--r--nixos/modules/services/x11/window-managers/metacity.nix4
-rw-r--r--nixos/modules/system/boot/initrd-ssh.nix10
-rw-r--r--nixos/modules/system/boot/kernel.nix5
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl6
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py6
-rw-r--r--nixos/modules/system/boot/modprobe.nix41
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh42
-rw-r--r--nixos/modules/system/boot/stage-1.nix25
-rw-r--r--nixos/modules/system/boot/stage-2-init.sh1
-rw-r--r--nixos/modules/tasks/cpu-freq.nix2
-rw-r--r--nixos/modules/tasks/encrypted-devices.nix2
-rw-r--r--nixos/modules/tasks/filesystems.nix42
-rw-r--r--nixos/modules/tasks/filesystems/cifs.nix4
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix22
-rw-r--r--nixos/modules/virtualisation/brightbox-image.nix2
-rw-r--r--nixos/modules/virtualisation/docker.nix3
-rw-r--r--nixos/modules/virtualisation/google-compute-image.nix2
-rw-r--r--nixos/modules/virtualisation/qemu-opts4
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix26
-rw-r--r--nixos/modules/virtualisation/virtualbox-image.nix21
73 files changed, 1526 insertions, 516 deletions
diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix
index 02568f9de51e..a3f52fbd9199 100644
--- a/nixos/modules/config/fonts/fontconfig-ultimate.nix
+++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix
@@ -3,6 +3,95 @@
 with lib;
 
 let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>";
+
+    cfg = config.fonts.fontconfig.ultimate;
+
+    latestVersion  = pkgs.fontconfig.configVersion;
+
+    # fontconfig ultimate main configuration file
+    # priority 52
+    fontconfigUltimateConf = pkgs.writeText "fc-52-fontconfig-ultimate.conf" ''
+      <?xml version="1.0"?>
+      <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+      <fontconfig>
+
+        ${optionalString (!cfg.allowBitmaps) ''
+        <!-- Reject bitmap fonts -->
+        <selectfont>
+          <rejectfont>
+            <pattern>
+              <patelt name="scalable"><bool>false</bool></patelt>
+            </pattern>
+          </rejectfont>
+        </selectfont>
+        ''}
+
+        ${optionalString cfg.allowType1 ''
+        <!-- Reject Type 1 fonts -->
+        <selectfont>
+          <rejectfont>
+            <pattern>
+              <patelt name="fontformat">
+                <string>Type 1</string>
+              </patelt>
+            </pattern>
+          </rejectfont>
+        </selectfont>
+        ''}
+
+        <!-- Use embedded bitmaps in fonts like Calibri? -->
+        <match target="font">
+          <edit name="embeddedbitmap" mode="assign">
+            ${fcBool cfg.useEmbeddedBitmaps}
+          </edit>
+        </match>
+
+        <!-- Force autohint always -->
+        <match target="font">
+          <edit name="force_autohint" mode="assign">
+            ${fcBool cfg.forceAutohint}
+          </edit>
+        </match>
+
+        <!-- Render some monospace TTF fonts as bitmaps -->
+        <match target="pattern">
+          <edit name="bitmap_monospace" mode="assign">
+            ${fcBool cfg.renderMonoTTFAsBitmap}
+          </edit>
+        </match>
+
+      </fontconfig>
+    '';
+
+    # The configuration to be included in /etc/font/
+    confPkg = pkgs.runCommand "font-ultimate-conf" {} ''
+      support_folder=$out/etc/fonts/conf.d
+      latest_folder=$out/etc/fonts/${latestVersion}/conf.d
+
+      mkdir -p $support_folder
+      mkdir -p $latest_folder
+
+      # 52-fontconfig-ultimate.conf
+      ln -s ${fontconfigUltimateConf} \
+            $support_folder/52-fontconfig-ultimate.conf
+      ln -s ${fontconfigUltimateConf} \
+            $latest_folder/52-fontconfig-ultimate.conf
+
+      # fontconfig ultimate substitutions
+      ${optionalString (cfg.substitutions != "none") ''
+      ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \
+            $support_folder
+      ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/presets/${cfg.substitutions}/*.conf \
+            $latest_folder
+      ''}
+
+      # fontconfig ultimate various configuration files
+      ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/conf.d/*.conf \
+            $support_folder
+      ln -s ${pkgs.fontconfig-ultimate}/etc/fonts/conf.d/*.conf \
+            $latest_folder
+    '';
+
 in
 {
 
@@ -64,9 +153,7 @@ in
           };
 
           substitutions = mkOption {
-            type = types.str // {
-              check = flip elem ["none" "free" "combi" "ms"];
-            };
+            type = types.nullOr (types.enum ["free" "combi" "ms"]);
             default = "free";
             description = ''
               Font substitutions to replace common Type 1 fonts with nicer
@@ -77,35 +164,12 @@ in
             '';
           };
 
-          rendering = mkOption {
-            type = types.attrs;
-            default = pkgs.fontconfig-ultimate.rendering.ultimate;
+          preset = mkOption {
+            type = types.enum ["ultimate1" "ultimate2" "ultimate3" "ultimate4" "ultimate5" "osx" "windowsxp"];
+            default = "ultimate3";
             description = ''
-              FreeType rendering settings presets. The default is
-              <literal>pkgs.fontconfig-ultimate.rendering.ultimate</literal>.
-              The other available styles are:
-              <literal>ultimate-lighter</literal>,
-              <literal>ultimate-darker</literal>,
-              <literal>ultimate-lightest</literal>,
-              <literal>ultimate-darkest</literal>,
-              <literal>default</literal> (the original Infinality default),
-              <literal>osx</literal>,
-              <literal>ipad</literal>,
-              <literal>ubuntu</literal>,
-              <literal>linux</literal>,
-              <literal>winxplight</literal>,
-              <literal>win7light</literal>,
-              <literal>winxp</literal>,
-              <literal>win7</literal>,
-              <literal>vanilla</literal>,
-              <literal>classic</literal>,
-              <literal>nudge</literal>,
-              <literal>push</literal>,
-              <literal>shove</literal>,
-              <literal>sharpened</literal>,
-              <literal>infinality</literal>. Any of the presets may be
-              customized by editing the attributes. To disable, set this option
-              to the empty attribute set <literal>{}</literal>.
+              FreeType rendering settings preset. Any of the presets may be
+              customized by setting environment variables.
             '';
           };
         };
@@ -114,80 +178,11 @@ in
 
   };
 
+  config = mkIf (config.fonts.fontconfig.enable && cfg.enable) {
 
-  config =
-    let ultimate = config.fonts.fontconfig.ultimate;
-        fontconfigUltimateConf = ''
-          <?xml version="1.0"?>
-          <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-          <fontconfig>
-
-            ${optionalString (!ultimate.allowBitmaps) ''
-            <!-- Reject bitmap fonts -->
-            <selectfont>
-              <rejectfont>
-                <pattern>
-                  <patelt name="scalable"><bool>false</bool></patelt>
-                </pattern>
-              </rejectfont>
-            </selectfont>
-            ''}
-
-            ${optionalString ultimate.allowType1 ''
-            <!-- Reject Type 1 fonts -->
-            <selectfont>
-              <rejectfont>
-                <pattern>
-                  <patelt name="fontformat">
-                    <string>Type 1</string>
-                  </patelt>
-                </pattern>
-              </rejectfont>
-            </selectfont>
-            ''}
-
-            <!-- Use embedded bitmaps in fonts like Calibri? -->
-            <match target="font">
-              <edit name="embeddedbitmap" mode="assign">
-                ${fcBool ultimate.useEmbeddedBitmaps}
-              </edit>
-            </match>
-
-            <!-- Force autohint always -->
-            <match target="font">
-              <edit name="force_autohint" mode="assign">
-                ${fcBool ultimate.forceAutohint}
-              </edit>
-            </match>
-
-            <!-- Render some monospace TTF fonts as bitmaps -->
-            <match target="pattern">
-              <edit name="bitmap_monospace" mode="assign">
-                ${fcBool ultimate.renderMonoTTFAsBitmap}
-              </edit>
-            </match>
-
-            ${optionalString (ultimate.substitutions != "none") ''
-            <!-- Type 1 font substitutions -->
-            <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${ultimate.substitutions}</include>
-            ''}
-
-            <include ignore_missing="yes">${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d</include>
-
-          </fontconfig>
-        '';
-    in mkIf (config.fonts.fontconfig.enable && ultimate.enable) {
-
-      environment.etc."fonts/conf.d/52-fontconfig-ultimate.conf" = {
-        text = fontconfigUltimateConf;
-      };
-
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/52-fontconfig-ultimate.conf" = {
-        text = fontconfigUltimateConf;
-      };
-
-      environment.variables = ultimate.rendering;
+    fonts.fontconfig.confPackages = [ confPkg ];
+    environment.variables."INFINALITY_FT" = cfg.preset;
 
-    };
+  };
 
 }
diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
index 1eaebe4b2bbd..770c3a03f9d8 100644
--- a/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixos/modules/config/fonts/fontconfig.nix
@@ -1,7 +1,207 @@
+/*
+
+NixOS support 2 fontconfig versions, "support" and "latest".
+
+- "latest" refers to default fontconfig package (pkgs.fontconfig).
+  configuration files are linked to /etc/fonts/VERSION/conf.d/
+- "support" refers to supportPkg (pkgs."fontconfig_${supportVersion}").
+  configuration files are linked to /etc/fonts/conf.d/
+
+This module generates a package containing configuration files and link it in /etc/fonts.
+
+Fontconfig reads files in folder name / file name order, so the number prepended to the configuration file name decide the order of parsing.
+Low number means high priority.
+
+*/
+
 { config, lib, pkgs, ... }:
 
 with lib;
 
+let cfg = config.fonts.fontconfig;
+
+    fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>";
+
+    # back-supported fontconfig version and package
+    # version is used for font cache generation
+    supportVersion = "210";
+    supportPkg     = pkgs."fontconfig_${supportVersion}";
+
+    # latest fontconfig version and package
+    # version is used for configuration folder name, /etc/fonts/VERSION/
+    # note: format differs from supportVersion and can not be used with makeCacheConf
+    latestVersion  = pkgs.fontconfig.configVersion;
+    latestPkg      = pkgs.fontconfig;
+
+    # supported version fonts.conf
+    supportFontsConf = pkgs.makeFontsConf { fontconfig = supportPkg; fontDirectories = config.fonts.fonts; };
+
+    # configuration file to read fontconfig cache
+    # version dependent
+    # priority 0
+    cacheConfSupport = makeCacheConf { version = supportVersion; };
+    cacheConfLatest  = makeCacheConf {};
+    
+    # generate the font cache setting file for a fontconfig version
+    # use latest when no version is passed
+    makeCacheConf = { version ? null }:
+      let 
+        fcPackage = if builtins.isNull version
+                    then "fontconfig"
+                    else "fontconfig_${version}";
+        makeCache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
+        cache     = makeCache pkgs."${fcPackage}";
+        cache32   = makeCache pkgs.pkgsi686Linux."${fcPackage}";
+      in
+      pkgs.writeText "fc-00-nixos-cache.conf" ''
+        <?xml version='1.0'?>
+        <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+        <fontconfig>
+          <!-- Font directories -->
+          ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
+          <!-- Pre-generated font caches -->
+          <cachedir>${cache}</cachedir>
+          ${optionalString (pkgs.stdenv.isx86_64 && cfg.cache32Bit) ''
+            <cachedir>${cache32}</cachedir>
+          ''}
+        </fontconfig>
+      '';
+
+    # rendering settings configuration file
+    # priority 10
+    renderConf = pkgs.writeText "fc-10-nixos-rendering.conf" ''
+      <?xml version='1.0'?>
+      <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+      <fontconfig>
+
+        <!-- Default rendering settings -->
+        <match target="font">
+          <edit mode="assign" name="hinting">
+            ${fcBool cfg.hinting.enable}
+          </edit>
+          <edit mode="assign" name="autohint">
+            ${fcBool cfg.hinting.autohint}
+          </edit>
+          <edit mode="assign" name="hintstyle">
+            <const>hint${cfg.hinting.style}</const>
+          </edit>
+          <edit mode="assign" name="antialias">
+            ${fcBool cfg.antialias}
+          </edit>
+          <edit mode="assign" name="rgba">
+            <const>${cfg.subpixel.rgba}</const>
+          </edit>
+          <edit mode="assign" name="lcdfilter">
+            <const>lcd${cfg.subpixel.lcdfilter}</const>
+          </edit>
+        </match>
+
+        ${optionalString (cfg.dpi != 0) ''
+        <match target="pattern">
+          <edit name="dpi" mode="assign">
+            <double>${toString cfg.dpi}</double>
+          </edit>
+        </match>
+        ''}
+
+      </fontconfig>
+    '';
+
+    # local configuration file
+    # priority 51
+    localConf = pkgs.writeText "fc-local.conf" cfg.localConf;
+
+    # default fonts configuration file
+    # priority 52
+    defaultFontsConf = 
+      let genDefault = fonts: name:
+        optionalString (fonts != []) ''
+          <alias>
+            <family>${name}</family>
+            <prefer>
+            ${concatStringsSep ""
+            (map (font: ''
+              <family>${font}</family>
+            '') fonts)}
+            </prefer>
+          </alias>
+        '';
+      in
+      pkgs.writeText "fc-52-nixos-default-fonts.conf" ''
+      <?xml version='1.0'?>
+      <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+      <fontconfig>
+
+        <!-- Default fonts -->
+        ${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
+
+        ${genDefault cfg.defaultFonts.serif     "serif"}
+
+        ${genDefault cfg.defaultFonts.monospace "monospace"}
+
+      </fontconfig>
+    '';
+
+    # fontconfig configuration package 
+    confPkg = pkgs.runCommand "fontconfig-conf" {} ''
+      support_folder=$out/etc/fonts
+      latest_folder=$out/etc/fonts/${latestVersion}
+
+      mkdir -p $support_folder/conf.d
+      mkdir -p $latest_folder/conf.d
+
+      # fonts.conf
+      ln -s ${supportFontsConf} $support_folder/fonts.conf
+      ln -s ${latestPkg.out}/etc/fonts/fonts.conf \
+            $latest_folder/fonts.conf
+
+      # fontconfig default config files
+      ln -s ${supportPkg.out}/etc/fonts/conf.d/*.conf \
+            $support_folder/conf.d/
+      ln -s ${latestPkg.out}/etc/fonts/conf.d/*.conf \
+            $latest_folder/conf.d/
+
+      # update latest 51-local.conf path to look at the latest local.conf
+      rm    $latest_folder/conf.d/51-local.conf
+
+      substitute ${latestPkg.out}/etc/fonts/conf.d/51-local.conf \
+                 $latest_folder/conf.d/51-local.conf \
+                 --replace local.conf /etc/fonts/${latestVersion}/local.conf 
+
+      # 00-nixos-cache.conf
+      ln -s ${cacheConfSupport} \
+            $support_folder/conf.d/00-nixos-cache.conf
+      ln -s ${cacheConfLatest}  $latest_folder/conf.d/00-nixos-cache.conf
+
+      # 10-nixos-rendering.conf
+      ln -s ${renderConf}       $support_folder/conf.d/10-nixos-rendering.conf
+      ln -s ${renderConf}       $latest_folder/conf.d/10-nixos-rendering.conf
+
+      # 50-user.conf
+      ${optionalString (! cfg.includeUserConf) ''
+      rm    $support_folder/conf.d/50-user.conf
+      rm    $latest_folder/conf.d/50-user.conf
+      ''}
+
+      # local.conf (indirect priority 51)
+      ${optionalString (cfg.localConf != "") ''
+      ln -s ${localConf}        $support_folder/local.conf
+      ln -s ${localConf}        $latest_folder/local.conf
+      ''}
+
+      # 52-nixos-default-fonts.conf
+      ln -s ${defaultFontsConf} $support_folder/conf.d/52-nixos-default-fonts.conf
+      ln -s ${defaultFontsConf} $latest_folder/conf.d/52-nixos-default-fonts.conf
+    '';
+
+    # Package with configuration files
+    # this merge all the packages in the fonts.fontconfig.confPackages list
+    fontconfigEtc = pkgs.buildEnv {
+      name  = "fontconfig-etc";
+      paths = cfg.confPackages;
+      ignoreCollisions = true;
+    };
+in
 {
 
   options = {
@@ -21,6 +221,15 @@ with lib;
           '';
         };
 
+        confPackages = mkOption {
+          internal = true;
+          type     = with types; listOf path;
+          default  = [ ];
+          description = ''
+            Fontconfig configuration packages.
+          '';
+        };
+
         antialias = mkOption {
           type = types.bool;
           default = true;
@@ -36,6 +245,15 @@ with lib;
           '';
         };
 
+        localConf = mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            System-wide customization file contents, has higher priority than 
+            <literal>defaultFonts</literal> settings.
+          '';
+        };
+
         defaultFonts = {
           monospace = mkOption {
             type = types.listOf types.str;
@@ -142,136 +360,11 @@ with lib;
     };
 
   };
+  config = mkIf cfg.enable {
+    fonts.fontconfig.confPackages = [ confPkg ];
 
-  config =
-    let fontconfig = config.fonts.fontconfig;
-        fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>";
-        renderConf = ''
-          <?xml version='1.0'?>
-          <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
-          <fontconfig>
-
-            <!-- Default rendering settings -->
-            <match target="font">
-              <edit mode="assign" name="hinting">
-                ${fcBool fontconfig.hinting.enable}
-              </edit>
-              <edit mode="assign" name="autohint">
-                ${fcBool fontconfig.hinting.autohint}
-              </edit>
-              <edit mode="assign" name="hintstyle">
-                <const>hint${fontconfig.hinting.style}</const>
-              </edit>
-              <edit mode="assign" name="antialias">
-                ${fcBool fontconfig.antialias}
-              </edit>
-              <edit mode="assign" name="rgba">
-                <const>${fontconfig.subpixel.rgba}</const>
-              </edit>
-              <edit mode="assign" name="lcdfilter">
-                <const>lcd${fontconfig.subpixel.lcdfilter}</const>
-              </edit>
-            </match>
-
-            ${optionalString (fontconfig.dpi != 0) ''
-            <match target="pattern">
-              <edit name="dpi" mode="assign">
-                <double>${toString fontconfig.dpi}</double>
-              </edit>
-            </match>
-            ''}
-
-          </fontconfig>
-        '';
-        genericAliasConf = ''
-          <?xml version='1.0'?>
-          <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
-          <fontconfig>
-
-            <!-- Default fonts -->
-            ${optionalString (fontconfig.defaultFonts.sansSerif != []) ''
-            <alias>
-              <family>sans-serif</family>
-              <prefer>
-                ${concatStringsSep "\n"
-                  (map (font: "<family>${font}</family>")
-                    fontconfig.defaultFonts.sansSerif)}
-              </prefer>
-            </alias>
-            ''}
-            ${optionalString (fontconfig.defaultFonts.serif != []) ''
-            <alias>
-              <family>serif</family>
-              <prefer>
-                ${concatStringsSep "\n"
-                  (map (font: "<family>${font}</family>")
-                    fontconfig.defaultFonts.serif)}
-              </prefer>
-            </alias>
-            ''}
-            ${optionalString (fontconfig.defaultFonts.monospace != []) ''
-            <alias>
-              <family>monospace</family>
-              <prefer>
-                ${concatStringsSep "\n"
-                  (map (font: "<family>${font}</family>")
-                    fontconfig.defaultFonts.monospace)}
-              </prefer>
-            </alias>
-            ''}
-
-          </fontconfig>
-        '';
-    in mkIf fontconfig.enable {
-
-      # Fontconfig 2.10 backward compatibility
-
-      # Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10
-      environment.etc."fonts/fonts.conf".source =
-        pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; };
-
-      environment.etc."fonts/conf.d/10-nixos-rendering.conf".text = renderConf;
-      environment.etc."fonts/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf;
-
-      # Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig.
-      # Otherwise specify only font directories.
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source =
-        "${pkgs.fontconfig.out}/etc/fonts/fonts.conf";
-
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text =
-        let
-          cache = fontconfig: pkgs.makeFontsCache { inherit fontconfig; fontDirectories = config.fonts.fonts; };
-        in ''
-          <?xml version='1.0'?>
-          <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
-          <fontconfig>
-            <!-- Font directories -->
-            ${concatStringsSep "\n" (map (font: "<dir>${font}</dir>") config.fonts.fonts)}
-            <!-- Pre-generated font caches -->
-            <cachedir>${cache pkgs.fontconfig}</cachedir>
-            ${optionalString (pkgs.stdenv.isx86_64 && config.fonts.fontconfig.cache32Bit) ''
-              <cachedir>${cache pkgs.pkgsi686Linux.fontconfig}</cachedir>
-            ''}
-          </fontconfig>
-        '';
-
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/10-nixos-rendering.conf".text = renderConf;
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/60-nixos-generic-alias.conf".text = genericAliasConf;
-
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/99-user.conf" = {
-        enable = fontconfig.includeUserConf;
-        text = ''
-          <?xml version="1.0"?>
-          <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-          <fontconfig>
-            <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
-            <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
-          </fontconfig>
-        '';
-      };
-
-      environment.systemPackages = [ pkgs.fontconfig ];
-
-    };
+    environment.systemPackages    = [ pkgs.fontconfig ];
+    environment.etc.fonts.source  = "${fontconfigEtc}/etc/fonts/";
+  };
 
 }
diff --git a/nixos/modules/config/ldap.nix b/nixos/modules/config/ldap.nix
index 7064ef64b4c8..da875d6e4821 100644
--- a/nixos/modules/config/ldap.nix
+++ b/nixos/modules/config/ldap.nix
@@ -62,6 +62,18 @@ in
         description = "Whether to enable authentication against an LDAP server.";
       };
 
+      loginPam = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to include authentication against LDAP in login PAM";
+      };
+
+      nsswitch = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to include lookup against LDAP in NSS";
+      };
+
       server = mkOption {
         example = "ldap://ldap.example.org/";
         description = "The URL of the LDAP server.";
diff --git a/nixos/modules/config/nsswitch.nix b/nixos/modules/config/nsswitch.nix
index a39c2895bf84..f30136be44e1 100644
--- a/nixos/modules/config/nsswitch.nix
+++ b/nixos/modules/config/nsswitch.nix
@@ -8,7 +8,7 @@ let
 
   inherit (config.services.avahi) nssmdns;
   inherit (config.services.samba) nsswins;
-  ldap = config.users.ldap.enable;
+  ldap = (config.users.ldap.enable && config.users.ldap.nsswitch);
 
 in
 
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index 71ac3f9a72c4..06ce52004202 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -34,7 +34,7 @@ let
         ${addModuleIf cfg.zeroconf.publish.enable "module-zeroconf-publish"}
         ${addModuleIf cfg.zeroconf.discovery.enable "module-zeroconf-discover"}
         ${addModuleIf cfg.tcp.enable (concatStringsSep " "
-           ([ "load-module module-native-protocol-tcp" ] ++ allAnon ++ ipAnon))}
+           ([ "module-native-protocol-tcp" ] ++ allAnon ++ ipAnon))}
         ${cfg.extraConfig}
       '';
     };
diff --git a/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix
index 019932b04e8d..ad41ad4f3d7c 100644
--- a/nixos/modules/config/zram.nix
+++ b/nixos/modules/config/zram.nix
@@ -8,7 +8,7 @@ let
 
   devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
 
-  modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
+  modprobe = "${pkgs.kmod}/bin/modprobe";
 
 in
 
diff --git a/nixos/modules/hardware/video/amdgpu.nix b/nixos/modules/hardware/video/amdgpu.nix
new file mode 100644
index 000000000000..42fc8fa362de
--- /dev/null
+++ b/nixos/modules/hardware/video/amdgpu.nix
@@ -0,0 +1,9 @@
+{ config, lib, ... }:
+
+with lib;
+{
+  config = mkIf (elem "amdgpu" config.services.xserver.videoDrivers) {
+    boot.blacklistedKernelModules = [ "radeon" ];
+  };
+}
+
diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix
index b10846ac18a1..69db518ab21c 100644
--- a/nixos/modules/hardware/video/bumblebee.nix
+++ b/nixos/modules/hardware/video/bumblebee.nix
@@ -75,7 +75,6 @@ in
       serviceConfig = {
         ExecStart = "${bumblebee}/bin/bumblebeed --use-syslog -g ${cfg.group} --driver ${cfg.driver}";
       };
-      environment.MODULE_DIR="/run/current-system/kernel-modules/lib/modules/";
     };
   };
 }
diff --git a/nixos/modules/hardware/video/webcam/facetimehd.nix b/nixos/modules/hardware/video/webcam/facetimehd.nix
index 2a2fcf3057d4..d311f600c319 100644
--- a/nixos/modules/hardware/video/webcam/facetimehd.nix
+++ b/nixos/modules/hardware/video/webcam/facetimehd.nix
@@ -36,7 +36,6 @@ in
 
     # and load it back on resume
     powerManagement.resumeCommands = ''
-      export MODULE_DIR=/run/current-system/kernel-modules/lib/modules
       ${pkgs.kmod}/bin/modprobe -v facetimehd
     '';
 
diff --git a/nixos/modules/i18n/input-method/default.xml b/nixos/modules/i18n/input-method/default.xml
index c55ac1ec2456..a32ed100df30 100644
--- a/nixos/modules/i18n/input-method/default.xml
+++ b/nixos/modules/i18n/input-method/default.xml
@@ -88,6 +88,8 @@ i18n.inputMethod = {
       methods among Traditional Chinese Unix users.</para></listitem>
   <listitem><para>Hangul (<literal>fcitx-engines.hangul</literal>): Korean input 
       method.</para></listitem>
+  <listitem><para>Unikey (<literal>fcitx-engines.unikey</literal>): Vietnamese input 
+      method.</para></listitem>
   <listitem><para>m17n (<literal>fcitx-engines.m17n</literal>): m17n is an input 
       method that uses input methods and corresponding icons in the m17n 
       database.</para></listitem>
diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
index 0247925f4144..62ea98c4676c 100644
--- a/nixos/modules/installer/tools/nixos-install.sh
+++ b/nixos/modules/installer/tools/nixos-install.sh
@@ -24,7 +24,7 @@ fi
 # Parse the command line for the -I flag
 extraBuildFlags=()
 chrootCommand=(/run/current-system/sw/bin/bash)
-bootLoader=1
+buildUsersGroup="nixbld"
 
 while [ "$#" -gt 0 ]; do
     i="$1"; shift 1
@@ -43,6 +43,7 @@ while [ "$#" -gt 0 ]; do
             ;;
         --closure)
             closure="$1"; shift 1
+            buildUsersGroup=""
             ;;
         --no-channel-copy)
             noChannelCopy=1
@@ -51,7 +52,7 @@ while [ "$#" -gt 0 ]; do
             noRootPasswd=1
             ;;
         --no-bootloader)
-            bootLoader=0
+            noBootLoader=1
             ;;
         --show-trace)
             extraBuildFlags+=("$i")
@@ -101,8 +102,8 @@ mount -t tmpfs -o "mode=0755" none $mountPoint/run
 mount -t tmpfs -o "mode=0755" none $mountPoint/var/setuid-wrappers
 rm -rf $mountPoint/var/run
 ln -s /run $mountPoint/var/run
-rm -f $mountPoint/etc/{resolv.conf,hosts}
-cp -Lf /etc/resolv.conf /etc/hosts $mountPoint/etc/
+for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done
+for f in /etc/passwd /etc/group;      do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done
 
 cp -Lf "@cacert@" "$mountPoint/tmp/ca-cert.crt"
 export SSL_CERT_FILE=/tmp/ca-cert.crt
@@ -135,14 +136,13 @@ fi
 mkdir -m 0755 -p \
     $mountPoint/nix/var/nix/gcroots \
     $mountPoint/nix/var/nix/temproots \
-    $mountPoint/nix/var/nix/manifests \
     $mountPoint/nix/var/nix/userpool \
     $mountPoint/nix/var/nix/profiles \
     $mountPoint/nix/var/nix/db \
     $mountPoint/nix/var/log/nix/drvs
 
 mkdir -m 1775 -p $mountPoint/nix/store
-chown root:nixbld $mountPoint/nix/store
+chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
 
 
 # There is no daemon in the chroot.
@@ -155,18 +155,13 @@ export LC_ALL=
 export LC_TIME=
 
 
-# Create a temporary Nix config file that causes the nixbld users to
-# be used.
-echo "build-users-group = nixbld" > $mountPoint/tmp/nix.conf # FIXME: remove in Nix 1.8
-binary_caches=$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')
-if test -n "$binary_caches"; then
-    echo "binary-caches = $binary_caches" >> $mountPoint/tmp/nix.conf
-fi
-export NIX_CONF_DIR=/tmp
+# Builds will use users that are members of this group
+extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
+
 
-touch $mountPoint/etc/passwd $mountPoint/etc/group
-mount --bind -o ro /etc/passwd $mountPoint/etc/passwd
-mount --bind -o ro /etc/group $mountPoint/etc/group
+# Inherit binary caches from the host
+binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
+extraBuildFlags+=(--option "binary-caches" "$binary_caches")
 
 
 # Copy Nix to the Nix store on the target device, unless it's already there.
@@ -205,14 +200,6 @@ p=@nix@/libexec/nix/substituters
 export NIX_SUBSTITUTERS=$p/copy-from-other-stores.pl:$p/download-from-binary-cache.pl
 
 
-# Make manifests available in the chroot.
-rm -f $mountPoint/nix/var/nix/manifests/*
-for i in /nix/var/nix/manifests/*.nixmanifest; do
-    chroot $mountPoint @nix@/bin/nix-store -r "$(readlink -f "$i")" > /dev/null
-    cp -pd "$i" $mountPoint/nix/var/nix/manifests/
-done
-
-
 if [ -z "$closure" ]; then
     # Get the absolute path to the NixOS/Nixpkgs sources.
     nixpkgs="$(readlink -f $(nix-instantiate --find-file nixpkgs))"
@@ -247,7 +234,7 @@ ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defex
 
 
 # Get rid of the /etc bind mounts.
-umount $mountPoint/etc/passwd $mountPoint/etc/group
+for f in /etc/passwd /etc/group; do [ -f "$f" ] && umount $mountPoint/$f; done
 
 
 # Grub needs an mtab.
@@ -263,16 +250,17 @@ touch $mountPoint/etc/NIXOS
 # a menu default pointing at the kernel/initrd/etc of the new
 # configuration.
 echo "finalising the installation..."
-NIXOS_INSTALL_GRUB="$bootLoader" chroot $mountPoint \
-    /nix/var/nix/profiles/system/bin/switch-to-configuration boot
-
+if [ -z "$noBootLoader" ]; then
+  NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint \
+      /nix/var/nix/profiles/system/bin/switch-to-configuration boot
+fi
 
 # Run the activation script.
 chroot $mountPoint /nix/var/nix/profiles/system/activate
 
 
 # Ask the user to set a root password.
-if [ -z "$noRootPasswd" ] && [ "$(chroot $mountPoint /run/current-system/sw/bin/sh -l -c "nix-instantiate --eval '<nixpkgs/nixos>' -A config.users.mutableUsers")" = true ] && [ -t 0 ] ; then
+if [ -z "$noRootPasswd" ] && [ -x $mountPoint/var/setuid-wrappers/passwd ] && [ -t 0 ]; then
     echo "setting root password..."
     chroot $mountPoint /var/setuid-wrappers/passwd
 fi
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index e26a9f6cf635..803989789838 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -33,7 +33,11 @@ while [ "$#" -gt 0 ]; do
         action="$i"
         ;;
       --install-grub)
-        export NIXOS_INSTALL_GRUB=1
+        echo "$0: --install-grub deprecated, use --install-bootloader instead" >&2
+        export NIXOS_INSTALL_BOOTLOADER=1
+        ;;
+      --install-bootloader)
+        export NIXOS_INSTALL_BOOTLOADER=1
         ;;
       --no-build-nix)
         buildNix=
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index a55c03bd9528..fc39a653abdc 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -24,6 +24,8 @@ let
     inherit (pkgs) perl pathsFromGraph rsync;
     nix = config.nix.package.out;
     cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
+    root_uid = config.ids.uids.root;
+    nixbld_gid = config.ids.gids.nixbld;
 
     nixClosure = pkgs.runCommand "closure"
       { exportReferencesGraph = ["refs" config.nix.package.out]; }
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 83b47728639c..31c93028bc52 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -274,6 +274,7 @@
       gocd-agent = 251;
       gocd-server = 252;
       terraria = 253;
+      mattermost = 254;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -518,6 +519,7 @@
       gocd-agent = 251;
       gocd-server = 252;
       terraria = 253;
+      mattermost = 254;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index 5eb38c510b48..7d50b8025bdd 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -21,6 +21,11 @@ let
       packageOverrides = pkgs:
         optCall lhs.packageOverrides pkgs //
         optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs;
+    } //
+    optionalAttrs (lhs ? perlPackageOverrides) {
+      perlPackageOverrides = pkgs:
+        optCall lhs.perlPackageOverrides pkgs //
+        optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs;
     };
 
   configType = mkOptionType {
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 35a48ca601be..dfc1d694e976 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -37,9 +37,10 @@
   ./hardware/network/rtl8192c.nix
   ./hardware/opengl.nix
   ./hardware/pcmcia.nix
+  ./hardware/video/amdgpu.nix
+  ./hardware/video/ati.nix
   ./hardware/video/bumblebee.nix
   ./hardware/video/nvidia.nix
-  ./hardware/video/ati.nix
   ./hardware/video/webcam/facetimehd.nix
   ./i18n/input-method/default.nix
   ./i18n/input-method/fcitx.nix
@@ -62,8 +63,7 @@
   ./programs/bash/bash.nix
   ./programs/blcr.nix
   ./programs/cdemu.nix
-  # see https://github.com/NixOS/nixos-channel-scripts/issues/4
-  #./programs/command-not-found/command-not-found.nix
+  ./programs/command-not-found/command-not-found.nix
   ./programs/dconf.nix
   ./programs/environment.nix
   ./programs/freetds.nix
@@ -335,12 +335,14 @@
   ./services/networking/docker-registry-server.nix
   ./services/networking/ejabberd.nix
   ./services/networking/fan.nix
+  ./services/networking/ferm.nix
   ./services/networking/firefox/sync-server.nix
   ./services/networking/firewall.nix
   ./services/networking/flashpolicyd.nix
   ./services/networking/freenet.nix
   ./services/networking/gale.nix
   ./services/networking/gateone.nix
+  ./services/networking/gdomap.nix
   ./services/networking/git-daemon.nix
   ./services/networking/gnunet.nix
   ./services/networking/gogoclient.nix
@@ -464,6 +466,7 @@
   ./services/ttys/agetty.nix
   ./services/ttys/gpm.nix
   ./services/ttys/kmscon.nix
+  ./services/web-apps/mattermost.nix
   ./services/web-apps/pump.io.nix
   ./services/web-apps/tt-rss.nix
   ./services/web-servers/apache-httpd/default.nix
diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix
index 6398509357a6..878c9cc0cf09 100644
--- a/nixos/modules/programs/shadow.nix
+++ b/nixos/modules/programs/shadow.nix
@@ -103,10 +103,9 @@ in
       };
 
     security.setuidPrograms = [ "su" "chfn" ]
+      ++ [ "newuidmap" "newgidmap" ] # new in shadow 4.2.x
       ++ lib.optionals config.users.mutableUsers
-      [ "passwd" "sg" "newgrp"
-        "newuidmap" "newgidmap" # new in shadow 4.2.x
-      ];
+      [ "passwd" "sg" "newgrp" ];
 
   };
 
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 3f8a770cbce7..0f10ecd4de71 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -29,7 +29,7 @@ with lib;
     (mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
 
     (mkRenamedOptionModule [ "services" "gitlab" "stateDir" ] [ "services" "gitlab" "statePath" ])
-    (mkRemovedOptionModule [ "services" "gitlab" "satelliteDir" ])
+    (mkRemovedOptionModule [ "services" "gitlab" "satelliteDir" ] "")
 
     # Old Grub-related options.
     (mkRenamedOptionModule [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ])
@@ -112,7 +112,7 @@ with lib;
     (mkRenamedOptionModule [ "services" "iodined" "domain" ] [ "services" "iodine" "server" "domain" ])
     (mkRenamedOptionModule [ "services" "iodined" "ip" ] [ "services" "iodine" "server" "ip" ])
     (mkRenamedOptionModule [ "services" "iodined" "extraConfig" ] [ "services" "iodine" "server" "extraConfig" ])
-    (mkRemovedOptionModule [ "services" "iodined" "client" ])
+    (mkRemovedOptionModule [ "services" "iodined" "client" ] "")
 
     # Grsecurity
     (mkRemovedOptionModule [ "security" "grsecurity" "kernelPatch" ])
@@ -137,19 +137,22 @@ with lib;
     # Unity3D
     (mkRenamedOptionModule [ "programs" "unity3d" "enable" ] [ "security" "chromiumSuidSandbox" "enable" ])
 
-    # Options that are obsolete and have no replacement.
-    (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ])
-    (mkRemovedOptionModule [ "programs" "bash" "enable" ])
-    (mkRemovedOptionModule [ "services" "samba" "defaultShare" ])
-    (mkRemovedOptionModule [ "services" "syslog-ng" "serviceName" ])
-    (mkRemovedOptionModule [ "services" "syslog-ng" "listenToJournal" ])
-    (mkRemovedOptionModule [ "ec2" "metadata" ])
-    (mkRemovedOptionModule [ "services" "openvpn" "enable" ])
-    (mkRemovedOptionModule [ "services" "printing" "cupsFilesConf" ])
-    (mkRemovedOptionModule [ "services" "printing" "cupsdConf" ])
-    (mkRemovedOptionModule [ "services" "xserver" "startGnuPGAgent" ])
-    (mkRemovedOptionModule [ "services" "phpfpm" "phpIni" ])
-    (mkRemovedOptionModule [ "services" "dovecot2" "package" ])
+    # fontconfig-ultimate
+    (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "rendering" ] [ "fonts" "fontconfig" "ultimate" "preset" ])
 
+    # Options that are obsolete and have no replacement.
+    (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
+    (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
+    (mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
+    (mkRemovedOptionModule [ "services" "syslog-ng" "serviceName" ] "")
+    (mkRemovedOptionModule [ "services" "syslog-ng" "listenToJournal" ] "")
+    (mkRemovedOptionModule [ "ec2" "metadata" ] "")
+    (mkRemovedOptionModule [ "services" "openvpn" "enable" ] "")
+    (mkRemovedOptionModule [ "services" "printing" "cupsFilesConf" ] "")
+    (mkRemovedOptionModule [ "services" "printing" "cupsdConf" ] "")
+    (mkRemovedOptionModule [ "services" "xserver" "startGnuPGAgent" ]
+      "See the 16.03 release notes for more information.")
+    (mkRemovedOptionModule [ "services" "phpfpm" "phpIni" ] "")
+    (mkRemovedOptionModule [ "services" "dovecot2" "package" ] "")
   ];
 }
diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix
index 60e9058dd69e..c6332ca9f9f6 100644
--- a/nixos/modules/security/grsecurity.nix
+++ b/nixos/modules/security/grsecurity.nix
@@ -12,7 +12,7 @@ let
     (fs: (fs.neededForBoot
           || elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ])
           && fs.fsType == "zfs")
-    (attrValues config.fileSystems) != [];
+    config.system.build.fileSystems != [];
 
   # Ascertain whether NixOS container support is required
   containerSupportRequired =
@@ -119,11 +119,13 @@ in
       "kernel.grsecurity.chroot_deny_chroot" = mkForce 0;
       "kernel.grsecurity.chroot_deny_mount" = mkForce 0;
       "kernel.grsecurity.chroot_deny_pivot" = mkForce 0;
+      "kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
     } // optionalAttrs containerSupportRequired {
       # chroot(2) restrictions that conflict with NixOS lightweight containers
       "kernel.grsecurity.chroot_deny_chmod" = mkForce 0;
       "kernel.grsecurity.chroot_deny_mount" = mkForce 0;
       "kernel.grsecurity.chroot_restrict_nice" = mkForce 0;
+      "kernel.grsecurity.chroot_caps" = mkForce 0;
     };
 
     assertions = [
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 231a1890e0c0..77815cd6dcc1 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -221,7 +221,7 @@ let
         (''
           # Account management.
           account sufficient pam_unix.so
-          ${optionalString config.users.ldap.enable
+          ${optionalString use_ldap
               "account sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
           ${optionalString config.krb5.enable
               "account sufficient ${pam_krb5}/lib/security/pam_krb5.so"}
@@ -261,7 +261,7 @@ let
               "auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"}
           ${let oath = config.security.pam.oath; in optionalString cfg.oathAuth
               "auth sufficient ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}"}
-          ${optionalString config.users.ldap.enable
+          ${optionalString use_ldap
               "auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"}
           ${optionalString config.krb5.enable ''
             auth [default=ignore success=1 service_err=reset] ${pam_krb5}/lib/security/pam_krb5.so use_first_pass
@@ -276,7 +276,7 @@ let
               "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
           ${optionalString cfg.pamMount
               "password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
-          ${optionalString config.users.ldap.enable
+          ${optionalString use_ldap
               "password sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
           ${optionalString config.krb5.enable
               "password sufficient ${pam_krb5}/lib/security/pam_krb5.so use_first_pass"}
@@ -296,7 +296,7 @@ let
               "session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"}
           ${optionalString config.security.pam.enableEcryptfs
               "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
-          ${optionalString config.users.ldap.enable
+          ${optionalString use_ldap
               "session optional ${pam_ldap}/lib/security/pam_ldap.so"}
           ${optionalString config.krb5.enable
               "session optional ${pam_krb5}/lib/security/pam_krb5.so"}
@@ -322,6 +322,7 @@ let
 
   inherit (pkgs) pam_krb5 pam_ccreds;
 
+  use_ldap = (config.users.ldap.enable && config.users.ldap.loginPam);
   pam_ldap = if config.users.ldap.daemon.enable then pkgs.nss_pam_ldapd else pkgs.pam_ldap;
 
   # Create a limits.conf(5) file.
diff --git a/nixos/modules/services/backup/crashplan.nix b/nixos/modules/services/backup/crashplan.nix
index a69526f968b0..38cf8eb72fb8 100644
--- a/nixos/modules/services/backup/crashplan.nix
+++ b/nixos/modules/services/backup/crashplan.nix
@@ -28,7 +28,7 @@ with lib;
       description = "CrashPlan Backup Engine";
 
       wantedBy = [ "multi-user.target" ];
-      after    = [ "network.target" ];
+      after    = [ "network.target" "local-fs.target" ];
 
       preStart = ''
         ensureDir() {
diff --git a/nixos/modules/services/continuous-integration/buildkite-agent.nix b/nixos/modules/services/continuous-integration/buildkite-agent.nix
index b1449882b04f..267bc16862c9 100644
--- a/nixos/modules/services/continuous-integration/buildkite-agent.nix
+++ b/nixos/modules/services/continuous-integration/buildkite-agent.nix
@@ -77,15 +77,11 @@ in
         preStart = ''
             ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/lib/buildkite-agent/.ssh
 
-            if ! [ -f /var/lib/buildkite-agent/.ssh/id_rsa ]; then
-              echo "${cfg.openssh.privateKey}" > /var/lib/buildkite-agent/.ssh/id_rsa
-              ${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa
-            fi
+            echo "${cfg.openssh.privateKey}" > /var/lib/buildkite-agent/.ssh/id_rsa
+            ${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa
 
-            if ! [ -f /var/lib/buildkite-agent/.ssh/id_rsa.pub ]; then
-              echo "${cfg.openssh.publicKey}" > /var/lib/buildkite-agent/.ssh/id_rsa.pub
-              ${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa.pub
-            fi
+            echo "${cfg.openssh.publicKey}" > /var/lib/buildkite-agent/.ssh/id_rsa.pub
+            ${pkgs.coreutils}/bin/chmod 600 /var/lib/buildkite-agent/.ssh/id_rsa.pub
           '';
 
         serviceConfig =
diff --git a/nixos/modules/services/continuous-integration/gocd-agent/default.nix b/nixos/modules/services/continuous-integration/gocd-agent/default.nix
index 36f6527ee47b..21f319f7fcf6 100644
--- a/nixos/modules/services/continuous-integration/gocd-agent/default.nix
+++ b/nixos/modules/services/continuous-integration/gocd-agent/default.nix
@@ -36,7 +36,7 @@ in {
       };
 
       packages = mkOption {
-        default = [ pkgs.stdenv pkgs.jre config.programs.ssh.package pkgs.nix ];
+        default = [ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ];
         type = types.listOf types.package;
         description = ''
           Packages to add to PATH for the Go.CD agent process.
@@ -57,18 +57,10 @@ in {
       };
 
       goServer = mkOption {
-        default = "127.0.0.1";
+        default = "https://127.0.0.1:8154/go";
         type = types.str;
         description = ''
-          Address of GoCD Server to attach the Go.CD Agent to.
-        '';
-      };
-
-      goServerPort = mkOption {
-        default = 8153;
-        type = types.int;
-        description = ''
-          Port that Go.CD Server is Listening on.
+          URL of the GoCD Server to attach the Go.CD Agent to.
         '';
       };
 
@@ -80,26 +72,26 @@ in {
         '';
       };
 
-      heapSize = mkOption {
+      initialJavaHeapSize = mkOption {
         default = "128m";
         type = types.str;
         description = ''
-          Specifies the java heap memory size for the Go.CD agent java process.
+          Specifies the initial java heap memory size for the Go.CD agent java process.
         '';
       };
 
-      maxMemory = mkOption {
+      maxJavaHeapMemory = mkOption {
         default = "256m";
         type = types.str;
         description = ''
-          Specifies the java maximum memory size for the Go.CD agent java process.
+          Specifies the java maximum heap memory size for the Go.CD agent java process.
         '';
       };
 
       startupOptions = mkOption {
         default = [
-          "-Xms${cfg.heapSize}"
-          "-Xmx${cfg.maxMemory}"
+          "-Xms${cfg.initialJavaHeapSize}"
+          "-Xmx${cfg.maxJavaHeapMemory}"
           "-Djava.io.tmpdir=/tmp"
           "-Dcruise.console.publish.interval=10"
           "-Djava.security.egd=file:/dev/./urandom"
@@ -112,8 +104,8 @@ in {
 
       extraOptions = mkOption {
         default = [ ];
-        example = [ 
-          "-X debug" 
+        example = [
+          "-X debug"
           "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006"
           "-verbose:gc"
           "-Xloggc:go-agent-gc.log"
@@ -170,7 +162,7 @@ in {
               config.environment.sessionVariables;
         in
           selectedSessionVars //
-            { 
+            {
               NIX_REMOTE = "daemon";
               AGENT_WORK_DIR = cfg.workDir;
               AGENT_STARTUP_ARGS = ''${concatStringsSep " "  cfg.startupOptions}'';
@@ -199,13 +191,14 @@ in {
         ${pkgs.jre}/bin/java ${concatStringsSep " " cfg.startupOptions} \
                         ${concatStringsSep " " cfg.extraOptions} \
                               -jar ${pkgs.gocd-agent}/go-agent/agent-bootstrapper.jar \
-                              ${cfg.goServer} \
-                              ${toString cfg.goServerPort}
+                              -serverUrl ${cfg.goServer}
       '';
 
       serviceConfig = {
         User = cfg.user;
         WorkingDirectory = cfg.workDir;
+        RestartSec = 30;
+        Restart = "on-failure";
       };
     };
   };
diff --git a/nixos/modules/services/continuous-integration/hydra/default.nix b/nixos/modules/services/continuous-integration/hydra/default.nix
index c8edfaf18537..b1b3404add09 100644
--- a/nixos/modules/services/continuous-integration/hydra/default.nix
+++ b/nixos/modules/services/continuous-integration/hydra/default.nix
@@ -166,7 +166,7 @@ in
 
       buildMachinesFiles = mkOption {
         type = types.listOf types.path;
-        default = [];
+        default = [ "/etc/nix/machines" ];
         example = [ "/etc/nix/machines" "/var/lib/hydra/provisioner/machines" ];
         description = "List of files containing build machines.";
       };
@@ -193,7 +193,9 @@ in
 
   config = mkIf cfg.enable {
 
-    users.extraGroups.hydra = { };
+    users.extraGroups.hydra = {
+      gid = config.ids.gids.hydra;
+    };
 
     users.extraUsers.hydra =
       { description = "Hydra";
@@ -201,6 +203,7 @@ in
         createHome = true;
         home = baseDir;
         useDefaultShell = true;
+        uid = config.ids.uids.hydra;
       };
 
     users.extraUsers.hydra-queue-runner =
@@ -208,12 +211,14 @@ in
         group = "hydra";
         useDefaultShell = true;
         home = "${baseDir}/queue-runner"; # really only to keep SSH happy
+        uid = config.ids.uids.hydra-queue-runner;
       };
 
     users.extraUsers.hydra-www =
       { description = "Hydra web server";
         group = "hydra";
         useDefaultShell = true;
+        uid = config.ids.uids.hydra-www;
       };
 
     nix.trustedUsers = [ "hydra-queue-runner" ];
diff --git a/nixos/modules/services/databases/cassandra.nix b/nixos/modules/services/databases/cassandra.nix
new file mode 100644
index 000000000000..c98af617587d
--- /dev/null
+++ b/nixos/modules/services/databases/cassandra.nix
@@ -0,0 +1,449 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.cassandra;
+  cassandraPackage = cfg.package.override {
+    jre = cfg.jre;
+  };
+  cassandraUser = {
+    name = cfg.user;
+    home = "/var/lib/cassandra";
+    description = "Cassandra role user";
+  };
+
+  cassandraRackDcProperties = ''
+    dc=${cfg.dc}
+    rack=${cfg.rack}
+  '';
+
+  cassandraConf = ''
+    cluster_name: ${cfg.clusterName}
+    num_tokens: 256
+    auto_bootstrap: ${if cfg.autoBootstrap then "true" else "false"}
+    hinted_handoff_enabled: ${if cfg.hintedHandOff then "true" else "false"}
+    hinted_handoff_throttle_in_kb: ${builtins.toString cfg.hintedHandOffThrottle}
+    max_hints_delivery_threads: 2
+    max_hint_window_in_ms: 10800000 # 3 hours
+    authenticator: ${cfg.authenticator}
+    authorizer: ${cfg.authorizer}
+    permissions_validity_in_ms: 2000
+    partitioner: org.apache.cassandra.dht.Murmur3Partitioner
+    data_file_directories:
+    ${builtins.concatStringsSep "\n" (map (v: "  - "+v) cfg.dataDirs)}
+    commitlog_directory: ${cfg.commitLogDirectory}
+    disk_failure_policy: stop
+    key_cache_size_in_mb:
+    key_cache_save_period: 14400
+    row_cache_size_in_mb: 0
+    row_cache_save_period: 0
+    saved_caches_directory: ${cfg.savedCachesDirectory}
+    commitlog_sync: ${cfg.commitLogSync}
+    commitlog_sync_period_in_ms: ${builtins.toString cfg.commitLogSyncPeriod}
+    commitlog_segment_size_in_mb: 32
+    seed_provider:
+      - class_name: org.apache.cassandra.locator.SimpleSeedProvider
+        parameters:
+          - seeds: "${builtins.concatStringsSep "," cfg.seeds}"
+    concurrent_reads: ${builtins.toString cfg.concurrentReads}
+    concurrent_writes: ${builtins.toString cfg.concurrentWrites}
+    memtable_flush_queue_size: 4
+    trickle_fsync: false
+    trickle_fsync_interval_in_kb: 10240
+    storage_port: 7000
+    ssl_storage_port: 7001
+    listen_address: ${cfg.listenAddress}
+    start_native_transport: true
+    native_transport_port: 9042
+    start_rpc: true
+    rpc_address: ${cfg.rpcAddress}
+    rpc_port: 9160
+    rpc_keepalive: true
+    rpc_server_type: sync
+    thrift_framed_transport_size_in_mb: 15
+    incremental_backups: ${if cfg.incrementalBackups then "true" else "false"}
+    snapshot_before_compaction: false
+    auto_snapshot: true
+    column_index_size_in_kb: 64
+    in_memory_compaction_limit_in_mb: 64
+    multithreaded_compaction: false
+    compaction_throughput_mb_per_sec: 16
+    compaction_preheat_key_cache: true
+    read_request_timeout_in_ms: 10000
+    range_request_timeout_in_ms: 10000
+    write_request_timeout_in_ms: 10000
+    cas_contention_timeout_in_ms: 1000
+    truncate_request_timeout_in_ms: 60000
+    request_timeout_in_ms: 10000
+    cross_node_timeout: false
+    endpoint_snitch: ${cfg.snitch}
+    dynamic_snitch_update_interval_in_ms: 100
+    dynamic_snitch_reset_interval_in_ms: 600000
+    dynamic_snitch_badness_threshold: 0.1
+    request_scheduler: org.apache.cassandra.scheduler.NoScheduler
+    server_encryption_options:
+      internode_encryption: ${cfg.internodeEncryption}
+      keystore: ${cfg.keyStorePath}
+      keystore_password: ${cfg.keyStorePassword}
+      truststore: ${cfg.trustStorePath}
+      truststore_password: ${cfg.trustStorePassword}
+    client_encryption_options:
+      enabled: ${if cfg.clientEncryption then "true" else "false"}
+      keystore: ${cfg.keyStorePath}
+      keystore_password: ${cfg.keyStorePassword}
+    internode_compression: all
+    inter_dc_tcp_nodelay: false
+    preheat_kernel_page_cache: false
+    streaming_socket_timeout_in_ms: ${toString cfg.streamingSocketTimoutInMS}
+  '';
+
+  cassandraLog = ''
+    log4j.rootLogger=${cfg.logLevel},stdout
+    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] %d{HH:mm:ss,SSS} %m%n
+  '';
+
+  cassandraConfFile = pkgs.writeText "cassandra.yaml" cassandraConf;
+  cassandraLogFile = pkgs.writeText "log4j-server.properties" cassandraLog;
+  cassandraRackFile = pkgs.writeText "cassandra-rackdc.properties" cassandraRackDcProperties;
+
+  cassandraEnvironment = {
+    CASSANDRA_HOME = cassandraPackage;
+    JAVA_HOME = cfg.jre;
+    CASSANDRA_CONF = "/etc/cassandra";
+  };
+
+in {
+
+  ###### interface
+
+  options.services.cassandra = {
+    enable = mkOption {
+      description = "Whether to enable cassandra.";
+      default = false;
+      type = types.bool;
+    };
+    package = mkOption {
+      description = "Cassandra package to use.";
+      default = pkgs.cassandra;
+      defaultText = "pkgs.cassandra";
+      type = types.package;
+    };
+    jre = mkOption {
+      description = "JRE package to run cassandra service.";
+      default = pkgs.jre;
+      defaultText = "pkgs.jre";
+      type = types.package;
+    };
+    user = mkOption {
+      description = "User that runs cassandra service.";
+      default = "cassandra";
+      type = types.string;
+    };
+    group = mkOption {
+      description = "Group that runs cassandra service.";
+      default = "cassandra";
+      type = types.string;
+    };
+    envFile = mkOption {
+      description = "path to cassandra-env.sh";
+      default = "${cassandraPackage}/conf/cassandra-env.sh";
+      defaultText = "\${cassandraPackage}/conf/cassandra-env.sh";
+      type = types.path;
+    };
+    clusterName = mkOption {
+      description = "set cluster name";
+      default = "cassandra";
+      example = "prod-cluster0";
+      type = types.string;
+    };
+    commitLogDirectory = mkOption {
+      description = "directory for commit logs";
+      default = "/var/lib/cassandra/commit_log";
+      type = types.string;
+    };
+    savedCachesDirectory = mkOption {
+      description = "directory for saved caches";
+      default = "/var/lib/cassandra/saved_caches";
+      type = types.string;
+    };
+    hintedHandOff = mkOption {
+      description = "enable hinted handoff";
+      default = true;
+      type = types.bool;
+    };
+    hintedHandOffThrottle = mkOption {
+      description = "hinted hand off throttle rate in kb";
+      default = 1024;
+      type = types.int;
+    };
+    commitLogSync = mkOption {
+      description = "commitlog sync method";
+      default = "periodic";
+      type = types.str;
+      example = "batch";
+    };
+    commitLogSyncPeriod = mkOption {
+      description = "commitlog sync period in ms ";
+      default = 10000;
+      type = types.int;
+    };
+    envScript = mkOption {
+      default = "${cassandraPackage}/conf/cassandra-env.sh";
+      defaultText = "\${cassandraPackage}/conf/cassandra-env.sh";
+      type = types.path;
+      description = "Supply your own cassandra-env.sh rather than using the default";
+    };
+    extraParams = mkOption {
+      description = "add additional lines to cassandra-env.sh";
+      default = [];
+      example = [''JVM_OPTS="$JVM_OPTS -Dcassandra.available_processors=1"''];
+      type = types.listOf types.str;
+    };
+    dataDirs = mkOption {
+      type = types.listOf types.path;
+      default = [ "/var/lib/cassandra/data" ];
+      description = "Data directories for cassandra";
+    };
+    logLevel = mkOption {
+      type = types.str;
+      default = "INFO";
+      description = "default logging level for log4j";
+    };
+    internodeEncryption = mkOption {
+      description = "enable internode encryption";
+      default = "none";
+      example = "all";
+      type = types.str;
+    };
+    clientEncryption = mkOption {
+      description = "enable client encryption";
+      default = false;
+      type = types.bool;
+    };
+    trustStorePath = mkOption {
+      description = "path to truststore";
+      default = ".conf/truststore";
+      type = types.str;
+    };
+    keyStorePath = mkOption {
+      description = "path to keystore";
+      default = ".conf/keystore";
+      type = types.str;
+    };
+    keyStorePassword = mkOption {
+      description = "password to keystore";
+      default = "cassandra";
+      type = types.str;
+    };
+    trustStorePassword = mkOption {
+      description = "password to truststore";
+      default = "cassandra";
+      type = types.str;
+    };
+    seeds = mkOption {
+      description = "password to truststore";
+      default = [ "127.0.0.1" ];
+      type = types.listOf types.str;
+    };
+    concurrentWrites = mkOption {
+      description = "number of concurrent writes allowed";
+      default = 32;
+      type = types.int;
+    };
+    concurrentReads = mkOption {
+      description = "number of concurrent reads allowed";
+      default = 32;
+      type = types.int;
+    };
+    listenAddress = mkOption {
+      description = "listen address";
+      default = "localhost";
+      type = types.str;
+    };
+    rpcAddress = mkOption {
+      description = "rpc listener address";
+      default = "localhost";
+      type = types.str;
+    };
+    incrementalBackups = mkOption {
+      description = "enable incremental backups";
+      default = false;
+      type = types.bool;
+    };
+    snitch = mkOption {
+      description = "snitch to use for topology discovery";
+      default = "GossipingPropertyFileSnitch";
+      example = "Ec2Snitch";
+      type = types.str;
+    };
+    dc = mkOption {
+      description = "datacenter for use in topology configuration";
+      default = "DC1";
+      example = "DC1";
+      type = types.str;
+    };
+    rack = mkOption {
+      description = "rack for use in topology configuration";
+      default = "RAC1";
+      example = "RAC1";
+      type = types.str;
+    };
+    authorizer = mkOption {
+      description = "
+        Authorization backend, implementing IAuthorizer; used to limit access/provide permissions
+      ";
+      default = "AllowAllAuthorizer";
+      example = "CassandraAuthorizer";
+      type = types.str;
+    };
+    authenticator = mkOption {
+      description = "
+        Authentication backend, implementing IAuthenticator; used to identify users
+      ";
+      default = "AllowAllAuthenticator";
+      example = "PasswordAuthenticator";
+      type = types.str;
+    };
+    autoBootstrap = mkOption {
+      description = "It makes new (non-seed) nodes automatically migrate the right data to themselves.";
+      default = true;
+      example = true;
+      type = types.bool;
+    };
+    streamingSocketTimoutInMS = mkOption {
+      description = "Enable or disable socket timeout for streaming operations";
+      default = 3600000; #CASSANDRA-8611
+      example = 120;
+      type = types.int;
+    };
+    repairStartAt = mkOption {
+      default = "Sun";
+      type = types.string;
+      description = ''
+      Defines realtime (i.e. wallclock) timers with calendar event
+      expressions. For more details re: systemd OnCalendar at
+      https://www.freedesktop.org/software/systemd/man/systemd.time.html#Displaying%20Time%20Spans
+      '';
+      example = ["weekly" "daily" "08:05:40" "mon,fri *-1/2-1,3 *:30:45"];
+    };
+    repairRandomizedDelayInSec = mkOption {
+      default = 0;
+      type = types.int;
+      description = ''Delay the timer by a randomly selected, evenly distributed
+      amount of time between 0 and the specified time value. re: systemd timer
+      RandomizedDelaySec for more details
+      '';
+    };
+    repairPostStop = mkOption {
+      default = null;
+      type = types.nullOr types.string;
+      description = ''
+      Run a script when repair is over. One can use it to send statsd events, email, etc.
+      '';
+    };
+    repairPostStart = mkOption {
+      default = null;
+      type = types.nullOr types.string;
+      description = ''
+      Run a script when repair starts. One can use it to send statsd events, email, etc.
+      It has same semantics as systemd ExecStopPost; So, if it fails, unit is consisdered
+      failed.
+      '';
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.etc."cassandra/cassandra-rackdc.properties" = {
+      source = cassandraRackFile;
+    };
+    environment.etc."cassandra/cassandra.yaml" = {
+      source = cassandraConfFile;
+    };
+    environment.etc."cassandra/log4j-server.properties" = {
+      source = cassandraLogFile;
+    };
+    environment.etc."cassandra/cassandra-env.sh" = {
+      text = ''
+        ${builtins.readFile cfg.envFile}
+        ${concatStringsSep "\n" cfg.extraParams}
+      '';
+    };
+    systemd.services.cassandra = {
+      description = "Cassandra Daemon";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-interfaces.target" ];
+      environment = cassandraEnvironment;
+      restartTriggers = [ cassandraConfFile cassandraLogFile cassandraRackFile ];
+      serviceConfig = {
+
+        User = cfg.user;
+        PermissionsStartOnly = true;
+        LimitAS = "infinity";
+        LimitNOFILE = "100000";
+        LimitNPROC = "32768";
+        LimitMEMLOCK = "infinity";
+
+      };
+      script = ''
+         ${cassandraPackage}/bin/cassandra -f
+        '';
+      path = [
+        cfg.jre
+        cassandraPackage
+        pkgs.coreutils
+      ];
+      preStart = ''
+        mkdir -m 0700 -p /etc/cassandra/triggers
+        mkdir -m 0700 -p /var/lib/cassandra /var/log/cassandra
+        chown ${cfg.user} /var/lib/cassandra /var/log/cassandra /etc/cassandra/triggers
+      '';
+      postStart = ''
+        sleep 2
+        while ! nodetool status >/dev/null 2>&1; do
+          sleep 2
+        done
+        nodetool status
+      '';
+    };
+
+    environment.systemPackages = [ cassandraPackage ];
+
+    networking.firewall.allowedTCPPorts = [
+      7000
+      7001
+      9042
+      9160
+    ];
+
+    users.extraUsers.cassandra =
+      if config.ids.uids ? "cassandra"
+      then { uid = config.ids.uids.cassandra; } // cassandraUser
+      else cassandraUser ;
+
+    boot.kernel.sysctl."vm.swappiness" = pkgs.lib.mkOptionDefault 0;
+
+    systemd.timers."cassandra-repair" = {
+      timerConfig = {
+        OnCalendar = "${toString cfg.repairStartAt}";
+        RandomizedDelaySec = cfg.repairRandomizedDelayInSec;
+      };
+    };
+
+    systemd.services."cassandra-repair" = {
+      description = "Cassandra repair daemon";
+      environment = cassandraEnvironment;
+      script = "${cassandraPackage}/bin/nodetool repair -pr";
+      postStop = mkIf (cfg.repairPostStop != null) cfg.repairPostStop;
+      postStart = mkIf (cfg.repairPostStart != null) cfg.repairPostStart;
+      serviceConfig = {
+        User = cfg.user;
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix
index 480e1184ffa3..a039ad138f6f 100644
--- a/nixos/modules/services/databases/redis.nix
+++ b/nixos/modules/services/databases/redis.nix
@@ -234,9 +234,8 @@ in
         serviceConfig.Type = "oneshot";
 
         script = ''
-          if ! test -e ${cfg.dbpath}; then
-              install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
-          fi
+          install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
+          chown -R ${cfg.user} ${cfg.dbpath}
         '';
       };
 
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
index 5ab7daafa85b..281d02a8c65e 100644
--- a/nixos/modules/services/hardware/tlp.nix
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -72,8 +72,6 @@ in
           ExecStart = "${tlp}/bin/tlp init start";
           ExecStop = "${tlp}/bin/tlp init stop";
         };
-
-        environment.MODULE_DIR="/run/current-system/kernel-modules/lib/modules/";
       };
 
       tlp-sleep = {
@@ -92,8 +90,6 @@ in
           ExecStart = "${tlp}/bin/tlp suspend";
           ExecStop = "${tlp}/bin/tlp resume";
         };
-
-        environment.MODULE_DIR="/run/current-system/kernel-modules/lib/modules/";
       };
     };
 
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index e7741083d1ae..7c4c93d0fcb3 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -58,7 +58,7 @@ let
       # Fix some paths in the standard udev rules.  Hacky.
       for i in $out/*.rules; do
         substituteInPlace $i \
-          --replace \"/sbin/modprobe \"${config.system.sbin.modprobe}/sbin/modprobe \
+          --replace \"/sbin/modprobe \"${pkgs.kmod}/bin/modprobe \
           --replace \"/sbin/mdadm \"${pkgs.mdadm}/sbin/mdadm \
           --replace \"/sbin/blkid \"${pkgs.utillinux}/sbin/blkid \
           --replace \"/bin/mount \"${pkgs.utillinux}/bin/mount \
@@ -316,8 +316,7 @@ in
       '';
 
     systemd.services.systemd-udevd =
-      { environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
-        restartTriggers = cfg.packages;
+      { restartTriggers = cfg.packages;
       };
 
   };
diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix
index 8913030e0ea2..18f0c3eb83d5 100644
--- a/nixos/modules/services/misc/autofs.nix
+++ b/nixos/modules/services/misc/autofs.nix
@@ -75,9 +75,10 @@ in
     boot.kernelModules = [ "autofs4" ];
 
     systemd.services.autofs =
-      { description = "Filesystem automounter";
+      { description = "Automounts filesystems on demand";
+        after = [ "network.target" "ypbind.service" "sssd.service" "network-online.target" ];
+        wants = [ "network-online.target" ];
         wantedBy = [ "multi-user.target" ];
-        after = [ "network.target" ];
 
         preStart = ''
           # There should be only one autofs service managed by systemd, so this should be safe.
@@ -85,7 +86,9 @@ in
         '';
 
         serviceConfig = {
-          ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}";
+          Type = "forking";
+          PIDFile = "/run/autofs.pid";
+          ExecStart = "${pkgs.autofs5}/bin/automount ${optionalString cfg.debug "-d"} -p /run/autofs.pid -t ${builtins.toString cfg.timeout} ${autoMaster}";
           ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
         };
       };
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index 285e1933fc87..b3f09999adba 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -41,6 +41,13 @@ let
       namespace: resque:gitlab
   '';
 
+  secretsYml = ''
+    production:
+      secret_key_base: ${cfg.secrets.secret}
+      otp_key_base: ${cfg.secrets.otp}
+      db_key_base: ${cfg.secrets.db}
+  '';
+
   gitlabConfig = {
     # These are the default settings from config/gitlab.example.yml
     production = flip recursiveUpdate cfg.extraConfig {
@@ -116,7 +123,7 @@ let
       makeWrapper ${cfg.packages.gitlab.env}/bin/bundle $out/bin/gitlab-bundle \
           ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \
           --set GITLAB_CONFIG_PATH '${cfg.statePath}/config' \
-          --set PATH '${pkgs.nodejs}/bin:${pkgs.gzip}/bin:${config.services.postgresql.package}/bin:$PATH' \
+          --set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip config.services.postgresql.package ]}:$PATH' \
           --set RAKEOPT '-f ${cfg.packages.gitlab}/share/gitlab/Rakefile' \
           --run 'cd ${cfg.packages.gitlab}/share/gitlab'
       makeWrapper $out/bin/gitlab-bundle $out/bin/gitlab-rake \
@@ -313,6 +320,42 @@ in {
         };
       };
 
+      secrets.secret = mkOption {
+        type = types.str;
+        description = ''
+          The secret is used to encrypt variables in the DB. If
+          you change or lose this key you will be unable to access variables
+          stored in database.
+
+          Make sure the secret is at least 30 characters and all random,
+          no regular words or you'll be exposed to dictionary attacks.
+        '';
+      };
+
+      secrets.db = mkOption {
+        type = types.str;
+        description = ''
+          The secret is used to encrypt variables in the DB. If
+          you change or lose this key you will be unable to access variables
+          stored in database.
+
+          Make sure the secret is at least 30 characters and all random,
+          no regular words or you'll be exposed to dictionary attacks.
+        '';
+      };
+
+      secrets.otp = mkOption {
+        type = types.str;
+        description = ''
+          The secret is used to encrypt secrets for OTP tokens. If
+          you change or lose this key, users which have 2FA enabled for login
+          won't be able to login anymore.
+
+          Make sure the secret is at least 30 characters and all random,
+          no regular words or you'll be exposed to dictionary attacks.
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.attrs;
         default = {};
@@ -380,6 +423,7 @@ in {
         User = cfg.user;
         Group = cfg.group;
         TimeoutSec = "300";
+        Restart = "on-failure";
         WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
         ExecStart="${cfg.packages.gitlab.env}/bin/bundle exec \"sidekiq -q post_receive -q mailers -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.statePath}/tmp/sidekiq.pid\"";
       };
@@ -404,6 +448,7 @@ in {
         User = cfg.user;
         Group = cfg.group;
         TimeoutSec = "300";
+        Restart = "on-failure";
         ExecStart =
           "${cfg.packages.gitlab-workhorse}/bin/gitlab-workhorse "
           + "-listenUmask 0 "
@@ -438,8 +483,7 @@ in {
         rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks
         mkdir -p ${cfg.statePath}/config ${cfg.statePath}/shell
 
-        # TODO: What exactly is gitlab-shell doing with the secret?
-        tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 20 > ${cfg.statePath}/config/gitlab_shell_secret
+        tr -dc A-Za-z0-9 < /dev/urandom | head -c 32 > ${cfg.statePath}/config/gitlab_shell_secret
 
         # The uploads directory is hardcoded somewhere deep in rails. It is
         # symlinked in the gitlab package to /run/gitlab/uploads to make it
@@ -465,6 +509,7 @@ in {
         # JSON is a subset of YAML
         ln -fs ${pkgs.writeText "gitlab.yml" (builtins.toJSON gitlabConfig)} ${cfg.statePath}/config/gitlab.yml
         ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.statePath}/config/database.yml
+        ln -fs ${pkgs.writeText "secrets.yml" secretsYml} ${cfg.statePath}/config/secrets.yml
         ln -fs ${pkgs.writeText "unicorn.rb" unicornConfig} ${cfg.statePath}/config/unicorn.rb
 
         chown -R ${cfg.user}:${cfg.group} ${cfg.statePath}/
diff --git a/nixos/modules/services/misc/gitlab.xml b/nixos/modules/services/misc/gitlab.xml
index a8147b3a74f9..f9636f8e1278 100644
--- a/nixos/modules/services/misc/gitlab.xml
+++ b/nixos/modules/services/misc/gitlab.xml
@@ -62,6 +62,11 @@ services.gitlab = {
     address = "localhost";
     port = 25;
   };
+  secrets = {
+    db = "uPgq1gtwwHiatiuE0YHqbGa5lEIXH7fMsvuTNgdzJi8P0Dg12gibTzBQbq5LT7PNzcc3BP9P1snHVnduqtGF43PgrQtU7XL93ts6gqe9CBNhjtaqUwutQUDkygP5NrV6";
+    secret = "devzJ0Tz0POiDBlrpWmcsjjrLaltyiAdS8TtgT9YNBOoUcDsfppiY3IXZjMVtKgXrFImIennFGOpPN8IkP8ATXpRgDD5rxVnKuTTwYQaci2NtaV1XxOQGjdIE50VGsR3";
+    otp = "e1GATJVuS2sUh7jxiPzZPre4qtzGGaS22FR50Xs1TerRVdgI3CBVUi5XYtQ38W4xFeS4mDqi5cQjExE838iViSzCdcG19XSL6qNsfokQP9JugwiftmhmCadtsnHErBMI";
+  };
   extraConfig = {
     gitlab = {
       email_from = "gitlab-no-reply@example.com";
@@ -74,6 +79,13 @@ services.gitlab = {
 </programlisting>
 </para>
 
+<para>If you're setting up a new Gitlab instance, generate new secrets. You
+for instance use <literal>tr -dc A-Za-z0-9 &lt; /dev/urandom | head -c 128</literal>
+to generate a new secret. Gitlab encrypts sensitive data stored in the database.
+If you're restoring an existing Gitlab instance, you must specify the secrets
+secret from <literal>config/secrets.yml</literal> located in your Gitlab state
+folder.</para>
+
 <para>Refer to <xref linkend="ch-options" /> for all available configuration
 options for the <literal>services.gitlab</literal> module.</para>
 
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index d71837737ab3..fe5132d4973e 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -248,7 +248,7 @@ in
         description = ''
           List of binary cache URLs that non-root users can use (in
           addition to those specified using
-          <option>nix.binaryCaches</option> by passing
+          <option>nix.binaryCaches</option>) by passing
           <literal>--option binary-caches</literal> to Nix commands.
         '';
       };
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index e50728aff8f8..08fc3f04dbfc 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -390,7 +390,7 @@ in {
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
+          ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
           PermissionsStartOnly = true;
@@ -413,7 +413,7 @@ in {
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
+          ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
           PIDFile="/run/${name}/${name}.pid";
@@ -429,7 +429,7 @@ in {
         after = [ "network-interfaces.target" ];
         environment = carbonEnv;
         serviceConfig = {
-          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts name}";
+          ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd ${carbonOpts name}";
           User = "graphite";
           Group = "graphite";
           PIDFile="/run/${name}/${name}.pid";
@@ -461,11 +461,11 @@ in {
               penvPack = "${penv}/${pkgs.python.sitePackages}";
               # opt/graphite/webapp contains graphite/settings.py
               # explicitly adding pycairo in path because it cannot be imported via buildEnv
-            in "${penvPack}/opt/graphite/webapp:${penvPack}:${pkgs.pycairo}/${pkgs.python.sitePackages}";
+            in "${penvPack}/opt/graphite/webapp:${penvPack}:${pkgs.pythonPackages.pycairo}/${pkgs.python.sitePackages}";
           DJANGO_SETTINGS_MODULE = "graphite.settings";
           GRAPHITE_CONF_DIR = configDir;
           GRAPHITE_STORAGE_DIR = dataDir;
-          LD_LIBRARY_PATH = "${pkgs.cairo}/lib";
+          LD_LIBRARY_PATH = "${pkgs.cairo.out}/lib";
         };
         serviceConfig = {
           ExecStart = ''
diff --git a/nixos/modules/services/network-filesystems/openafs-client/default.nix b/nixos/modules/services/network-filesystems/openafs-client/default.nix
index 61c66bb88357..891f41c8dcdc 100644
--- a/nixos/modules/services/network-filesystems/openafs-client/default.nix
+++ b/nixos/modules/services/network-filesystems/openafs-client/default.nix
@@ -80,7 +80,7 @@ in
       preStart = ''
         mkdir -p -m 0755 /afs
         mkdir -m 0700 -p ${cfg.cacheDirectory}
-        ${pkgs.kmod}/sbin/insmod ${openafsPkgs}/lib/openafs/libafs-*.ko || true
+        ${pkgs.kmod}/bin/insmod ${openafsPkgs}/lib/openafs/libafs-*.ko || true
         ${openafsPkgs}/sbin/afsd -confdir ${afsConfig} -cachedir ${cfg.cacheDirectory} ${if cfg.sparse then "-dynroot-sparse" else "-dynroot"} -fakestat -afsdb
         ${openafsPkgs}/bin/fs setcrypt ${if cfg.crypt then "on" else "off"}
       '';
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix
index f4063a3406f1..0495b32c6fa8 100644
--- a/nixos/modules/services/networking/cjdns.nix
+++ b/nixos/modules/services/networking/cjdns.nix
@@ -253,7 +253,7 @@ in
     networking.extraHosts = "${cjdnsHosts}";
 
     assertions = [
-      { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile == "" );
+      { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != "" );
         message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
       }
       { assertion = config.networking.enableIPv6;
diff --git a/nixos/modules/services/networking/ejabberd.nix b/nixos/modules/services/networking/ejabberd.nix
index 8ecc16257db8..82ed7fc4a837 100644
--- a/nixos/modules/services/networking/ejabberd.nix
+++ b/nixos/modules/services/networking/ejabberd.nix
@@ -111,10 +111,10 @@ in {
       description = "ejabberd server";
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" ];
-      path = [ pkgs.findutils pkgs.coreutils ] ++ lib.optional cfg.imagemagick pkgs.imagemagick;
+      path = [ pkgs.findutils pkgs.coreutils pkgs.runit ] ++ lib.optional cfg.imagemagick pkgs.imagemagick;
 
       serviceConfig = {
-        Type = "forking";
+        ExecStart = ''${ectl} foreground'';
         # FIXME: runit is used for `chpst` -- can we get rid of this?
         ExecStop = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} stop'';
         ExecReload = ''${pkgs.runit}/bin/chpst -u "${cfg.user}:${cfg.group}" ${ectl} reload_config'';
@@ -132,29 +132,24 @@ in {
 
         mkdir -p -m750 "${cfg.spoolDir}"
         chown -R "${cfg.user}:${cfg.group}" "${cfg.spoolDir}"
-      '';
-
-      script = ''
-        [ -z "$(ls -A '${cfg.spoolDir}')" ] && firstRun=1
 
-        ${ectl} start
+        if [ -z "$(ls -A '${cfg.spoolDir}')" ]; then
+          touch "${cfg.spoolDir}/.firstRun"
+        fi
+      '';
 
-        count=0
+      postStart = ''
         while ! ${ectl} status >/dev/null 2>&1; do
-          if [ $count -eq 30 ]; then
-            echo "ejabberd server hasn't started in 30 seconds, giving up"
-            exit 1
-          fi
-
-          count=$((count++))
-          sleep 1
+          if ! kill -0 "$MAINPID"; then exit 1; fi
+          sleep 0.1
         done
 
-        if [ -n "$firstRun" ]; then
+        if [ -e "${cfg.spoolDir}/.firstRun" ]; then
+          rm "${cfg.spoolDir}/.firstRun"
           for src in ${dumps}; do
             find "$src" -type f | while read dump; do
               echo "Loading configuration dump at $dump"
-              ${ectl} load "$dump"
+              chpst -u "${cfg.user}:${cfg.group}" ${ectl} load "$dump"
             done
           done
         fi
diff --git a/nixos/modules/services/networking/fan.nix b/nixos/modules/services/networking/fan.nix
index 3170567e5b4a..7f4e36478325 100644
--- a/nixos/modules/services/networking/fan.nix
+++ b/nixos/modules/services/networking/fan.nix
@@ -5,7 +5,7 @@ with lib;
 let
 
   cfg = config.networking.fan;
-  modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
+  modprobe = "${pkgs.kmod}/bin/modprobe";
 
 in
 
diff --git a/nixos/modules/services/networking/ferm.nix b/nixos/modules/services/networking/ferm.nix
new file mode 100644
index 000000000000..6271e82541f4
--- /dev/null
+++ b/nixos/modules/services/networking/ferm.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.ferm;
+
+  configFile = pkgs.stdenv.mkDerivation {
+    name = "ferm.conf";
+    text = cfg.config;
+    preferLocalBuild = true;
+    buildCommand = ''
+      echo -n "$text" > $out
+      ${cfg.package}/bin/ferm --noexec $out
+    '';
+  };
+in {
+  options = {
+    services.ferm = {
+      enable = mkOption {
+        default = false;
+        example = true;
+        type = types.bool;
+        description = ''
+          Whether to enable Ferm Firewall.
+          *Warning*: Enabling this service WILL disable the existing NixOS
+          firewall! Default firewall rules provided by packages are not
+          considered at the moment.
+        '';
+      };
+      config = mkOption {
+        description = "Verbatim ferm.conf configuration.";
+        default = "";
+        defaultText = "empty firewall, allows any traffic";
+        type = types.lines;
+      };
+      package = mkOption {
+        description = "The ferm package.";
+        type = types.package;
+        default = pkgs.ferm;
+        defaultText = "pkgs.ferm";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.firewall.enable = false;
+    systemd.services.ferm = {
+      description = "Ferm Firewall";
+      after = [ "ipset.target" ];
+      before = [ "network-pre.target" ];
+      wants = [ "network-pre.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        Type="oneshot";
+        RemainAfterExit = "yes";
+        ExecStart = "${cfg.package}/bin/ferm ${configFile}";
+        ExecReload = "${cfg.package}/bin/ferm ${configFile}";
+        ExecStop = "${cfg.package}/bin/ferm -F ${configFile}";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/gdomap.nix b/nixos/modules/services/networking/gdomap.nix
new file mode 100644
index 000000000000..b3fd91d037fa
--- /dev/null
+++ b/nixos/modules/services/networking/gdomap.nix
@@ -0,0 +1,32 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.gdomap;
+in
+{
+  #
+  # interface
+  #
+  options = {
+    services.gdomap = {
+      enable = mkEnableOption "GNUstep Distributed Objects name server";
+   };
+  };
+
+  #
+  # implementation
+  #
+  config = mkIf config.services.gdomap.enable {
+    # NOTE: gdomap runs as root
+    # TODO: extra user for gdomap?
+    systemd.services.gdomap = {
+      description = "gdomap server";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+      path  = [ pkgs.gnustep.base ];
+      serviceConfig.ExecStart = "${pkgs.gnustep.base}/bin/gdomap -f";
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 8aac1360526f..d198e3bfc02c 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -235,19 +235,13 @@ in {
 
     systemd.packages = cfg.packages;
 
-    # Create an initialisation service that both starts
-    # NetworkManager when network.target is reached,
-    # and sets up necessary directories for NM.
-    systemd.services."networkmanager-init" = {
-      description = "NetworkManager initialisation";
+    systemd.services."network-manager" = {
       wantedBy = [ "network.target" ];
-      wants = [ "network-manager.service" ];
-      before = [ "network-manager.service" ];
-      script = ''
+
+      preStart = ''
         mkdir -m 700 -p /etc/NetworkManager/system-connections
         mkdir -m 755 -p ${stateDirs}
       '';
-      serviceConfig.Type = "oneshot";
     };
 
     # Turn off NixOS' network management
diff --git a/nixos/modules/services/networking/strongswan.nix b/nixos/modules/services/networking/strongswan.nix
index d6960a5df471..8778b0364f9a 100644
--- a/nixos/modules/services/networking/strongswan.nix
+++ b/nixos/modules/services/networking/strongswan.nix
@@ -118,7 +118,7 @@ in
     systemd.services.strongswan = {
       description = "strongSwan IPSec Service";
       wantedBy = [ "multi-user.target" ];
-      path = with pkgs; [ config.system.sbin.modprobe iproute iptables utillinux ]; # XXX Linux
+      path = with pkgs; [ kmod iproute iptables utillinux ]; # XXX Linux
       wants = [ "keys.target" ];
       after = [ "network.target" "keys.target" ];
       environment = {
diff --git a/nixos/modules/services/networking/unifi.nix b/nixos/modules/services/networking/unifi.nix
index cb5a88e67aae..a8cff638d3b2 100644
--- a/nixos/modules/services/networking/unifi.nix
+++ b/nixos/modules/services/networking/unifi.nix
@@ -46,6 +46,18 @@ in
       '';
     };
 
+    services.unifi.openPorts = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether or not to open the minimum required ports on the firewall.
+
+        This is necessary to allow firmware upgrades and device discovery to
+        work. For remote login, you should additionally open (or forward) port
+        8443.
+      '';
+    };
+
   };
 
   config = mkIf cfg.enable {
@@ -56,6 +68,19 @@ in
       home = "${stateDir}";
     };
 
+    networking.firewall = mkIf cfg.openPorts {
+      # https://help.ubnt.com/hc/en-us/articles/204910084-UniFi-Change-Default-Ports-for-Controller-and-UAPs
+      allowedTCPPorts = [
+        8080  # Port for UAP to inform controller.
+        8880  # Port for HTTP portal redirect, if guest portal is enabled.
+        8843  # Port for HTTPS portal redirect, ditto.
+      ];
+      allowedUDPPorts = [
+        3478  # UDP port used for STUN.
+        10001 # UDP port used for device discovery.
+      ];
+    };
+
     # We must create the binary directories as bind mounts instead of symlinks
     # This is because the controller resolves all symlinks to absolute paths
     # to be used as the working directory.
@@ -79,9 +104,9 @@ in
       environment.LD_LIBRARY_PATH = with pkgs.stdenv; "${cc.cc.lib}/lib";
 
       preStart = ''
-        # Ensure privacy of state
-        chown unifi "${stateDir}"
-        chmod 0700 "${stateDir}"
+        # Ensure privacy of state and data.
+        chown unifi "${stateDir}" "${stateDir}/data"
+        chmod 0700 "${stateDir}" "${stateDir}/data"
 
         # Create the volatile webapps
         rm -rf "${stateDir}/webapps"
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index 0bcb1a0c20c4..368d7ac761ac 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -4,7 +4,7 @@ with lib;
 
 let
 
-  inherit (pkgs) cups cups-pk-helper cups_filters gutenprint;
+  inherit (pkgs) cups cups-pk-helper cups-filters gutenprint;
 
   cfg = config.services.printing;
 
@@ -34,7 +34,7 @@ let
   bindir = pkgs.buildEnv {
     name = "cups-progs";
     paths =
-      [ cups.out additionalBackends cups_filters pkgs.ghostscript ]
+      [ cups.out additionalBackends cups-filters pkgs.ghostscript ]
       ++ optional cfg.gutenprint gutenprint
       ++ cfg.drivers;
     pathsToLink = [ "/lib/cups" "/share/cups" "/bin" ];
@@ -329,7 +329,7 @@ in
 
         path = [ cups ];
 
-        serviceConfig.ExecStart = "${cups_filters}/bin/cups-browsed";
+        serviceConfig.ExecStart = "${cups-filters}/bin/cups-browsed";
 
         restartTriggers = [ browsedFile ];
       };
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index 5154aaca3bc2..5b2e4ca16066 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -133,7 +133,7 @@ in
           @{PROC}/sys/kernel/random/uuid   r,
           @{PROC}/sys/vm/overcommit_memory r,
 
-          ${pkgs.openssl}/etc/**                     r,
+          ${pkgs.openssl.out}/etc/**                     r,
           ${pkgs.transmission}/share/transmission/** r,
 
           owner ${settingsDir}/** rw,
diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix
new file mode 100644
index 000000000000..bf3a8eed6004
--- /dev/null
+++ b/nixos/modules/services/web-apps/mattermost.nix
@@ -0,0 +1,228 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.mattermost;
+
+  defaultConfig = builtins.fromJSON (readFile "${pkgs.mattermost}/config/config.json");
+
+  mattermostConf = foldl recursiveUpdate defaultConfig
+    [ { ServiceSettings.SiteURL = cfg.siteUrl;
+        ServiceSettings.ListenAddress = cfg.listenAddress;
+        TeamSettings.SiteName = cfg.siteName;
+        SqlSettings.DriverName = "postgres";
+        SqlSettings.DataSource = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10";
+      }
+      cfg.extraConfig
+    ];
+
+  mattermostConfJSON = pkgs.writeText "mattermost-config-raw.json" (builtins.toJSON mattermostConf);
+
+in
+
+{
+  options = {
+    services.mattermost = {
+      enable = mkEnableOption "Mattermost chat platform";
+
+      statePath = mkOption {
+        type = types.str;
+        default = "/var/lib/mattermost";
+        description = "Mattermost working directory";
+      };
+
+      siteUrl = mkOption {
+        type = types.str;
+        example = "https://chat.example.com";
+        description = ''
+          URL this Mattermost instance is reachable under, without trailing slash.
+        '';
+      };
+
+      siteName = mkOption {
+        type = types.str;
+        default = "Mattermost";
+        description = "Name of this Mattermost site.";
+      };
+
+      listenAddress = mkOption {
+        type = types.str;
+        default = ":8065";
+        example = "[::1]:8065";
+        description = ''
+          Address and port this Mattermost instance listens to.
+        '';
+      };
+
+      mutableConfig = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether the Mattermost config.json is writeable by Mattermost.
+
+          Most of the settings can be edited in the system console of
+          Mattermost if this option is enabled. A template config using
+          the options specified in services.mattermost will be generated
+          but won't be overwritten on changes or rebuilds.
+
+          If this option is disabled, changes in the system console won't
+          be possible (default). If an config.json is present, it will be
+          overwritten!
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.attrs;
+        default = { };
+        description = ''
+          Addtional configuration options as Nix attribute set in config.json schema.
+        '';
+      };
+
+      localDatabaseCreate = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Create a local PostgreSQL database for Mattermost automatically.
+        '';
+      };
+
+      localDatabaseName = mkOption {
+        type = types.str;
+        default = "mattermost";
+        description = ''
+          Local Mattermost database name.
+        '';
+      };
+
+      localDatabaseUser = mkOption {
+        type = types.str;
+        default = "mattermost";
+        description = ''
+          Local Mattermost database username.
+        '';
+      };
+
+      localDatabasePassword = mkOption {
+        type = types.str;
+        default = "mmpgsecret";
+        description = ''
+          Password for local Mattermost database user.
+        '';
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "mattermost";
+        description = ''
+          User which runs the Mattermost service.
+        '';
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "mattermost";
+        description = ''
+          Group which runs the Mattermost service.
+        '';
+      };
+
+      matterircd = {
+        enable = mkEnableOption "Mattermost IRC bridge";
+        parameters = mkOption {
+          type = types.listOf types.str;
+          default = [ ];
+          example = [ "-mmserver chat.example.com" "-bind [::]:6667" ];
+          description = ''
+            Set commandline parameters to pass to matterircd. See
+            https://github.com/42wim/matterircd#usage for more information.
+          '';
+        };
+      };
+    };
+  };
+
+  config = mkMerge [
+    (mkIf cfg.enable {
+      users.extraUsers = optionalAttrs (cfg.user == "mattermost") (singleton {
+        name = "mattermost";
+        group = cfg.group;
+        uid = config.ids.uids.mattermost;
+        home = cfg.statePath;
+      });
+
+      users.extraGroups = optionalAttrs (cfg.group == "mattermost") (singleton {
+        name = "mattermost";
+        gid = config.ids.gids.mattermost;
+      });
+
+      services.postgresql.enable = cfg.localDatabaseCreate;
+
+      # The systemd service will fail to execute the preStart hook
+      # if the WorkingDirectory does not exist
+      system.activationScripts.mattermost = ''
+        mkdir -p ${cfg.statePath}
+      '';
+
+      systemd.services.mattermost = {
+        description = "Mattermost chat platform service";
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" "postgresql.service" ];
+
+        preStart = ''
+          mkdir -p ${cfg.statePath}/{data,config,logs}
+          ln -sf ${pkgs.mattermost}/{bin,fonts,i18n,templates,webapp} ${cfg.statePath}
+        '' + lib.optionalString (!cfg.mutableConfig) ''
+          ln -sf ${mattermostConfJSON} ${cfg.statePath}/config/config.json
+        '' + lib.optionalString cfg.mutableConfig ''
+          if ! test -e "${cfg.statePath}/config/.initial-created"; then
+            rm -f ${cfg.statePath}/config/config.json
+            cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json
+            touch ${cfg.statePath}/config/.initial-created
+          fi
+        '' + lib.optionalString cfg.localDatabaseCreate ''
+          if ! test -e "${cfg.statePath}/.db-created"; then
+            ${config.services.postgresql.package}/bin/psql postgres -c \
+              "CREATE ROLE ${cfg.localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.localDatabasePassword}'"
+            ${config.services.postgresql.package}/bin/createdb \
+              --owner ${cfg.localDatabaseUser} ${cfg.localDatabaseName}
+            touch ${cfg.statePath}/.db-created
+          fi
+        '' + ''
+          chown ${cfg.user}:${cfg.group} -R ${cfg.statePath}
+          chmod u+rw,g+r,o-rwx -R ${cfg.statePath}
+        '';
+
+        serviceConfig = {
+          PermissionsStartOnly = true;
+          User = cfg.user;
+          Group = cfg.group;
+          ExecStart = "${pkgs.mattermost}/bin/mattermost-platform";
+          WorkingDirectory = "${cfg.statePath}";
+          PrivateTmp = true;
+          Restart = "always";
+          RestartSec = "10";
+          LimitNOFILE = "49152";
+        };
+      };
+    })
+    (mkIf cfg.matterircd.enable {
+      systemd.services.matterircd = {
+        description = "Mattermost IRC bridge service";
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "nobody";
+          Group = "nogroup";
+          ExecStart = "${pkgs.matterircd.bin}/bin/matterircd ${concatStringsSep " " cfg.matterircd.parameters}";
+          WorkingDirectory = "/tmp";
+          PrivateTmp = true;
+          Restart = "always";
+          RestartSec = "5";
+        };
+      };
+    })
+  ];
+}
+
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index af7753470de6..6e62606f323e 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -165,6 +165,8 @@ let
   mkLocations = locations: concatStringsSep "\n" (mapAttrsToList (location: config: ''
     location ${location} {
       ${optionalString (config.proxyPass != null) "proxy_pass ${config.proxyPass};"}
+      ${optionalString (config.index != null) "index ${config.index};"}
+      ${optionalString (config.tryFiles != null) "try_files ${config.tryFiles};"}
       ${optionalString (config.root != null) "root ${config.root};"}
       ${config.extraConfig}
     }
diff --git a/nixos/modules/services/web-servers/nginx/location-options.nix b/nixos/modules/services/web-servers/nginx/location-options.nix
index 8aaa3e96f800..e1885b160664 100644
--- a/nixos/modules/services/web-servers/nginx/location-options.nix
+++ b/nixos/modules/services/web-servers/nginx/location-options.nix
@@ -14,8 +14,25 @@ with lib;
       default = null;
       example = "http://www.example.org/";
       description = ''
-        Adds proxy_pass directive and sets default proxy headers Host, X-Real-Ip
-        and X-Forwarded-For.
+        Adds proxy_pass directive.
+      '';
+    };
+
+    index = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "index.php index.html";
+      description = ''
+        Adds index directive.
+      '';
+    };
+
+    tryFiles = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "$uri =404";
+      description = ''
+        Adds try_files directive.
       '';
     };
 
diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix
index 819d0c251bf3..29cfbb8e9a08 100644
--- a/nixos/modules/services/web-servers/phpfpm/default.nix
+++ b/nixos/modules/services/web-servers/phpfpm/default.nix
@@ -105,7 +105,7 @@ in {
     };
   };
 
-  config = mkIf (cfg.pools != {}) {
+  config = mkIf (cfg.pools != {} || cfg.poolConfigs != {}) {
 
     systemd.services.phpfpm = {
       wantedBy = [ "multi-user.target" ];
diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix
index 2e788d869607..8a03dd65b335 100644
--- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix
+++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix
@@ -29,7 +29,7 @@ in
   config = mkIf (xcfg.enable && cfg.enable) {
 
     environment.systemPackages = [
-      e.efl e.evas e.emotion e.elementary e.enlightenment
+      e.efl e.enlightenment
       e.terminology e.econnman
       pkgs.xorg.xauth # used by kdesu
       pkgs.gtk # To get GTK+'s themes.
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 86b98c2b6601..bc010d1ce1cf 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -169,7 +169,7 @@ in
       ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm
       ++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa
       ++ lib.optional config.powerManagement.enable kde5.powerdevil
-      ++ lib.optional config.services.colord.enable kde5.colord-kde
+      ++ lib.optional config.services.colord.enable pkgs.colord-kde
       ++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ];
 
     environment.pathsToLink = [ "/share" ];
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 83d679ebe016..75d80609f73f 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -134,8 +134,9 @@ let
         (*) echo "$0: Desktop manager '$desktopManager' not found.";;
       esac
 
+      # FIXME: gdbus should not be in glib.dev!
       ${optionalString (cfg.startDbusSession && cfg.updateDbusEnvironment) ''
-        ${pkgs.glib}/bin/gdbus call --session \
+        ${pkgs.glib.dev}/bin/gdbus call --session \
           --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus \
           --method org.freedesktop.DBus.UpdateActivationEnvironment \
           "{$(env | ${pkgs.gnused}/bin/sed "s/'/\\\\'/g; s/\([^=]*\)=\(.*\)/'\1':'\2'/" \
@@ -305,7 +306,8 @@ in
   };
 
   imports = [
-   (mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ])
+   (mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ]
+     "The option is no longer necessary because all display managers have already delegated lid management to systemd.")
   ];
 
 }
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index 63ffa29c1997..78a97df98775 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -108,7 +108,12 @@ in {
         RestartSec = 3;
         Restart = "always";
       };
-      environment = { DISPLAY = ":${toString config.services.xserver.display}"; };
+      environment = {
+        DISPLAY = ":${toString (
+          let display = config.services.xserver.display;
+          in if display != null then display else 0
+        )}";
+      };
     };
   };
 
diff --git a/nixos/modules/services/x11/window-managers/metacity.nix b/nixos/modules/services/x11/window-managers/metacity.nix
index 2957ad91be45..436eccbaf0c2 100644
--- a/nixos/modules/services/x11/window-managers/metacity.nix
+++ b/nixos/modules/services/x11/window-managers/metacity.nix
@@ -20,9 +20,9 @@ in
     services.xserver.windowManager.session = singleton
       { name = "metacity";
         start = ''
-          env LD_LIBRARY_PATH=${xorg.libX11.out}/lib:${xorg.libXext.out}/lib:/usr/lib/
+          env LD_LIBRARY_PATH=${lib.makeLibraryPath [ xorg.libX11 xorg.libXext ]}:/usr/lib/
           # !!! Hack: load the schemas for Metacity.
-          GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
+          GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf.out}/bin/gconftool-2 \
             --makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */
           ${gnome.metacity}/bin/metacity &
           waitPID=$!
diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix
index d0a4ce51148f..bc899984c57d 100644
--- a/nixos/modules/system/boot/initrd-ssh.nix
+++ b/nixos/modules/system/boot/initrd-ssh.nix
@@ -93,6 +93,10 @@ in
     boot.initrd.extraUtilsCommands = ''
       copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear
       cp -pv ${pkgs.glibc.out}/lib/libnss_files.so.* $out/lib
+
+      ${optionalString (cfg.hostRSAKey != null) "install -D ${cfg.hostRSAKey} $out/etc/dropbear/dropbear_rsa_host_key"}
+      ${optionalString (cfg.hostDSSKey != null) "install -D ${cfg.hostDSSKey} $out/etc/dropbear/dropbear_dss_host_key"}
+      ${optionalString (cfg.hostECDSAKey != null) "install -D ${cfg.hostECDSAKey} $out/etc/dropbear/dropbear_ecdsa_host_key"}
     '';
 
     boot.initrd.extraUtilsCommandsTest = ''
@@ -108,9 +112,9 @@ in
       touch /var/log/lastlog
 
       mkdir -p /etc/dropbear
-      ${optionalString (cfg.hostRSAKey != null) "ln -s ${cfg.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"}
-      ${optionalString (cfg.hostDSSKey != null) "ln -s ${cfg.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"}
-      ${optionalString (cfg.hostECDSAKey != null) "ln -s ${cfg.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"}
+      ${optionalString (cfg.hostRSAKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_rsa_host_key /etc/dropbear/dropbear_rsa_host_key"}
+      ${optionalString (cfg.hostDSSKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_dss_host_key /etc/dropbear/dropbear_dss_host_key"}
+      ${optionalString (cfg.hostECDSAKey != null) "ln -s $extraUtils/etc/dropbear/dropbear_ecdsa_host_key /etc/dropbear/dropbear_ecdsa_host_key"}
 
       mkdir -p /root/.ssh
       ${concatStrings (map (key: ''
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index a6bbca9b30bb..0f342f44fe76 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -228,7 +228,6 @@ in
     systemd.services."systemd-modules-load" =
       { wantedBy = [ "multi-user.target" ];
         restartTriggers = [ kernelModulesConf ];
-        environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
         serviceConfig =
           { # Ignore failed module loads.  Typically some of the
             # modules in ‘boot.kernelModules’ are "nice to have but
@@ -238,10 +237,6 @@ in
           };
       };
 
-    systemd.services.kmod-static-nodes =
-      { environment.MODULE_DIR = "/run/booted-system/kernel-modules/lib/modules";
-      };
-
     lib.kernelConfig = {
       isYes = option: {
         assertion = config: config.isYes option;
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 0640ec306e18..46776f45d96b 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -500,7 +500,7 @@ in
 
 
   imports =
-    [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ])
+    [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "")
       (mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ])
       (mkRenamedOptionModule [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ])
       (mkRenamedOptionModule [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ])
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 94d87b436065..4fa157641a4a 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -508,7 +508,11 @@ my $nameDiffer = get("fullName") ne $prevGrubState->name;
 my $versionDiffer = get("fullVersion") ne $prevGrubState->version;
 my $efiDiffer = $efiTarget ne $prevGrubState->efi;
 my $efiMountPointDiffer = $efiSysMountPoint ne $prevGrubState->efiMountPoint;
-my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");
+if (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1") {
+    warn "NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER";
+    $ENV{'NIXOS_INSTALL_BOOTLOADER'} = "1";
+}
+my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_BOOTLOADER'} // "") eq "1");
 
 # install a symlink so that grub can detect the boot drive
 my $tmpDir = File::Temp::tempdir(CLEANUP => 1) or die "Failed to create temporary space";
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index c38af1b67f17..c703a3e083ba 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -7,6 +7,7 @@ import subprocess
 import glob
 import tempfile
 import errno
+import warnings
 
 def copy_if_not_exists(source, dest):
     if not os.path.exists(dest):
@@ -92,8 +93,11 @@ parser = argparse.ArgumentParser(description='Update NixOS-related systemd-boot
 parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot')
 args = parser.parse_args()
 
-# We deserve our own env var!
 if os.getenv("NIXOS_INSTALL_GRUB") == "1":
+    warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning)
+    os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1"
+
+if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1":
     if "@canTouchEfiVariables@" == "1":
         subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"])
     else:
diff --git a/nixos/modules/system/boot/modprobe.nix b/nixos/modules/system/boot/modprobe.nix
index 9bb10eac9880..b915a98d5375 100644
--- a/nixos/modules/system/boot/modprobe.nix
+++ b/nixos/modules/system/boot/modprobe.nix
@@ -8,41 +8,6 @@ with lib;
 
   options = {
 
-    system.sbin.modprobe = mkOption {
-      internal = true;
-      default = pkgs.stdenv.mkDerivation {
-        name = "modprobe";
-        buildCommand = ''
-          mkdir -p $out/bin
-          for i in ${pkgs.kmod}/sbin/*; do
-            name=$(basename $i)
-            echo "$text" > $out/bin/$name
-            echo 'exec '$i' "$@"' >> $out/bin/$name
-            chmod +x $out/bin/$name
-          done
-          ln -s bin $out/sbin
-        '';
-        text =
-          ''
-            #! ${pkgs.stdenv.shell}
-            export MODULE_DIR=/run/current-system/kernel-modules/lib/modules
-
-            # Fall back to the kernel modules used at boot time if the
-            # modules in the current configuration don't match the
-            # running kernel.
-            if [ ! -d "$MODULE_DIR/$(${pkgs.coreutils}/bin/uname -r)" ]; then
-                MODULE_DIR=/run/booted-system/kernel-modules/lib/modules/
-            fi
-
-          '';
-        meta.priority = 4;
-      };
-      description = ''
-        Wrapper around modprobe that sets the path to the modules
-        tree.
-      '';
-    };
-
     boot.blacklistedKernelModules = mkOption {
       type = types.listOf types.str;
       default = [];
@@ -87,7 +52,7 @@ with lib;
       '';
     environment.etc."modprobe.d/debian.conf".source = pkgs.kmod-debian-aliases;
 
-    environment.systemPackages = [ config.system.sbin.modprobe pkgs.kmod ];
+    environment.systemPackages = [ pkgs.kmod ];
 
     system.activationScripts.modprobe =
       ''
@@ -95,11 +60,9 @@ with lib;
         # in the right location in the Nix store for kernel modules).
         # We need this when the kernel (or some module) auto-loads a
         # module.
-        echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe
+        echo ${pkgs.kmod}/bin/modprobe > /proc/sys/kernel/modprobe
       '';
 
-    environment.sessionVariables.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
-
   };
 
 }
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index fbb32901f64e..65d1dcb61681 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -312,8 +312,50 @@ mountFS() {
         echo "retrying..."
         n=$((n + 1))
     done
+
+    [ "$mountPoint" == "/" ] &&
+        [ -f "/mnt-root/etc/NIXOS_LUSTRATE" ] &&
+        lustrateRoot "/mnt-root"
 }
 
+lustrateRoot () {
+    local root="$1"
+
+    echo
+    echo -e "\e[1;33m<<< NixOS is now lustrating the root filesystem (cruft goes to /old-root) >>>\e[0m"
+    echo
+
+    mkdir -m 0755 -p "$root/old-root.tmp"
+
+    echo
+    echo "Moving impurities out of the way:"
+    for d in "$root"/*
+    do
+        [ "$d" == "$root/nix"          ] && continue
+        [ "$d" == "$root/boot"         ] && continue # Don't render the system unbootable
+        [ "$d" == "$root/old-root.tmp" ] && continue
+
+        mv -v "$d" "$root/old-root.tmp"
+    done
+
+    # Use .tmp to make sure subsequent invokations don't clash
+    mv -v "$root/old-root.tmp" "$root/old-root"
+
+    mkdir -m 0755 -p "$root/etc"
+    touch "$root/etc/NIXOS"
+
+    exec 4< "$root/old-root/etc/NIXOS_LUSTRATE"
+
+    echo
+    echo "Restoring selected impurities:"
+    while read -u 4 keeper; do
+        dirname="$(dirname "$keeper")"
+        mkdir -m 0755 -p "$root/$dirname"
+        cp -av "$root/old-root/$keeper" "$root/$keeper"
+    done
+
+    exec 4>&-
+}
 
 # Function for waiting a device to appear.
 waitDevice() {
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 70429e9c0a22..a5c05f3dbbaf 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -3,7 +3,7 @@
 # the modules necessary to mount the root file system, then calls the
 # init in the root file system to start the second boot stage.
 
-{ config, lib, pkgs, ... }:
+{ config, lib, utils, pkgs, ... }:
 
 with lib;
 
@@ -23,6 +23,12 @@ let
   };
 
 
+  # The initrd only has to mount `/` or any FS marked as necessary for
+  # booting (such as the FS containing `/nix/store`, or an FS needed for
+  # mounting `/`, like `/` on a loopback).
+  fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems;
+
+
   # Some additional utilities needed in stage 1, like mount, lvm, fsck
   # etc.  We don't want to bring in all of those packages, so we just
   # copy what we need.  Instead of using statically linked binaries,
@@ -71,7 +77,7 @@ let
       ln -sf kmod $out/bin/modprobe
 
       # Copy resize2fs if needed.
-      ${optionalString (any (fs: fs.autoResize) (attrValues config.fileSystems)) ''
+      ${optionalString (any (fs: fs.autoResize) fileSystems) ''
         # We need mke2fs in the initrd.
         copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs
       ''}
@@ -128,14 +134,6 @@ let
     ''; # */
 
 
-  # The initrd only has to mount / or any FS marked as necessary for
-  # booting (such as the FS containing /nix/store, or an FS needed for
-  # mounting /, like / on a loopback).
-  fileSystems = filter
-    (fs: fs.neededForBoot || elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ])
-    (attrValues config.fileSystems);
-
-
   udevRules = pkgs.stdenv.mkDerivation {
     name = "udev-rules";
     allowedReferences = [ extraUtils ];
@@ -198,7 +196,9 @@ let
       preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
 
     resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
-                    (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices);
+                    (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption 
+                    # Don't include zram devices
+                    && !(hasPrefix "/dev/zram" sd.device)) config.swapDevices);
 
     fsInfo =
       let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType (builtins.concatStringsSep "," fs.options) ];
@@ -396,9 +396,8 @@ in
   };
 
   config = mkIf (!config.boot.isContainer) {
-
     assertions = [
-      { assertion = any (fs: fs.mountPoint == "/") (attrValues config.fileSystems);
+      { assertion = any (fs: fs.mountPoint == "/") fileSystems;
         message = "The ‘fileSystems’ option does not specify your root file system.";
       }
       { assertion = let inherit (config.boot) resumeDevice; in
diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh
index 4a7f073ea8ad..c5a14f0766d5 100644
--- a/nixos/modules/system/boot/stage-2-init.sh
+++ b/nixos/modules/system/boot/stage-2-init.sh
@@ -207,6 +207,5 @@ exec {logOutFd}>&- {logErrFd}>&-
 # Start systemd.
 echo "starting systemd..."
 PATH=/run/current-system/systemd/lib/systemd \
-    MODULE_DIR=/run/booted-system/kernel-modules/lib/modules \
     LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive \
     exec systemd
diff --git a/nixos/modules/tasks/cpu-freq.nix b/nixos/modules/tasks/cpu-freq.nix
index 1f4d1db33cef..2fe7f4f8197a 100644
--- a/nixos/modules/tasks/cpu-freq.nix
+++ b/nixos/modules/tasks/cpu-freq.nix
@@ -38,7 +38,7 @@ in
       description = "CPU Frequency Governor Setup";
       after = [ "systemd-modules-load.service" ];
       wantedBy = [ "multi-user.target" ];
-      path = [ cpupower config.system.sbin.modprobe ];
+      path = [ cpupower pkgs.kmod ];
       unitConfig.ConditionVirtualization = false;
       serviceConfig = {
         Type = "oneshot";
diff --git a/nixos/modules/tasks/encrypted-devices.nix b/nixos/modules/tasks/encrypted-devices.nix
index 457b86e95ab5..b1a7711ddcb4 100644
--- a/nixos/modules/tasks/encrypted-devices.nix
+++ b/nixos/modules/tasks/encrypted-devices.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  fileSystems = attrValues config.fileSystems ++ config.swapDevices;
+  fileSystems = config.system.build.fileSystems ++ config.swapDevices;
   encDevs = filter (dev: dev.encrypted.enable) fileSystems;
   keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs;
   keylessEncDevs = filter (dev: dev.encrypted.keyFile == null) encDevs;
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index cf8232c36154..f146448200f9 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -5,7 +5,16 @@ with utils;
 
 let
 
-  fileSystems = attrValues config.fileSystems;
+  fileSystems' = toposort fsBefore (attrValues config.fileSystems);
+
+  fileSystems = if fileSystems' ? "result"
+                then # use topologically sorted fileSystems everywhere
+                     fileSystems'.result
+                else # the assertion below will catch this,
+                     # but we fall back to the original order
+                     # anyway so that other modules could check
+                     # their assertions too
+                     (attrValues config.fileSystems);
 
   prioOption = prio: optionalString (prio != null) " pri=${toString prio}";
 
@@ -162,6 +171,17 @@ in
 
   config = {
 
+    assertions = let
+      ls = sep: concatMapStringsSep sep (x: x.mountPoint);
+    in [
+      { assertion = ! (fileSystems' ? "cycle");
+        message = "The ‘fileSystems’ option can't be topologically sorted: mountpoint dependency path ${ls " -> " fileSystems'.cycle} loops to ${ls ", " fileSystems'.loops}";
+      }
+    ];
+
+    # Export for use in other modules
+    system.build.fileSystems = fileSystems;
+
     boot.supportedFilesystems = map (fs: fs.fsType) fileSystems;
 
     # Add the mount helpers to the system path so that `mount' can find them.
@@ -175,9 +195,12 @@ in
         skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
       in ''
         # This is a generated file.  Do not edit!
+        #
+        # To make changes, edit the fileSystems and swapDevices NixOS options
+        # in your /etc/nixos/configuration.nix file.
 
         # Filesystems.
-        ${flip concatMapStrings fileSystems (fs:
+        ${concatMapStrings (fs:
             (if fs.device != null then fs.device
              else if fs.label != null then "/dev/disk/by-label/${fs.label}"
              else throw "No device specified for mount point ‘${fs.mountPoint}’.")
@@ -188,7 +211,7 @@ in
             + " " + (if skipCheck fs then "0" else
                      if fs.mountPoint == "/" then "1" else "2")
             + "\n"
-        )}
+        ) fileSystems}
 
         # Swap devices.
         ${flip concatMapStrings config.swapDevices (sw:
@@ -208,14 +231,15 @@ in
 
         formatDevice = fs:
           let
-            mountPoint' = escapeSystemdPath fs.mountPoint;
-            device' = escapeSystemdPath fs.device;
+            mountPoint' = "${escapeSystemdPath fs.mountPoint}.mount";
+            device'  = escapeSystemdPath fs.device;
+            device'' = "${device}.device";
           in nameValuePair "mkfs-${device'}"
           { description = "Initialisation of Filesystem ${fs.device}";
-            wantedBy = [ "${mountPoint'}.mount" ];
-            before = [ "${mountPoint'}.mount" "systemd-fsck@${device'}.service" ];
-            requires = [ "${device'}.device" ];
-            after = [ "${device'}.device" ];
+            wantedBy = [ mountPoint' ];
+            before = [ mountPoint' "systemd-fsck@${device'}.service" ];
+            requires = [ device'' ];
+            after = [ device'' ];
             path = [ pkgs.utillinux ] ++ config.system.fsPackages;
             script =
               ''
diff --git a/nixos/modules/tasks/filesystems/cifs.nix b/nixos/modules/tasks/filesystems/cifs.nix
index a928fcae415f..47ba0c03c563 100644
--- a/nixos/modules/tasks/filesystems/cifs.nix
+++ b/nixos/modules/tasks/filesystems/cifs.nix
@@ -11,14 +11,14 @@ in
 {
   config = {
 
-    system.fsPackages = mkIf (any (fs: fs == "cifs") config.boot.supportedFilesystems) [ pkgs.cifs_utils ];
+    system.fsPackages = mkIf (any (fs: fs == "cifs") config.boot.supportedFilesystems) [ pkgs.cifs-utils ];
 
     boot.initrd.availableKernelModules = mkIf inInitrd
       [ "cifs" "nls_utf8" "hmac" "md4" "ecb" "des_generic" "sha256" ];
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        copy_bin_and_libs ${pkgs.cifs_utils}/sbin/mount.cifs
+        copy_bin_and_libs ${pkgs.cifs-utils}/sbin/mount.cifs
       '';
 
   };
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 05fd160f20b7..c5f41cc338cf 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -36,13 +36,11 @@ let
 
   fsToPool = fs: datasetToPool fs.device;
 
-  zfsFilesystems = filter (x: x.fsType == "zfs") (attrValues config.fileSystems);
-
-  isRoot = fs: fs.neededForBoot || elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ];
+  zfsFilesystems = filter (x: x.fsType == "zfs") config.system.build.fileSystems;
 
   allPools = unique ((map fsToPool zfsFilesystems) ++ cfgZfs.extraPools);
 
-  rootPools = unique (map fsToPool (filter isRoot zfsFilesystems));
+  rootPools = unique (map fsToPool (filter fsNeededForBoot zfsFilesystems));
 
   dataPools = unique (filter (pool: !(elem pool rootPools)) allPools);
 
@@ -247,8 +245,18 @@ in
               esac
             done
             ''] ++ (map (pool: ''
-            echo "importing root ZFS pool \"${pool}\"..."
-            zpool import -d ${cfgZfs.devNodes} -N $ZFS_FORCE "${pool}"
+            echo -n "importing root ZFS pool \"${pool}\"..."
+            trial=0
+            until msg="$(zpool import -d ${cfgZfs.devNodes} -N $ZFS_FORCE '${pool}' 2>&1)"; do
+              sleep 0.25
+              echo -n .
+              trial=$(($trial + 1))
+              if [[ $trial -eq 60 ]]; then
+                break
+              fi
+            done
+            echo
+            if [[ -n "$msg" ]]; then echo "$msg"; fi
         '') rootPools));
       };
 
@@ -267,7 +275,7 @@ in
 
       systemd.services = let
         getPoolFilesystems = pool:
-          filter (x: x.fsType == "zfs" && (fsToPool x) == pool) (attrValues config.fileSystems);
+          filter (x: x.fsType == "zfs" && (fsToPool x) == pool) config.system.build.fileSystems;
 
         getPoolMounts = pool:
           let
diff --git a/nixos/modules/virtualisation/brightbox-image.nix b/nixos/modules/virtualisation/brightbox-image.nix
index 456a19fc2512..760a7100c6e0 100644
--- a/nixos/modules/virtualisation/brightbox-image.nix
+++ b/nixos/modules/virtualisation/brightbox-image.nix
@@ -20,7 +20,7 @@ in
 
           postVM =
             ''
-              PATH=$PATH:${pkgs.gnutar}/bin:${pkgs.gzip}/bin
+              PATH=$PATH:${stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
               pushd $out
               ${pkgs.qemu_kvm}/bin/qemu-img convert -c -O qcow2 $diskImageBase nixos.qcow2
               rm $diskImageBase
diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix
index c99fc78d49e7..ebc2be087a5b 100644
--- a/nixos/modules/virtualisation/docker.nix
+++ b/nixos/modules/virtualisation/docker.nix
@@ -95,8 +95,7 @@ in
           LimitNPROC = 1048576;
         } // proxy_env;
 
-        path = [ config.system.sbin.modprobe ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs);
-        environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
+        path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs);
 
         postStart = if cfg.socketActivation then "" else cfg.postStart;
 
diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix
index 2b522dbe2660..59b77dde5d9a 100644
--- a/nixos/modules/virtualisation/google-compute-image.nix
+++ b/nixos/modules/virtualisation/google-compute-image.nix
@@ -23,7 +23,7 @@ in
 
           postVM =
             ''
-              PATH=$PATH:${pkgs.gnutar}/bin:${pkgs.gzip}/bin
+              PATH=$PATH:${stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
               pushd $out
               mv $diskImageBase disk.raw
               tar -Szcf $diskImageBase.tar.gz disk.raw
diff --git a/nixos/modules/virtualisation/qemu-opts b/nixos/modules/virtualisation/qemu-opts
deleted file mode 100644
index f06a5136608a..000000000000
--- a/nixos/modules/virtualisation/qemu-opts
+++ /dev/null
@@ -1,4 +0,0 @@
-          -device virtio-serial \
-          -chardev socket,id=charconsole0,path=/tmp/nixos-socket,server,nowait \
-          #-device virtconsole,chardev=charconsole0,id=console0 \
-          -device virtserialport,chardev=chardev=charconsole0,id=serial0
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index b77b319f4a28..777ee31e4dcc 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -135,13 +135,13 @@ let
         }
         ''
           # Create a /boot EFI partition with 40M
-          ${pkgs.gptfdisk}/sbin/sgdisk -G /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -A 1:set:1 /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -A 2:set:2 /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -h 2 /dev/vda
-          ${pkgs.gptfdisk}/sbin/sgdisk -C /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -G /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -A 1:set:1 /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -A 2:set:2 /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -h 2 /dev/vda
+          ${pkgs.gptfdisk}/bin/sgdisk -C /dev/vda
           ${pkgs.utillinux}/bin/sfdisk /dev/vda -A 2
           . /sys/class/block/vda2/uevent
           mknod /dev/vda2 b $MAJOR $MINOR
@@ -151,11 +151,11 @@ let
           ${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
 
           # Mount /boot; load necessary modules first.
-          ${pkgs.kmod}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_cp437.ko.xz || true
-          ${pkgs.kmod}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_iso8859-1.ko.xz || true
-          ${pkgs.kmod}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/fat.ko.xz || true
-          ${pkgs.kmod}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/vfat.ko.xz || true
-          ${pkgs.kmod}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/efivarfs/efivarfs.ko.xz || true
+          ${pkgs.kmod}/bin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_cp437.ko.xz || true
+          ${pkgs.kmod}/bin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_iso8859-1.ko.xz || true
+          ${pkgs.kmod}/bin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/fat.ko.xz || true
+          ${pkgs.kmod}/bin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/vfat.ko.xz || true
+          ${pkgs.kmod}/bin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/efivarfs/efivarfs.ko.xz || true
           mkdir /boot
           mount /dev/vda2 /boot
 
@@ -370,7 +370,7 @@ in
     boot.initrd.extraUtilsCommands =
       ''
         # We need mke2fs in the initrd.
-        copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/mke2fs
+        copy_bin_and_libs ${pkgs.e2fsprogs}/bin/mke2fs
       '';
 
     boot.initrd.postDeviceCommands =
diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix
index fab59b2525a5..3a598a1c7dc5 100644
--- a/nixos/modules/virtualisation/virtualbox-image.nix
+++ b/nixos/modules/virtualisation/virtualbox-image.nix
@@ -29,22 +29,15 @@ in {
       partitioned = true;
       diskSize = cfg.baseImageSize;
 
-      configFile = pkgs.writeText "configuration.nix"
-        ''
-          {
-            imports = [ <nixpkgs/nixos/modules/virtualisation/virtualbox-image.nix> ];
-          }
-        '';
-
       postVM =
         ''
-          echo "creating VirtualBox disk image..."
-          ${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi $diskImage disk.vdi
-          rm $diskImage
-
-          echo "creating VirtualBox VM..."
           export HOME=$PWD
           export PATH=${pkgs.linuxPackages.virtualbox}/bin:$PATH
+
+          echo "creating VirtualBox pass-through disk wrapper (no copying invovled)..."
+          VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk $diskImage
+
+          echo "creating VirtualBox VM..."
           vmName="NixOS ${config.system.nixosLabel} (${pkgs.stdenv.system})"
           VBoxManage createvm --name "$vmName" --register \
             --ostype ${if pkgs.stdenv.system == "x86_64-linux" then "Linux26_64" else "Linux26"}
@@ -57,13 +50,15 @@ in {
             --usb on --mouse usbtablet
           VBoxManage storagectl "$vmName" --name SATA --add sata --portcount 4 --bootable on --hostiocache on
           VBoxManage storageattach "$vmName" --storagectl SATA --port 0 --device 0 --type hdd \
-            --medium disk.vdi
+            --medium disk.vmdk
 
           echo "exporting VirtualBox VM..."
           mkdir -p $out
           fn="$out/nixos-${config.system.nixosLabel}-${pkgs.stdenv.system}.ova"
           VBoxManage export "$vmName" --output "$fn"
 
+          rm -v $diskImage
+
           mkdir -p $out/nix-support
           echo "file ova $fn" >> $out/nix-support/hydra-build-products
         '';