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.nix31
-rw-r--r--nixos/modules/config/system-path.nix18
-rw-r--r--nixos/modules/config/timezone.nix1
-rw-r--r--nixos/modules/config/users-groups.nix53
-rw-r--r--nixos/modules/hardware/all-firmware.nix4
-rw-r--r--nixos/modules/hardware/video/bumblebee.nix2
-rw-r--r--nixos/modules/hardware/video/encoder/wis-go7007.nix8
-rw-r--r--nixos/modules/installer/cd-dvd/channel.nix17
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix14
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix40
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix46
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image.nix127
-rw-r--r--nixos/modules/installer/tools/auto-upgrade.nix81
-rw-r--r--nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh2
-rw-r--r--nixos/modules/installer/tools/nixos-checkout.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl5
-rw-r--r--nixos/modules/installer/tools/nixos-install.sh8
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh4
-rw-r--r--nixos/modules/installer/tools/tools.nix5
-rw-r--r--nixos/modules/misc/assertions.nix2
-rw-r--r--nixos/modules/misc/extra-arguments.nix7
-rw-r--r--nixos/modules/misc/ids.nix6
-rw-r--r--nixos/modules/misc/locate.nix16
-rw-r--r--nixos/modules/misc/nixpkgs.nix2
-rw-r--r--nixos/modules/misc/version.nix30
-rw-r--r--nixos/modules/module-list.nix12
-rw-r--r--nixos/modules/profiles/clone-config.nix2
-rw-r--r--nixos/modules/profiles/minimal.nix4
-rw-r--r--nixos/modules/programs/command-not-found/command-not-found.nix4
-rw-r--r--nixos/modules/programs/command-not-found/command-not-found.pl6
-rw-r--r--nixos/modules/programs/environment.nix9
-rw-r--r--nixos/modules/programs/info.nix38
-rw-r--r--nixos/modules/programs/ssh.nix106
-rw-r--r--nixos/modules/programs/xfs_quota.nix110
-rw-r--r--nixos/modules/rename.nix15
-rw-r--r--nixos/modules/security/apparmor.nix8
-rw-r--r--nixos/modules/security/pam.nix14
-rw-r--r--nixos/modules/services/cluster/kubernetes.nix125
-rw-r--r--nixos/modules/services/databases/postgresql.nix7
-rw-r--r--nixos/modules/services/databases/riak.nix148
-rw-r--r--nixos/modules/services/hardware/freefall.nix7
-rw-r--r--nixos/modules/services/hardware/tcsd.nix24
-rw-r--r--nixos/modules/services/hardware/udev.nix22
-rw-r--r--nixos/modules/services/mail/dovecot.nix7
-rw-r--r--nixos/modules/services/mail/mlmmj.nix2
-rw-r--r--nixos/modules/services/misc/confd.nix2
-rw-r--r--nixos/modules/services/misc/etcd.nix8
-rw-r--r--nixos/modules/services/misc/gitit.nix157
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix24
-rw-r--r--nixos/modules/services/misc/nix-gc.nix2
-rw-r--r--nixos/modules/services/misc/rogue.nix1
-rw-r--r--nixos/modules/services/monitoring/dd-agent.nix43
-rw-r--r--nixos/modules/services/monitoring/grafana.nix6
-rw-r--r--nixos/modules/services/monitoring/scollector.nix18
-rw-r--r--nixos/modules/services/monitoring/smartd.nix211
-rw-r--r--nixos/modules/services/network-filesystems/nfsd.nix5
-rw-r--r--nixos/modules/services/networking/copy-com.nix106
-rw-r--r--nixos/modules/services/networking/dnsmasq.nix1
-rw-r--r--nixos/modules/services/networking/fan.nix60
-rw-r--r--nixos/modules/services/networking/firewall.nix14
-rw-r--r--nixos/modules/services/networking/gateone.nix61
-rw-r--r--nixos/modules/services/networking/heyefi.nix82
-rw-r--r--nixos/modules/services/networking/i2p.nix10
-rw-r--r--nixos/modules/services/networking/kippo.nix10
-rw-r--r--nixos/modules/services/networking/quassel.nix2
-rw-r--r--nixos/modules/services/networking/racoon.nix5
-rw-r--r--nixos/modules/services/networking/shout.nix80
-rw-r--r--nixos/modules/services/networking/skydns.nix2
-rw-r--r--nixos/modules/services/networking/softether.nix150
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix96
-rw-r--r--nixos/modules/services/networking/syncthing.nix12
-rw-r--r--nixos/modules/services/printing/cupsd.nix16
-rw-r--r--nixos/modules/services/scheduling/cron.nix65
-rw-r--r--nixos/modules/services/security/hologram.nix2
-rw-r--r--nixos/modules/services/system/dbus.nix1
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix31
-rw-r--r--nixos/modules/services/web-servers/nginx/reverse_proxy.nix233
-rw-r--r--nixos/modules/services/x11/desktop-managers/e19.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix24
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde4.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kodi.nix3
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix3
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix10
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix75
-rw-r--r--nixos/modules/services/x11/redshift.nix10
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix1
-rw-r--r--nixos/modules/services/x11/window-managers/icewm.nix17
-rw-r--r--nixos/modules/services/x11/window-managers/oroborus.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/qtile.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/wmii.nix28
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl5
-rw-r--r--nixos/modules/system/activation/top-level.nix2
-rw-r--r--nixos/modules/system/boot/kernel.nix7
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix3
-rw-r--r--nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh36
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix42
-rw-r--r--nixos/modules/system/boot/loader/grub/install-grub.pl13
-rw-r--r--nixos/modules/system/boot/modprobe.nix1
-rw-r--r--nixos/modules/system/boot/systemd.nix12
-rw-r--r--nixos/modules/tasks/network-interfaces.nix9
-rw-r--r--nixos/modules/virtualisation/brightbox-config.nix5
-rw-r--r--nixos/modules/virtualisation/brightbox-image.nix166
-rw-r--r--nixos/modules/virtualisation/containers.nix14
-rw-r--r--nixos/modules/virtualisation/docker.nix36
-rw-r--r--nixos/modules/virtualisation/openvswitch.nix6
-rw-r--r--nixos/modules/virtualisation/virtualbox-guest.nix19
-rw-r--r--nixos/modules/virtualisation/virtualbox-host.nix (renamed from nixos/modules/programs/virtualbox-host.nix)6
-rw-r--r--nixos/modules/virtualisation/virtualbox-image.nix2
-rw-r--r--nixos/modules/virtualisation/xen-dom0.nix10
110 files changed, 2654 insertions, 681 deletions
diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
index 6f17bd396a0b..922a9cf961df 100644
--- a/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixos/modules/config/fonts/fontconfig.nix
@@ -142,7 +142,7 @@ with lib;
   config =
     let fontconfig = config.fonts.fontconfig;
         fcBool = x: "<bool>" + (if x then "true" else "false") + "</bool>";
-        nixosConf = ''
+        renderConf = ''
           <?xml version='1.0'?>
           <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
           <fontconfig>
@@ -169,6 +169,21 @@ with lib;
               </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>
@@ -201,14 +216,6 @@ with lib;
             </alias>
             ''}
 
-            ${optionalString (fontconfig.dpi != 0) ''
-            <match target="pattern">
-              <edit name="dpi" mode="assign">
-                <double>${toString fontconfig.dpi}</double>
-              </edit>
-            </match>
-            ''}
-
           </fontconfig>
         '';
     in mkIf fontconfig.enable {
@@ -219,7 +226,8 @@ with lib;
       environment.etc."fonts/fonts.conf".source =
         pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; };
 
-      environment.etc."fonts/conf.d/98-nixos.conf".text = nixosConf;
+      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.
@@ -236,7 +244,8 @@ with lib;
           </fontconfig>
         '';
 
-      environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/98-nixos.conf".text = nixosConf;
+      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;
diff --git a/nixos/modules/config/system-path.nix b/nixos/modules/config/system-path.nix
index 62390f452ba2..3a9a09ee87c1 100644
--- a/nixos/modules/config/system-path.nix
+++ b/nixos/modules/config/system-path.nix
@@ -45,6 +45,7 @@ let
       pkgs.strace
       pkgs.su
       pkgs.time
+      pkgs.texinfoInteractive
       pkgs.utillinux
       extraManpages
     ];
