summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-1411.xml13
-rw-r--r--nixos/lib/make-iso9660-image.nix13
-rw-r--r--nixos/lib/make-iso9660-image.sh48
-rw-r--r--nixos/modules/config/update-users-groups.pl7
-rw-r--r--nixos/modules/config/users-groups.nix78
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-base.nix5
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix132
-rw-r--r--nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix1
-rw-r--r--nixos/modules/profiles/base.nix1
-rw-r--r--nixos/modules/programs/ssmtp.nix17
-rw-r--r--nixos/modules/security/sudo.nix12
-rw-r--r--nixos/modules/services/hardware/thermald.nix2
-rw-r--r--nixos/modules/services/misc/gitolite.nix15
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix14
-rw-r--r--nixos/modules/services/monitoring/graphite.nix20
-rw-r--r--nixos/modules/services/monitoring/zabbix-server.nix13
-rw-r--r--nixos/modules/services/torrent/transmission.nix2
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/default.nix14
-rw-r--r--nixos/modules/system/boot/stage-1.nix4
-rw-r--r--nixos/modules/testing/test-instrumentation.nix2
-rw-r--r--nixos/modules/virtualisation/amazon-image.nix5
-rw-r--r--nixos/modules/virtualisation/docker-image.nix12
-rw-r--r--nixos/tests/gnome3.nix2
-rw-r--r--nixos/tests/gnome3_12.nix2
-rw-r--r--nixos/tests/proxy.nix7
-rw-r--r--nixos/tests/run-in-machine.nix8
26 files changed, 298 insertions, 151 deletions
diff --git a/nixos/doc/manual/release-notes/rl-1411.xml b/nixos/doc/manual/release-notes/rl-1411.xml
index 74cf8323e692..e355118139dc 100644
--- a/nixos/doc/manual/release-notes/rl-1411.xml
+++ b/nixos/doc/manual/release-notes/rl-1411.xml
@@ -11,6 +11,19 @@ following incompatible changes:
 
 <itemizedlist>
 
+  <listitem><para>The default version of Apache httpd is now 2.4. If
+  you use the <option>extraConfig</option> option to pass literal
+  Apache configuration text, you may need to update it — see <link
+  xlink:href="http://httpd.apache.org/docs/2.4/upgrading.html">Apache’s
+  documentation</link> for details. If you wish to continue to use
+  httpd 2.2, add the following line to your NixOS configuration:
+
+<programlisting>
+services.httpd.package = pkgs.apacheHttpd_2_2;
+</programlisting>
+
+  </para></listitem>
+
   <listitem><para>The host side of a container virtual Ethernet pair
   is now called <literal>ve-<replaceable>container-name</replaceable></literal>
   rather than <literal>c-<replaceable>container-name</replaceable></literal>.</para></listitem>