@@ -57,7 +58,7 @@ in
     environment = {
 
       systemPackages = mkOption {
-        type = types.listOf types.path;
+        type = types.listOf types.package;
         default = [];
         example = literalExample "[ pkgs.firefox pkgs.thunderbird ]";
         description = ''
@@ -105,12 +106,14 @@ in
         "/lib"
         "/man"
         "/sbin"
+        "/share/doc"
         "/share/emacs"
-        "/share/vim-plugins"
-        "/share/org"
         "/share/info"
-        "/share/terminfo"
         "/share/man"
+        "/share/nano"
+        "/share/org"
+        "/share/terminfo"
+        "/share/vim-plugins"
       ];
 
     system.path = pkgs.buildEnv {
@@ -136,6 +139,13 @@ in
           if [ -x $out/bin/update-desktop-database -a -w $out/share/applications ]; then
               $out/bin/update-desktop-database $out/share/applications
           fi
+
+          if [ -x $out/bin/install-info -a -w $out/share/info ]; then
+            shopt -s nullglob
+            for i in $out/share/info/*.info $out/share/info/*.info.gz; do
+                $out/bin/install-info $i $out/share/info/dir
+            done
+          fi
         '';
     };
 
diff --git a/nixos/modules/config/timezone.nix b/nixos/modules/config/timezone.nix
index 068571393116..b9844b4adade 100644
--- a/nixos/modules/config/timezone.nix
+++ b/nixos/modules/config/timezone.nix
@@ -26,6 +26,7 @@ in
 
       hardwareClockInLocalTime = mkOption {
         default = false;
+        type = types.bool;
         description = "If set, keep the hardware clock in local time instead of UTC.";
       };
 
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 478f433b431c..adc014eed415 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -216,7 +216,7 @@ let
           exist. If <option>users.mutableUsers</option> is true, the
           password can be changed subsequently using the
           <command>passwd</command> command. Otherwise, it's
-          equivalent to setting the <option>password</option> option.
+          equivalent to setting the <option>hashedPassword</option> option.
 
           ${hashedPasswordDescription}
         '';
@@ -336,13 +336,13 @@ let
     map (range: "${user.name}:${toString range.startUid}:${toString range.count}\n")
       user.subUidRanges);
 
-  subuidFile = concatStrings (map mkSubuidEntry (attrValues cfg.extraUsers));
+  subuidFile = concatStrings (map mkSubuidEntry (attrValues cfg.users));
 
   mkSubgidEntry = user: concatStrings (
     map (range: "${user.name}:${toString range.startGid}:${toString range.count}\n")
         user.subGidRanges);
 
-  subgidFile = concatStrings (map mkSubgidEntry (attrValues cfg.extraUsers));
+  subgidFile = concatStrings (map mkSubgidEntry (attrValues cfg.users));
 
   idsAreUnique = set: idAttr: !(fold (name: args@{ dup, acc }:
     let
@@ -354,8 +354,8 @@ let
       else { dup = false; acc = newAcc; }
     ) { dup = false; acc = {}; } (builtins.attrNames set)).dup;
 
-  uidsAreUnique = idsAreUnique (filterAttrs (n: u: u.uid != null) cfg.extraUsers) "uid";
-  gidsAreUnique = idsAreUnique (filterAttrs (n: g: g.gid != null) cfg.extraGroups) "gid";
+  uidsAreUnique = idsAreUnique (filterAttrs (n: u: u.uid != null) cfg.users) "uid";
+  gidsAreUnique = idsAreUnique (filterAttrs (n: g: g.gid != null) cfg.groups) "gid";
 
   spec = pkgs.writeText "users-groups.json" (builtins.toJSON {
     inherit (cfg) mutableUsers;
@@ -364,13 +364,13 @@ let
           name uid group description home shell createHome isSystemUser
           password passwordFile hashedPassword
           initialPassword initialHashedPassword;
-      }) cfg.extraUsers;
+      }) cfg.users;
     groups = mapAttrsToList (n: g:
       { inherit (g) name gid;
         members = g.members ++ (mapAttrsToList (n: u: u.name) (
-          filterAttrs (n: u: elem g.name u.extraGroups) cfg.extraUsers
+          filterAttrs (n: u: elem g.name u.extraGroups) cfg.users
         ));
-      }) cfg.extraGroups;
+      }) cfg.groups;
   });
 
 in {
@@ -388,10 +388,10 @@ in {
         <literal>groupadd</literal> commands. On system activation, the
         existing contents of the <literal>/etc/passwd</literal> and
         <literal>/etc/group</literal> files will be merged with the
-        contents generated from the <literal>users.extraUsers</literal> and
-        <literal>users.extraGroups</literal> options.
+        contents generated from the <literal>users.users</literal> and
+        <literal>users.groups</literal> options.
         The initial password for a user will be set
-        according to <literal>users.extraUsers</literal>, but existing passwords
+        according to <literal>users.users</literal>, but existing passwords
         will not be changed.
 
         <warning><para>
@@ -399,7 +399,7 @@ in {
         group files will simply be replaced on system activation. This also
         holds for the user passwords; all changed
         passwords will be reset according to the
-        <literal>users.extraUsers</literal> configuration on activation.
+        <literal>users.users</literal> configuration on activation.
         </para></warning>
       '';
     };
@@ -412,7 +412,7 @@ in {
       '';
     };
 
-    users.extraUsers = mkOption {
+    users.users = mkOption {
       default = {};
       type = types.loaOf types.optionSet;
       example = {
@@ -433,7 +433,7 @@ in {
       options = [ userOpts ];
     };
 
-    users.extraGroups = mkOption {
+    users.groups = mkOption {
       default = {};
       example =
         { students.gid = 1001;
@@ -461,7 +461,7 @@ in {
 
   config = {
 
-    users.extraUsers = {
+    users.users = {
       root = {
         uid = ids.uids.root;
         description = "System administrator";
@@ -478,7 +478,7 @@ in {
       };
     };
 
-    users.extraGroups = {
+    users.groups = {
       root.gid = ids.gids.root;
       wheel.gid = ids.gids.wheel;
       disk.gid = ids.gids.disk;
@@ -525,6 +525,27 @@ in {
       { assertion = !cfg.enforceIdUniqueness || (uidsAreUnique && gidsAreUnique);
         message = "UIDs and GIDs must be unique!";
       }
+      { # If mutableUsers is false, to prevent users creating a
+        # configuration that locks them out of the system, ensure that
+        # there is at least one "privileged" account that has a
+        # password or an SSH authorized key. Privileged accounts are
+        # root and users in the wheel group.
+        assertion = !cfg.mutableUsers ->
+          any id (mapAttrsToList (name: cfg:
+            (name == "root"
+             || cfg.group == "wheel"
+             || elem "wheel" cfg.extraGroups)
+            &&
+            ((cfg.hashedPassword != null && cfg.hashedPassword != "!")
+             || cfg.password != null
+             || cfg.passwordFile != null
+             || cfg.openssh.authorizedKeys.keys != []
+             || cfg.openssh.authorizedKeys.keyFiles != [])
+          ) cfg.users);
+        message = ''
+          Neither the root account nor any wheel user has a password or SSH authorized key.
+          You must set one to prevent being locked out of your system.'';
+      }
     ];
 
   };
diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix
index e4bdeb55cadc..1a04baef1930 100644
--- a/nixos/modules/hardware/all-firmware.nix
+++ b/nixos/modules/hardware/all-firmware.nix
@@ -22,9 +22,7 @@ with lib;
   ###### implementation
 
   config = mkIf config.hardware.enableAllFirmware {
-    hardware.firmware = [
-      "${pkgs.firmwareLinuxNonfree}/lib/firmware"
-    ];
+    hardware.firmware = [ pkgs.firmwareLinuxNonfree ];
   };
 
 }
diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix
index e341eac4a819..e2202e1e17df 100644
--- a/nixos/modules/hardware/video/bumblebee.nix
+++ b/nixos/modules/hardware/video/bumblebee.nix
@@ -52,9 +52,9 @@ in
     systemd.services.bumblebeed = {
       description = "Bumblebee Hybrid Graphics Switcher";
       wantedBy = [ "display-manager.service" ];
-      script = "bumblebeed --use-syslog -g ${config.hardware.bumblebee.group}";
       path = [ kernel.bbswitch bumblebee ];
       serviceConfig = {
+        ExecStart = "${bumblebee}/bin/bumblebeed --use-syslog -g ${config.hardware.bumblebee.group}";
         Restart = "always";
         RestartSec = 60;
         CPUSchedulingPolicy = "idle";
diff --git a/nixos/modules/hardware/video/encoder/wis-go7007.nix b/nixos/modules/hardware/video/encoder/wis-go7007.nix
index c0eb2b814b33..e9b3cf72a8dd 100644
--- a/nixos/modules/hardware/video/encoder/wis-go7007.nix
+++ b/nixos/modules/hardware/video/encoder/wis-go7007.nix
@@ -5,11 +5,11 @@ let
 in
 
 {
-  boot.extraModulePackages = [wis_go7007];
+  boot.extraModulePackages = [ wis_go7007 ];
 
-  environment.systemPackages = [wis_go7007];
+  environment.systemPackages = [ wis_go7007 ];
 
-  hardware.firmware = ["${wis_go7007}/firmware"];
+  hardware.firmware = [ wis_go7007 ];
 
-  services.udev.packages = [wis_go7007];
+  services.udev.packages = [ wis_go7007 ];
 }
diff --git a/nixos/modules/installer/cd-dvd/channel.nix b/nixos/modules/installer/cd-dvd/channel.nix
index ca0e233f9e3f..eccb19da5cb3 100644
--- a/nixos/modules/installer/cd-dvd/channel.nix
+++ b/nixos/modules/installer/cd-dvd/channel.nix
@@ -9,18 +9,17 @@ let
 
   # We need a copy of the Nix expressions for Nixpkgs and NixOS on the
   # CD.  These are installed into the "nixos" channel of the root
-  # user, as expected by nixos-rebuild/nixos-install.
+  # user, as expected by nixos-rebuild/nixos-install. FIXME: merge
+  # with make-channel.nix.
   channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}"
-    { expr = readFile ../../../lib/channel-expr.nix; }
+    { }
     ''
-      mkdir -p $out/nixos
-      cp -prd ${pkgs.path} $out/nixos/nixpkgs
-      ln -s nixpkgs/nixos $out/nixos/nixos
+      mkdir -p $out
+      cp -prd ${pkgs.path} $out/nixos
       chmod -R u+w $out/nixos
-      rm -rf $out/nixos/nixpkgs/.git
-      echo -n ${config.system.nixosVersion} > $out/nixos/nixpkgs/.version
-      echo -n "" > $out/nixos/nixpkgs/.version-suffix
-      echo "$expr" > $out/nixos/default.nix
+      ln -s . $out/nixos/nixpkgs
+      rm -rf $out/nixos/.git
+      echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
     '';
 
 in
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index c9abff2ecfc0..fa9cc6fa20b9 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -30,8 +30,7 @@ let
   #   * COM32 entries (chainload, reboot, poweroff) are not recognized. They
   #     result in incorrect boot entries.
 
-  baseIsolinuxCfg =
-    ''
+  baseIsolinuxCfg = ''
     SERIAL 0 38400
     TIMEOUT ${builtins.toString syslinuxTimeout}
     UI vesamenu.c32
@@ -44,7 +43,7 @@ let
     LINUX /boot/bzImage
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
     INITRD /boot/initrd
-    '';
+  '';
 
   isolinuxMemtest86Entry = ''
     LABEL memtest
@@ -55,12 +54,12 @@ let
 
   isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
 
-  # The efi boot image
+  # The EFI boot image.
   efiDir = pkgs.runCommand "efi-directory" {} ''
     mkdir -p $out/EFI/boot
     cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
     mkdir -p $out/loader/entries
-    echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
+    echo "title NixOS Live CD" > $out/loader/entries/nixos-livecd.conf
     echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
     echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf
     echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf
@@ -218,6 +217,8 @@ in
     system.boot.loader.kernelFile = "bzImage";
     environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
 
+    boot.consoleLogLevel = mkDefault 7;
+
     # In stage 1 of the boot, mount the CD as the root FS by label so
     # that we don't need to know its device.  We pass the label of the
     # root filesystem on the kernel command line, rather than in
@@ -229,6 +230,7 @@ in
     boot.kernelParams =
       [ "root=LABEL=${config.isoImage.volumeID}"
         "boot.shell_on_fail"
+        "nomodeset"
       ];
 
     fileSystems."/" =
@@ -268,6 +270,8 @@ in
 
     boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
 
+    boot.blacklistedKernelModules = [ "nouveau" ];
+
     boot.initrd.kernelModules = [ "loop" ];
 
     # Closures to be copied to the Nix store on the CD, namely the init
diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
new file mode 100644
index 000000000000..0ca57a4635f4
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -0,0 +1,40 @@
+{ config, lib, pkgs, ... }:
+
+let
+  extlinux-conf-builder =
+    import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
+      inherit pkgs;
+    };
+in
+{
+  imports = [
+    ../../profiles/minimal.nix
+    ../../profiles/installation-device.nix
+    ./sd-image.nix
+  ];
+
+  assertions = lib.singleton {
+    assertion = pkgs.stdenv.system == "armv7l-linux";
+    message = "sd-image-armv7l-multiplatform.nix can be only built natively on ARMv7; " +
+      "it cannot be cross compiled";
+  };
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  # FIXME: change this to linuxPackages_latest once v4.2 is out
+  boot.kernelPackages = pkgs.linuxPackages_testing;
+  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
+
+  # FIXME: fix manual evaluation on ARM
+  services.nixosManual.enable = lib.mkOverride 0 false;
+
+  # FIXME: this probably should be in installation-device.nix
+  users.extraUsers.root.initialHashedPassword = "";
+
+  sdImage = {
+    populateBootCommands = ''
+        ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
+    '';
+  };
+}
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
new file mode 100644
index 000000000000..199a252ad2b5
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -0,0 +1,46 @@
+{ config, lib, pkgs, ... }:
+
+let
+  extlinux-conf-builder =
+    import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
+      inherit pkgs;
+    };
+in
+{
+  imports = [
+    ../../profiles/minimal.nix
+    ../../profiles/installation-device.nix
+    ./sd-image.nix
+  ];
+
+  assertions = lib.singleton {
+    assertion = pkgs.stdenv.system == "armv6l-linux";
+    message = "sd-image-raspberrypi.nix can be only built natively on ARMv6; " +
+      "it cannot be cross compiled";
+  };
+
+  # Needed by RPi firmware
+  nixpkgs.config.allowUnfree = true;
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  boot.kernelPackages = pkgs.linuxPackages_rpi;
+
+  # FIXME: fix manual evaluation on ARM
+  services.nixosManual.enable = lib.mkOverride 0 false;
+
+  # FIXME: this probably should be in installation-device.nix
+  users.extraUsers.root.initialHashedPassword = "";
+
+  sdImage = {
+    populateBootCommands = ''
+      for f in bootcode.bin fixup.dat start.elf; do
+        cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/$f boot/
+      done
+      cp ${pkgs.ubootRaspberryPi}/u-boot.bin boot/u-boot-rpi.bin
+      echo 'kernel u-boot-rpi.bin' > boot/config.txt
+      ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
+    '';
+  };
+}
diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix
new file mode 100644
index 000000000000..12b4f3045614
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -0,0 +1,127 @@
+# This module creates a bootable SD card image containing the given NixOS
+# configuration. The generated image is MBR partitioned, with a FAT /boot
+# partition, and ext4 root partition. The generated image is sized to fit
+# its contents, and a boot script automatically resizes the root partition
+# to fit the device on the first boot.
+#
+# The derivation for the SD image will be placed in
+# config.system.build.sdImage
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  rootfsImage = import ../../../lib/make-ext4-fs.nix {
+    inherit pkgs;
+    inherit (config.sdImage) storePaths;
+    volumeLabel = "NIXOS_SD";
+  };
+in
+{
+  options.sdImage = {
+    storePaths = mkOption {
+      type = with types; listOf package;
+      example = literalExample "[ pkgs.stdenv ]";
+      description = ''
+        Derivations to be included in the Nix store in the generated SD image.
+      '';
+    };
+
+    bootSize = mkOption {
+      type = types.int;
+      default = 128;
+      description = ''
+        Size of the /boot partition, in megabytes.
+      '';
+    };
+
+    populateBootCommands = mkOption {
+      example = literalExample "'' cp \${pkgs.myBootLoader}/u-boot.bin boot/ ''";
+      description = ''
+        Shell commands to populate the ./boot directory.
+        All files in that directory are copied to the
+        /boot partition on the SD image.
+      '';
+    };
+  };
+
+  config = {
+    fileSystems = {
+      "/boot" = {
+        device = "/dev/disk/by-label/NIXOS_BOOT";
+        fsType = "vfat";
+      };
+      "/" = {
+        device = "/dev/disk/by-label/NIXOS_SD";
+        fsType = "ext4";
+      };
+    };
+
+    sdImage.storePaths = [ config.system.build.toplevel ];
+
+    system.build.sdImage = pkgs.stdenv.mkDerivation {
+      name = "sd-image-${pkgs.stdenv.system}.img";
+
+      buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
+
+      buildCommand = ''
+        # Create the image file sized to fit /boot and /, plus 4M of slack
+        rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
+        bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
+        imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 4096 * 1024))
+        truncate -s $imageSize $out
+
+        # type=b is 'W95 FAT32', type=83 is 'Linux'.
+        sfdisk $out <<EOF
+            label: dos
+            label-id: 0x2178694e
+
+            start=1M, size=$bootSizeBlocks, type=b, bootable
+            type=83
+        EOF
+
+        # Copy the rootfs into the SD image
+        eval $(partx $out -o START,SECTORS --nr 2 --pairs)
+        dd conv=notrunc if=${rootfsImage} of=$out seek=$START count=$SECTORS
+
+        # Create a FAT32 /boot partition of suitable size into bootpart.img
+        eval $(partx $out -o START,SECTORS --nr 1 --pairs)
+        truncate -s $((SECTORS * 512)) bootpart.img
+        faketime "1970-01-01 00:00:00" mkfs.vfat -i 0x2178694e -n NIXOS_BOOT bootpart.img
+
+        # Populate the files intended for /boot
+        mkdir boot
+        ${config.sdImage.populateBootCommands}
+
+        # Copy the populated /boot into the SD image
+        (cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
+        dd conv=notrunc if=bootpart.img of=$out seek=$START count=$SECTORS
+      '';
+    };
+
+    boot.postBootCommands = ''
+      # On the first boot do some maintenance tasks
+      if [ -f /nix-path-registration ]; then
+        # Figure out device names for the boot device and root filesystem.
+        rootPart=$(readlink -f /dev/disk/by-label/NIXOS_SD)
+        bootDevice=$(lsblk -npo PKNAME $rootPart)
+
+        # Resize the root partition and the filesystem to fit the disk
+        echo ",+," | sfdisk -N2 --no-reread $bootDevice
+        ${pkgs.parted}/bin/partprobe
+        ${pkgs.e2fsprogs}/bin/resize2fs $rootPart
+
+        # Register the contents of the initial Nix store
+        ${config.nix.package}/bin/nix-store --load-db < /nix-path-registration
+
+        # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
+        touch /etc/NIXOS
+        ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
+
+        # Prevents this from running on later boots.
+        rm -f /nix-path-registration
+      fi
+    '';
+  };
+}
diff --git a/nixos/modules/installer/tools/auto-upgrade.nix b/nixos/modules/installer/tools/auto-upgrade.nix
new file mode 100644
index 000000000000..b2676b05a02c
--- /dev/null
+++ b/nixos/modules/installer/tools/auto-upgrade.nix
@@ -0,0 +1,81 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.system.autoUpgrade; in
+
+{
+
+  options = {
+
+    system.autoUpgrade = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to periodically upgrade NixOS to the latest
+          version. If enabled, a systemd timer will run
+          <literal>nixos-rebuild switch --upgrade</literal> once a
+          day.
+        '';
+      };
+
+      channel = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = https://nixos.org/channels/nixos-14.12-small;
+        description = ''
+          The URI of the NixOS channel to use for automatic
+          upgrades. By default, this is the channel set using
+          <command>nix-channel</command> (run <literal>nix-channel
+          --list</literal> to see the current value).
+        '';
+      };
+
+      flags = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        example = [ "-I" "stuff=/home/alice/nixos-stuff" "--option" "extra-binary-caches" "http://my-cache.example.org/" ];
+        description = ''
+          Any additional flags passed to <command>nixos-rebuild</command>.
+        '';
+      };
+
+    };
+
+  };
+
+  config = {
+
+    system.autoUpgrade.flags =
+      [ "--no-build-output" ]
+      ++ (if cfg.channel == null
+          then [ "--upgrade" ]
+          else [ "-I" "nixpkgs=${cfg.channel}/nixexprs.tar.xz" ]);
+
+    systemd.services.nixos-upgrade = {
+      description = "NixOS Upgrade";
+
+      restartIfChanged = false;
+      unitConfig.X-StopOnRemoval = false;
+
+      serviceConfig.Type = "oneshot";
+
+      environment = config.nix.envVars //
+        { inherit (config.environment.sessionVariables) NIX_PATH SSL_CERT_FILE;
+          HOME = "/root";
+        };
+
+      path = [ pkgs.gnutar pkgs.xz config.nix.package ];
+
+      script = ''
+        ${config.system.build.nixos-rebuild}/bin/nixos-rebuild test ${toString cfg.flags}
+      '';
+
+      startAt = mkIf cfg.enable "04:40";
+    };
+
+  };
+
+}
diff --git a/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
index f9cbfffde704..4e981c074a57 100644
--- a/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
+++ b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
@@ -53,5 +53,5 @@ fi
 
 # Build a network of VMs
 
-nix-build '<nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
+nix-build '<nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
     --argstr networkExpr $networkExpr $noOutLinkArg $showTraceArg
diff --git a/nixos/modules/installer/tools/nixos-checkout.nix b/nixos/modules/installer/tools/nixos-checkout.nix
index 9cdd8a74a188..07274e139f7d 100644
--- a/nixos/modules/installer/tools/nixos-checkout.nix
+++ b/nixos/modules/installer/tools/nixos-checkout.nix
@@ -27,7 +27,7 @@ let
 
         if [ -z "$(type -P git)" ]; then
             echo "installing Git..."
-            nix-env -iA nixos.pkgs.git || nix-env -i git
+            nix-env -iA nixos.git
         fi
 
         # Move any old nixpkgs directories out of the way.
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 187ea7635eb5..39ef4c51ba10 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -235,7 +235,7 @@ chomp $virt;
 # Check if we're a VirtualBox guest.  If so, enable the guest
 # additions.
 if ($virt eq "oracle") {
-    push @attrs, "services.virtualboxGuest.enable = true;"
+    push @attrs, "virtualisation.virtualbox.guest.enable = true;"
 }
 
 
@@ -544,6 +544,9 @@ $bootLoaderConfig
   #   uid = 1000;
   # };
 
+  # The NixOS release to be compatible with for stateful data such as databases.
+  system.stateVersion = "@nixosRelease@";
+
 }
 EOF
     } else {
diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
index b1f4772d5705..f7fe6245d6d9 100644
--- a/nixos/modules/installer/tools/nixos-install.sh
+++ b/nixos/modules/installer/tools/nixos-install.sh
@@ -256,14 +256,8 @@ NIXOS_INSTALL_GRUB=1 chroot $mountPoint \
 chroot $mountPoint /nix/var/nix/profiles/system/activate
 
 
-# Some systems may not be prepared to use NixOS' paths.
-export PATH=/run/current-system/sw/bin:/run/current-system/sw/sbin:$PATH
-export NIX_PATH=/nix/var/nix/profiles/per-user/root/channels/nixos:nixpkgs=/etc/nixos/nixpkgs
-export NIX_PATH=$NIX_PATH:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
-
-
 # Ask the user to set a root password.
-if [ "$(chroot $mountPoint nix-instantiate --eval '<nixpkgs/nixos>' -A config.users.mutableUsers)" = true ] && [ -t 0 ] ; then
+if [ "$(chroot $mountPoint /run/current-system/sw/bin/sh -l -c "nix-instantiate --eval '<nixpkgs/nixos>' -A config.users.mutableUsers")" = true ] && [ -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 ccafa30856c5..7d0e5913cfb1 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -157,9 +157,9 @@ if [ -n "$buildNix" ]; then
             if ! nix-build '<nixpkgs>' -A nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
                 machine="$(uname -m)"
                 if [ "$machine" = x86_64 ]; then
-                    nixStorePath=/nix/store/ffig6yaggbh12dh9y5pnf1grf5lqyipz-nix-1.8
+                    nixStorePath=/nix/store/664kxr14kfgx4dl095crvmr7pbh9xlh5-nix-1.9
                 elif [[ "$machine" =~ i.86 ]]; then
-                    nixStorePath=/nix/store/lglhfp4mimfa5wzjjf1kqz6f5wlsj2mn-nix-1.8
+                    nixStorePath=/nix/store/p7xdvz72xx3rhm121jclsbdmmcds7xh6-nix-1.9
                 else
                     echo "$0: unsupported platform"
                     exit 1
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index 99a74b6d59ed..04e4c1eb9459 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -40,6 +40,7 @@ let
     src = ./nixos-generate-config.pl;
     path = [ pkgs.btrfsProgs ];
     perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
+    inherit (config.system) nixosRelease;
   };
 
   nixos-option = makeProg {
@@ -56,7 +57,9 @@ let
 in
 
 {
+
   config = {
+
     environment.systemPackages =
       [ nixos-build-vms
         nixos-install
@@ -69,5 +72,7 @@ in
     system.build = {
       inherit nixos-install nixos-generate-config nixos-option nixos-rebuild;
     };
+
   };
+
 }
diff --git a/nixos/modules/misc/assertions.nix b/nixos/modules/misc/assertions.nix
index c42de038e61f..3b50e60a0ffb 100644
--- a/nixos/modules/misc/assertions.nix
+++ b/nixos/modules/misc/assertions.nix
@@ -30,5 +30,5 @@ with lib;
     };
 
   };
-  # impl of assertions is in <nixos/modules/system/activation/top-level.nix>
+  # impl of assertions is in <nixpkgs/nixos/modules/system/activation/top-level.nix>
 }
diff --git a/nixos/modules/misc/extra-arguments.nix b/nixos/modules/misc/extra-arguments.nix
index ff2ff7cd4322..19002b17dace 100644
--- a/nixos/modules/misc/extra-arguments.nix
+++ b/nixos/modules/misc/extra-arguments.nix
@@ -2,8 +2,13 @@
 
 {
   _module.args = {
-    pkgs_i686 = import ../../lib/nixpkgs.nix {
+    pkgs_i686 = import ../../.. {
       system = "i686-linux";
+      # FIXME: we enable config.allowUnfree to make packages like
+      # nvidia-x11 available. This isn't a problem because if the user has
+      # ‘nixpkgs.config.allowUnfree = false’, then evaluation will fail on
+      # the 64-bit package anyway. However, it would be cleaner to respect
+      # nixpkgs.config here.
       config.allowUnfree = true;
     };
 
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index fd75db1abe77..1e5393f26b54 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -226,6 +226,9 @@
       gitit = 202;
       riemanntools = 203;
       subsonic = 204;
+      riak = 205;
+      shout = 206;
+      gateone = 207;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -430,6 +433,9 @@
       gitit = 202;
       riemanntools = 203;
       subsonic = 204;
+      riak = 205;
+      #shout = 206; #unused
+      gateone = 207;
 
       # 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/locate.nix b/nixos/modules/misc/locate.nix
index f3ed2aaba09d..4f9c8d4e5ba1 100644
--- a/nixos/modules/misc/locate.nix
+++ b/nixos/modules/misc/locate.nix
@@ -35,7 +35,7 @@ in {
         type = types.listOf types.str;
         default = [ ];
         description = ''
-          Extra flags to append to <command>updatedb</command>.
+          Extra flags to pass to <command>updatedb</command>.
         '';
       };
 
@@ -56,6 +56,14 @@ in {
         '';
       };
 
+      includeStore = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to include <filename>/nix/store</filename> in the locate database.
+        '';
+      };
+
     };
 
   };
@@ -63,7 +71,6 @@ in {
   ###### implementation
 
   config = {
-
     systemd.services.update-locatedb =
       { description = "Update Locate Database";
         path  = [ pkgs.su ];
@@ -71,8 +78,9 @@ in {
           ''
             mkdir -m 0755 -p $(dirname ${toString cfg.output})
             exec updatedb \
-            --localuser=${cfg.localuser} \
-            --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
+              --localuser=${cfg.localuser} \
+              ${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
+              --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
           '';
         serviceConfig.Nice = 19;
         serviceConfig.IOSchedulingClass = "idle";
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index fb5516c953c2..5eb38c510b48 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -72,7 +72,7 @@ in
   };
 
   config = {
-    _module.args.pkgs = import ../../lib/nixpkgs.nix {
+    _module.args.pkgs = import ../../.. {
       system = config.nixpkgs.system;
 
       inherit (config.nixpkgs) config;
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 5afdcf214f27..b4b0281fe587 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -6,12 +6,35 @@ with lib;
 
   options = {
 
+    system.stateVersion = mkOption {
+      type = types.str;
+      default = config.system.nixosRelease;
+      description = ''
+        Every once in a while, a new NixOS release may change
+        configuration defaults in a way incompatible with stateful
+        data. For instance, if the default version of PostgreSQL
+        changes, the new version will probably be unable to read your
+        existing databases. To prevent such breakage, you can set the
+        value of this option to the NixOS release with which you want
+        to be compatible. The effect is that NixOS will option
+        defaults corresponding to the specified release (such as using
+        an older version of PostgreSQL).
+      '';
+    };
+
     system.nixosVersion = mkOption {
       internal = true;
       type = types.str;
       description = "NixOS version.";
     };
 
+    system.nixosRelease = mkOption {
+      readOnly = true;
+      type = types.str;
+      default = readFile "${toString pkgs.path}/.version";
+      description = "NixOS release.";
+    };
+
     system.nixosVersionSuffix = mkOption {
       internal = true;
       type = types.str;
@@ -25,7 +48,7 @@ with lib;
     };
 
     system.nixosCodeName = mkOption {
-      internal = true;
+      readOnly = true;
       type = types.str;
       description = "NixOS release code name.";
     };
@@ -41,8 +64,7 @@ with lib;
 
   config = {
 
-    system.nixosVersion =
-      mkDefault (readFile "${toString pkgs.path}/.version" + config.system.nixosVersionSuffix);
+    system.nixosVersion = mkDefault (config.system.nixosRelease + config.system.nixosVersionSuffix);
 
     system.nixosVersionSuffix =
       let suffixFile = "${toString pkgs.path}/.version-suffix"; in
@@ -53,7 +75,7 @@ with lib;
       mkDefault (if pathExists fn then readFile fn else "master");
 
     # Note: code names must only increase in alphabetical order.
-    system.nixosCodeName = "Dingo";
+    system.nixosCodeName = "Emu";
 
     # Generate /etc/os-release.  See
     # http://0pointer.de/public/systemd-man/os-release.html for the
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index f771bced5ef6..6734fa0b862b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -41,6 +41,7 @@
   ./hardware/video/bumblebee.nix
   ./hardware/video/nvidia.nix
   ./hardware/video/ati.nix
+  ./installer/tools/auto-upgrade.nix
   ./installer/tools/nixos-checkout.nix
   ./installer/tools/tools.nix
   ./misc/assertions.nix
@@ -60,7 +61,6 @@
   ./programs/command-not-found/command-not-found.nix
   ./programs/dconf.nix
   ./programs/environment.nix
-  ./programs/info.nix
   ./programs/ibus.nix
   ./programs/kbdlight.nix
   ./programs/light.nix
@@ -72,9 +72,9 @@
   ./programs/ssmtp.nix
   ./programs/uim.nix
   ./programs/venus.nix
-  ./programs/virtualbox-host.nix
   ./programs/wvdial.nix
   ./programs/freetds.nix
+  ./programs/xfs_quota.nix
   ./programs/zsh/zsh.nix
   ./rename.nix
   ./security/apparmor.nix
@@ -131,6 +131,7 @@
   ./services/databases/opentsdb.nix
   ./services/databases/postgresql.nix
   ./services/databases/redis.nix
+  ./services/databases/riak.nix
   ./services/databases/virtuoso.nix
   ./services/desktops/accountsservice.nix
   ./services/desktops/geoclue2.nix
@@ -278,15 +279,18 @@
   ./services/networking/dnsmasq.nix
   ./services/networking/docker-registry-server.nix
   ./services/networking/ejabberd.nix
+  ./services/networking/fan.nix
   ./services/networking/firefox/sync-server.nix
   ./services/networking/firewall.nix
   ./services/networking/flashpolicyd.nix
   ./services/networking/freenet.nix
+  ./services/networking/gateone.nix
   ./services/networking/git-daemon.nix
   ./services/networking/gnunet.nix
   ./services/networking/gogoclient.nix
   ./services/networking/gvpe.nix
   ./services/networking/haproxy.nix
+  ./services/networking/heyefi.nix
   ./services/networking/hostapd.nix
   ./services/networking/i2pd.nix
   ./services/networking/i2p.nix
@@ -326,6 +330,8 @@
   ./services/networking/searx.nix
   ./services/networking/seeks.nix
   ./services/networking/skydns.nix
+  ./services/networking/shout.nix
+  ./services/networking/softether.nix
   ./services/networking/spiped.nix
   ./services/networking/sslh.nix
   ./services/networking/ssh/lshd.nix
@@ -387,6 +393,7 @@
   ./services/web-servers/lighttpd/default.nix
   ./services/web-servers/lighttpd/gitweb.nix
   ./services/web-servers/nginx/default.nix
+  ./services/web-servers/nginx/reverse_proxy.nix
   ./services/web-servers/phpfpm.nix
   ./services/web-servers/shellinabox.nix
   ./services/web-servers/tomcat.nix
@@ -483,6 +490,7 @@
   ./virtualisation/openvswitch.nix
   ./virtualisation/parallels-guest.nix
   ./virtualisation/virtualbox-guest.nix
+  ./virtualisation/virtualbox-host.nix
   ./virtualisation/vmware-guest.nix
   ./virtualisation/xen-dom0.nix
 ]
diff --git a/nixos/modules/profiles/clone-config.nix b/nixos/modules/profiles/clone-config.nix
index f0d60bb6c428..77d86f8d7405 100644
--- a/nixos/modules/profiles/clone-config.nix
+++ b/nixos/modules/profiles/clone-config.nix
@@ -30,7 +30,7 @@ let
   relocatedModuleFiles =
     let
       relocateNixOS = path:
-        "<nixos" + removePrefix nixosPath (toString path) + ">";
+        "<nixpkgs/nixos" + removePrefix nixosPath (toString path) + ">";
       relocateOthers = null;
     in
       { nixos = map relocateNixOS partitionedModuleFiles.nixos;
diff --git a/nixos/modules/profiles/minimal.nix b/nixos/modules/profiles/minimal.nix
index 3b18ae129b93..c353da227aeb 100644
--- a/nixos/modules/profiles/minimal.nix
+++ b/nixos/modules/profiles/minimal.nix
@@ -7,6 +7,8 @@ with lib;
 
 {
   environment.noXlibs = mkDefault true;
-  i18n.supportedLocales = [ config.i18n.defaultLocale ];
+
+  # This isn't perfect, but let's expect the user specifies an UTF-8 defaultLocale
+  i18n.supportedLocales = [ (config.i18n.defaultLocale + "/UTF-8") ];
   services.nixosManual.enable = mkDefault false;
 }
diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix
index bead2dcdcf90..9524d91ea3bc 100644
--- a/nixos/modules/programs/command-not-found/command-not-found.nix
+++ b/nixos/modules/programs/command-not-found/command-not-found.nix
@@ -57,9 +57,9 @@ in
           if [ $? = 126 ]; then
             "$@"
           fi
-	else
+        else
           # Indicate than there was an error so ZSH falls back to its default handler
-	  return 127
+          return 127
         fi
       }
     '';
diff --git a/nixos/modules/programs/command-not-found/command-not-found.pl b/nixos/modules/programs/command-not-found/command-not-found.pl
index 916649059d37..b233d973a4ab 100644
--- a/nixos/modules/programs/command-not-found/command-not-found.pl
+++ b/nixos/modules/programs/command-not-found/command-not-found.pl
@@ -30,11 +30,11 @@ The program ‘$program’ is currently not installed. It is provided by
 the package ‘$package’, which I will now install for you.
 EOF
         ;
-        exit 126 if system("nix-env", "-i", $package) == 0;
+        exit 126 if system("nix-env", "-iA", "nixos.$package") == 0;
     } else {
         print STDERR <<EOF;
 The program ‘$program’ is currently not installed. You can install it by typing:
-  nix-env -i $package
+  nix-env -iA nixos.$package
 EOF
     }
 } else {
@@ -42,7 +42,7 @@ EOF
 The program ‘$program’ is currently not installed. It is provided by
 several packages. You can install it by typing one of the following:
 EOF
-    print STDERR "  nix-env -i $_->{package}\n" foreach @$res;
+    print STDERR "  nix-env -iA nixos.$_->{package}\n" foreach @$res;
 }
 
 exit 127;
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index dce757ceb623..52f6cc221119 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -23,15 +23,6 @@ in
         EDITOR = mkDefault "nano";
       };
 
-    environment.sessionVariables =
-      { NIX_PATH =
-          [ "/nix/var/nix/profiles/per-user/root/channels/nixos"
-            "nixpkgs=/etc/nixos/nixpkgs"
-            "nixos-config=/etc/nixos/configuration.nix"
-            "/nix/var/nix/profiles/per-user/root/channels"
-          ];
-      };
-
     environment.profiles =
       [ "$HOME/.nix-profile"
         "/nix/var/nix/profiles/default"
diff --git a/nixos/modules/programs/info.nix b/nixos/modules/programs/info.nix
deleted file mode 100644
index 253f9e877693..000000000000
--- a/nixos/modules/programs/info.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{config, pkgs, ...}:
-
-let
-
-  texinfo = pkgs.texinfoInteractive;
-
-  # Quick hack to make the `info' command work properly.  `info' needs
-  # a "dir" file containing all the installed Info files, which we
-  # don't have (it would be impure to have a package installation
-  # update some global "dir" file).  So this wrapper script around
-  # "info" builds a temporary "dir" file on the fly.  This is a bit
-  # slow (on a cold cache) but not unacceptably so.
-  infoWrapper = pkgs.writeScriptBin "info"
-    ''
-      #! ${pkgs.stdenv.shell}
-
-      dir=$(mktemp --tmpdir -d "info.dir.XXXXXX")
-
-      if test -z "$dir"; then exit 1; fi
-
-      trap 'rm -rf "$dir"' EXIT
-
-      shopt -s nullglob
-
-      for i in $(IFS=:; echo $INFOPATH); do
-          for j in $i/*.info; do
-              ${texinfo}/bin/install-info --quiet $j $dir/dir
-          done
-      done
-
-      INFOPATH=$dir:$INFOPATH ${texinfo}/bin/info "$@"
-    ''; # */
-
-in
-
-{
-  environment.systemPackages = [ infoWrapper texinfo ];
-}
diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix
index 0d1ec500afc4..cf7ef455eb85 100644
--- a/nixos/modules/programs/ssh.nix
+++ b/nixos/modules/programs/ssh.nix
@@ -18,6 +18,14 @@ let
       exec ${askPassword}
     '';
 
+  knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
+
+  knownHostsText = flip (concatMapStringsSep "\n") knownHosts
+    (h: assert h.hostNames != [];
+      concatStringsSep "," h.hostNames + " "
+      + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
+    );
+
 in
 {
   ###### interface
@@ -92,31 +100,93 @@ in
         '';
       };
 
+      knownHosts = mkOption {
+        default = {};
+        type = types.loaOf (types.submodule ({ name, ... }: {
+          options = {
+            hostNames = mkOption {
+              type = types.listOf types.str;
+              default = [];
+              description = ''
+                A list of host names and/or IP numbers used for accessing
+                the host's ssh service.
+              '';
+            };
+            publicKey = mkOption {
+              default = null;
+              type = types.nullOr types.str;
+              example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
+              description = ''
+                The public key data for the host. You can fetch a public key
+                from a running SSH server with the <command>ssh-keyscan</command>
+                command. The public key should not include any host names, only
+                the key type and the key itself.
+              '';
+            };
+            publicKeyFile = mkOption {
+              default = null;
+              type = types.nullOr types.path;
+              description = ''
+                The path to the public key file for the host. The public
+                key file is read at build time and saved in the Nix store.
+                You can fetch a public key file from a running SSH server
+                with the <command>ssh-keyscan</command> command. The content
+                of the file should follow the same format as described for
+                the <literal>publicKey</literal> option.
+              '';
+            };
+          };
+          config = {
+            hostNames = mkDefault [ name ];
+          };
+        }));
+        description = ''
+          The set of system-wide known SSH hosts.
+        '';
+        example = [
+          {
+            hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
+            publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub";
+          }
+          {
+            hostNames = [ "myhost2" ];
+            publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub";
+          }
+        ];
+      };
+
     };
 
   };
 
   config = {
 
-    assertions = singleton
-      { assertion = cfg.forwardX11 -> cfg.setXAuthLocation;
-        message = "cannot enable X11 forwarding without setting XAuth location";
-      };
-
-    environment.etc =
-      [ { # SSH configuration.  Slight duplication of the sshd_config
-          # generation in the sshd service.
-          source = pkgs.writeText "ssh_config" ''
-            AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
-            ${optionalString cfg.setXAuthLocation ''
-              XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
-            ''}
-            ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}
-            ${cfg.extraConfig}
-          '';
-          target = "ssh/ssh_config";
+    assertions =
+      [ { assertion = cfg.forwardX11 -> cfg.setXAuthLocation;
+          message = "cannot enable X11 forwarding without setting XAuth location";
         }
-      ];
+      ] ++ flip mapAttrsToList cfg.knownHosts (name: data: {
+        assertion = (data.publicKey == null && data.publicKeyFile != null) ||
+                    (data.publicKey != null && data.publicKeyFile == null);
+        message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
+      });
+
+    # SSH configuration. Slight duplication of the sshd_config
+    # generation in the sshd service.
+    environment.etc."ssh/ssh_config".text =
+      ''
+        AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
+
+        ${optionalString cfg.setXAuthLocation ''
+          XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
+        ''}
+
+        ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}
+
+        ${cfg.extraConfig}
+      '';
+
+    environment.etc."ssh/ssh_known_hosts".text = knownHostsText;
 
     # FIXME: this should really be socket-activated for über-awesomeness.
     systemd.user.services.ssh-agent =
diff --git a/nixos/modules/programs/xfs_quota.nix b/nixos/modules/programs/xfs_quota.nix
new file mode 100644
index 000000000000..d30a85922cff
--- /dev/null
+++ b/nixos/modules/programs/xfs_quota.nix
@@ -0,0 +1,110 @@
+# Configuration for the xfs_quota command
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.programs.xfs_quota;
+
+  limitOptions = opts: concatStringsSep " " [
+    (optionalString (opts.sizeSoftLimit != null) "bsoft=${opts.sizeSoftLimit}")
+    (optionalString (opts.sizeHardLimit != null) "bhard=${opts.sizeHardLimit}")
+  ];
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    programs.xfs_quota = {
+      projects = mkOption {
+        default = {};
+        type = types.attrsOf (types.submodule {
+          options = {
+            id = mkOption {
+              type = types.int;
+              description = "Project ID.";
+            };
+
+            fileSystem = mkOption {
+              type = types.string;
+              description = "XFS filesystem hosting the xfs_quota project.";
+              default = "/";
+            };
+
+            path = mkOption {
+              type = types.string;
+              description = "Project directory.";
+            };
+
+            sizeSoftLimit = mkOption {
+              type = types.nullOr types.string;
+              default = null;
+              example = "30g";
+              description = "Soft limit of the project size";
+            };
+
+            sizeHardLimit = mkOption {
+              type = types.nullOr types.string;
+              default = null;
+              example = "50g";
+              description = "Hard limit of the project size.";
+            };
+          };
+        });
+
+        description = "Setup of xfs_quota projects. Make sure the filesystem is mounted with the pquota option.";
+
+        example = {
+          "projname" = {
+            id = 50;
+            path = "/xfsprojects/projname";
+            sizeHardLimit = "50g";
+          };
+        };
+      };
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf (cfg.projects != {}) {
+
+    environment.etc.projects.source = pkgs.writeText "etc-project"
+      (concatStringsSep "\n" (mapAttrsToList
+        (name: opts: "${toString opts.id}:${opts.path}") cfg.projects));
+
+    environment.etc.projid.source = pkgs.writeText "etc-projid"
+      (concatStringsSep "\n" (mapAttrsToList
+        (name: opts: "${name}:${toString opts.id}") cfg.projects));
+
+    systemd.services = mapAttrs' (name: opts:
+      nameValuePair "xfs_quota-${name}" {
+        description = "Setup xfs_quota for project ${name}";
+        script = ''
+          ${pkgs.xfsprogs}/bin/xfs_quota -x -c 'project -s ${name}' ${opts.fileSystem}
+          ${pkgs.xfsprogs}/bin/xfs_quota -x -c 'limit -p ${limitOptions opts} ${name}' ${opts.fileSystem}
+        '';
+
+        wantedBy = [ "multi-user.target" ];
+        after = [ ((replaceChars [ "/" ] [ "-" ] opts.fileSystem) + ".mount") ];
+
+        restartTriggers = [ config.environment.etc.projects.source ];
+
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = true;
+        };
+      }
+    ) cfg.projects;
+
+  };
+
+}
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index a928f47f439e..cb378b024490 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -77,6 +77,8 @@ in zipModules ([]
 ++ obsolete [ "environment" "nix" ] [ "nix" "package" ]
 ++ obsolete [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ]
 ++ obsolete [ "fonts" "extraFonts" ] [ "fonts" "fonts" ]
+++ alias [ "users" "extraUsers" ] [ "users" "users" ]
+++ alias [ "users" "extraGroups" ] [ "users" "groups" ]
 
 ++ obsolete [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ]
 ++ obsolete [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ]
@@ -98,6 +100,9 @@ in zipModules ([]
 ++ obsolete [ "boot" "initrd" "extraKernelModules" ] [ "boot" "initrd" "kernelModules" ]
 ++ obsolete [ "boot" "extraKernelParams" ] [ "boot" "kernelParams" ]
 
+# smartd
+++ obsolete [ "services" "smartd" "deviceOpts" ] [ "services" "smartd" "defaults" "monitored" ]
+
 # OpenSSH
 ++ obsolete [ "services" "sshd" "ports" ] [ "services" "openssh" "ports" ]
 ++ alias [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]
@@ -107,9 +112,17 @@ in zipModules ([]
 ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ]
 ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ]
 ++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ]
+++ alias [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]
 
 # VirtualBox
-++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ]
+++ obsolete [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]
+++ obsolete [ "services" "virtualboxGuest" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ]
+++ obsolete [ "programs" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]
+++ obsolete [ "programs" "virtualbox" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]
+++ obsolete [ "programs" "virtualbox" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]
+++ obsolete [ "services" "virtualboxHost" "enable" ] [ "virtualisation" "virtualbox" "host" "enable" ]
+++ obsolete [ "services" "virtualboxHost" "addNetworkInterface" ] [ "virtualisation" "virtualbox" "host" "addNetworkInterface" ]
+++ obsolete [ "services" "virtualboxHost" "enableHardening" ] [ "virtualisation" "virtualbox" "host" "enableHardening" ]
 
 # Tarsnap
 ++ obsolete [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ]
diff --git a/nixos/modules/security/apparmor.nix b/nixos/modules/security/apparmor.nix
index 4fef62cbffd7..202639f98701 100644
--- a/nixos/modules/security/apparmor.nix
+++ b/nixos/modules/security/apparmor.nix
@@ -37,13 +37,5 @@ in
          ) cfg.profiles;
        };
      };
-
-     security.pam.services.apparmor.text = ''
-       ## AppArmor changes hats according to `order`: first try user, then
-       ## group, and finally fall back to a hat called "DEFAULT"
-       ##
-       ## For now, enable debugging as this is an experimental feature.
-       session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug
-     '';
    };
 }
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 02520fb88cdd..474b93b4984d 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -192,6 +192,16 @@ let
         description = "Whether to log authentication failures in <filename>/var/log/faillog</filename>.";
       };
 