diff --git a/nixos/lib/make-iso9660-image.nix b/nixos/lib/make-iso9660-image.nix
index 5ad546e9534d..b2409c6006bc 100644
--- a/nixos/lib/make-iso9660-image.nix
+++ b/nixos/lib/make-iso9660-image.nix
@@ -1,4 +1,4 @@
-{ stdenv, perl, cdrkit, pathsFromGraph
+{ stdenv, perl, pathsFromGraph, xorriso, syslinux
 
 , # The file name of the resulting ISO image.
   isoName ? "cd.iso"
@@ -22,12 +22,18 @@
 , # Whether this should be an efi-bootable El-Torito CD.
   efiBootable ? false
 
+, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
+  usbBootable ? false
+
 , # The path (in the ISO file system) of the boot image.
   bootImage ? ""
 
 , # The path (in the ISO file system) of the efi boot image.
   efiBootImage ? ""
 
+, # The path (outside the ISO file system) of the isohybrid-mbr image.
+  isohybridMbrImage ? ""
+
 , # Whether to compress the resulting ISO image with bzip2.
   compressImage ? false
 
@@ -38,13 +44,14 @@
 
 assert bootable -> bootImage != "";
 assert efiBootable -> efiBootImage != "";
+assert usbBootable -> isohybridMbrImage != "";
 
 stdenv.mkDerivation {
   name = "iso9660-image";
   builder = ./make-iso9660-image.sh;
-  buildInputs = [perl cdrkit];
+  buildInputs = [perl xorriso syslinux];
 
-  inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable;
+  inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
 
   # !!! should use XML.
   sources = map (x: x.source) contents;
diff --git a/nixos/lib/make-iso9660-image.sh b/nixos/lib/make-iso9660-image.sh
index 675b5bb35148..c8522513aa23 100644
--- a/nixos/lib/make-iso9660-image.sh
+++ b/nixos/lib/make-iso9660-image.sh
@@ -31,11 +31,20 @@ if test -n "$bootable"; then
         fi
     done
 
-    bootFlags="-b $bootImage -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+    isoBootFlags="-eltorito-boot ${bootImage}
+                  -eltorito-catalog .boot.cat
+                  -no-emul-boot -boot-load-size 4 -boot-info-table"
+fi
+
+if test -n "$usbBootable"; then
+    usbBootFlags="-isohybrid-mbr ${isohybridMbrImage}"
 fi
 
 if test -n "$efiBootable"; then
-    bootFlags="$bootFlags -eltorito-alt-boot -e $efiBootImage -no-emul-boot"
+    efiBootFlags="-eltorito-alt-boot
+                  -e $efiBootImage
+                  -no-emul-boot
+                  -isohybrid-gpt-basdat"
 fi
 
 touch pathlist
@@ -74,18 +83,41 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
     fi
 done
 
-# !!! what does this do?
+# Escape filenames that contain '='.
+# TODO: Handle this properly. This fails for filenames
+#       that contain multiple '=' symbols.
 cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
 
 
 mkdir -p $out/iso
-genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
-if test -z "$compressImage"; then
-    $genCommand -o $out/iso/$isoName
-else
-    $genCommand | bzip2 > $out/iso/$isoName.bz2
+
+xorriso="xorriso
+ -as mkisofs
+ -iso-level 3
+ -volid ${volumeID}
+ -appid nixos
+ -publisher nixos
+ -graft-points
+ -full-iso9660-filenames
+ ${isoBootFlags}
+ ${usbBootFlags}
+ ${efiBootFlags}
+ -r
+ -path-list pathlist.safer
+ --sort-weight 0 /
+ --sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
+
+$xorriso -output $out/iso/$isoName
+
+if test -n "$usbBootable"; then
+    echo "Making image hybrid..."
+    isohybrid --uefi $out/iso/$isoName
 fi
 
+if test -n "$compressImage"; then
+    echo "Compressing image..."
+    bzip2 $out/iso/$isoName
+fi
 
 mkdir -p $out/nix-support
 echo $system > $out/nix-support/system
diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl
index abcb082af8e5..63e1c82dd6de 100644
--- a/nixos/modules/config/update-users-groups.pl
+++ b/nixos/modules/config/update-users-groups.pl
@@ -169,6 +169,12 @@ foreach my $u (@{$spec->{users}}) {
     } else {
         $u->{uid} = allocUid($u->{isSystemUser}) if !defined $u->{uid};
 
+        if (defined $u->{initialPassword}) {
+            $u->{hashedPassword} = hashPassword($u->{initialPassword});
+        } elsif (defined $u->{initialHashedPassword}) {
+            $u->{hashedPassword} = $u->{initialHashedPassword};
+        }
+
         # Create a home directory.
         if ($u->{createHome}) {
             make_path($u->{home}, { mode => 0700 }) if ! -e $u->{home};
@@ -222,6 +228,7 @@ foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
     my ($name, $hashedPassword, @rest) = split(':', $line, -9);
     my $u = $usersOut{$name};;
     next if !defined $u;
+    $hashedPassword = "!" if !$spec->{mutableUsers};
     $hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
     push @shadowNew, join(":", $name, $hashedPassword, @rest) . "\n";
     $shadowSeen{$name} = 1;
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 773f9b412afe..256c5888cb94 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -8,19 +8,19 @@ let
   cfg = config.users;
 
   passwordDescription = ''
-    The options <literal>hashedPassword</literal>,
-    <literal>password</literal> and <literal>passwordFile</literal>
+    The options <option>hashedPassword</option>,
+    <option>password</option> and <option>passwordFile</option>
     controls what password is set for the user.
-    <literal>hashedPassword</literal> overrides both
-    <literal>password</literal> and <literal>passwordFile</literal>.
-    <literal>password</literal> overrides <literal>passwordFile</literal>.
+    <option>hashedPassword</option> overrides both
+    <option>password</option> and <option>passwordFile</option>.
+    <option>password</option> overrides <option>passwordFile</option>.
     If none of these three options are set, no password is assigned to
     the user, and the user will not be able to do password logins.
-    If the option <literal>users.mutableUsers</literal> is true, the
+    If the option <option>users.mutableUsers</option> is true, the
     password defined in one of the three options will only be set when
     the user is created for the first time. After that, you are free to
     change the password with the ordinary user management commands. If
-    <literal>users.mutableUsers</literal> is false, you cannot change
+    <option>users.mutableUsers</option> is false, you cannot change
     user passwords, they will always be set according to the password
     options.
   '';
@@ -155,7 +155,7 @@ let
         default = false;
         description = ''
           If true, the user's shell will be set to
-          <literal>cfg.defaultUserShell</literal>.
+          <option>users.defaultUserShell</option>.
         '';
       };
 
@@ -163,7 +163,7 @@ let
         type = with types; uniq (nullOr str);
         default = null;
         description = ''
-          Specifies the (hashed) password for the user.
+          Specifies the hashed password for the user.
           ${passwordDescription}
         '';
       };
@@ -191,6 +191,37 @@ let
           ${passwordDescription}
         '';
       };
+
+      initialHashedPassword = mkOption {
+        type = with types; uniq (nullOr str);
+        default = null;
+        description = ''
+          Specifies the initial hashed password for the user, i.e. the
+          hashed password assigned if the user does not already
+          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.
+        '';
+      };
+
+      initialPassword = mkOption {
+        type = with types; uniq (nullOr str);
+        default = null;
+        description = ''
+          Specifies the initial password for the user, i.e. the
+          password assigned if the user does not already 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. The same caveat applies: the password specified here
+          is world-readable in the Nix store, so it should only be
+          used for guest accounts or passwords that will be changed
+          promptly.
+        '';
+      };
+
     };
 
     config = mkMerge
@@ -204,6 +235,14 @@ let
           useDefaultShell = mkDefault true;
           isSystemUser = mkDefault false;
         })