+      enableAppArmor = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enable support for attaching AppArmor profiles at the
+          user/group level, e.g., as part of a role based access
+          control scheme.
+        '';
+      };
+
       text = mkOption {
         type = types.nullOr types.lines;
         description = "Contents of the PAM service file.";
@@ -251,9 +261,9 @@ let
           ${optionalString (!(config.security.pam.enableEcryptfs || cfg.pamMount)) "auth required pam_deny.so"}
 
           # Password management.
+          password requisite pam_unix.so nullok sha512
           ${optionalString config.security.pam.enableEcryptfs
               "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
-          password requisite pam_unix.so nullok sha512
           ${optionalString cfg.pamMount
               "password optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
           ${optionalString config.users.ldap.enable
@@ -294,6 +304,8 @@ let
               "session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"}
           ${optionalString cfg.pamMount
               "session optional ${pkgs.pam_mount}/lib/security/pam_mount.so"}
+          ${optionalString (cfg.enableAppArmor && config.security.apparmor.enable)
+              "session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug"}
         '';
     };
 
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
index d00c1aaa1055..ba09f04d502b 100644
--- a/nixos/modules/services/cluster/kubernetes.nix
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -78,12 +78,6 @@ in {
         type = types.int;
       };
 
-      readOnlyPort = mkOption {
-        description = "Kubernets apiserver read-only port.";
-        default = 7080;
-        type = types.int;
-      };
-
       securePort = mkOption {
         description = "Kubernetes apiserver secure port.";
         default = 6443;
@@ -102,10 +96,16 @@ in {
         type = types.str;
       };
 
+      clientCaFile = mkOption {
+        description = "Kubernetes apiserver CA file for client auth.";
+        default = "";
+        type = types.str;
+      };
+
       tokenAuth = mkOption {
         description = ''
           Kubernetes apiserver token authentication file. See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authentication.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authentication.html"/>
         '';
         default = {};
         example = literalExample ''
@@ -120,7 +120,7 @@ in {
       authorizationMode = mkOption {
         description = ''
           Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC). See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authorization.html"/>
         '';
         default = "AlwaysAllow";
         type = types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC"];
@@ -129,7 +129,7 @@ in {
       authorizationPolicy = mkOption {
         description = ''
           Kubernetes apiserver authorization policy file. See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authorization.html"/>
         '';
         default = [];
         example = literalExample ''
@@ -158,6 +158,38 @@ in {
         type = types.str;
       };
 
+      runtimeConfig = mkOption {
+        description = ''
+          Api runtime configuration. See
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/cluster-management.html"/>
+        '';
+        default = "";
+        example = "api/all=false,api/v1=true";
+        type = types.str;
+      };
+
+      admissionControl = mkOption {
+        description = ''
+          Kubernetes admission control plugins to use. See
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/admission-controllers.html"/>
+        '';
+        default = ["AlwaysAdmit"];
+        example = [
+          "NamespaceLifecycle" "NamespaceExists" "LimitRanger"
+          "SecurityContextDeny" "ServiceAccount" "ResourceQuota"
+        ];
+        type = types.listOf types.str;
+      };
+
+      serviceAccountKey = mkOption {
+        description = ''
+          Kubernetes apiserver PEM-encoded x509 RSA private or public key file,
+          used to verify ServiceAccount tokens.
+        '';
+        default = null;
+        type = types.nullOr types.path;
+      };
+
       extraOpts = mkOption {
         description = "Kubernetes apiserver extra command line options.";
         default = "";
@@ -222,14 +254,26 @@ in {
         type = types.str;
       };
 
-      machines = mkOption {
-        description = "Kubernetes controller list of machines to schedule to schedule onto";
-        default = [];
-        type = types.listOf types.str;
+      serviceAccountPrivateKey = mkOption {
+        description = ''
+          Kubernetes controller manager PEM-encoded private RSA key file used to
+          sign service account tokens
+        '';
+        default = null;
+        type = types.nullOr types.path;
+      };
+
+      rootCaFile = mkOption {
+        description = ''
+          Kubernetes controller manager certificate authority file included in
+          service account's token secret.
+        '';
+        default = null;
+        type = types.nullOr types.path;
       };
 
       extraOpts = mkOption {
-        description = "Kubernetes controller extra command line options.";
+        description = "Kubernetes controller manager extra command line options.";
         default = "";
         type = types.str;
       };
@@ -260,6 +304,20 @@ in {
         type = types.int;
       };
 
+      healthz = {
+        bind = mkOption {
+          description = "Kubernetes kubelet healthz listening address.";
+          default = "127.0.0.1";
+          type = types.str;
+        };
+
+        port = mkOption {
+          description = "Kubernetes kubelet healthz port.";
+          default = 10248;
+          type = types.int;
+        };
+      };
+
       hostname = mkOption {
         description = "Kubernetes kubelet hostname override";
         default = config.networking.hostName;
@@ -273,7 +331,10 @@ in {
       };
 
       apiServers = mkOption {
-        description = "Kubernetes kubelet list of Kubernetes API servers for publishing events, and reading pods and services.";
+        description = ''
+          Kubernetes kubelet list of Kubernetes API servers for publishing events,
+          and reading pods and services.
+        '';
         default = ["${cfg.apiserver.address}:${toString cfg.apiserver.port}"];
         type = types.listOf types.str;
       };
@@ -374,7 +435,6 @@ in {
             --etcd-servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
             --insecure-bind-address=${cfg.apiserver.address} \
             --insecure-port=${toString cfg.apiserver.port} \
-            --read-only-port=${toString cfg.apiserver.readOnlyPort} \
             --bind-address=${cfg.apiserver.publicAddress} \
             --allow-privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
             ${optionalString (cfg.apiserver.tlsCertFile!="")
@@ -383,22 +443,24 @@ in {
               "--tls-private-key-file=${cfg.apiserver.tlsPrivateKeyFile}"} \
             ${optionalString (cfg.apiserver.tokenAuth!=[])
               "--token-auth-file=${tokenAuthFile}"} \
+            ${optionalString (cfg.apiserver.clientCaFile!="")
+              "--client-ca-file=${cfg.apiserver.clientCaFile}"} \
             --authorization-mode=${cfg.apiserver.authorizationMode} \
             ${optionalString (cfg.apiserver.authorizationMode == "ABAC")
               "--authorization-policy-file=${authorizationPolicyFile}"} \
             --secure-port=${toString cfg.apiserver.securePort} \
             --service-cluster-ip-range=${cfg.apiserver.portalNet} \
+            ${optionalString (cfg.apiserver.runtimeConfig!="")
+              "--runtime-config=${cfg.apiserver.runtimeConfig}"} \
+            --admission_control=${concatStringsSep "," cfg.apiserver.admissionControl} \
+            ${optionalString (cfg.apiserver.serviceAccountKey!=null)
+              "--service-account-key-file=${cfg.apiserver.serviceAccountKey}"} \
             --logtostderr=true \
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.apiserver.extraOpts}
           '';
           User = "kubernetes";
         };
-        postStart = ''
-          until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.apiserver.address}:${toString cfg.apiserver.port}/'; do
-            sleep 1;
-          done
-        '';
       };
     })
 
@@ -431,7 +493,10 @@ in {
             --address=${cfg.controllerManager.address} \
             --port=${toString cfg.controllerManager.port} \
             --master=${cfg.controllerManager.master} \
-            --machines=${concatStringsSep "," cfg.controllerManager.machines} \
+            ${optionalString (cfg.controllerManager.serviceAccountPrivateKey!=null)
+              "--service-account-private-key-file=${cfg.controllerManager.serviceAccountPrivateKey}"} \
+            ${optionalString (cfg.controllerManager.rootCaFile!=null)
+              "--root-ca-file=${cfg.controllerManager.rootCaFile}"} \
             --logtostderr=true \
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.controllerManager.extraOpts}
@@ -454,6 +519,8 @@ in {
             --register-node=${if cfg.kubelet.registerNode then "true" else "false"} \
             --address=${cfg.kubelet.address} \
             --port=${toString cfg.kubelet.port} \
+            --healthz-bind-address=${cfg.kubelet.healthz.bind} \
+            --healthz-port=${toString cfg.kubelet.healthz.port} \
             --hostname-override=${cfg.kubelet.hostname} \
             --allow-privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
             --root-dir=${cfg.dataDir} \
@@ -483,6 +550,8 @@ in {
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.proxy.extraOpts}
           '';
+          Restart = "always"; # Retry connection
+          RestartSec = "5s";
         };
       };
     })
@@ -504,9 +573,6 @@ in {
           User = "kubernetes";
         };
       };
-
-      services.skydns.enable = mkDefault true;
-      services.skydns.domain = mkDefault cfg.kubelet.clusterDomain;
     })
 
     (mkIf (any (el: el == "master") cfg.roles) {
@@ -524,6 +590,9 @@ in {
 
     (mkIf (any (el: el == "node" || el == "master") cfg.roles) {
       services.etcd.enable = mkDefault true;
+
+      services.skydns.enable = mkDefault true;
+      services.skydns.domain = mkDefault cfg.kubelet.clusterDomain;
     })
 
     (mkIf (
@@ -538,8 +607,10 @@ in {
         serviceConfig.Type = "oneshot";
         script = ''
           mkdir -p /var/run/kubernetes
-          chown kubernetes /var/run/kubernetes
-          ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} /var/run/kubernetes/.dockercfg
+          chown kubernetes /var/lib/kubernetes
+
+          rm ${cfg.dataDir}/.dockercfg || true
+          ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} ${cfg.dataDir}/.dockercfg
         '';
       };
 
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 97927055ce37..bae088c6610e 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -154,6 +154,12 @@ in
 
   config = mkIf config.services.postgresql.enable {
 
+    services.postgresql.package =
+      # Note: when changing the default, make it conditional on
+      # ‘system.stateVersion’ to maintain compatibility with existing
+      # systems!
+      mkDefault pkgs.postgresql94;
+
     services.postgresql.authentication = mkAfter
       ''
         # Generated file; do not edit!
@@ -207,6 +213,7 @@ in
 
         serviceConfig =
           { ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
+            ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
             User = "postgres";
             Group = "postgres";
             PermissionsStartOnly = true;
diff --git a/nixos/modules/services/databases/riak.nix b/nixos/modules/services/databases/riak.nix
new file mode 100644
index 000000000000..bee768fa42ae
--- /dev/null
+++ b/nixos/modules/services/databases/riak.nix
@@ -0,0 +1,148 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.riak;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.riak = {
+
+      enable = mkEnableOption "riak";
+
+      package = mkOption {
+        type = types.package;
+        example = literalExample "pkgs.riak2";
+        description = ''
+          Riak package to use.
+        '';
+      };
+
+      nodeName = mkOption {
+        type = types.string;
+        default = "riak@127.0.0.1";
+        description = ''
+          Name of the Erlang node.
+        '';
+      };
+
+      distributedCookie = mkOption {
+        type = types.string;
+        default = "riak";
+        description = ''
+          Cookie for distributed node communication.  All nodes in the
+          same cluster should use the same cookie or they will not be able to
+          communicate.
+        '';
+      };
+
+      dataDir = mkOption {
+        type = types.path;
+        default = "/var/db/riak";
+        description = ''
+          Data directory for Riak.
+        '';
+      };
+
+      logDir = mkOption {
+        type = types.path;
+        default = "/var/log/riak";
+        description = ''
+          Log directory for Riak.
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Additional text to be appended to <filename>riak.conf</filename>.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ cfg.package ];
+    environment.etc."riak/riak.conf".text = ''
+      nodename = ${cfg.nodeName}
+      distributed_cookie = ${cfg.distributedCookie}
+
+      platform_log_dir = ${cfg.logDir}
+      platform_etc_dir = /etc/riak
+      platform_data_dir = ${cfg.dataDir}
+
+      ${cfg.extraConfig}
+    '';
+
+    users.extraUsers.riak = {
+      name = "riak";
+      uid = config.ids.uids.riak;
+      group = "riak";
+      description = "Riak server user";
+    };
+
+    users.extraGroups.riak.gid = config.ids.gids.riak;
+
+    systemd.services.riak = {
+      description = "Riak Server";
+
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+
+      path = [
+        pkgs.utillinux # for `logger`
+        pkgs.bash
+      ];
+
+      environment.RIAK_DATA_DIR = "${cfg.dataDir}";
+      environment.RIAK_LOG_DIR = "${cfg.logDir}";
+      environment.RIAK_ETC_DIR = "/etc/riak";
+
+      preStart = ''
+        if ! test -e ${cfg.logDir}; then
+          mkdir -m 0755 -p ${cfg.logDir}
+          chown -R riak ${cfg.logDir}
+        fi
+
+        if ! test -e ${cfg.dataDir}; then
+          mkdir -m 0700 -p ${cfg.dataDir}
+          chown -R riak ${cfg.dataDir}
+        fi
+      '';
+
+      serviceConfig = {
+        ExecStart = "${cfg.package}/bin/riak console";
+        ExecStop = "${cfg.package}/bin/riak stop";
+        StandardInput = "tty";
+        User = "riak";
+        Group = "riak";
+        PermissionsStartOnly = true;
+        # Give Riak a decent amount of time to clean up.
+        TimeoutStopSec = 120;
+        LimitNOFILE = 65536;
+      };
+
+      unitConfig.RequiresMountsFor = [
+        "${cfg.dataDir}"
+        "${cfg.logDir}"
+        "/etc/riak"
+      ];
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/hardware/freefall.nix b/nixos/modules/services/hardware/freefall.nix
index 6e6960bac491..7867956c1ab0 100644
--- a/nixos/modules/services/hardware/freefall.nix
+++ b/nixos/modules/services/hardware/freefall.nix
@@ -39,11 +39,14 @@ with lib;
     mkService = dev:
       assert dev != "";
       let dev' = utils.escapeSystemdPath dev; in
-      nameValuePair "freefall-${dev'}"
-        { description = "Free-fall protection for ${dev}";
+      nameValuePair "freefall-${dev'}" {
+        description = "Free-fall protection for ${dev}";
         after = [ "${dev'}.device" ];
         wantedBy = [ "${dev'}.device" ];
         path = [ pkgs.freefall ];
+        unitConfig = {
+          DefaultDependencies = false;
+        };
         serviceConfig = {
           ExecStart = "${pkgs.freefall}/bin/freefall ${dev}";
           Restart = "on-failure";
diff --git a/nixos/modules/services/hardware/tcsd.nix b/nixos/modules/services/hardware/tcsd.nix
index 220b154bd97a..d957b5063d38 100644
--- a/nixos/modules/services/hardware/tcsd.nix
+++ b/nixos/modules/services/hardware/tcsd.nix
@@ -17,8 +17,8 @@ let
     # what is available directly from the PCR registers.
     firmware_log_file = /sys/kernel/security/tpm0/binary_bios_measurements
     kernel_log_file = /sys/kernel/security/ima/binary_runtime_measurements
-    #firmware_pcrs = 0,1,2,3,4,5,6,7
-    #kernel_pcrs = 10,11
+    firmware_pcrs = ${cfg.firmwarePCRs}
+    kernel_pcrs = ${cfg.kernelPCRs}
     platform_cred = ${cfg.platformCred}
     conformance_cred = ${cfg.conformanceCred}
     endorsement_cred = ${cfg.endorsementCred}
@@ -60,20 +60,32 @@ in
       };
 
       stateDir = mkOption {
-	default = "/var/lib/tpm";
+        default = "/var/lib/tpm";
         type = types.path;
-	description = ''
+        description = ''
           The location of the system persistent storage file.
           The system persistent storage file holds keys and data across
           restarts of the TCSD and system reboots. 
-	'';
+        '';
+      };
+
+      firmwarePCRs = mkOption {
+        default = "0,1,2,3,4,5,6,7";
+        type = types.string;
+        description = "PCR indices used in the TPM for firmware measurements.";
+      };
+
+      kernelPCRs = mkOption {
+        default = "8,9,10,11,12";
+        type = types.string;
+        description = "PCR indices used in the TPM for kernel measurements.";
       };
 
       platformCred = mkOption {
         default = "${cfg.stateDir}/platform.cert";
         type = types.path;
         description = ''
-	  Path to the platform credential for your TPM. Your TPM
+          Path to the platform credential for your TPM. Your TPM
           manufacturer may have provided you with a set of credentials
           (certificates) that should be used when creating identities
           using your TPM. When a user of your TPM makes an identity,
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index fc89de777e8e..513eb27b4069 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -171,25 +171,23 @@ in
     };
 
     hardware.firmware = mkOption {
-      type = types.listOf types.path;
+      type = types.listOf types.package;
       default = [];
       description = ''
-        List of directories containing firmware files.  Such files
+        List of packages containing firmware files.  Such files
         will be loaded automatically if the kernel asks for them
         (i.e., when it has detected specific hardware that requires
-        firmware to function).  If more than one path contains a
-        firmware file with the same name, the first path in the list
-        takes precedence.  Note that you must rebuild your system if
-        you add files to any of these directories.  For quick testing,
+        firmware to function).  If multiple packages contain firmware
+        files with the same name, the first package in the list takes
+        precedence.  Note that you must rebuild your system if you add
+        files to any of these directories.  For quick testing,
         put firmware files in <filename>/root/test-firmware</filename>
-        and add that directory to the list.  Note that you can also
-        add firmware packages to this list as these are directories in
-        the nix store.
+        and add that directory to the list.
       '';
       apply = list: pkgs.buildEnv {
         name = "firmware";
         paths = list;
-        pathsToLink = [ "/" ];
+        pathsToLink = [ "/lib/firmware" ];
         ignoreCollisions = true;
       };
     };
@@ -236,7 +234,7 @@ in
       (isYes "NET")
     ];
 
-    boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}";
+    boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}/lib/firmware";
 
     system.activationScripts.udevd =
       ''
@@ -254,7 +252,7 @@ in
 
         # Allow the kernel to find our firmware.
         if [ -e /sys/module/firmware_class/parameters/path ]; then
-          echo -n "${config.hardware.firmware}" > /sys/module/firmware_class/parameters/path
+          echo -n "${config.hardware.firmware}/lib/firmware" > /sys/module/firmware_class/parameters/path
         fi
       '';
 
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 50ff1b38db12..fca0d2a7f616 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -10,7 +10,7 @@ let
     ''
       base_dir = /var/run/dovecot2/
 
-      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"}
+      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"}
     ''
     + (if cfg.sslServerCert!="" then
     ''
@@ -70,6 +70,11 @@ in
         description = "Start the IMAP listener (when Dovecot is enabled).";
       };
 
+      enableLmtp = mkOption {
+        default = false;
+        description = "Start the LMTP listener (when Dovecot is enabled).";
+      };
+
       user = mkOption {
         default = "dovecot2";
         description = "Dovecot user name.";
diff --git a/nixos/modules/services/mail/mlmmj.nix b/nixos/modules/services/mail/mlmmj.nix
index db3a266d011f..5843a6745f58 100644
--- a/nixos/modules/services/mail/mlmmj.nix
+++ b/nixos/modules/services/mail/mlmmj.nix
@@ -11,7 +11,7 @@ let
   listCtl = domain: list: "${listDir domain list}/control";
   transport = domain: list: "${domain}--${list}@local.list.mlmmj mlmmj:${domain}/${list}";
   virtual = domain: list: "${list}@${domain} ${domain}--${list}@local.list.mlmmj";
-  alias = domain: list: "${list}: \"|${pkgs.mlmmj}/mlmmj-receive -L ${listDir domain list}/\"";
+  alias = domain: list: "${list}: \"|${pkgs.mlmmj}/bin/mlmmj-receive -L ${listDir domain list}/\"";
   subjectPrefix = list: "[${list}]";
   listAddress = domain: list: "${list}@${domain}";
   customHeaders = list: domain: [ "List-Id: ${list}" "Reply-To: ${list}@${domain}" ];
diff --git a/nixos/modules/services/misc/confd.nix b/nixos/modules/services/misc/confd.nix
index 98738b6497bf..50532a8a16fb 100644
--- a/nixos/modules/services/misc/confd.nix
+++ b/nixos/modules/services/misc/confd.nix
@@ -63,7 +63,7 @@ in {
 
     package = mkOption {
       description = "Confd package to use.";
-      default = pkgs.goPackages.confd;
+      default = pkgs.confd;
       type = types.package;
     };
   };
diff --git a/nixos/modules/services/misc/etcd.nix b/nixos/modules/services/misc/etcd.nix
index 26d2753879d0..e1839b936f01 100644
--- a/nixos/modules/services/misc/etcd.nix
+++ b/nixos/modules/services/misc/etcd.nix
@@ -122,14 +122,6 @@ in {
         mkdir -m 0700 -p ${cfg.dataDir}
         if [ "$(id -u)" = 0 ]; then chown etcd ${cfg.dataDir}; fi
       '';
-      postStart = ''
-        until ${pkgs.etcdctl}/bin/etcdctl set /nixos/state 'up'; do
-          sleep 1;
-        done
-        until ${pkgs.etcdctl}/bin/etcdctl get /nixos/state | grep up; do
-          sleep 1;
-        done
-      '';
     };
 
     environment.systemPackages = [ pkgs.etcdctl ];
diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix
index 56e735d7356b..10a706fbd71d 100644
--- a/nixos/modules/services/misc/gitit.nix
+++ b/nixos/modules/services/misc/gitit.nix
@@ -8,6 +8,8 @@ let
 
   homeDir = "/var/lib/gitit";
 
+  toYesNo = b: if b then "yes" else "no";
+
   gititShared = with cfg.haskellPackages; gitit + "/share/" + pkgs.stdenv.system + "-" + ghc.name + "/" + gitit.pname + "-" + gitit.version;
 
   gititWithPkgs = hsPkgs: extras: hsPkgs.ghcWithPackages (self: with self; [ gitit ] ++ (extras self));
@@ -17,9 +19,6 @@ let
   in writeScript "gitit" ''
     #!${stdenv.shell}
     cd $HOME
-    export PATH="${makeSearchPath "bin" (
-      [ git curl ] ++ (if cfg.pdfExport == "yes" then [texLiveFull] else [])
-      )}:$PATH";
     export NIX_GHC="${env}/bin/ghc"
     export NIX_GHCPKG="${env}/bin/ghc-pkg"
     export NIX_GHC_DOCDIR="${env}/share/doc/ghc/html"
@@ -27,11 +26,7 @@ let
     ${env}/bin/gitit -f ${configFile}
   '';
 
-  gititOptions = let
-
-    yesNo = types.enum [ "yes" "no" ];
-
-  in {
+  gititOptions = {
 
       enable = mkOption {
         type = types.bool;
@@ -40,7 +35,6 @@ let
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellPackages;
         defaultText = "pkgs.haskellPackages";
         example = literalExample "pkgs.haskell.packages.ghc784";
         description = "haskellPackages used to build gitit and plugins.";
@@ -143,7 +137,6 @@ let
 
       staticDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/static";
         description = ''
           Specifies the path of the static directory (containing javascript,
           css, and images).  If it does not exist, gitit will create it and
@@ -204,8 +197,8 @@ let
       };
 
       showLhsBirdTracks = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether to show Haskell code blocks in "bird style", with
           "> " at the beginning of each line.
@@ -214,7 +207,6 @@ let
 
       templatesDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/templates";
         description = ''
           Specifies the path of the directory containing page templates.  If it
           does not exist, gitit will create it with default templates.  Users
@@ -286,8 +278,8 @@ let
       };
 
       tableOfContents = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = ''
           Specifies whether to print a tables of contents (with links to
           sections) on each wiki page.
@@ -295,23 +287,18 @@ let
       };
 
       plugins = mkOption {
-        type = types.path;
-        default = gititShared + "/plugins/Dot.hs";
+        type = with types; listOf str;
         description = ''
-          Specifies a list of plugins to load.  Plugins may be specified either
-          by their path or by their module name.  If the plugin name starts
+          Specifies a list of plugins to load. Plugins may be specified either
+          by their path or by their module name. If the plugin name starts
           with Gitit.Plugin., gitit will assume that the plugin is an installed
           module and will not try to find a source file.
-          Examples:
-          plugins: plugins/DotPlugin.hs, CapitalizeEmphasisPlugin.hs
-          plugins: plugins/DotPlugin
-          plugins: Gitit.Plugin.InterwikiLinks
         '';
       };
 
       useCache = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether to cache rendered pages.  Note that if use-feed is
           selected, feeds will be cached regardless of the value of use-cache.
@@ -342,14 +329,14 @@ let
       };
 
       debugMode = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = "Causes debug information to be logged while gitit is running.";
       };
 
       compressResponses = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = "Specifies whether HTTP responses should be compressed.";
       };
 
@@ -361,16 +348,18 @@ let
           line of the file should contain two fields, separated by whitespace.
           The first field is the mime type, the second is a file extension.
           For example:
-          video/x-ms-wmx                    wmx
+<programlisting>
+video/x-ms-wmx  wmx
+</programlisting>
           If the file is not found, some simple defaults will be used.
         '';
       };
 
       useReCaptcha = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
-          If "yes", causes gitit to use the reCAPTCHA service
+          If true, causes gitit to use the reCAPTCHA service
           (http://recaptcha.net) to prevent bots from creating accounts.
         '';
       };
@@ -475,8 +464,8 @@ let
       };
 
       useFeed = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether an ATOM feed should be enabled (for the site and
           for individual pages).
@@ -488,19 +477,19 @@ let
         default = null;
         description = ''
           The base URL of the wiki, to be used in constructing feed IDs and RPX
-          token_urls.  Set this if use-feed is 'yes' or authentication-method
+          token_urls.  Set this if useFeed is false or authentication-method
           is 'rpx'.
         '';
       };
 
       absoluteUrls = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Make wikilinks absolute with respect to the base-url.  So, for
           example, in a wiki served at the base URL '/wiki', on a page
           Sub/Page, the wikilink '[Cactus]()' will produce a link to
-          '/wiki/Cactus' if absolute-urls is 'yes', and a relative link to
+          '/wiki/Cactus' if absoluteUrls is true, and a relative link to
           'Cactus' (referring to '/wiki/Sub/Cactus') if absolute-urls is 'no'.
         '';
       };
@@ -518,10 +507,10 @@ let
       };
 
       pdfExport = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
-          If yes, PDF will appear in export options. PDF will be created using
+          If true, PDF will appear in export options. PDF will be created using
           pdflatex, which must be installed and in the path. Note that PDF
           exports create significant additional server load.
         '';
@@ -541,10 +530,10 @@ let
       };
 
       xssSanitize = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = ''
-          If yes, all HTML (including that produced by pandoc) is filtered
+          If true, all HTML (including that produced by pandoc) is filtered
           through xss-sanitize.  Set to no only if you trust all of your users.
         '';
       };
@@ -564,7 +553,7 @@ let
     default-page-type: ${cfg.defaultPageType}
     math: ${cfg.math}
     mathjax-script: ${cfg.mathJaxScript}
-    show-lhs-bird-tracks: ${cfg.showLhsBirdTracks}
+    show-lhs-bird-tracks: ${toYesNo cfg.showLhsBirdTracks}
     templates-dir: ${cfg.templatesDir}
     log-file: ${cfg.logFile}
     log-level: ${cfg.logLevel}
@@ -572,16 +561,16 @@ let
     no-delete: ${cfg.noDelete}
     no-edit: ${cfg.noEdit}
     default-summary: ${cfg.defaultSummary}
-    table-of-contents: ${cfg.tableOfContents}
-    plugins: ${cfg.plugins}
-    use-cache: ${cfg.useCache}
+    table-of-contents: ${toYesNo cfg.tableOfContents}
+    plugins: ${concatStringsSep "," cfg.plugins}
+    use-cache: ${toYesNo cfg.useCache}
     cache-dir: ${cfg.cacheDir}
     max-upload-size: ${cfg.maxUploadSize}
     max-page-size: ${cfg.maxPageSize}
-    debug-mode: ${cfg.debugMode}
-    compress-responses: ${cfg.compressResponses}
+    debug-mode: ${toYesNo cfg.debugMode}
+    compress-responses: ${toYesNo cfg.compressResponses}
     mime-types-file: ${cfg.mimeTypesFile}
-    use-recaptcha: ${cfg.useReCaptcha}
+    use-recaptcha: ${toYesNo cfg.useReCaptcha}
     recaptcha-private-key: ${toString cfg.reCaptchaPrivateKey}
     recaptcha-public-key: ${toString cfg.reCaptchaPublicKey}
     access-question: ${cfg.accessQuestion}
@@ -590,14 +579,14 @@ let
     rpx-key: ${toString cfg.rpxKey}
     mail-command: ${cfg.mailCommand}
     reset-password-message: ${cfg.resetPasswordMessage}
-    use-feed: ${cfg.useFeed}
+    use-feed: ${toYesNo cfg.useFeed}
     base-url: ${toString cfg.baseUrl}
-    absolute-urls: ${cfg.absoluteUrls}
+    absolute-urls: ${toYesNo cfg.absoluteUrls}
     feed-days: ${toString cfg.feedDays}
     feed-refresh-time: ${toString cfg.feedRefreshTime}
-    pdf-export: ${cfg.pdfExport}
+    pdf-export: ${toYesNo cfg.pdfExport}
     pandoc-user-data: ${toString cfg.pandocUserData}
-    xss-sanitize: ${cfg.xssSanitize}
+    xss-sanitize: ${toYesNo cfg.xssSanitize}
   '';
 
 in
@@ -608,6 +597,13 @@ in
 
   config = mkIf cfg.enable {
 
+    services.gitit = {
+      haskellPackages = mkDefault pkgs.haskellPackages;
+      staticDir = gititShared + "/data/static";
+      templatesDir = gititShared + "/data/templates";
+      plugins = [ ];
+    };
+
     users.extraUsers.gitit = {
       group = config.users.extraGroups.gitit.name;
       description = "Gitit user";
@@ -625,8 +621,16 @@ in
       description = "Git and Pandoc Powered Wiki";
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
-
-      preStart = with cfg; ''
+      path = with pkgs; [ curl ]
+             ++ optional cfg.pdfExport texLiveFull
+	     ++ optional (cfg.repositoryType == "darcs") darcs
+	     ++ optional (cfg.repositoryType == "mercurial") mercurial
+	     ++ optional (cfg.repositoryType == "git") git;
+
+      preStart = let
+        gm = "gitit@${config.networking.hostName}";
+      in
+      with cfg; ''
         chown ${uid}:${gid} -R ${homeDir}
         for dir in ${repositoryPath} ${staticDir} ${templatesDir} ${cacheDir}
         do
@@ -638,14 +642,35 @@ in
           fi
         done
         cd ${repositoryPath}
-        if [ ! -d  .git ]
-        then
-          ${pkgs.git}/bin/git init
-          ${pkgs.git}/bin/git config user.email "gitit@${config.networking.hostName}"
-          ${pkgs.git}/bin/git config user.name "gitit"
-          chown ${uid}:${gid} -R {repositoryPath}
-        fi
-        cd -
+	${
+	  if repositoryType == "darcs" then
+	  ''
+	  if [ ! -d _darcs ]
+	  then
+	    ${pkgs.darcs}/bin/darcs initialize
+	    echo "${gm}" > _darcs/prefs/email
+	  ''
+	  else if repositoryType == "mercurial" then
+	  ''
+	  if [ ! -d .hg ]
+	  then
+	    ${pkgs.mercurial}/bin/hg init
+	    cat >> .hg/hgrc <<NAMED
+[ui]
+username = gitit ${gm}
+NAMED
+	  ''
+	  else
+	  ''
+	  if [ ! -d  .git ]
+          then
+            ${pkgs.git}/bin/git init
+            ${pkgs.git}/bin/git config user.email "${gm}"
+            ${pkgs.git}/bin/git config user.name "gitit"
+	  ''}
+          chown ${uid}:${gid} -R ${repositoryPath}
+          fi
+	cd -
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index b5a8a7df9fca..4aed91c34978 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -78,8 +78,8 @@ in
         description = ''
           This option defines the maximum number of jobs that Nix will try
           to build in parallel.  The default is 1.  You should generally
-          set it to the number of CPUs in your system (e.g., 2 on an Athlon
-          64 X2).
+          set it to the total number of logical cores in your system (e.g., 16
+          for two CPUs with 4 cores each and hyper-threading).
         '';
       };
 
@@ -254,7 +254,7 @@ in
 
       requireSignedBinaryCaches = mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description = ''
           If enabled, Nix will only download binaries from binary
           caches if they are cryptographically signed with any of the
@@ -309,6 +309,20 @@ in
         '';
       };
 
+      nixPath = mkOption {
+        type = types.listOf types.str;
+        default =
+          [ "/nix/var/nix/profiles/per-user/root/channels/nixos"
+            "nixos-config=/etc/nixos/configuration.nix"
+            "/nix/var/nix/profiles/per-user/root/channels"
+          ];
+        description = ''
+          The default Nix expression search path, used by the Nix
+          evaluator to look up paths enclosed in angle brackets
+          (e.g. <literal>&lt;nixpkgs&gt;</literal>).
+        '';
+      };
+
     };
 
   };
@@ -378,7 +392,9 @@ in
       };
 
     # Set up the environment variables for running Nix.
-    environment.sessionVariables = cfg.envVars;
+    environment.sessionVariables = cfg.envVars //
+      { NIX_PATH = concatStringsSep ":" cfg.nixPath;
+      };
 
     environment.extraInit =
       ''
diff --git a/nixos/modules/services/misc/nix-gc.nix b/nixos/modules/services/misc/nix-gc.nix
index 6a7a7f4cee72..981299352575 100644
--- a/nixos/modules/services/misc/nix-gc.nix
+++ b/nixos/modules/services/misc/nix-gc.nix
@@ -52,7 +52,7 @@ in
 
     systemd.services.nix-gc =
       { description = "Nix Garbage Collector";
-        script = "exec ${config.nix.package}/bin/nix-collect-garbage ${cfg.options}";
+        script = "exec ${config.nix.package}/bin/nix-store --gc ${cfg.options}";
         startAt = optionalString cfg.automatic cfg.dates;
       };
 
diff --git a/nixos/modules/services/misc/rogue.nix b/nixos/modules/services/misc/rogue.nix
index ed8da8a518ff..aae02e384c97 100644
--- a/nixos/modules/services/misc/rogue.nix
+++ b/nixos/modules/services/misc/rogue.nix
@@ -52,6 +52,7 @@ in
             TTYPath = "/dev/${cfg.tty}";
             TTYReset = true;
             TTYVTDisallocate = true;
+            WorkingDirectory = "/tmp";
             Restart = "always";
           };
       };
diff --git a/nixos/modules/services/monitoring/dd-agent.nix b/nixos/modules/services/monitoring/dd-agent.nix
index 3e90393a662d..8c847af3bfc0 100644
--- a/nixos/modules/services/monitoring/dd-agent.nix
+++ b/nixos/modules/services/monitoring/dd-agent.nix
@@ -51,12 +51,37 @@ let
     # ganglia_port: 8651
   '';
 