+        # If !mutableUsers, setting ‘initialPassword’ is equivalent to
+        # setting ‘password’ (and similarly for hashed passwords).
+        (mkIf (!cfg.mutableUsers && config.initialPassword != null) {
+          password = mkDefault config.initialPassword;
+        })
+        (mkIf (!cfg.mutableUsers && config.initialHashedPassword != null) {
+          hashedPassword = mkDefault config.initialHashedPassword;
+        })
       ];
 
   };
@@ -306,7 +345,8 @@ let
     users = mapAttrsToList (n: u:
       { inherit (u)
           name uid group description home shell createHome isSystemUser
-          password passwordFile hashedPassword;
+          password passwordFile hashedPassword
+          initialPassword initialHashedPassword;
       }) cfg.extraUsers;
     groups = mapAttrsToList (n: g:
       { inherit (g) name gid;
@@ -386,24 +426,12 @@ in {
       options = [ groupOpts ];
     };
 
+    # FIXME: obsolete - will remove.
     security.initialRootPassword = mkOption {
       type = types.str;
       default = "!";
       example = "";
-      description = ''
-        The (hashed) password for the root account set on initial
-        installation. The empty string denotes that root can login
-        locally without a password (but not via remote services such
-        as SSH, or indirectly via <command>su</command> or
-        <command>sudo</command>). The string <literal>!</literal>
-        prevents root from logging in using a password.
-        Note that setting this option sets
-        <literal>users.extraUsers.root.hashedPassword</literal>.
-        Also, if <literal>users.mutableUsers</literal> is false
-        you cannot change the root password manually, so in that case
-        the name of this option is a bit misleading, since it will define
-        the root password beyond the user initialisation phase.
-      '';
+      visible = false;
     };
 
   };
@@ -421,7 +449,7 @@ in {
         shell = mkDefault cfg.defaultUserShell;
         group = "root";
         extraGroups = [ "grsecurity" ];
-        hashedPassword = mkDefault config.security.initialRootPassword;
+        initialHashedPassword = mkDefault config.security.initialRootPassword;
       };
       nobody = {
         uid = ids.uids.nobody;
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
index 0a39e8dde9de..a68581c113fc 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -36,6 +36,9 @@ with lib;
   # EFI booting
   isoImage.makeEfiBootable = true;
 
+  # USB booting
+  isoImage.makeUsbBootable = true;
+
   # Add Memtest86+ to the CD.
   boot.loader.grub.memtest86.enable = true;
 
@@ -46,5 +49,5 @@ with lib;
   boot.supportedFilesystems = [ "zfs" "btrfs" ];
 
   # Allow the user to log in as root without a password.
-  security.initialRootPassword = "";
+  users.extraUsers.root.initialHashedPassword = "";
 }
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 22f31c460802..f387c64cb9c9 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -8,45 +8,37 @@ with lib;
 
 let
 
-  # The Grub image.
-  grubImage = pkgs.runCommand "grub_eltorito" {}
+  # The configuration file for syslinux.
+  isolinuxCfg =
     ''
-      ${pkgs.grub2}/bin/grub-mkimage -p /boot/grub -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
-      cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
-    ''; # */
-
-
-  # The configuration file for Grub.
-  grubCfg =
-    ''
-      set default=${builtins.toString config.boot.loader.grub.default}
-      set timeout=${builtins.toString config.boot.loader.grub.timeout}
-
-      if loadfont /boot/grub/unicode.pf2; then
-        set gfxmode=640x480
-        insmod gfxterm
-        insmod vbe
-        terminal_output gfxterm
-
-        insmod png
-        if background_image /boot/grub/splash.png; then
-          set color_normal=white/black
-          set color_highlight=black/white
-        else
-          set menu_color_normal=cyan/blue
-          set menu_color_highlight=white/blue
-        fi
-
-      fi
-
-      ${config.boot.loader.grub.extraEntries}
+    SERIAL 0 38400
+    UI vesamenu.c32
+    MENU TITLE NixOS
+    MENU BACKGROUND /isolinux/background.png
+
+    LABEL boot
+    MENU LABEL Boot NixOS
+    LINUX /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+    INITRD /boot/initrd
+
+    LABEL chain
+    MENU LABEL Boot existing OS
+    COM32 chain.c32
+    APPEND hd0 0
+
+    LABEL reboot
+    MENU LABEL Reboot
+    COM32 reboot.c32
+
+    LABEL poweroff
+    MENU LABEL Power Off
+    COM32 poweroff.c32
     '';
 
-
   # 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/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 "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
@@ -152,6 +144,22 @@ in
       '';
     };
 
+    isoImage.makeUsbBootable = mkOption {
+      default = false;
+      description = ''
+        Whether the ISO image should be bootable from CD as well as USB.
+      '';
+    };
+
+    isoImage.splashImage = mkOption {
+      default = pkgs.fetchurl {
+          url = https://raw.githubusercontent.com/NixOS/nixos-artwork/5729ab16c6a5793c10a2913b5a1b3f59b91c36ee/ideas/grub-splash/grub-nixos-1.png;
+          sha256 = "43fd8ad5decf6c23c87e9026170a13588c2eba249d9013cb9f888da5e2002217";
+        };
+      description = ''
+        The splash image to use in the bootloader.
+      '';
+    };
 
   };
 
@@ -166,7 +174,7 @@ in
 
     # !!! Hack - attributes expected by other modules.
     system.boot.loader.kernelFile = "bzImage";
-    environment.systemPackages = [ pkgs.grub2 ];
+    environment.systemPackages = [ pkgs.grub2 pkgs.syslinux ];
 
     # 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
@@ -213,7 +221,7 @@ in
         options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
       };
 
-    boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
+    boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
 
     boot.initrd.kernelModules = [ "loop" ];
 
@@ -233,15 +241,12 @@ in
     # Individual files to be included on the CD, outside of the Nix
     # store on the CD.
     isoImage.contents =