+  diskConfig = pkgs.writeText "disk.yaml" ''
+    init_config:
+
+    instances:
+      - use_mount: no
+  '';
+  
+  networkConfig = pkgs.writeText "network.yaml" ''
+    init_config:
+
+    instances:
+      # Network check only supports one configured instance
+      - collect_connection_state: false
+        excluded_interfaces:
+          - lo
+          - lo0
+  '';
+  
   postgresqlConfig = pkgs.writeText "postgres.yaml" cfg.postgresqlConfig;
   nginxConfig = pkgs.writeText "nginx.yaml" cfg.nginxConfig;
-
+  mongoConfig = pkgs.writeText "mongo.yaml" cfg.mongoConfig;
+  
   etcfiles =
     [ { source = ddConf;
         target = "dd-agent/datadog.conf";
+      }
+      { source = diskConfig;
+        target = "dd-agent/conf.d/disk.yaml";
+      }
+      { source = networkConfig;
+        target = "dd-agent/conf.d/network.yaml";
       } ] ++
     (optional (cfg.postgresqlConfig != null)
       { source = postgresqlConfig;
@@ -65,6 +90,10 @@ let
     (optional (cfg.nginxConfig != null)
       { source = nginxConfig;
         target = "dd-agent/conf.d/nginx.yaml";
+      }) ++
+    (optional (cfg.mongoConfig != null)
+      { source = mongoConfig;
+        target = "dd-agent/conf.d/mongo.yaml";
       });
 
 in {
@@ -106,6 +135,12 @@ in {
       default = null;
       type = types.uniq (types.nullOr types.string);
     };
+    
+    mongoConfig = mkOption {
+      description = "MongoDB integration configuration";
+      default = null;
+      type = types.uniq (types.nullOr types.string);
+    };
   };
 
   config = mkIf cfg.enable {
@@ -123,7 +158,7 @@ in {
 
     systemd.services.dd-agent = {
       description = "Datadog agent monitor";
-      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps];
+      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
         ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
@@ -132,7 +167,7 @@ in {
         Restart = "always";
         RestartSec = 2;
       };
-      restartTriggers = [ pkgs.dd-agent ddConf postgresqlConfig nginxConfig ];
+      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
     };
 
     systemd.services.dogstatsd = {
@@ -149,7 +184,7 @@ in {
         RestartSec = 2;
       };
       environment.SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
-      restartTriggers = [ pkgs.dd-agent ddConf postgresqlConfig nginxConfig ];
+      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
     };
 
     environment.etc = etcfiles;
diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix
index 6a1799dedc8e..f987c4792e93 100644
--- a/nixos/modules/services/monitoring/grafana.nix
+++ b/nixos/modules/services/monitoring/grafana.nix
@@ -200,13 +200,13 @@ in {
 
     staticRootPath = mkOption {
       description = "Root path for static assets.";
-      default = "${cfg.package}/share/go/src/github.com/grafana/grafana/public";
+      default = "${cfg.package.out}/share/go/src/github.com/grafana/grafana/public";
       type = types.str;
     };
 
     package = mkOption {
       description = "Package to use.";
-      default = pkgs.goPackages.grafana;
+      default = pkgs.grafana-backend;
       type = types.package;
     };
 
@@ -319,7 +319,7 @@ in {
       wantedBy = ["multi-user.target"];
       after = ["networking.target"];
       serviceConfig = {
-        ExecStart = "${cfg.package}/bin/grafana --config ${cfgFile} web";
+        ExecStart = "${cfg.package-backend}/bin/grafana --config ${cfgFile} web";
         WorkingDirectory = cfg.dataDir;
         User = "grafana";
       };
diff --git a/nixos/modules/services/monitoring/scollector.nix b/nixos/modules/services/monitoring/scollector.nix
index 179c587431ea..8b97daf8881a 100644
--- a/nixos/modules/services/monitoring/scollector.nix
+++ b/nixos/modules/services/monitoring/scollector.nix
@@ -20,9 +20,11 @@ let
           cfg.collectors)}
     '';
 
-  cmdLineOpts = concatStringsSep " " (
-    [ "-h=${cfg.bosunHost}" "-c=${collectors}" ] ++ cfg.extraOpts
-  );
+  conf = pkgs.writeText "scollector.toml" ''
+    Host = "${cfg.bosunHost}"
+    ColDir = "${collectors}"
+    ${cfg.extraConfig}
+  '';
 
 in {
 
@@ -92,6 +94,14 @@ in {
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Extra scollector configuration added to the end of scollector.toml
+        '';
+      };
+
     };
 
   };
@@ -108,7 +118,7 @@ in {
         PermissionsStartOnly = true;
         User = cfg.user;
         Group = cfg.group;
-        ExecStart = "${cfg.package}/bin/scollector ${cmdLineOpts}";
+        ExecStart = "${cfg.package}/bin/scollector -conf=${conf} ${lib.concatStringsSep " " cfg.extraOpts}";
       };
     };
 
diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix
index 803bd9e9a65a..61ba16123252 100644
--- a/nixos/modules/services/monitoring/smartd.nix
+++ b/nixos/modules/services/monitoring/smartd.nix
@@ -4,8 +4,66 @@ with lib;
 
 let
 
+  host = config.networking.hostName or "unknown"
+       + optionalString (config.networking.domain != null) ".${config.networking.domain}";
+
   cfg = config.services.smartd;
 
+  nm = cfg.notifications.mail;
+  nw = cfg.notifications.wall;
+  nx = cfg.notifications.x11;
+
+  smartdNotify = pkgs.writeScript "smartd-notify.sh" ''
+    #! ${pkgs.stdenv.shell}
+    ${optionalString nm.enable ''
+      {
+      cat << EOF
+      From: smartd on ${host} <root>
+      To: undisclosed-recipients:;
+      Subject: SMART error on $SMARTD_DEVICESTRING: $SMARTD_FAILTYPE
+
+      $SMARTD_FULLMESSAGE
+      EOF
+
+      ${pkgs.smartmontools}/sbin/smartctl -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE"
+      } | ${nm.mailer} -i "${nm.recipient}"
+    ''}
+    ${optionalString nw.enable ''
+      {
+      cat << EOF
+      Problem detected with disk: $SMARTD_DEVICESTRING
+      Warning message from smartd is:
+
+      $SMARTD_MESSAGE
+      EOF
+      } | ${pkgs.utillinux}/bin/wall 2>/dev/null
+    ''}
+    ${optionalString nx.enable ''
+      export DISPLAY=${nx.display}
+      {
+      cat << EOF
+      Problem detected with disk: $SMARTD_DEVICESTRING
+      Warning message from smartd is:
+
+      $SMARTD_FULLMESSAGE
+      EOF
+      } | ${pkgs.xorg.xmessage}/bin/xmessage -file - 2>/dev/null &
+    ''}
+  '';
+
+  notifyOpts = optionalString (nm.enable || nw.enable || nx.enable)
+    ("-m <nomailer> -M exec ${smartdNotify} " + optionalString cfg.notifications.test "-M test ");
+
+  smartdConf = pkgs.writeText "smartd.conf" ''
+    # Autogenerated smartd startup config file
+    DEFAULT ${notifyOpts}${cfg.defaults.monitored}
+
+    ${concatMapStringsSep "\n" (d: "${d.device} ${d.options}") cfg.devices}
+
+    ${optionalString cfg.autodetect
+       "DEVICESCAN ${notifyOpts}${cfg.defaults.autodetected}"}
+  '';
+
   smartdOpts = { name, ... }: {
 
     options = {
@@ -22,34 +80,11 @@ let
         type = types.separatedString " ";
         description = "Options that determine how smartd monitors the device.";
       };
+
     };
 
   };
 
-  smartdMail = pkgs.writeScript "smartdmail.sh" ''
-    #! ${pkgs.stdenv.shell}
-    TMPNAM=/tmp/smartd-message.$$.tmp
-    if test -n "$SMARTD_ADDRESS"; then
-      echo  >"$TMPNAM" "From: smartd <root>"
-      echo >>"$TMPNAM" 'To: undisclosed-recipients:;'
-      echo >>"$TMPNAM" "Subject: $SMARTD_SUBJECT"
-      echo >>"$TMPNAM"
-      echo >>"$TMPNAM" "Failure on $SMARTD_DEVICESTRING: $SMARTD_FAILTYPE"
-      echo >>"$TMPNAM"
-      cat  >>"$TMPNAM"
-      ${pkgs.smartmontools}/sbin/smartctl >>"$TMPNAM" -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE"
-      /var/setuid-wrappers/sendmail  <"$TMPNAM" -f "$SENDER" -i "$SMARTD_ADDRESS"
-    fi
-  '';
-
-  smartdConf = pkgs.writeText "smartd.conf" (concatMapStrings (device:
-    ''
-      ${device.device} -a -m root -M exec ${smartdMail} ${device.options} ${cfg.deviceOpts}
-    ''
-    ) cfg.devices);
-
-  smartdFlags = if (cfg.devices == []) then "" else "--configfile=${smartdConf}";
-
 in
 
 {
@@ -59,26 +94,104 @@ in
 
     services.smartd = {
 
-      enable = mkOption {
-        default = false;
+      enable = mkEnableOption "smartd daemon from <literal>smartmontools</literal> package";
+
+      autodetect = mkOption {
+        default = true;
         type = types.bool;
-        example = true;
         description = ''
-          Run smartd from the smartmontools package. Note that e-mail
-          notifications will not be enabled unless you configure the list of
-          devices with <varname>services.smartd.devices</varname> as well.
+          Whenever smartd should monitor all devices connected to the
+          machine at the time it's being started (the default).
+
+          Set to false to monitor the devices listed in
+          <option>services.smartd.devices</option> only.
         '';
       };
 
-      deviceOpts = mkOption {
-        default = "";
-        type = types.string;
-        example = "-o on -s (S/../.././02|L/../../7/04)";
-        description = ''
-          Additional options for each device that is monitored. The example
-          turns on SMART Automatic Offline Testing on startup, and schedules short
-          self-tests daily, and long self-tests weekly.
-        '';
+      notifications = {
+
+        mail = {
+          enable = mkOption {
+            default = config.services.mail.sendmailSetuidWrapper != null;
+            type = types.bool;
+            description = "Whenever to send e-mail notifications.";
+          };
+
+          recipient = mkOption {
+            default = "root";
+            type = types.string;
+            description = "Recipient of the notification messages.";
+          };
+
+          mailer = mkOption {
+            default = "/var/setuid-wrappers/sendmail";
+            type = types.path;
+            description = ''
+              Sendmail-compatible binary to be used to send the messages.
+
+              You should probably enable
+              <option>services.postfix</option> or some other MTA for
+              this to work.
+            '';
+          };
+        };
+
+        wall = {
+          enable = mkOption {
+            default = true;
+            type = types.bool;
+            description = "Whenever to send wall notifications to all users.";
+          };
+        };
+
+        x11 = {
+          enable = mkOption {
+            default = config.services.xserver.enable;
+            type = types.bool;
+            description = "Whenever to send X11 xmessage notifications.";
+          };
+
+          display = mkOption {
+            default = ":${toString config.services.xserver.display}";
+            type = types.string;
+            description = "DISPLAY to send X11 notifications to.";
+          };
+        };
+
+        test = mkOption {
+          default = false;
+          type = types.bool;
+          description = "Whenever to send a test notification on startup.";
+        };
+
+      };
+
+      defaults = {
+        monitored = mkOption {
+          default = "-a";
+          type = types.separatedString " ";
+          example = "-a -o on -s (S/../.././02|L/../../7/04)";
+          description = ''
+            Common default options for explicitly monitored (listed in
+            <option>services.smartd.devices</option>) devices.
+
+            The default value turns on monitoring of all the things (see
+            <literal>man 5 smartd.conf</literal>).
+
+            The example also turns on SMART Automatic Offline Testing on
+            startup, and schedules short self-tests daily, and long
+            self-tests weekly.
+          '';
+        };
+
+        autodetected = mkOption {
+          default = cfg.defaults.monitored;
+          type = types.separatedString " ";
+          description = ''
+            Like <option>services.smartd.defaults.monitored</option>, but for the
+            autodetected devices.
+          '';
+        };
       };
 
       devices = mkOption {
@@ -86,14 +199,9 @@ in
         example = [ { device = "/dev/sda"; } { device = "/dev/sdb"; options = "-d sat"; } ];
         type = types.listOf types.optionSet;
         options = [ smartdOpts ];
-        description = ''
-          List of devices to monitor. By default -- if this list is empty --,
-          smartd will monitor all devices connected to the machine at the time
-          it's being run. Configuring this option has the added benefit of
-          enabling e-mail notifications to "root" every time smartd detects an
-          error.
-        '';
-       };
+        description = "List of devices to monitor.";
+      };
+
     };
 
   };
@@ -103,12 +211,19 @@ in
 
   config = mkIf cfg.enable {
 
+    assertions = [ {
+      assertion = cfg.autodetect || cfg.devices != [];
+      message = "smartd can't run with both disabled autodetect and an empty list of devices to monitor.";
+    } ];
+
     systemd.services.smartd = {
       description = "S.M.A.R.T. Daemon";
 
       wantedBy = [ "multi-user.target" ];
 
-      serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
+      path = [ pkgs.nettools ]; # for hostname and dnsdomanname calls in smartd
+
+      serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork --configfile=${smartdConf}";
     };
 
   };
diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix
index 33b7ec3d9f1c..f1838224098b 100644
--- a/nixos/modules/services/network-filesystems/nfsd.nix
+++ b/nixos/modules/services/network-filesystems/nfsd.nix
@@ -88,10 +88,7 @@ in
 
     environment.systemPackages = [ pkgs.nfs-utils ];
 
-    environment.etc = singleton
-      { source = exports;
-        target = "exports";
-      };
+    environment.etc.exports.source = exports;
 
     boot.kernelModules = [ "nfsd" ];
 
diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix
index 36bd29109b8a..69a41ab97963 100644
--- a/nixos/modules/services/networking/copy-com.nix
+++ b/nixos/modules/services/networking/copy-com.nix
@@ -1,53 +1,53 @@
-{ config, lib, pkgs, ... }:

-

-with lib;

-

-let

-  

-  cfg = config.services.copy-com;

-

-in 

-

-{

-  options = {

-

-    services.copy-com = {

-	  

-	  enable = mkOption {

-          default = false;

-          description = "

-            Enable the copy.com client.

-

-            The first time copy.com is run, it needs to be configured. Before enabling run 

-            copy_console manually.

-          ";

-      };

-

-      user = mkOption {

-        description = "The user for which copy should run.";

-      };

-

-      debug = mkOption {

-        default = false;

-        description = "Output more.";

-      };

-	  };

-  };

-

-  config = mkIf cfg.enable {

-    environment.systemPackages = [ pkgs.postfix ];

-

-    systemd.services."copy-com-${cfg.user}" = {

-      description = "Copy.com Client";

-      after = [ "network.target" "local-fs.target" ];

-      wantedBy = [ "multi-user.target" ];

-      serviceConfig = {

-        ExecStart = "${pkgs.copy-com}/bin/copy_console ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";

-        User = "${cfg.user}";

-      };

-

-    };

-  };

-

-}

-

+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.copy-com;
+
+in
+
+{
+  options = {
+
+    services.copy-com = {
+
+	  enable = mkOption {
+          default = false;
+          description = "
+            Enable the Copy.com client.
+            NOTE: before enabling the client for the first time, it must be
+            configured by first running CopyConsole (command line) or CopyAgent
+            (graphical) as the appropriate user.
+          ";
+      };
+
+      user = mkOption {
+        description = "The user for which the Copy.com client should be run.";
+      };
+
+      debug = mkOption {
+        default = false;
+        description = "Output more (debugging) messages to the console.";
+      };
+	  };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.postfix ];
+
+    systemd.services."copy-com-${cfg.user}" = {
+      description = "Copy.com client";
+      after = [ "network.target" "local-fs.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.copy-com}/bin/CopyConsole ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";
+        User = "${cfg.user}";
+      };
+
+    };
+  };
+
+}
+
diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix
index 4a812167bb5f..eb3551515723 100644
--- a/nixos/modules/services/networking/dnsmasq.nix
+++ b/nixos/modules/services/networking/dnsmasq.nix
@@ -98,6 +98,7 @@ in
           ExecStart = "${dnsmasq}/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C ${dnsmasqConf}";
           ExecReload = "${dnsmasq}/bin/kill -HUP $MAINPID";
         };
+        restartTriggers = [ config.environment.etc.hosts.source ];
     };
 
   };
diff --git a/nixos/modules/services/networking/fan.nix b/nixos/modules/services/networking/fan.nix
new file mode 100644
index 000000000000..3170567e5b4a
--- /dev/null
+++ b/nixos/modules/services/networking/fan.nix
@@ -0,0 +1,60 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.networking.fan;
+  modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    networking.fan = {
+
+      enable = mkEnableOption "FAN Networking";
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.fanctl ];
+
+    systemd.services.fan = {
+      description = "FAN Networking";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-online.target" ];
+      before = [ "docker.service" ];
+      restartIfChanged = false;
+      preStart = ''
+        if [ ! -f /proc/sys/net/fan/version ]; then
+          ${modprobe} ipip
+          if [ ! -f /proc/sys/net/fan/version ]; then
+            echo "The Fan Networking patches have not been applied to this kernel!" 1>&2
+            exit 1
+          fi
+        fi
+
+        mkdir -p /var/lib/fan-networking
+      '';
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = "${pkgs.fanctl}/bin/fanctl up -a";
+        ExecStop = "${pkgs.fanctl}/bin/fanctl down -a";
+      };
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 40681f5b957a..a61f0250ef8b 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -420,6 +420,16 @@ in
         '';
     };
 
+    networking.firewall.extraPackages = mkOption {
+      default = [ ];
+      example = [ pkgs.ipset ];
+      description =
+        ''
+          Additional packages to be included in the environment of the system
+          as well as the path of networking.firewall.extraCommands.
+        '';
+    };
+
     networking.firewall.extraStopCommands = mkOption {
       type = types.lines;
       default = "";
@@ -443,7 +453,7 @@ in
 
     networking.firewall.trustedInterfaces = [ "lo" ];
 
-    environment.systemPackages = [ pkgs.iptables pkgs.ipset ];
+    environment.systemPackages = [ pkgs.iptables ] ++ cfg.extraPackages;
 
     boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
     boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
@@ -462,7 +472,7 @@ in
       before = [ "network-pre.target" ];
       after = [ "systemd-modules-load.service" ];
 
-      path = [ pkgs.iptables pkgs.ipset ];
+      path = [ pkgs.iptables ] ++ cfg.extraPackages;
 
       # FIXME: this module may also try to load kernel modules, but
       # containers don't have CAP_SYS_MODULE. So the host system had
diff --git a/nixos/modules/services/networking/gateone.nix b/nixos/modules/services/networking/gateone.nix
new file mode 100644
index 000000000000..93273837181e
--- /dev/null
+++ b/nixos/modules/services/networking/gateone.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ...}:
+with lib;
+let
+  cfg = config.services.gateone;
+in
+{
+options = {
+    services.gateone = {
+      enable = mkEnableOption "GateOne server";
+      pidDir = mkOption {
+        default = "/run/gateone";
+        type = types.path;
+        description = ''Path of pid files for GateOne.'';
+      };
+      settingsDir = mkOption {
+        default = "/var/lib/gateone";
+        type = types.path;
+        description = ''Path of configuration files for GateOne.'';
+      };
+    };
+};
+config = mkIf cfg.enable {
+  environment.systemPackages = with pkgs.pythonPackages; [
+    gateone pkgs.openssh pkgs.procps pkgs.coreutils ];
+
+  users.extraUsers.gateone = {
+    description = "GateOne privilege separation user";
+    uid = config.ids.uids.gateone;
+    home = cfg.settingsDir;
+  };
+  users.extraGroups.gateone.gid = config.ids.gids.gateone;
+
+  systemd.services.gateone = with pkgs; {
+    description = "GateOne web-based terminal";
+    path = [ pythonPackages.gateone nix openssh procps coreutils ];
+    preStart = ''
+      if [ ! -d ${cfg.settingsDir} ] ; then
+        mkdir -m 0750 -p ${cfg.settingsDir}
+        chown -R gateone.gateone ${cfg.settingsDir}
+      fi
+      if [ ! -d ${cfg.pidDir} ] ; then
+        mkdir -m 0750 -p ${cfg.pidDir}
+        chown -R gateone.gateone ${cfg.pidDir}
+      fi
+      '';
+    #unitConfig.RequiresMountsFor = "${cfg.settingsDir}";
+    serviceConfig = {
+      ExecStart = ''${pythonPackages.gateone}/bin/gateone --settings_dir=${cfg.settingsDir} --pid_file=${cfg.pidDir}/gateone.pid --gid=${toString config.ids.gids.gateone} --uid=${toString config.ids.uids.gateone}'';
+      User = "gateone";
+      Group = "gateone";
+      WorkingDirectory = cfg.settingsDir;
+      PermissionsStartOnly = true;
+
+    };
+
+    wantedBy = [ "multi-user.target" ];
+    requires = [ "network.target" ];
+  };
+};
+}
+  
diff --git a/nixos/modules/services/networking/heyefi.nix b/nixos/modules/services/networking/heyefi.nix
new file mode 100644
index 000000000000..fc2b5a848578
--- /dev/null
+++ b/nixos/modules/services/networking/heyefi.nix
@@ -0,0 +1,82 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.heyefi;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.heyefi = {
+
+      enable = mkEnableOption "heyefi";
+
+      cardMacaddress = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card MAC address.
+          '';
+      };
+
+      uploadKey = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card's upload key.
+          '';
+      };
+
+      uploadDir = mkOption {
+        example = "/home/username/pictures";
+        description = ''
+          The directory to upload the files to.
+          '';
+      };
+
+      user = mkOption {
+        default = "root";
+        description = ''
+          heyefi will be run under this user (user must exist,
+          this can be your user name).
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.heyefi =
+      {
+        description = "heyefi service";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "${cfg.user}";
+          Restart = "always";
+          ExecStart = "${pkgs.heyefi}/bin/heyefi";
+        };
+
+      };
+
+    environment.etc."heyefi/heyefi.config".text =
+      ''
+        # /etc/heyefi/heyefi.conf: DO NOT EDIT -- this file has been generated automatically.
+        cards = [["${config.services.heyefi.cardMacaddress}","${config.services.heyefi.uploadKey}"]]
+        upload_dir = "${toString config.services.heyefi.uploadDir}"
+      '';
+
+    environment.systemPackages = [ pkgs.heyefi ];
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/i2p.nix b/nixos/modules/services/networking/i2p.nix
index bad22c791388..e6ee5fd1f957 100644
--- a/nixos/modules/services/networking/i2p.nix
+++ b/nixos/modules/services/networking/i2p.nix
@@ -7,15 +7,7 @@ let
   homeDir = "/var/lib/i2p";
 in {
   ###### interface
-  options.services.i2p = {
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Enables i2p as a running service upon activation.
-        '';
-      };
-  };
+  options.services.i2p.enable = mkEnableOption "I2P router";
 
   ###### implementation
   config = mkIf cfg.enable {
diff --git a/nixos/modules/services/networking/kippo.nix b/nixos/modules/services/networking/kippo.nix
index 68f26eefe27e..7d70a3d05fa7 100644
--- a/nixos/modules/services/networking/kippo.nix
+++ b/nixos/modules/services/networking/kippo.nix
@@ -86,8 +86,7 @@ rec {
       wantedBy = [ "multi-user.target" ];
       environment.PYTHONPATH = "${pkgs.kippo}/src/:${pkgs.pythonPackages.pycrypto}/lib/python2.7/site-packages/:${pkgs.pythonPackages.pyasn1}/lib/python2.7/site-packages/:${pkgs.pythonPackages.python}/lib/python2.7/site-packages/:${pkgs.pythonPackages.twisted}/lib/python2.7/site-packages/:.";
       preStart = ''
-        if [ ! -d ${cfg.varPath}/ ] ; then 
-            mkdir -p ${cfg.pidPath}
+        if [ ! -d ${cfg.varPath}/ ] ; then
             mkdir -p ${cfg.logPath}/tty
             mkdir -p ${cfg.logPath}/dl
             mkdir -p ${cfg.varPath}/keys
@@ -97,12 +96,15 @@ rec {
             cp ${pkgs.kippo}/src/txtcmds ${cfg.varPath} -r
 
             chmod u+rw ${cfg.varPath} -R
-            chmod u+rw ${cfg.pidPath}
             chown kippo.kippo ${cfg.varPath} -R
-            chown kippo.kippo ${cfg.pidPath}
             chown kippo.kippo ${cfg.logPath} -R
             chmod u+rw ${cfg.logPath} -R
         fi
+        if [ ! -d ${cfg.pidPath}/ ] ; then
+            mkdir -p ${cfg.pidPath}
+            chmod u+rw ${cfg.pidPath}
+            chown kippo.kippo ${cfg.pidPath}
+        fi
       '';
 
       serviceConfig.ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd -y ${pkgs.kippo}/src/kippo.tac --syslog --rundir=${cfg.varPath}/ --pidfile=${cfg.pidPath}/kippo.pid --prefix=kippo -n";
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index 579d62884c78..005eb7bd7614 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  quassel = pkgs.kde4.quasselDaemon;
+  quassel = pkgs.quasselDaemon_qt5;
   cfg = config.services.quassel;
   user = if cfg.user != null then cfg.user else "quassel";
 in
diff --git a/nixos/modules/services/networking/racoon.nix b/nixos/modules/services/networking/racoon.nix
index 9428d9112a1b..86e13d1ea0d6 100644
--- a/nixos/modules/services/networking/racoon.nix
+++ b/nixos/modules/services/networking/racoon.nix
@@ -36,7 +36,10 @@ in {
         Type = "forking";
         Restart = "always";
       };
-      preStart = "rm /var/run/racoon.pid || true";
+      preStart = ''
+        rm /var/run/racoon.pid || true
+        mkdir -p /var/racoon
+      '';
     };
   };
 }
diff --git a/nixos/modules/services/networking/shout.nix b/nixos/modules/services/networking/shout.nix
new file mode 100644
index 000000000000..f55b87a96140
--- /dev/null
+++ b/nixos/modules/services/networking/shout.nix
@@ -0,0 +1,80 @@
+{ pkgs, lib, config, options, ... }:
+
+with lib;
+
+let
+  cfg = config.services.shout;
+  shoutHome = "/var/lib/shout";
+
+in {
+  options.services.shout = {
+    enable = mkEnableOption "Shout web IRC client";
+
+    private = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Make your shout instance private. You will need to configure user
+        accounts by adding entries in <filename>${shoutHome}/users</filename>.
+      '';
+    };
+
+    host = mkOption {
+      type = types.string;
+      default = "0.0.0.0";
+      description = "IP interface to listen on for http connections.";
+    };
+
+    port = mkOption {
+      type = types.int;
+      default = 9000;
+      description = "TCP port to listen on for http connections.";
+    };
+
+    configFile = mkOption {
+      type = types.nullOr types.lines;
+      default = null;
+      description = ''
+        Contents of Shout's <filename>config.js</filename> file. If left empty,
+        Shout will generate from its defaults at first startup.
+
+        Documentation: http://shout-irc.com/docs/server/configuration.html
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.extraUsers = singleton {
+      name = "shout";
+      uid = config.ids.uids.shout;
+      description = "Shout daemon user";
+      home = shoutHome;
+      createHome = true;
+    };
+
+    systemd.services.shout = {
+      description = "Shout web IRC client";
+      wantedBy = [ "multi-user.target" ];
+      wants = [ "network-online.target" ];
+      after = [ "network-online.target" ];
+      preStart = if isNull cfg.configFile then null
+                 else ''
+                   ln -sf ${pkgs.writeText "config.js" cfg.configFile} \
+                          ${shoutHome}/config.js
+                 '';
+      script = concatStringsSep " " [
+        "${pkgs.shout}/bin/shout"
+        (if cfg.private then "--private" else "--public")
+        "--port" (toString cfg.port)
+        "--host" (toString cfg.host)
+        "--home" shoutHome
+      ];
+      serviceConfig = {
+        User = "shout";
+        ProtectHome = "true";
+        ProtectSystem = "full";
+        PrivateTmp = "true";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/skydns.nix b/nixos/modules/services/networking/skydns.nix
index 3b9390914891..f5eb452fec62 100644
--- a/nixos/modules/services/networking/skydns.nix
+++ b/nixos/modules/services/networking/skydns.nix
@@ -79,7 +79,7 @@ in {
         ETCD_CACERT = cfg.etcd.caCert;
         SKYDNS_ADDR = cfg.address;
         SKYDNS_DOMAIN = cfg.domain;
-        SKYDNS_NAMESERVER = concatStringsSep "," cfg.nameservers;
+        SKYDNS_NAMESERVERS = concatStringsSep "," cfg.nameservers;
       };
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/skydns";
diff --git a/nixos/modules/services/networking/softether.nix b/nixos/modules/services/networking/softether.nix
new file mode 100644
index 000000000000..49538af7d351
--- /dev/null
+++ b/nixos/modules/services/networking/softether.nix
@@ -0,0 +1,150 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  pkg = pkgs.softether;
+  cfg = config.services.softether;
+
+in
+{
+
+  ###### interface
+
+  options = {
+
+    services.softether = {
+
+      enable = mkEnableOption "SoftEther VPN services";
+
+      vpnserver.enable = mkEnableOption "SoftEther VPN Server";
+
+      vpnbridge.enable = mkEnableOption "SoftEther VPN Bridge";
+
+      vpnclient = {
+        enable = mkEnableOption "SoftEther VPN Client";
+        up = mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            Shell commands executed when the Virtual Network Adapter(s) is/are starting.
+          '';
+        };
+        down = mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            Shell commands executed when the Virtual Network Adapter(s) is/are shutting down.
+          '';
+        };
+      };
+
+      dataDir = mkOption {
+        type = types.string;
+        default = "${pkg.dataDir}";
+        description = ''
+          Data directory for SoftEther VPN.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable (
+
+    mkMerge [{
+      environment.systemPackages = [
+          (pkgs.lib.overrideDerivation pkg (attrs: {
+            dataDir = cfg.dataDir;
+          }))
+        ];
+      jobs.softether = {
+        description = "SoftEther VPN services initial job";
+        startOn = "started network-interfaces";
+        preStart = ''
+            for d in vpnserver vpnbridge vpnclient vpncmd; do
+                if ! test -e ${cfg.dataDir}/$d; then
+                    ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
+                    install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
+                fi
+            done
+            rm -rf ${cfg.dataDir}/vpncmd/vpncmd
+            ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
+        '';
+        exec = "true";
+      };
+    }
+
+    (mkIf (cfg.vpnserver.enable) {
+      systemd.services.vpnserver = {
+        description = "SoftEther VPN Server";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnserver start";
+          ExecStop = "${pkg}/bin/vpnserver stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
+            ln -s ${pkg}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
+        '';
+      };
+    })
+
+    (mkIf (cfg.vpnbridge.enable) {
+      systemd.services.vpnbridge = {
+        description = "SoftEther VPN Bridge";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnbridge start";
+          ExecStop = "${pkg}/bin/vpnbridge stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
+            ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
+        '';
+      };
+    })
+
+    (mkIf (cfg.vpnclient.enable) {
+      systemd.services.vpnclient = {
+        description = "SoftEther VPN Client";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnclient start";
+          ExecStop = "${pkg}/bin/vpnclient stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnclient/vpnclient
+            ln -s ${pkg}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
+        '';
+        postStart = ''
+            sleep 1
+            ${cfg.vpnclient.up}
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnclient/vpnclient
+            sleep 1
+            ${cfg.vpnclient.down}
+        '';
+      };
+      boot.kernelModules = [ "tun" ];
+    })
+
+  ]);
+
+}
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 4be2b5fe0c0c..5baea4bc6aea 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -9,14 +9,6 @@ let
 
   nssModulesPath = config.system.nssModules.path;
 
-  knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
-
-  knownHostsText = flip (concatMapStringsSep "\n") knownHosts
-    (h:
-      concatStringsSep "," h.hostNames + " "
-      + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
-    );
-
   userOptions = {
 
     openssh.authorizedKeys = {
@@ -48,8 +40,7 @@ let
   };
 
   authKeysFiles = let
-    mkAuthKeyFile = u: {
-      target = "ssh/authorized_keys.d/${u.name}";
+    mkAuthKeyFile = u: nameValuePair "ssh/authorized_keys.d/${u.name}" {
       mode = "0444";
       source = pkgs.writeText "${u.name}-authorized_keys" ''
         ${concatStringsSep "\n" u.openssh.authorizedKeys.keys}
@@ -59,7 +50,7 @@ let
     usersWithKeys = attrValues (flip filterAttrs config.users.extraUsers (n: u:
       length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
     ));
-  in map mkAuthKeyFile usersWithKeys;
+  in listToAttrs (map mkAuthKeyFile usersWithKeys);
 
 in
 
@@ -184,16 +175,11 @@ in
       hostKeys = mkOption {
         type = types.listOf types.attrs;
         default =
-          [ { path = "/etc/ssh/ssh_host_dsa_key";
-              type = "dsa";
-            }
-            { path = "/etc/ssh/ssh_host_ecdsa_key";
-              type = "ecdsa";
-              bits = 521;
-            }
-            { path = "/etc/ssh/ssh_host_ed25519_key";
-              type = "ed25519";
-            }
+          [ { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
+            { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+          ] ++ optionals (!versionAtLeast config.system.stateVersion "15.07")
+          [ { type = "dsa"; path = "/etc/ssh/ssh_host_dsa_key"; }
+            { type = "ecdsa"; bits = 521; path = "/etc/ssh/ssh_host_ecdsa_key"; }
           ];
         description = ''
           NixOS can automatically generate SSH host keys.  This option
@@ -216,57 +202,6 @@ in
         description = "Verbatim contents of <filename>sshd_config</filename>.";
       };
 
-      knownHosts = mkOption {
-        default = {};
-        type = types.loaOf types.optionSet;
-        description = ''
-          The set of system-wide known SSH hosts.
-        '';
-        example = [
-          {
-            hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
-            publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub";
-          }
-          {
-            hostNames = [ "myhost2" ];
-            publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub";
-          }
-        ];
-        options = {
-          hostNames = mkOption {
-            type = types.listOf types.str;
-            default = [];
-            description = ''
-              A list of host names and/or IP numbers used for accessing
-              the host's ssh service.
-            '';
-          };
-          publicKey = mkOption {
-            default = null;
-            type = types.nullOr types.str;
-            example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
-            description = ''
-              The public key data for the host. You can fetch a public key
-              from a running SSH server with the <command>ssh-keyscan</command>
-              command. The public key should not include any host names, only
-              the key type and the key itself.
-            '';
-          };
-          publicKeyFile = mkOption {
-            default = null;
-            type = types.nullOr types.path;
-            description = ''
-              The path to the public key file for the host. The public
-              key file is read at build time and saved in the Nix store.
-              You can fetch a public key file from a running SSH server
-              with the <command>ssh-keyscan</command> command. The content
-              of the file should follow the same format as described for
-              the <literal>publicKey</literal> option.
-            '';
-          };
-        };
-      };
-
       moduliFile = mkOption {
         example = "services.openssh.moduliFile = /etc/my-local-ssh-moduli;";
         type = types.path;
@@ -279,7 +214,7 @@ in
 
     };
 
-    users.extraUsers = mkOption {
+    users.users = mkOption {
       options = [ userOptions ];
     };
 
@@ -297,14 +232,8 @@ in
 
     services.openssh.moduliFile = mkDefault "${cfgc.package}/etc/ssh/moduli";
 
-    environment.etc = authKeysFiles ++ [
-      { source = cfg.moduliFile;
-        target = "ssh/moduli";
-      }
-      { text = knownHostsText;
-        target = "ssh/ssh_known_hosts";
-      }
-    ];
+    environment.etc = authKeysFiles //
+      { "ssh/moduli".source = cfg.moduliFile; };
 
     systemd =
       let
@@ -422,11 +351,6 @@ in
 
     assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
                     message = "cannot enable X11 forwarding without setting xauth location";}]
-      ++ flip mapAttrsToList cfg.knownHosts (name: data: {
-        assertion = (data.publicKey == null && data.publicKeyFile != null) ||
-                    (data.publicKey != null && data.publicKeyFile == null);
-        message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
-      })
       ++ flip map cfg.listenAddresses ({ addr, port, ... }: {
         assertion = addr != null;
         message = "addr must be specified in each listenAddresses entry";
diff --git a/nixos/modules/services/networking/syncthing.nix b/nixos/modules/services/networking/syncthing.nix
index 02572c1e27d2..d5accfef1cb5 100644
--- a/nixos/modules/services/networking/syncthing.nix
+++ b/nixos/modules/services/networking/syncthing.nix
@@ -36,9 +36,7 @@ in
       dataDir = mkOption {
         default = "/var/lib/syncthing";
         description = ''
-          Path where the `.syncthing` (settings and keys) and `Sync`
-          (your synced files) directories will exist. This can be your home
-          directory.
+          Path where the settings and keys will exist.
         '';
       };
 
@@ -57,18 +55,12 @@ in
         after = [ "network.target" ];
         wantedBy = [ "multi-user.target" ];
         environment.STNORESTART = "placeholder";  # do not self-restart
-        environment.HOME = "${cfg.dataDir}";
         serviceConfig = {
           User = "${cfg.user}";
           PermissionsStartOnly = true;
           Restart = "always";
-          ExecStart = "${pkgs.syncthing}/bin/syncthing -home=${cfg.dataDir}/.syncthing";
+          ExecStart = "${pkgs.syncthing}/bin/syncthing -no-browser -home=${cfg.dataDir}";
         };
-        preStart = ''
-          mkdir -p ${cfg.dataDir}
-          chown ${cfg.user} ${cfg.dataDir}
-        '';
-
       };
 
     environment.systemPackages = [ pkgs.syncthing ];
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index fd9589883edc..69c76cf97cfd 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -160,6 +160,17 @@ in
         '';
       };
 
+      snmpConf = mkOption {
+        type = types.lines;
+        default = ''
+          Address @LOCAL
+        '';
+        description = ''
+          The contents of <filename>/etc/cups/snmp.conf</filename>. See "man
+          cups-snmp.conf" for a complete description.
+        '';
+      };
+
       drivers = mkOption {
         type = types.listOf types.path;
         example = literalExample "[ pkgs.splix ]";
@@ -199,6 +210,7 @@ in
     environment.etc."cups/cups-files.conf".text = cfg.cupsFilesConf;
     environment.etc."cups/cupsd.conf".text = cfg.cupsdConf;
     environment.etc."cups/cups-browsed.conf".text = cfg.browsedConf;
+    environment.etc."cups/snmp.conf".text = cfg.snmpConf;
 
     services.dbus.packages = [ cups ];
 
@@ -230,8 +242,8 @@ in
           ];
       };
 
-    systemd.services.cups-browsed =
-      { description = "Make remote CUPS printers available locally";
+    systemd.services.cups-browsed = mkIf config.services.avahi.enable
+      { description = "CUPS Remote Printer Discovery";
 
         wantedBy = [ "multi-user.target" ];
         wants = [ "cups.service" "avahi-daemon.service" ];
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 1f42086dc1ec..02d80a77da50 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -4,8 +4,6 @@ with lib;
 
 let
 
-  inherit (config.services) jobsTags;
-
   # Put all the system cronjobs together.
   systemCronJobsFile = pkgs.writeText "system-crontab"
     ''
@@ -25,9 +23,9 @@ let
     sendmailPath = "/var/setuid-wrappers/sendmail";
   };
 
-  allFiles = map (f: "\"${f}\"") (
-    [ "${systemCronJobsFile}" ] ++ config.services.cron.cronFiles
-  );
+  allFiles =
+    optional (config.services.cron.systemCronJobs != []) systemCronJobsFile
+    ++ config.services.cron.cronFiles;
 
 in
 
@@ -91,36 +89,49 @@ in
 
   ###### implementation
 
-  config = mkIf (config.services.cron.enable && allFiles != []) {
+  config = mkMerge [
 
-    security.setuidPrograms = [ "crontab" ];
+    { services.cron.enable = mkDefault (allFiles != []); }
 
-    environment.systemPackages = [ cronNixosPkg ];
+    (mkIf (config.services.cron.enable) {
 
-    systemd.services.cron =
-      { description = "Cron Daemon";
+      security.setuidPrograms = [ "crontab" ];
 
-        wantedBy = [ "multi-user.target" ];
+      environment.systemPackages = [ cronNixosPkg ];
 
-        preStart =
-          ''
-            rm -f /etc/crontab
-            cat ${toString allFiles} > /etc/crontab
-            chmod 0600 /etc/crontab
+      environment.etc.crontab =
+        { source = pkgs.runCommand "crontabs" { inherit allFiles; }
+            ''
+              touch $out
+              for i in $allFiles; do
+                cat "$i" >> $out
+              done
+            '';
+          mode = "0600"; # Cron requires this.
+        };
 
-            mkdir -m 710 -p /var/cron
+      systemd.services.cron =
+        { description = "Cron Daemon";
 
-            # By default, allow all users to create a crontab.  This
-            # is denoted by the existence of an empty cron.deny file.
-            if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
-                touch /var/cron/cron.deny
-            fi
-          '';
+          wantedBy = [ "multi-user.target" ];
 
-        restartTriggers = [ config.environment.etc.localtime.source ];
-        serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
-      };
+          preStart =
+            ''
+              mkdir -m 710 -p /var/cron
 
-  };
+              # By default, allow all users to create a crontab.  This
+              # is denoted by the existence of an empty cron.deny file.
+              if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
+                  touch /var/cron/cron.deny
+              fi
+            '';
+
+          restartTriggers = [ config.environment.etc.localtime.source ];
+          serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
+        };
+
+    })
+
+  ];
 
 }
diff --git a/nixos/modules/services/security/hologram.nix b/nixos/modules/services/security/hologram.nix
index f9abf38942f4..58f308df7a21 100644
--- a/nixos/modules/services/security/hologram.nix
+++ b/nixos/modules/services/security/hologram.nix
@@ -95,7 +95,7 @@ in {
       wantedBy    = [ "multi-user.target" ];
 
       serviceConfig = {
-        ExecStart = "${pkgs.goPackages.hologram}/bin/hologram-server --debug --conf ${cfgFile}";
+        ExecStart = "${pkgs.hologram}/bin/hologram-server --debug --conf ${cfgFile}";
       };
     };
   };
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index 5c20901427cb..77427ce9606e 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -73,6 +73,7 @@ in
       enable = mkOption {
         type = types.bool;
         default = true;
+        internal = true;
         description = ''
           Whether to start the D-Bus message bus daemon, which is
           required by many other system services and applications.
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index fe50c182bfe5..b16f701a0c9f 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -11,7 +11,9 @@ let
     ${cfg.config}
     ${optionalString (cfg.httpConfig != "") ''
     http {
-      ${cfg.httpConfig}
+    ${cfg.httpConfig}
+    ${cfg.httpServers}
+    ${cfg.httpDefaultServer}
     }
     ''}
     ${cfg.appendConfig}
@@ -60,7 +62,32 @@ in
       httpConfig = mkOption {
         type = types.lines;
         default = "";
-        description = "Configuration lines to be appended inside of the http {} block.";
+        description = ''
+          Configuration lines to be placed at the top inside of
+          the http {} block. The option is intended to be used for
+          the default configuration of the servers.
+        '';
+      };
+
+      httpServers = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Configuration lines to be placed inside of the http {}
+          block. The option is intended to be used for defining
+          individual servers.
+        '';
+      };
+
+      httpDefaultServer = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Configuration lines to be placed at the bottom inside of
+          the http {} block. The option is intended to be used for
+          setting up the default servers. The default server is used
+          if no previously specified server matches a request.
+        '';
       };
 
       stateDir = mkOption {
diff --git a/nixos/modules/services/web-servers/nginx/reverse_proxy.nix b/nixos/modules/services/web-servers/nginx/reverse_proxy.nix
new file mode 100644
index 000000000000..c21406dff29a
--- /dev/null
+++ b/nixos/modules/services/web-servers/nginx/reverse_proxy.nix
@@ -0,0 +1,233 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.nginx;
+
+  defaultSSL = cfg.httpDefaultKey != null || cfg.httpDefaultCertificate != null;
+
+  validSSL = key: cert: cert != null && key != null || cert == null && key == null;
+
+in
+
+{
+  options = {
+
+    services.nginx = {
+
+      reverseProxies = mkOption {
+        type = types.attrsOf (types.submodule (
+          {
+            options = {
+              proxy = mkOption {
+                type = types.str;
+                default = [];
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+
+              key = mkOption {
+                type = types.nullOr types.path;
+                default = null;
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+
+              certificate = mkOption {
+                type = types.nullOr types.path;
+                default = null;
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+            };
+          }
+        ));
+
+        default = {};
+
+        example = literalExample ''
+          {
+            "hydra.yourdomain.org" =
+              { proxy = "localhost:3000";
+                key = "/etc/nixos/certs/hydra_key.key";
+                certificate = "/etc/nixos/certs/hydra_cert.crt";
+              };
+          }
+        '';
+
+        description = ''
+          A reverse proxy server configuration is created for every attribute.
+          The attribute name corresponds to the name the server is listening to,
+          and the proxy option defines the target to forward the requests to.
+          If a key and certificate are given, then the server is secured through
+          a SSL connection. Non-SSL requests on port 80 are automatically
+          re-directed to the SSL server on port 443.
+        '';
+      };
+
+      httpDefaultKey = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/etc/nixos/certs/defaut_key.key";
+        description = ''
+           Key of SSL certificate for default server.
+           The default certificate is presented by the default server during
+           the SSL handshake when no specialized server configuration matches
+           a request.
+           A default SSL certificate is also helpful if browsers do not
+           support the TLS Server Name Indication extension (SNI, RFC 6066).
+        '';
+      };
+
+      httpDefaultCertificate = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/etc/nixos/certs/defaut_key.crt";
+        description = ''
+           SSL certificate for default server.
+           The default certificate is presented by the default server during
+           the SSL handshake when no specialized server configuration matches
+           a request.
+           A default SSL certificate is also helpful if browsers do not
+           support the TLS Server Name Indication extension (SNI, RFC 6066).
+        '';
+      };
+
+    };
+
+  };
+
+
+  config = mkIf (cfg.reverseProxies != {}) {
+
+    assertions = [
+      { assertion = all id (mapAttrsToList (n: v: validSSL v.certificate v.key) cfg.reverseProxies);
+        message = ''
+          One (or more) reverse proxy configurations specify only either
+          the key option or the certificate option. Both certificate
+          with associated key have to be configured to enable SSL for a
+          server configuration.
+
+          services.nginx.reverseProxies: ${toString cfg.reverseProxies}
+        '';
+      }
+      { assertion = validSSL cfg.httpDefaultCertificate cfg.httpDefaultKey;
+        message = ''
+          The default server configuration specifies only either the key
+          option or the certificate option. Both httpDefaultCertificate
+          with associated httpDefaultKey have to be configured to enable
+          SSL for the default server configuration.
+
+          services.nginx.httpDefaultCertificate: ${toString cfg.httpDefaultCertificate}
+
+          services.nginx.httpDefaultKey : ${toString cfg.httpDefaultKey}
+        '';
+      }
+    ];
+
+    services.nginx.config = mkBefore ''
+      worker_processes 1;
+      error_log logs/error.log debug;
+      pid logs/nginx.pid;
+      events {
+         worker_connections  1024;
+      }
+    '';
+
+    services.nginx.httpConfig = mkBefore ''
+      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                '$status $body_bytes_sent "$http_referer" '
+                '"$http_user_agent" "$http_x_forwarded_for"';
+      access_log  logs/access.log  main;
+      sendfile        on;
+      tcp_nopush      on;
+      keepalive_timeout  10;
+      gzip            on;
+
+      ${lib.optionalString defaultSSL ''
+      ssl_session_cache    shared:SSL:10m;
+      ssl_session_timeout  10m;
+      ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
+      ssl_ciphers          HIGH:!aNULL:!MD5;
+      ssl_certificate      ${cfg.httpDefaultCertificate};
+      ssl_certificate_key  ${cfg.httpDefaultKey};
+      ''}
+    '';
+
+    services.nginx.httpDefaultServer = mkBefore ''
+      # reject as default policy
+      server {
+          listen 80 default_server;
+          listen [::]:80 default_server;
+          ${lib.optionalString defaultSSL "listen 443 default_server ssl;"}
+          return      444;
+      }
+    '';
+
+    services.nginx.httpServers =
+      let
+        useSSL = certificate: key: certificate != null && key != null;
+
+        server = servername: proxy: certificate: key: useSSL: ''
+          server {
+            server_name ${servername};
+            keepalive_timeout    70;
+
+            ${if !useSSL then ''
+            listen 80;
+            listen [::]:80;
+            '' else ''
+            listen 443 ssl;
+            ssl_session_cache    shared:SSL:10m;
+            ssl_session_timeout  10m;
+            ssl_certificate      ${certificate};
+            ssl_certificate_key  ${key};
+            ''}
+
+            location / {
+              proxy_pass ${proxy};
+
+              ### force timeouts if one of backend is dead ##
+              proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
+
+              ### Set headers ####
+              proxy_set_header        Accept-Encoding   "";
+              proxy_set_header        Host            $host;
+              proxy_set_header        X-Real-IP       $remote_addr;
+              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+
+              ${lib.optionalString useSSL ''
+              ### Most PHP, Python, Rails, Java App can use this header ###
+              #proxy_set_header X-Forwarded-Proto https;##
+              #This is better##
+              proxy_set_header        X-Forwarded-Proto $scheme;
+              add_header              Front-End-Https   on;
+              ''}
+
+              ### By default we don't want to redirect it ####
+              proxy_redirect     off;
+              proxy_buffering    off;
+            }
+          }
+
+          ${lib.optionalString useSSL ''
+          # redirect http to https
+          server {
+              listen 80;
+              listen [::]:80;
+              server_name ${servername};
+              return 301 https://$server_name$request_uri;
+          }
+          ''}
+        '';
+      in
+      concatStrings (mapAttrsToList (n: v: server n v.proxy v.certificate v.key (useSSL v.proxy v.certificate)) cfg.reverseProxies);
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/e19.nix b/nixos/modules/services/x11/desktop-managers/e19.nix
index 2d5c7b192bc6..74065c862ef7 100644
--- a/nixos/modules/services/x11/desktop-managers/e19.nix
+++ b/nixos/modules/services/x11/desktop-managers/e19.nix
@@ -62,6 +62,7 @@ in
         waitPID=$!
       '';
     }];
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidPrograms = [ "e19_freqset" ];
 
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index cf6d2cab3492..507c2d2da139 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -25,6 +25,24 @@ let
     '';
   };
 
+  nixos-gsettings-desktop-schemas = pkgs.stdenv.mkDerivation {
+    name = "nixos-gsettings-desktop-schemas";
+    buildInputs = [ pkgs.nixos-artwork ];
+    buildCommand = ''
+     mkdir -p $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas
+     cp -rf ${gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0 $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/
+     chmod -R a+w $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas
+     cat - > $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
+       [org.gnome.desktop.background]
+       picture-uri='${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png'
+
+       [org.gnome.desktop.screensaver]
+       picture-uri='${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png'
+     EOF
+     ${pkgs.glib}/bin/glib-compile-schemas $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/glib-2.0/schemas/
+    '';
+  };
+
 in {
 
   options = {
@@ -40,7 +58,7 @@ in {
       example = literalExample "[ pkgs.gnome3.gpaste ]";
       description = "Additional list of packages to be added to the session search path.
                      Useful for gnome shell extensions or gsettings-conditionated autostart.";
-      apply = list: list ++ [ gnome3.gnome_shell ]; 
+      apply = list: list ++ [ gnome3.gnome_shell gnome3.gnome-shell-extensions ];
     };
 
     environment.gnome3.packageSet = mkOption {
@@ -81,6 +99,7 @@ in {
     networking.networkmanager.enable = mkDefault true;
     services.upower.enable = config.powerManagement.enable;
     hardware.bluetooth.enable = mkDefault true;
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = false; # true doesn't make sense here, GNOME just doesn't handle it anymore
 
     fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
 
@@ -109,6 +128,9 @@ in {
           # Override default mimeapps
           export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${mimeAppsList}/share
 
+          # Override gsettings-desktop-schema
+          export XDG_DATA_DIRS=${nixos-gsettings-desktop-schemas}/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS
+
           # Let nautilus find extensions
           export NAUTILUS_EXTENSION_DIR=${config.system.path}/lib/nautilus/extensions-3.0/
 
diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix
index 21b6243ba188..7830e984219a 100644
--- a/nixos/modules/services/x11/desktop-managers/kde4.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde4.nix
@@ -111,6 +111,7 @@ in
             exec ${kde_workspace}/bin/startkde
           '';
       };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidOwners = singleton
       { program = "kcheckpass";
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 5061d59b7c7f..01a8704fea71 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -78,6 +78,7 @@ in
       bgSupport = true;
       start = ''exec ${plasma5.plasma-workspace}/bin/startkde;'';
     };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidOwners = singleton {
       program = "kcheckpass";
diff --git a/nixos/modules/services/x11/desktop-managers/kodi.nix b/nixos/modules/services/x11/desktop-managers/kodi.nix
index 1e30308a5139..e6d6efaf3a61 100644
--- a/nixos/modules/services/x11/desktop-managers/kodi.nix
+++ b/nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -25,7 +25,8 @@ in
         waitPID=$!
       '';
     }];
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     environment.systemPackages = [ pkgs.kodi ];
   };
-}
\ No newline at end of file
+}
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index fce5bf11f053..746f810a11ff 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -37,6 +37,7 @@ in
             exec ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc}
           '';
       };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     environment.systemPackages =
       [ pkgs.gtk # To get GTK+'s themes.
@@ -62,7 +63,7 @@ in
         pkgs.xfce.xfwm4
         # This supplies some "abstract" icons such as
         # "utilities-terminal" and "accessories-text-editor".
-        pkgs.gnome.gnomeicontheme
+        pkgs.gnome3.defaultIconTheme
         pkgs.desktop_file_utils
         pkgs.xfce.libxfce4ui
         pkgs.xfce.garcon
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 7e05cd84be64..fc0803f2acaf 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -62,7 +62,7 @@ let
         if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
           export _INHIBITION_LOCK_TAKEN=1
           if ! ${config.systemd.package}/bin/loginctl show-session $XDG_SESSION_ID | grep -q '^RemoteHost='; then
-            exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key --why="See NixOS configuration option 'services.xserver.displayManager.desktopManagerHandlesLidAndPower' for more information." "$0" "$sessionType"
+            exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key --why="Desktop environment handles power events" "$0" "$sessionType"
           fi
         fi
 
@@ -161,7 +161,11 @@ let
       exit 0
     '';
 
-  mkDesktops = names: pkgs.runCommand "desktops" {}
+  mkDesktops = names: pkgs.runCommand "desktops"
+    { # trivial derivation
+      preferLocalBuild = true;
+      allowSubstitutes = false;
+    }
     ''
       mkdir -p $out
       ${concatMapStrings (n: ''
@@ -225,7 +229,7 @@ in
 
       desktopManagerHandlesLidAndPower = mkOption {
         type = types.bool;
-        default = true;
+        default = false;
         description = ''
           Whether the display manager should prevent systemd from handling
           lid and power events. This is normally handled by the desktop
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index 6c3c52730863..55af2ecbb764 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -18,14 +18,45 @@ in
 
     services.xserver.displayManager.gdm = {
 
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        example = true;
+      enable = mkEnableOption ''
+        GDM as the display manager.
+        <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+      '';
+
+      autoLogin = mkOption {
+        default = {};
         description = ''
-          Whether to enable GDM as the display manager.
-          <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+          Auto login configuration attrset.
         '';
+
+        type = types.submodule {
+          options = {
+            enable = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                Automatically log in as the sepecified <option>autoLogin.user</option>.
+              '';
+            };
+
+            user = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                User to be used for the autologin.
+              '';
+            };
+
+            delay = mkOption {
+              type = types.int;
+              default = 0;
+              description = ''
+                Seconds of inactivity after which the autologin will be performed.
+              '';
+            };
+
+          };
+        };
       };
 
     };
@@ -37,6 +68,13 @@ in
 
   config = mkIf cfg.gdm.enable {
 
+    assertions = [
+      { assertion = let autoLogin = cfg.gdm.autoLogin; in
+          if autoLogin.enable then autoLogin.user != null else true;
+        message = "GDM auto-login requires services.xserver.displayManager.gdm.autoLogin.user to be set";
+      }
+    ];
+
     services.xserver.displayManager.slim.enable = false;
 
     users.extraUsers.gdm =
@@ -50,7 +88,7 @@ in
     users.extraGroups.gdm.gid = config.ids.gids.gdm;
 
     services.xserver.displayManager.job =
-      { 
+      {
         environment = {
           GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}";
           GDM_SESSIONS_DIR = "${cfg.session.desktops}";
@@ -71,6 +109,25 @@ in
 
     programs.dconf.profiles.gdm = "${gdm}/share/dconf/profile/gdm";
 
+    environment.etc."gdm/custom.conf".text = ''
+      [daemon]
+      ${optionalString cfg.gdm.autoLogin.enable ''
+      TimedLoginEnable=true
+      TimedLogin=${cfg.gdm.autoLogin.user}
+      TimedLoginDelay=${toString cfg.gdm.autoLogin.delay}
+      ''}
+
+      [security]
+
+      [xdmcp]
+
+      [greeter]
+
+      [chooser]
+
+      [debug]
+    '';
+
     # GDM LFS PAM modules, adapted somehow to NixOS
     security.pam.services = {
       gdm-launch-environment.text = ''
@@ -89,7 +146,7 @@ in
         session  optional       pam_permit.so
       '';
 
-     gdm.text = ''
+      gdm.text = ''
         auth     requisite      pam_nologin.so
         auth     required       pam_env.so
 
@@ -130,7 +187,7 @@ in
           "auth     required       pam_deny.so"}
 
         account  sufficient     pam_unix.so
-        
+
         password requisite      pam_unix.so nullok sha512
         ${optionalString config.security.pam.enableEcryptfs
           "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index 99d19f6ab151..4f39e05f0f8d 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -47,6 +47,13 @@ in {
         type = types.str;
       };
     };
+
+    services.redshift.extraOptions = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = [ "-v" "-m randr" ];
+      description = "Additional command-line arguments to pass to the redshift(1) command";
+    };
   };
 
   config = mkIf cfg.enable {
@@ -59,7 +66,8 @@ in {
         ${pkgs.redshift}/bin/redshift \
           -l ${cfg.latitude}:${cfg.longitude} \
           -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \
-          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night}
+          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \
+          ${lib.strings.concatStringsSep " " cfg.extraOptions}
       '';
       environment = { DISPLAY = ":0"; };
       serviceConfig.Restart = "always";
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index a8b1044ad365..4751de07a15d 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -25,6 +25,7 @@ in
     ./windowmaker.nix
     ./wmii.nix
     ./xmonad.nix
+    ./qtile.nix
     ./none.nix ];
 
   options = {
diff --git a/nixos/modules/services/x11/window-managers/icewm.nix b/nixos/modules/services/x11/window-managers/icewm.nix
index 36028da453a5..9a3e80221890 100644
--- a/nixos/modules/services/x11/window-managers/icewm.nix
+++ b/nixos/modules/services/x11/window-managers/icewm.nix
@@ -3,29 +3,16 @@
 with lib;
 
 let
-
   cfg = config.services.xserver.windowManager.icewm;
-
 in
-
 {
-
   ###### interface
-
   options = {
-
-    services.xserver.windowManager.icewm.enable = mkOption {
-      default = false;
-      description = "Enable the IceWM window manager.";
-    };
-
+    services.xserver.windowManager.icewm.enable = mkEnableOption "oroborus";
   };
 
-
   ###### implementation
-
   config = mkIf cfg.enable {
-
     services.xserver.windowManager.session = singleton
       { name = "icewm";
         start =
@@ -36,7 +23,5 @@ in
       };
 
     environment.systemPackages = [ pkgs.icewm ];
-
   };
-
 }
diff --git a/nixos/modules/services/x11/window-managers/oroborus.nix b/nixos/modules/services/x11/window-managers/oroborus.nix
new file mode 100644
index 000000000000..bd7e3396864b
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/oroborus.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.oroborus;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.oroborus.enable = mkEnableOption "oroborus";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "oroborus";
+      start = ''
+        ${pkgs.oroborus}/bin/oroborus &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.oroborus ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix
new file mode 100644
index 000000000000..37f84f0903c3
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/qtile.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.qtile;
+in
+
+{
+  options = {
+    services.xserver.windowManager.qtile.enable = mkEnableOption "qtile";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = [{
+      name = "qtile";
+      start = ''
+        ${pkgs.qtile}/bin/qtile
+        waitPID=$!
+      '';
+    }];
+    
+    environment.systemPackages = [ pkgs.qtile ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/wmii.nix b/nixos/modules/services/x11/window-managers/wmii.nix
index 75f6fdfe3bc4..e6f534a1be66 100644
--- a/nixos/modules/services/x11/window-managers/wmii.nix
+++ b/nixos/modules/services/x11/window-managers/wmii.nix
@@ -1,47 +1,43 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
+{ config, lib, pkgs, options, modulesPath }:
 
 let
-
+  inherit (lib) mkOption mkIf singleton;
   cfg = config.services.xserver.windowManager.wmii;
-
+  wmii = pkgs.wmii_hg;
 in
-
 {
   options = {
-
     services.xserver.windowManager.wmii.enable = mkOption {
       default = false;
       example = true;
       description = "Enable the wmii window manager.";
     };
-
   };
 
   config = mkIf cfg.enable {
-
     services.xserver.windowManager.session = singleton
       # stop wmii by
       #   $wmiir xwrite /ctl quit
       # this will cause wmii exiting with exit code 0
+      # (or "mod+a quit", which is bound to do the same thing in wmiirc
+      # by default)
       #
       # why this loop?
       # wmii crashes once a month here. That doesn't matter that much
-      # wmii can recover very well. However without loop the x session terminates and then your workspace setup is
-      # lost and all applications running on X will terminate.
+      # wmii can recover very well. However without loop the X session
+      # terminates and then your workspace setup is lost and all
+      # applications running on X will terminate.
       # Another use case is kill -9 wmii; after rotating screen.
-      # Note: we don't like kill for that purpose. But it works (-> subject "wmii and xrandr" on mailinglist)
+      # Note: we don't like kill for that purpose. But it works (->
+      # subject "wmii and xrandr" on mailinglist)
       { name = "wmii";
         start = ''
           while :; do
-            ${pkgs.wmiiSnap}/bin/wmii && break
+            ${wmii}/bin/wmii && break
           done
         '';
       };
 
-    environment.systemPackages = [ pkgs.wmiiSnap ];
-
+    environment.systemPackages = [ wmii ];
   };
-
 }
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 4289740322ad..655fbab2a843 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -97,7 +97,7 @@ sub parseFstab {
 sub parseUnit {
     my ($filename) = @_;
     my $info = {};
-    parseKeyValues($info, read_file($filename));
+    parseKeyValues($info, read_file($filename)) if -f $filename;
     parseKeyValues($info, read_file("${filename}.d/overrides.conf")) if -f "${filename}.d/overrides.conf";
     return $info;
 }
@@ -157,7 +157,8 @@ while (my ($unit, $state) = each %{$activePrev}) {
 
     if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
         if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
-            $unitsToStop{$unit} = 1;
+            my $unitInfo = parseUnit($prevUnitFile);
+            $unitsToStop{$unit} = 1 if boolIsTrue($unitInfo->{'X-StopOnRemoval'} // "yes");
         }
 
         elsif ($unit =~ /\.target$/) {
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 839300798167..a977ddb7bb4d 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -50,7 +50,7 @@ let
 
         ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd
 
-        ln -s ${config.hardware.firmware} $out/firmware
+        ln -s ${config.hardware.firmware}/lib/firmware $out/firmware
       ''}
 
       echo "$activationScript" > $out/activate
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index 63a095be6311..ac40e8a49acf 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -49,9 +49,8 @@ in
       type = types.int;
       default = 4;
       description = ''
-        The kernel console log level.  Only log messages with a
-        priority numerically less than this will appear on the
-        console.
+        The kernel console log level.  Log messages with a priority
+        numerically less than this will not appear on the console.
       '';
     };
 
@@ -217,7 +216,7 @@ in
       ];
 
     # The Linux kernel >= 2.6.27 provides firmware.
-    hardware.firmware = [ "${kernel}/lib/firmware" ];
+    hardware.firmware = [ kernel ];
 
     # Create /etc/modules-load.d/nixos.conf, which is read by
     # systemd-modules-load.service to load required kernel modules.
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
index 261192c6d24e..c5c250c14cea 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix
@@ -3,6 +3,7 @@
 pkgs.substituteAll {
   src = ./extlinux-conf-builder.sh;
   isExecutable = true;
-  inherit (pkgs) bash;
   path = [pkgs.coreutils pkgs.gnused pkgs.gnugrep];
+  inherit (pkgs) bash;
+  kernelDTB = pkgs.stdenv.platform.kernelDTB or false;
 }
diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
index 8f2a496de8b6..b9a42b2a196d 100644
--- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
+++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh
@@ -75,8 +75,10 @@ addEntry() {
 
     copyToKernelsDir "$path/kernel"; kernel=$result
     copyToKernelsDir "$path/initrd"; initrd=$result
-    # XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
-    copyToKernelsDir $(readlink -m "$path/kernel/../dtbs"); dtbs=$result
+    if [ -n "@kernelDTB@" ]; then
+        # XXX UGLY: maybe the system config should have a top-level "dtbs" entry?
+        copyToKernelsDir $(readlink -m "$path/kernel/../dtbs"); dtbs=$result
+    fi
 
     timestampEpoch=$(stat -L -c '%Z' $path)
 
@@ -93,7 +95,9 @@ addEntry() {
     fi
     echo "  LINUX ../nixos/$(basename $kernel)"
     echo "  INITRD ../nixos/$(basename $initrd)"
-    echo "  FDTDIR ../nixos/$(basename $dtbs)"
+    if [ -n "@kernelDTB@" ]; then
+        echo "  FDTDIR ../nixos/$(basename $dtbs)"
+    fi
     echo "  APPEND systemConfig=$path init=$path/init $extraParams"
 }
 
@@ -105,20 +109,24 @@ cat > $tmpFile <<EOF
 # Change this to e.g. nixos-42 to temporarily boot to an older configuration.
 DEFAULT nixos-default
 
+MENU TITLE ------------------------------------------------------------
 TIMEOUT $timeout
-$(addEntry $default default)
 EOF
 
-# Add up to $numGenerations generations of the system profile to the menu,
-# in reverse (most recent to least recent) order.
-for generation in $(
-        (cd /nix/var/nix/profiles && ls -d system-*-link) \
-        | sed 's/system-\([0-9]\+\)-link/\1/' \
-        | sort -n -r \
-        | head -n $numGenerations); do
-    link=/nix/var/nix/profiles/system-$generation-link
-    addEntry $link $generation
-done >> $tmpFile
+addEntry $default default >> $tmpFile
+
+if [ "$numGenerations" -gt 0 ]; then
+    # Add up to $numGenerations generations of the system profile to the menu,
+    # in reverse (most recent to least recent) order.
+    for generation in $(
+            (cd /nix/var/nix/profiles && ls -d system-*-link) \
+            | sed 's/system-\([0-9]\+\)-link/\1/' \
+            | sort -n -r \
+            | head -n $numGenerations); do
+        link=/nix/var/nix/profiles/system-$generation-link
+        addEntry $link $generation
+    done >> $tmpFile
+fi
 
 mv -f $tmpFile $target/extlinux/extlinux.conf
 
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index c7cf712e3c2b..0b349749244f 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -10,7 +10,7 @@ let
 
   realGrub = if cfg.version == 1 then pkgs.grub
     else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
-    else if cfg.enableTrustedboot then pkgs.trustedGrub
+    else if cfg.enableTrustedBoot then pkgs.trustedGrub
            else pkgs.grub2;
 
   grub =
@@ -112,7 +112,7 @@ in
         description = ''
           The devices on which the boot loader, GRUB, will be
           installed. Can be used instead of <literal>device</literal> to
-          install grub into multiple devices (e.g., if as softraid arrays holding /boot).
+          install GRUB onto multiple devices.
         '';
       };
 
@@ -135,8 +135,8 @@ in
             example = "/boot1";
             type = types.str;
             description = ''
-              The path to the boot directory where grub will be written. Generally
-              this boot parth should double as an efi path.
+              The path to the boot directory where GRUB will be written. Generally
+              this boot path should double as an EFI path.
             '';
           };
 
@@ -166,7 +166,7 @@ in
             example = [ "/dev/sda" "/dev/sdb" ];
             type = types.listOf types.str;
             description = ''
-              The path to the devices which will have the grub mbr written.
+              The path to the devices which will have the GRUB MBR written.
               Note these are typically device paths and not paths to partitions.
             '';
           };
@@ -197,7 +197,7 @@ in
         type = types.lines;
         description = ''
           Additional bash commands to be run at the script that
-          prepares the grub menu entries.
+          prepares the GRUB menu entries.
         '';
       };
 
@@ -276,7 +276,7 @@ in
         example = "1024x768";
         type = types.str;
         description = ''
-          The gfxmode to pass to grub when loading a graphical boot interface under efi.
+          The gfxmode to pass to GRUB when loading a graphical boot interface under EFI.
         '';
       };
 
@@ -285,7 +285,7 @@ in
         example = "auto";
         type = types.str;
         description = ''
-          The gfxmode to pass to grub when loading a graphical boot interface under bios.
+          The gfxmode to pass to GRUB when loading a graphical boot interface under BIOS.
         '';
       };
 
@@ -330,10 +330,10 @@ in
         type = types.addCheck types.str
           (type: type == "uuid" || type == "label" || type == "provided");
         description = ''
-          Determines how grub will identify devices when generating the
+          Determines how GRUB will identify devices when generating the
           configuration file. A value of uuid / label signifies that grub
           will always resolve the uuid or label of the device before using
-          it in the configuration. A value of provided means that grub will
+          it in the configuration. A value of provided means that GRUB will
           use the device name as show in <command>df</command> or
           <command>mount</command>. Note, zfs zpools / datasets are ignored
           and will always be mounted using their labels.
@@ -344,7 +344,7 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Whether grub should be build against libzfs.
+          Whether GRUB should be build against libzfs.
           ZFS support is only available for GRUB v2.
           This option is ignored for GRUB v1.
         '';
@@ -354,7 +354,7 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Whether grub should be build with EFI support.
+          Whether GRUB should be build with EFI support.
           EFI support is only available for GRUB v2.
           This option is ignored for GRUB v1.
         '';
@@ -364,16 +364,16 @@ in
         default = false;
         type = types.bool;
         description = ''
-          Enable support for encrypted partitions. Grub should automatically
+          Enable support for encrypted partitions. GRUB should automatically
           unlock the correct encrypted partition and look for filesystems.
         '';
       };
 
-      enableTrustedboot = mkOption {
+      enableTrustedBoot = mkOption {
         default = false;
         type = types.bool;
         description = ''
-          Enable trusted boot. Grub will measure all critical components during
+          Enable trusted boot. GRUB will measure all critical components during
           the boot process to offer TCG (TPM) support.
         '';
       };
@@ -429,7 +429,7 @@ in
       assertions = [
         {
           assertion = !cfg.zfsSupport || cfg.version == 2;
-          message = "Only grub version 2 provides zfs support";
+          message = "Only GRUB version 2 provides ZFS support";
         }
         {
           assertion = cfg.mirroredBoots != [ ];
@@ -441,19 +441,19 @@ in
           message = "You cannot have duplicated devices in mirroredBoots";
         }
         {
-          assertion = !cfg.enableTrustedboot || cfg.version == 2;
+          assertion = !cfg.enableTrustedBoot || cfg.version == 2;
           message = "Trusted GRUB is only available for GRUB 2";
         }
         {
-          assertion = !cfg.efiSupport || !cfg.enableTrustedboot;
+          assertion = !cfg.efiSupport || !cfg.enableTrustedBoot;
           message = "Trusted GRUB does not have EFI support";
         }
         {
-          assertion = !cfg.zfsSupport || !cfg.enableTrustedboot;
+          assertion = !cfg.zfsSupport || !cfg.enableTrustedBoot;
           message = "Trusted GRUB does not have ZFS support";
         }
         {
-          assertion = !cfg.enableTrustedboot;
+          assertion = !cfg.enableTrustedBoot;
           message = "Trusted GRUB can break your system. Remove assertion if you want to test trustedGRUB nevertheless.";
         }
       ] ++ flip concatMap cfg.mirroredBoots (args: [
@@ -471,7 +471,7 @@ in
         }
       ] ++ flip map args.devices (device: {
         assertion = device == "nodev" || hasPrefix "/" device;
-        message = "Grub devices must be absolute paths, not ${dev} in ${args.path}";
+        message = "GRUB devices must be absolute paths, not ${dev} in ${args.path}";
       }));
     })
 
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 34bff727b73a..af39e50ff72d 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -237,6 +237,7 @@ else {
         $conf .= "
             " . $grubStore->search;
     }
+    # FIXME: should use grub-mkconfig.
     $conf .= "
         " . $grubBoot->search . "
         if [ -s \$prefix/grubenv ]; then
@@ -245,14 +246,12 @@ else {
 
         # ‘grub-reboot’ sets a one-time saved entry, which we process here and
         # then delete.
-        if [ \"\${saved_entry}\" ]; then
-          # The next line *has* to look exactly like this, otherwise KDM's
-          # reboot feature won't work properly with GRUB 2.
+        if [ \"\${next_entry}\" ]; then
+          # FIXME: KDM expects the next line to be present.
           set default=\"\${saved_entry}\"
-          set saved_entry=
-          set prev_saved_entry=
-          save_env saved_entry
-          save_env prev_saved_entry
+          set default=\"\${next_entry}\"
+          set next_entry=
+          save_env next_entry
           set timeout=1
         else
           set default=$defaultEntry
diff --git a/nixos/modules/system/boot/modprobe.nix b/nixos/modules/system/boot/modprobe.nix
index a3b616ff3eff..c49380899664 100644
--- a/nixos/modules/system/boot/modprobe.nix
+++ b/nixos/modules/system/boot/modprobe.nix
@@ -35,6 +35,7 @@ with lib;
             fi
 
           '';
+        meta.priority = 4;
       };
       description = ''
         Wrapper around modprobe that sets the path to the modules
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index c4c84784feac..366bec7187ba 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -642,6 +642,10 @@ in
         if ! [ -e /etc/machine-id ]; then
           ${systemd}/bin/systemd-machine-id-setup
         fi
+
+        # Keep a persistent journal. Note that systemd-tmpfiles will
+        # set proper ownership/permissions.
+        mkdir -m 0700 -p /var/log/journal
       '';
 
     users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
@@ -712,6 +716,14 @@ in
         })
         (filterAttrs (name: service: service.startAt != "") cfg.services);
 
+    # Generate timer units for all services that have a ‘startAt’ value.
+    systemd.user.timers =
+      mapAttrs (name: service:
+        { wantedBy = [ "timers.target" ];
+          timerConfig.OnCalendar = service.startAt;
+        })
+        (filterAttrs (name: service: service.startAt != "") cfg.user.services);
+
     systemd.sockets.systemd-journal-gatewayd.wantedBy =
       optional config.services.journald.enableHttpGateway "sockets.target";
 
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 6361ed2cc431..a967fc77e686 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -708,11 +708,14 @@ in
         pkgs.iproute
         pkgs.iputils
         pkgs.nettools
-        pkgs.wirelesstools
+        pkgs.openresolv
+      ]
+      ++ optionals (!config.boot.isContainer) [
+        pkgs.wirelesstools # FIXME: obsolete?
         pkgs.iw
         pkgs.rfkill
-        pkgs.openresolv
-      ] ++ bridgeStp;
+      ]
+      ++ bridgeStp;
 
     systemd.targets."network-interfaces" =
       { description = "All Network Interfaces";
diff --git a/nixos/modules/virtualisation/brightbox-config.nix b/nixos/modules/virtualisation/brightbox-config.nix
new file mode 100644
index 000000000000..528ffecc0bf2
--- /dev/null
+++ b/nixos/modules/virtualisation/brightbox-config.nix
@@ -0,0 +1,5 @@
+{ config, pkgs, modulesPath, ... }:
+
+{
+  imports = [ "${modulesPath}/virtualisation/brightbox-image.nix" ];
+}
diff --git a/nixos/modules/virtualisation/brightbox-image.nix b/nixos/modules/virtualisation/brightbox-image.nix
new file mode 100644
index 000000000000..3a956caca0c3
--- /dev/null
+++ b/nixos/modules/virtualisation/brightbox-image.nix
@@ -0,0 +1,166 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  diskSize = "20G";
+in
+{
+  imports = [ ../profiles/headless.nix ../profiles/qemu-guest.nix ];
+
+  system.build.brightboxImage =
+    pkgs.vmTools.runInLinuxVM (
+      pkgs.runCommand "brightbox-image"
+        { preVM =
+            ''
+              mkdir $out
+              diskImage=$out/$diskImageBase
+              truncate $diskImage --size ${diskSize}
+              mv closure xchg/
+            '';
+
+          postVM =
+            ''
+              PATH=$PATH:${pkgs.gnutar}/bin:${pkgs.gzip}/bin
+              pushd $out
+              ${pkgs.qemu_kvm}/bin/qemu-img convert -c -O qcow2 $diskImageBase nixos.qcow2
+              rm $diskImageBase
+              popd
+            '';
+          diskImageBase = "nixos-${config.system.nixosVersion}-${pkgs.stdenv.system}.raw";
+          buildInputs = [ pkgs.utillinux pkgs.perl ];
+          exportReferencesGraph =
+            [ "closure" config.system.build.toplevel ];
+        }
+        ''
+          # Create partition table
+          ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
+          ${pkgs.parted}/sbin/parted /dev/vda mkpart primary ext4 1 ${diskSize}
+          ${pkgs.parted}/sbin/parted /dev/vda print
+          . /sys/class/block/vda1/uevent
+          mknod /dev/vda1 b $MAJOR $MINOR
+
+          # Create an empty filesystem and mount it.
+          ${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L nixos /dev/vda1
+          ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
+
+          mkdir /mnt
+          mount /dev/vda1 /mnt
+
+          # The initrd expects these directories to exist.
+          mkdir /mnt/dev /mnt/proc /mnt/sys
+
+          mount --bind /proc /mnt/proc
+          mount --bind /dev /mnt/dev
+          mount --bind /sys /mnt/sys
+
+          # Copy all paths in the closure to the filesystem.
+          storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
+
+          mkdir -p /mnt/nix/store
+          echo "copying everything (will take a while)..."
+          cp -prd $storePaths /mnt/nix/store/
+
+          # Register the paths in the Nix database.
+          printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
+              chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
+
+          # Create the system profile to allow nixos-rebuild to work.
+          chroot /mnt ${config.nix.package}/bin/nix-env \
+              -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} \
+              --option build-users-group ""
+
+          # `nixos-rebuild' requires an /etc/NIXOS.
+          mkdir -p /mnt/etc
+          touch /mnt/etc/NIXOS
+
+          # `switch-to-configuration' requires a /bin/sh
+          mkdir -p /mnt/bin
+          ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
+
+          # Install a configuration.nix.
+          mkdir -p /mnt/etc/nixos /mnt/boot/grub
+          cp ${./brightbox-config.nix} /mnt/etc/nixos/configuration.nix
+
+          # Generate the GRUB menu.
+          ln -s vda /dev/sda
+          chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
+
+          umount /mnt/proc /mnt/dev /mnt/sys
+          umount /mnt
+        ''
+    );
+
+  fileSystems."/".label = "nixos";
+
+  # Generate a GRUB menu.  Amazon's pv-grub uses this to boot our kernel/initrd.
+  boot.loader.grub.device = "/dev/vda";
+  boot.loader.grub.timeout = 0;
+
+  # Don't put old configurations in the GRUB menu.  The user has no
+  # way to select them anyway.
+  boot.loader.grub.configurationLimit = 0;
+
+  # Allow root logins only using the SSH key that the user specified
+  # at instance creation time.
+  services.openssh.enable = true;
+  services.openssh.permitRootLogin = "without-password";
+
+  # Force getting the hostname from Google Compute.
+  networking.hostName = mkDefault "";
+
+  # Always include cryptsetup so that NixOps can use it.
+  environment.systemPackages = [ pkgs.cryptsetup ];
+
+  systemd.services."fetch-ec2-data" =
+    { description = "Fetch EC2 Data";
+
+      wantedBy = [ "multi-user.target" "sshd.service" ];
+      before = [ "sshd.service" ];
+      wants = [ "ip-up.target" ];
+      after = [ "ip-up.target" ];
+
+      path = [ pkgs.wget pkgs.iproute ];
+
+      script =
+        ''
+          wget="wget -q --retry-connrefused -O -"
+
+          ${optionalString (config.networking.hostName == "") ''
+            echo "setting host name..."
+            ${pkgs.nettools}/bin/hostname $($wget http://169.254.169.254/latest/meta-data/hostname)
+          ''}
+
+          # Don't download the SSH key if it has already been injected
+          # into the image (a Nova feature).
+          if ! [ -e /root/.ssh/authorized_keys ]; then
+              echo "obtaining SSH key..."
+              mkdir -m 0700 -p /root/.ssh
+              $wget http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /root/key.pub
+              if [ $? -eq 0 -a -e /root/key.pub ]; then
+                  if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then
+                      cat /root/key.pub >> /root/.ssh/authorized_keys
+                      echo "new key added to authorized_keys"
+                  fi
+                  chmod 600 /root/.ssh/authorized_keys
+                  rm -f /root/key.pub
+              fi
+          fi
+
+          # Extract the intended SSH host key for this machine from
+          # the supplied user data, if available.  Otherwise sshd will
+          # generate one normally.
+          $wget http://169.254.169.254/2011-01-01/user-data > /root/user-data || true
+          key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' /root/user-data)"
+          key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' /root/user-data)"
+          if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_dsa_key ]; then
+              mkdir -m 0755 -p /etc/ssh
+              (umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key)
+              echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
+          fi
+        '';
+
+      serviceConfig.Type = "oneshot";
+      serviceConfig.RemainAfterExit = true;
+    };
+
+}
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index da39dda85353..59f486ff78b7 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -120,6 +120,15 @@ in
               '';
             };
 
+            interfaces = mkOption {
+              type = types.listOf types.string;
+              default = [];
+              example = [ "eth1" "eth2" ];
+              description = ''
+                The list of interfaces to be moved into the container.
+              '';
+            };
+
             autoStart = mkOption {
               type = types.bool;
               default = false;
@@ -218,6 +227,10 @@ in
               extraFlags+=" --network-veth"
             fi
 
+            for iface in $INTERFACES; do
+              extraFlags+=" --network-interface=$iface"
+            done
+
             for iface in $MACVLANS; do
               extraFlags+=" --network-macvlan=$iface"
             done
@@ -331,6 +344,7 @@ in
                 LOCAL_ADDRESS=${cfg.localAddress}
               ''}
             ''}
+             INTERFACES="${toString cfg.interfaces}"
            ${optionalString cfg.autoStart ''
              AUTO_START=1
            ''}
diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix
index ef9cc2280db7..ba078cc0a11f 100644
--- a/nixos/modules/virtualisation/docker.nix
+++ b/nixos/modules/virtualisation/docker.nix
@@ -43,6 +43,17 @@ in
             in future.  So set this option explicitly to false if you wish.
           '';
       };
+    storageDriver =
+      mkOption {
+        type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"];
+        description =
+          ''
+            This option determines which Docker storage driver to use.
+            It is required but lacks a default value as its most
+            suitable value will depend the filesystems available on the
+            host.
+          '';
+      };
     extraOptions =
       mkOption {
         type = types.separatedString " ";
@@ -54,6 +65,21 @@ in
           '';
       };
 
+    postStart =
+      mkOption {
+        type = types.string;
+        default = ''
+          while ! [ -e /var/run/docker.sock ]; do
+            sleep 0.1
+          done
+        '';
+        description = ''
+          The postStart phase of the systemd service. You may need to
+          override this if you are passing in flags to docker which
+          don't cause the socket file to be created.
+        '';
+      };
+
 
   };
 