-      [ { source = grubImage;
-          target = "/boot/grub/grub_eltorito";
-        }
-        { source = pkgs.substituteAll  {
-            name = "grub.cfg";
-            src = pkgs.writeText "grub.cfg-in" grubCfg;
+      [ { source = pkgs.substituteAll  {
+            name = "isolinux.cfg";
+            src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
             bootRoot = "/boot";
           };
-          target = "/boot/grub/grub.cfg";
+          target = "/isolinux/isolinux.cfg";
         }
         { source = config.boot.kernelPackages.kernel + "/bzImage";
           target = "/boot/bzImage";
@@ -249,51 +254,38 @@ in
         { source = config.system.build.initialRamdisk + "/initrd";
           target = "/boot/initrd";
         }
-        { source = "${pkgs.grub2}/share/grub/unicode.pf2";
-          target = "/boot/grub/unicode.pf2";
-        }
-        { source = config.boot.loader.grub.splashImage;
-          target = "/boot/grub/splash.png";
-        }
         { source = config.system.build.squashfsStore;
           target = "/nix-store.squashfs";
         }
+        { source = "${pkgs.syslinux}/share/syslinux";
+          target = "/isolinux";
+        }
+        { source = config.isoImage.splashImage;
+          target = "/isolinux/background.png";
+        }
       ] ++ optionals config.isoImage.makeEfiBootable [
         { source = efiImg;
           target = "/boot/efi.img";
         }
-        { source = "${efiDir}/efi";
-          target = "/efi";
+        { source = "${efiDir}/EFI";
+          target = "/EFI";
         }
         { source = "${efiDir}/loader";
           target = "/loader";
         }
-      ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles;
-
-    # The Grub menu.
-    boot.loader.grub.extraEntries =
-      ''
-        menuentry "NixOS ${config.system.nixosVersion} Installer" {
-          linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
-          initrd /boot/initrd
-        }
-
-        menuentry "Boot from hard disk" {
-          set root=(hd0)
-          chainloader +1
-        }
-      '';
-
-    boot.loader.grub.timeout = 10;
+      ];
 
     # Create the ISO image.
     system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
-      inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
+      inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
 
       inherit (config.isoImage) isoName compressImage volumeID contents;
 
       bootable = true;
-      bootImage = "/boot/grub/grub_eltorito";
+      bootImage = "/isolinux/isolinux.bin";
+    } // optionalAttrs config.isoImage.makeUsbBootable {
+      usbBootable = true;
+      isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
     } // optionalAttrs config.isoImage.makeEfiBootable {
       efiBootable = true;
       efiBootImage = "boot/efi.img";
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
index 7d3346e4ea1f..bbf0311c04d6 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
@@ -76,7 +76,6 @@ in
       pkgs.ntfsprogs # for resizing NTFS partitions
       pkgs.btrfsProgs
       pkgs.jfsutils
-      pkgs.jfsrec
 
       # Some compression/archiver tools.
       pkgs.unzip
diff --git a/nixos/modules/profiles/base.nix b/nixos/modules/profiles/base.nix
index 7a6f76572058..3d1412b56859 100644
--- a/nixos/modules/profiles/base.nix
+++ b/nixos/modules/profiles/base.nix
@@ -34,7 +34,6 @@
     pkgs.xfsprogs
     pkgs.jfsutils
     pkgs.f2fs-tools
-    #pkgs.jfsrec # disabled because of Boost dependency
 
     # Some compression/archiver tools.
     pkgs.unzip
diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix
index 34eafd4fa846..7b00efbb4686 100644
--- a/nixos/modules/programs/ssmtp.nix
+++ b/nixos/modules/programs/ssmtp.nix
@@ -20,6 +20,7 @@ in
     networking.defaultMailServer = {
 
       directDelivery = mkOption {
+        type = types.bool;
         default = false;
         example = true;
         description = ''
@@ -35,6 +36,7 @@ in
       };
 
       hostName = mkOption {
+        type = types.str;
         example = "mail.example.org";
         description = ''
           The host name of the default mail server to use to deliver
@@ -42,7 +44,17 @@ in
         '';
       };
 
+      root = mkOption {
+        type = types.str;
+        default = "";
+        example = "root@example.org";
+        description = ''
+          The e-mail to which mail for users with UID &lt; 1000 is forwarded.
+        '';
+      };
+
       domain = mkOption {
+        type = types.str;
         default = "";
         example = "example.org";
         description = ''
@@ -51,6 +63,7 @@ in
       };
 
       useTLS = mkOption {
+        type = types.bool;
         default = false;
         example = true;
         description = ''
@@ -60,6 +73,7 @@ in
       };
 
       useSTARTTLS = mkOption {
+        type = types.bool;
         default = false;
         example = true;
         description = ''
@@ -70,6 +84,7 @@ in
       };
 
       authUser = mkOption {
+        type = types.str;
         default = "";
         example = "foo@example.org";
         description = ''
@@ -78,6 +93,7 @@ in
       };
 
       authPass = mkOption {
+        type = types.str;
         default = "";
         example = "correctHorseBatteryStaple";
         description = ''
@@ -96,6 +112,7 @@ in
       ''
         MailHub=${cfg.hostName}
         FromLineOverride=YES
+        ${if cfg.root != "" then "root=${cfg.root}" else ""}
         ${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""}
         UseTLS=${if cfg.useTLS then "YES" else "NO"}
         UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"}
diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix
index cbd1628caaec..4c6a1c26426e 100644
--- a/nixos/modules/security/sudo.nix
+++ b/nixos/modules/security/sudo.nix
@@ -46,6 +46,14 @@ in
           <filename>sudoers</filename> file.
         '';
     };
+
+    security.sudo.extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = ''
+        Extra configuration text appended to <filename>sudoers</filename>.
+      '';
+    };
   };
 
 
@@ -55,7 +63,8 @@ in
 
     security.sudo.configFile =
       ''
-        # Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead.
+        # Don't edit this file. Set the NixOS options ‘security.sudo.configFile’
+        # and security.sudo.extraConfig instead.
 
         # Environment variables to keep for root and %wheel.
         Defaults:root,%wheel env_keep+=TERMINFO_DIRS
@@ -69,6 +78,7 @@ in
 
         # Users in the "wheel" group can do anything.
         %wheel      ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
+        ${cfg.extraConfig}
       '';
 
     security.setuidPrograms = [ "sudo" "sudoedit" ];
diff --git a/nixos/modules/services/hardware/thermald.nix b/nixos/modules/services/hardware/thermald.nix
index 5233794a20cc..88c3f99aed4e 100644
--- a/nixos/modules/services/hardware/thermald.nix
+++ b/nixos/modules/services/hardware/thermald.nix
@@ -19,6 +19,8 @@ in {
 
   ###### implementation
   config = mkIf cfg.enable {
+    services.dbus.packages = [ pkgs.thermald ];
+
     systemd.services.thermald = {
       description = "Thermal Daemon Service";
       wantedBy = [ "multi-user.target" ];
diff --git a/nixos/modules/services/misc/gitolite.nix b/nixos/modules/services/misc/gitolite.nix
index 961af48e0f86..462b68aa0a1c 100644
--- a/nixos/modules/services/misc/gitolite.nix
+++ b/nixos/modules/services/misc/gitolite.nix
@@ -15,14 +15,21 @@ in
         default = false;
         description = ''
           Enable gitolite management under the
-          <literal>gitolite</literal> user. The Gitolite home
-          directory is <literal>/var/lib/gitolite</literal>. After
+          <literal>gitolite</literal> user. After
           switching to a configuration with Gitolite enabled, you can
           then run <literal>git clone
           gitolite@host:gitolite-admin.git</literal> to manage it further.
         '';
       };
 
+      dataDir = mkOption {
+        type = types.str;
+        default = "/var/lib/gitolite";
+        description = ''
+          Gitolite home directory (used to store all the repositories).
+        '';
+      };
+
       adminPubkey = mkOption {
         type = types.str;
         description = ''
@@ -45,7 +52,7 @@ in
   config = mkIf cfg.enable {
     users.extraUsers.gitolite = {
       description     = "Gitolite user";
-      home            = "/var/lib/gitolite";
+      home            = cfg.dataDir;
       createHome      = true;
       uid             = config.ids.uids.gitolite;
       useDefaultShell = true;
@@ -61,7 +68,7 @@ in
 
       path = [ pkgs.gitolite pkgs.git pkgs.perl pkgs.bash pkgs.openssh ];
       script = ''
-        cd /var/lib/gitolite
+        cd ${cfg.dataDir}
         mkdir -p .gitolite/logs
         if [ ! -d repositories ]; then
           gitolite setup -pk ${pubkeyFile}
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index c98c0511b566..4b398979fbaa 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -36,6 +36,7 @@ let
         # /etc/nixos/configuration.nix.  Do not edit it!
         build-users-group = nixbld
         build-max-jobs = ${toString (cfg.maxJobs)}
+        build-cores = ${toString (cfg.buildCores)}
         build-use-chroot = ${if cfg.useChroot then "true" else "false"}
         build-chroot-dirs = ${toString cfg.chrootDirs} /bin/sh=${sh} $(echo $extraPaths)
         binary-caches = ${toString cfg.binaryCaches}
@@ -74,6 +75,19 @@ in
         ";
       };
 
+      buildCores = mkOption {
+        type = types.int;
+        default = 1;
+        example = 64;
+        description = ''
+          This option defines the maximum number of concurrent tasks during
+          one build. It affects, e.g., -j option for make. The default is 1.
+          Some builds may become non-deterministic with this option; use with
+          care! Packages will only be affected if enableParallelBuilding is
+          set for them.
+        '';
+      };
+
       useChroot = mkOption {
         type = types.bool;
         default = false;
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index e21ef167a4ec..bbbbcbccb9be 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -306,7 +306,7 @@ in {
         example = literalExample ''
           {
             GRAPHITE_USERNAME = "user";
-            GRAPHITE_PASSWORD = "pass"; 
+            GRAPHITE_PASSWORD = "pass";
           }
         '';
       };
@@ -344,7 +344,7 @@ in {
               name: Test
         '';
         example = literalExample ''
-          pushbullet_key: pushbullet_api_key 
+          pushbullet_key: pushbullet_api_key
           alerts:
             - target: stats.seatgeek.app.deal_quality.venue_info_cache.hit
               warning: .5
@@ -456,7 +456,7 @@ in {
       environment.systemPackages = [ pkgs.python27Packages.graphite_web ];
     })
 
-    (mkIf cfg.api.enable { 
+    (mkIf cfg.api.enable {
       systemd.services.graphiteApi = {
         description = "Graphite Api Interface";
         wantedBy = [ "multi-user.target" ];
@@ -472,7 +472,7 @@ in {
           ExecStart = ''
             ${pkgs.python27Packages.waitress}/bin/waitress-serve \
             --host=${cfg.api.host} --port=${toString cfg.api.port} \
-            graphite_api.app:app 
+            graphite_api.app:app
           '';
           User = "graphite";
           Group = "graphite";
@@ -501,7 +501,7 @@ in {
           ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}";
           WorkingDirectory = dataDir;
           User = "graphite";
-          Group = "graphite"; 
+          Group = "graphite";
         };
         preStart = ''
           if ! test -e ${dataDir}/db-created; then
@@ -526,7 +526,7 @@ in {
         serviceConfig = {
           ExecStart = "${pkgs.pythonPackages.graphite_pager}/bin/graphite-pager --config ${pagerConfig}";
           User = "graphite";
-          Group = "graphite"; 
+          Group = "graphite";
         };
       };
 
@@ -535,7 +535,11 @@ in {
       environment.systemPackages = [ pkgs.pythonPackages.graphite_pager ];
     })
 
-    {
+    (mkIf (
+      cfg.carbon.enableCache || cfg.carbon.enableAggregator || cfg.carbon.enableRelay ||
+      cfg.web.enable || cfg.api.enable ||
+      cfg.seyren.enable || cfg.pager.enable
+     ) {
       users.extraUsers = singleton {
         name = "graphite";
         uid = config.ids.uids.graphite;
@@ -543,6 +547,6 @@ in {
         home = dataDir;
       };
       users.extraGroups.graphite.gid = config.ids.gids.graphite;
-    }
+    })
   ];
 }
diff --git a/nixos/modules/services/monitoring/zabbix-server.nix b/nixos/modules/services/monitoring/zabbix-server.nix
index ca283ea2a99f..acd1279ddf47 100644
--- a/nixos/modules/services/monitoring/zabbix-server.nix
+++ b/nixos/modules/services/monitoring/zabbix-server.nix
@@ -32,6 +32,8 @@ let
       ${optionalString (cfg.dbPassword != "") ''
         DBPassword = ${cfg.dbPassword}
       ''}
+
+      ${config.services.zabbixServer.extraConfig}
     '';
 
   useLocalPostgres = cfg.dbServer == "localhost" || cfg.dbServer == "";
@@ -46,6 +48,7 @@ in
 
     services.zabbixServer.enable = mkOption {
       default = false;
+      type = types.bool;
       description = ''
         Whether to run the Zabbix server on this machine.
       '';
@@ -53,6 +56,7 @@ in
 
     services.zabbixServer.dbServer = mkOption {
       default = "localhost";
+      type = types.str;
       description = ''
         Hostname or IP address of the database server.
         Use an empty string ("") to use peer authentication.
@@ -61,9 +65,18 @@ in
 
     services.zabbixServer.dbPassword = mkOption {
       default = "";
+      type = types.str;
       description = "Password used to connect to the database server.";
     };
 
+    services.zabbixServer.extraConfig = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        Configuration that is injected verbatim into the configuration file.
+      '';
+    };
+
   };
 
   ###### implementation
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index 02db4a7a5b2b..1b38ea3b679b 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -88,7 +88,7 @@ in
   config = mkIf cfg.enable {
     systemd.services.transmission = {
       description = "Transmission BitTorrent Service";
-      after = [ "network.target" ] ++ optional apparmor "apparmor.service";
+      after = [ "local-fs.target" "network.target" ] ++ optional apparmor "apparmor.service";
       requires = mkIf apparmor [ "apparmor.service" ];
       wantedBy = [ "multi-user.target" ];
 
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index 85458a2ab565..1f0729c1b715 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -109,6 +109,9 @@ let
       "mpm_${mainCfg.multiProcessingModule}"
       "authz_core"
       "unixd"
+      "cache" "cache_disk"
+      "slotmem_shm"
+      "socache_shmcb"
     ]
     ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
     ++ optional enableSSL "ssl"
@@ -160,9 +163,9 @@ let
 
 
   sslConf = ''
-    SSLSessionCache shm:${mainCfg.stateDir}/ssl_scache(512000)
+    SSLSessionCache ${if version24 then "shmcb" else "shm"}:${mainCfg.stateDir}/ssl_scache(512000)
 
-    SSLMutex posixsem
+    ${if version24 then "Mutex" else "SSLMutex"} posixsem
 
     SSLRandomSeed startup builtin
     SSLRandomSeed connect builtin
@@ -420,8 +423,7 @@ in
 
       package = mkOption {
         type = types.package;
-        default = pkgs.apacheHttpd.override { mpm = mainCfg.multiProcessingModule; };
-        example = literalExample "pkgs.apacheHttpd_2_4";
+        default = pkgs.apacheHttpd;
         description = ''
           Overridable attribute of the Apache HTTP Server package to use.
         '';
@@ -593,11 +595,11 @@ in
   ###### implementation
 
   config = mkIf config.services.httpd.enable {
-  
+
     assertions = [ { assertion = mainCfg.enableSSL == true
                                -> mainCfg.sslServerCert != null
                                     && mainCfg.sslServerKey != null;
-                     message = "SSL is enabled for HTTPD, but sslServerCert and/or sslServerKey haven't been specified."; }
+                     message = "SSL is enabled for httpd, but sslServerCert and/or sslServerKey haven't been specified."; }
                  ];
 
     users.extraUsers = optionalAttrs (mainCfg.user == "wwwrun") (singleton
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 6b09559876ca..e101bbfe72ce 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -128,6 +128,7 @@ let
       cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/
       cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/
       cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
+      cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/
 
       for i in $out/*.rules; do
           substituteInPlace $i \
@@ -137,7 +138,8 @@ let
             --replace ${pkgs.utillinux}/sbin/blkid ${extraUtils}/bin/blkid \
             --replace /sbin/blkid ${extraUtils}/bin/blkid \
             --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
-            --replace /sbin/mdadm ${extraUtils}/bin/mdadm
+            --replace /sbin/mdadm ${extraUtils}/bin/mdadm \
+            --replace /bin/sh ${extraUtils}/bin/sh
       done
 
       # Work around a bug in QEMU, which doesn't implement the "READ
diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix
index 54a376c9560e..4b4284d85319 100644
--- a/nixos/modules/testing/test-instrumentation.nix
+++ b/nixos/modules/testing/test-instrumentation.nix
@@ -98,7 +98,7 @@ let kernel = config.boot.kernelPackages.kernel; in
     networking.usePredictableInterfaceNames = false;
 
     # Make it easy to log in as root when running the test interactively.
-    security.initialRootPassword = mkDefault "";
+    users.extraUsers.root.initialHashedPassword = mkOverride 150 "";
 
   };
 
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index 552d787b4478..d175bac3074d 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -191,10 +191,5 @@ in
     environment.systemPackages = [ pkgs.cryptsetup ];
 
     boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
-
-    # Prevent logging in as root without a password.  This doesn't really matter,
-    # since the only PAM services that allow logging in with a null
-    # password are local ones that are inaccessible on EC2 machines.
-    security.initialRootPassword = mkDefault "!";
   };
 }
diff --git a/nixos/modules/virtualisation/docker-image.nix b/nixos/modules/virtualisation/docker-image.nix
index 13b861dc9884..cabb1712b6c0 100644
--- a/nixos/modules/virtualisation/docker-image.nix
+++ b/nixos/modules/virtualisation/docker-image.nix
@@ -38,8 +38,8 @@ in {
     '';
 
 
-  # docker image config
-  require = [
+  # Docker image config.
+  imports = [
     ../installer/cd-dvd/channel.nix
     ../profiles/minimal.nix
     ../profiles/clone-config.nix
@@ -47,16 +47,16 @@ in {
 
   boot.isContainer = true;
 
-  # Iptables do not work in docker
+  # Iptables do not work in Docker.
   networking.firewall.enable = false;
 
   services.openssh.enable = true;
 
-  # Socket activated ssh presents problem in docker
+  # Socket activated ssh presents problem in Docker.
   services.openssh.startWhenNeeded = false;
 
-  # Allow the user to login as root without password
-  security.initialRootPassword = "";
+  # Allow the user to login as root without password.
+  users.extraUsers.root.initialHashedPassword = mkOverride 150 "";
 
   # Some more help text.
   services.mingetty.helpLine =
diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix
index df30283e3155..6f2925e52fa4 100644
--- a/nixos/tests/gnome3.nix
+++ b/nixos/tests/gnome3.nix
@@ -11,6 +11,8 @@ import ./make-test.nix {
       services.xserver.displayManager.auto.enable = true;
       services.xserver.displayManager.auto.user = "alice";
       services.xserver.desktopManager.gnome3.enable = true;
+
+      virtualisation.memorySize = 512;
     };
 
   testScript =
diff --git a/nixos/tests/gnome3_12.nix b/nixos/tests/gnome3_12.nix
index 723d1bc45229..3b38d779b6f8 100644
--- a/nixos/tests/gnome3_12.nix
+++ b/nixos/tests/gnome3_12.nix
@@ -12,6 +12,8 @@ import ./make-test.nix {
       services.xserver.displayManager.auto.user = "alice";
       services.xserver.desktopManager.gnome3.enable = true;
       environment.gnome3.packageSet = pkgs.gnome3_12;
+
+      virtualisation.memorySize = 512;
     };
 
   testScript =
diff --git a/nixos/tests/proxy.nix b/nixos/tests/proxy.nix
index 01f0f3fe17a3..8350bc5c6a4b 100644
--- a/nixos/tests/proxy.nix
+++ b/nixos/tests/proxy.nix
@@ -22,20 +22,19 @@ in
 
         { services.httpd.enable = true;
           services.httpd.adminAddr = "bar@example.org";
-          services.httpd.extraModules = ["proxy_balancer"];
+          services.httpd.extraModules = [ "proxy_balancer" "lbmethod_byrequests" ];
 
           services.httpd.extraConfig =
             ''
               ExtendedStatus on
 
               <Location /server-status>
-                Order deny,allow
-                Allow from all
+                Require all granted
                 SetHandler server-status
               </Location>
 
               <Proxy balancer://cluster>
-                Allow from all
+                Require all granted
                 BalancerMember http://${nodes.backend1.config.networking.hostName} retry=0
                 BalancerMember http://${nodes.backend2.config.networking.hostName} retry=0
               </Proxy>
diff --git a/nixos/tests/run-in-machine.nix b/nixos/tests/run-in-machine.nix
index 7f6e6a6dc573..d1102f8d4073 100644
--- a/nixos/tests/run-in-machine.nix
+++ b/nixos/tests/run-in-machine.nix
@@ -2,9 +2,7 @@
 
 with import ../lib/testing.nix { inherit system; };
 
-{
-  test = runInMachine {
-    drv = pkgs.hello;
-    machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
-  };
+runInMachine {
+  drv = pkgs.hello;
+  machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
 }