@@ -70,7 +96,7 @@ in
         after = [ "network.target" "docker.socket" ];
         requires = [ "docker.socket" ];
         serviceConfig = {
-          ExecStart = "${pkgs.docker}/bin/docker --daemon=true --host=fd:// --group=docker ${cfg.extraOptions}";
+          ExecStart = "${pkgs.docker}/bin/docker daemon --host=fd:// --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}";
           #  I'm not sure if that limits aren't too high, but it's what
           #  goes in config bundled with docker itself
           LimitNOFILE = 1048576;
@@ -96,7 +122,7 @@ in
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
         serviceConfig = {
-          ExecStart = "${pkgs.docker}/bin/docker --daemon=true --group=docker ${cfg.extraOptions}";
+          ExecStart = "${pkgs.docker}/bin/docker daemon --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}";
           #  I'm not sure if that limits aren't too high, but it's what
           #  goes in config bundled with docker itself
           LimitNOFILE = 1048576;
@@ -106,11 +132,7 @@ in
         path = [ pkgs.kmod ];
         environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";
 
-        postStart = ''
-          while ! [ -e /var/run/docker.sock ]; do
-            sleep 0.1
-          done
-        '';
+        postStart = cfg.postStart;
 
         # Presumably some containers are running we don't want to interrupt
         restartIfChanged = false;
diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix
index 69ca13a71479..b5155246fdad 100644
--- a/nixos/modules/virtualisation/openvswitch.nix
+++ b/nixos/modules/virtualisation/openvswitch.nix
@@ -67,7 +67,6 @@ in {
       description = "Open_vSwitch Database Server";
       wantedBy = [ "multi-user.target" ];
       after = [ "systemd-udev-settle.service" ];
-      wants = [ "vswitchd.service" ];
       path = [ cfg.package ];
       restartTriggers = [ db cfg.package ];
       # Create the config database
@@ -108,6 +107,7 @@ in {
 
     systemd.services.vswitchd = {
       description = "Open_vSwitch Daemon";
+      wantedBy = [ "multi-user.target" ];
       bindsTo = [ "ovsdb.service" ];
       after = [ "ovsdb.service" ];
       path = [ cfg.package ];
@@ -135,8 +135,8 @@ in {
     systemd.services.ovs-monitor-ipsec = {
       description = "Open_vSwitch Ipsec Daemon";
       wantedBy = [ "multi-user.target" ];
-      requires = [ "racoon.service" ];
-      after = [ "vswitchd.service" ];
+      requires = [ "ovsdb.service" ];
+      before = [ "vswitchd.service" "racoon.service" ];
       environment.UNIXCTLPATH = "/tmp/ovsdb.ctl.sock";
       serviceConfig = {
         ExecStart = ''
diff --git a/nixos/modules/virtualisation/virtualbox-guest.nix b/nixos/modules/virtualisation/virtualbox-guest.nix
index a0e4bd558e05..642ea3154b1b 100644
--- a/nixos/modules/virtualisation/virtualbox-guest.nix
+++ b/nixos/modules/virtualisation/virtualbox-guest.nix
@@ -6,7 +6,7 @@ with lib;
 
 let
 
-  cfg = config.services.virtualboxGuest;
+  cfg = config.virtualisation.virtualbox.guest;
   kernel = config.boot.kernelPackages;
 
 in
@@ -15,20 +15,11 @@ in
 
   ###### interface
 
-  options = {
-
-    services.virtualboxGuest = {
-
-      enable = mkOption {
-        default = false;
-        description = "Whether to enable the VirtualBox service and other guest additions.";
-      };
-
-    };
-
+  options.virtualisation.virtualbox.guest.enable = mkOption {
+    default = false;
+    description = "Whether to enable the VirtualBox service and other guest additions.";
   };
 
-
   ###### implementation
 
   config = mkIf cfg.enable {
@@ -54,7 +45,7 @@ in
 
         unitConfig.ConditionVirtualization = "oracle";
 
-        serviceConfig.ExecStart = "@${kernel.virtualboxGuestAdditions}/sbin/VBoxService VBoxService --foreground";
+        serviceConfig.ExecStart = "@${kernel.virtualboxGuestAdditions}/bin/VBoxService VBoxService --foreground";
       };
 
     services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" ];
diff --git a/nixos/modules/programs/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix
index fc113a08a356..00486df5c4ba 100644
--- a/nixos/modules/programs/virtualbox-host.nix
+++ b/nixos/modules/virtualisation/virtualbox-host.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  cfg = config.services.virtualboxHost;
+  cfg = config.virtualisation.virtualbox.host;
   virtualbox = config.boot.kernelPackages.virtualbox.override {
     inherit (cfg) enableHardening;
   };
@@ -11,12 +11,12 @@ let
 in
 
 {
-  options.services.virtualboxHost = {
+  options.virtualisation.virtualbox.host = {
     enable = mkOption {
       type = types.bool;
       default = false;
       description = ''
-        Whether to enable host-side support for VirtualBox.
+        Whether to enable VirtualBox.
 
         <note><para>
           In order to pass USB devices from the host to the guests, the user
diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix
index 8232f6e50dfc..c1538feb9df5 100644
--- a/nixos/modules/virtualisation/virtualbox-image.nix
+++ b/nixos/modules/virtualisation/virtualbox-image.nix
@@ -128,6 +128,6 @@ in {
     boot.loader.grub.version = 2;
     boot.loader.grub.device = "/dev/sda";
   
-    services.virtualboxGuest.enable = true;
+    virtualisation.virtualbox.guest.enable = true;
   };
 }
diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix
index c750286a3970..a0b2d5363eb2 100644
--- a/nixos/modules/virtualisation/xen-dom0.nix
+++ b/nixos/modules/virtualisation/xen-dom0.nix
@@ -121,6 +121,10 @@ in
         "xenfs"
       ];
 
+    # The xenfs module is needed in system.activationScripts.xen, but
+    # the modprobe command there fails silently. Include xenfs in the
+    # initrd as a work around.
+    boot.initrd.kernelModules = [ "xenfs" ];
 
     # The radeonfb kernel module causes the screen to go black as soon
     # as it's loaded, so don't load it.
@@ -182,6 +186,9 @@ in
         { source = "${pkgs.xen}/etc/xen/scripts";
           target = "xen/scripts";
         }
+        { source = "${pkgs.xen}/etc/default/xendomains";
+          target = "default/xendomains";
+        }
       ];
 
     # Xen provides udev rules.
@@ -199,7 +206,8 @@ in
         rm -f "$XENSTORED_ROOTDIR"/tdb* &>/dev/null
 
         mkdir -p /var/run
-        ${optionalString cfg.trace "mkdir -p /var/log/xen"}
+        mkdir -p /var/log/xen # Running xl requires /var/log/xen and /var/lib/xen,
+        mkdir -p /var/lib/xen # so we create them here unconditionally.
         grep -q control_d /proc/xen/capabilities
         '';
       serviceConfig.ExecStart = ''