summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/default.nix16
-rw-r--r--nixos/doc/manual/configuration/configuration.xml1
-rw-r--r--nixos/doc/manual/default.nix1
-rw-r--r--nixos/doc/manual/installation/obtaining.xml4
-rw-r--r--nixos/doc/manual/release-notes/rl-unstable.xml35
-rw-r--r--nixos/modules/config/i18n.nix17
-rw-r--r--nixos/modules/misc/ids.nix3
-rw-r--r--nixos/modules/misc/nixos.nix82
-rw-r--r--nixos/modules/misc/nixos.xml84
-rw-r--r--nixos/modules/module-list.nix8
-rw-r--r--nixos/modules/profiles/base.nix4
-rw-r--r--nixos/modules/programs/bash/bash.nix4
-rw-r--r--nixos/modules/programs/environment.nix4
-rw-r--r--nixos/modules/programs/ibus.nix2
-rw-r--r--nixos/modules/programs/zsh/zsh.nix22
-rw-r--r--nixos/modules/services/cluster/kubernetes.nix1
-rw-r--r--nixos/modules/services/continuous-integration/jenkins/job-builder.nix155
-rw-r--r--nixos/modules/services/databases/influxdb.nix239
-rw-r--r--nixos/modules/services/hardware/actkbd.nix3
-rw-r--r--nixos/modules/services/hardware/tlp.nix24
-rw-r--r--nixos/modules/services/mail/postfix.nix39
-rw-r--r--nixos/modules/services/misc/autofs.nix45
-rw-r--r--nixos/modules/services/misc/bepasty.nix151
-rw-r--r--nixos/modules/services/misc/devmon.nix8
-rw-r--r--nixos/modules/services/misc/ihaskell.nix6
-rw-r--r--nixos/modules/services/monitoring/bosun.nix38
-rw-r--r--nixos/modules/services/monitoring/grafana.nix193
-rw-r--r--nixos/modules/services/monitoring/heapster.nix57
-rw-r--r--nixos/modules/services/monitoring/longview.nix118
-rw-r--r--nixos/modules/services/networking/i2pd.nix172
-rw-r--r--nixos/modules/services/networking/networkmanager.nix20
-rw-r--r--nixos/modules/services/networking/nix-serve.nix2
-rw-r--r--nixos/modules/services/networking/quassel.nix13
-rw-r--r--nixos/modules/services/networking/tlsdated.nix2
-rw-r--r--nixos/modules/services/networking/wakeonlan.nix2
-rw-r--r--nixos/modules/services/scheduling/cron.nix2
-rw-r--r--nixos/modules/services/torrent/transmission.nix8
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix2
-rw-r--r--nixos/modules/services/web-servers/lighttpd/default.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix137
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix10
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix6
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix2
-rw-r--r--nixos/modules/services/x11/display-managers/slim.nix5
-rw-r--r--nixos/modules/services/x11/redshift.nix12
-rw-r--r--nixos/modules/services/x11/window-managers/clfswm.nix31
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix1
-rw-r--r--nixos/modules/services/x11/window-managers/xmonad.nix6
-rw-r--r--nixos/modules/system/boot/initrd-network.nix149
-rw-r--r--nixos/modules/system/boot/luksroot.nix26
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh4
-rw-r--r--nixos/modules/system/boot/stage-1.nix12
-rw-r--r--nixos/modules/system/boot/systemd-unit-options.nix9
-rw-r--r--nixos/modules/system/boot/systemd.nix8
-rw-r--r--nixos/modules/tasks/filesystems.nix16
-rw-r--r--nixos/modules/tasks/kbd.nix4
-rw-r--r--nixos/modules/tasks/network-interfaces.nix45
-rw-r--r--nixos/modules/tasks/scsi-link-power-management.nix34
-rw-r--r--nixos/modules/virtualisation/docker.nix7
-rw-r--r--nixos/modules/virtualisation/virtualbox-host.nix3
-rw-r--r--nixos/release.nix2
-rw-r--r--nixos/tests/gnome3_18.nix36
-rw-r--r--nixos/tests/nixos-pin-version.nix57
-rw-r--r--nixos/tests/sddm.nix28
64 files changed, 1706 insertions, 532 deletions
diff --git a/nixos/default.nix b/nixos/default.nix
index 5d69b79e13a6..6359d10c8805 100644
--- a/nixos/default.nix
+++ b/nixos/default.nix
@@ -1,12 +1,20 @@
 { configuration ? import ./lib/from-env.nix "NIXOS_CONFIG" <nixos-config>
 , system ? builtins.currentSystem
+, extraModules ? []
+  # This attribute is used to specify a different nixos version, a different
+  # system or additional modules which might be set conditionally.
+, reEnter ? false
 }:
 
 let
+  reEnterModule = {
+    config.nixos.path = with (import ../lib); mkIf reEnter (mkForce null);
+    config.nixos.configuration = configuration;
+  };
 
   eval = import ./lib/eval-config.nix {
     inherit system;
-    modules = [ configuration ];
+    modules = [ configuration reEnterModule ] ++ extraModules;
   };
 
   inherit (eval) pkgs;
@@ -14,14 +22,14 @@ let
   # This is for `nixos-rebuild build-vm'.
   vmConfig = (import ./lib/eval-config.nix {
     inherit system;
-    modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
+    modules = [ configuration reEnterModule ./modules/virtualisation/qemu-vm.nix ] ++ extraModules;
   }).config;
 
   # This is for `nixos-rebuild build-vm-with-bootloader'.
   vmWithBootLoaderConfig = (import ./lib/eval-config.nix {
     inherit system;
     modules =
-      [ configuration
+      [ configuration reEnterModule
         ./modules/virtualisation/qemu-vm.nix
         { virtualisation.useBootLoader = true; }
       ];
@@ -30,7 +38,7 @@ let
 in
 
 {
-  inherit (eval) config options;
+  inherit (eval.config.nixos.reflect) config options;
 
   system = eval.config.system.build.toplevel;
 
diff --git a/nixos/doc/manual/configuration/configuration.xml b/nixos/doc/manual/configuration/configuration.xml
index 8fde0dc7e611..afffd60bc485 100644
--- a/nixos/doc/manual/configuration/configuration.xml
+++ b/nixos/doc/manual/configuration/configuration.xml
@@ -26,6 +26,7 @@ effect after you run <command>nixos-rebuild</command>.</para>
 
 <!-- FIXME: auto-include NixOS module docs -->
 <xi:include href="postgresql.xml" />
+<xi:include href="nixos.xml" />
 
 <!-- Apache; libvirtd virtualisation -->
 
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 87964e27bb9c..844cba57cd85 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -55,6 +55,7 @@ let
       cp -prd $sources/* . # */
       chmod -R u+w .
       cp ${../../modules/services/databases/postgresql.xml} configuration/postgresql.xml
+      cp ${../../modules/misc/nixos.xml} configuration/nixos.xml
       ln -s ${optionsDocBook} options-db.xml
       echo "${version}" > version
     '';
diff --git a/nixos/doc/manual/installation/obtaining.xml b/nixos/doc/manual/installation/obtaining.xml
index afd6c9543f70..f6e8b218e2b3 100644
--- a/nixos/doc/manual/installation/obtaining.xml
+++ b/nixos/doc/manual/installation/obtaining.xml
@@ -39,8 +39,8 @@ running NixOS system through several other means:
     <para>Using NixOps, the NixOS-based cloud deployment tool, which
     allows you to provision VirtualBox and EC2 NixOS instances from
     declarative specifications.  Check out the <link
-    xlink:href="https://github.com/NixOS/nixops">NixOps
-    homepage</link> for details.</para>
+    xlink:href="https://nixos.org/nixops">NixOps homepage</link> for
+    details.</para>
   </listitem>
 </itemizedlist>
 
diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml
index 573b99d4902f..97ac03a770f6 100644
--- a/nixos/doc/manual/release-notes/rl-unstable.xml
+++ b/nixos/doc/manual/release-notes/rl-unstable.xml
@@ -6,6 +6,26 @@
 
 <title>Unstable</title>
 
+<para>In addition to numerous new and upgraded packages, this release
+has the following highlights:</para>
+
+<itemizedlist>
+
+  <listitem>
+    <para>You can now pin a specific version of NixOS in your <filename>configuration.nix</filename>
+    by setting:
+
+<programlisting>
+nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
+</programlisting>
+
+    This will make NixOS re-evaluate your configuration with the modules of
+    the specified NixOS version at the given path.  For more details, see
+    <xref linkend="module-misc-nixos" /></para>
+  </listitem>
+
+</itemizedlist>
+
 <para>When upgrading from a previous release, please be aware of the
 following incompatible changes:</para>
 
@@ -54,6 +74,21 @@ nginx.override {
     </para>
   </listitem>
 
+  <listitem>
+    <para><command>s3sync</command> is removed, as it hasn't been
+    developed by upstream for 4 years and only runs with ruby 1.8.
+    For an actively-developer alternative look at
+    <command>tarsnap</command> and others.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para><command>ruby_1_8</command> has been removed as it's not
+    supported from upstream anymore and probably contains security
+    issues.
+    </para>
+  </listitem>
+
 </itemizedlist>
 
 </section>
diff --git a/nixos/modules/config/i18n.nix b/nixos/modules/config/i18n.nix
index f58e540a6e5c..b20fac6ad3e2 100644
--- a/nixos/modules/config/i18n.nix
+++ b/nixos/modules/config/i18n.nix
@@ -74,6 +74,23 @@ in
         '';
       };
 
+      consoleColors = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        example = [
+          "002b36" "dc322f" "859900" "b58900"
+          "268bd2" "d33682" "2aa198" "eee8d5"
+          "002b36" "cb4b16" "586e75" "657b83"
+          "839496" "6c71c4" "93a1a1" "fdf6e3"
+        ];
+        description = ''
+          The 16 colors palette used by the virtual consoles.
+          Leave empty to use the default colors.
+          Colors must be in hexadecimal format and listed in
+          order from color 0 to color 15.
+        '';
+      };
+
     };
 
   };
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 7ade145ad73a..2b40120641a0 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -235,6 +235,8 @@
       kibana = 211;
       xtreemfs = 212;
       calibre-server = 213;
+      heapster = 214;
+      bepasty = 215;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -448,6 +450,7 @@
       #kibana = 211;
       xtreemfs = 212;
       calibre-server = 213;
+      bepasty = 215;
 
       # 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/nixos.nix b/nixos/modules/misc/nixos.nix
new file mode 100644
index 000000000000..356129211d06
--- /dev/null
+++ b/nixos/modules/misc/nixos.nix
@@ -0,0 +1,82 @@
+{ config, options, lib, ... }:
+
+# This modules is used to inject a different NixOS version as well as its
+# argument such that one can pin a specific version with the versionning
+# system of the configuration.
+let
+  nixosReentry = import config.nixos.path {
+    inherit (config.nixos) configuration extraModules;
+    inherit (config.nixpkgs) system;
+    reEnter = true;
+  };
+in
+
+with lib;
+
+{
+  options = {
+    nixos.path = mkOption {
+      default = null;
+      example = literalExample "./nixpkgs-15.09/nixos";
+      type = types.nullOr types.path;
+      description = ''
+        This option give the ability to evaluate the current set of modules
+        with a different version of NixOS. This option can be used version
+        the version of NixOS with the configuration without relying on the
+        <literal>NIX_PATH</literal> environment variable.
+      '';
+    };
+
+    nixos.system = mkOption {
+      example = "i686-linux";
+      type = types.uniq types.str;
+      description = ''
+        Name of the system used to compile NixOS.
+      '';
+    };
+
+    nixos.extraModules = mkOption {
+      default = [];
+      example = literalExample "mkIf config.services.openssh.enable [ ./sshd-config.nix ]";
+      type = types.listOf types.unspecified;
+      description = ''
+        Define additional modules which would be loaded to evaluate the
+        configuration.
+      '';
+    };
+
+    nixos.configuration = mkOption {
+      type = types.unspecified;
+      internal = true;
+      description = ''
+        Option used by <filename>nixos/default.nix</filename> to re-inject
+        the same configuration module as the one used for the current
+        execution.
+      '';
+    };
+
+    nixos.reflect = mkOption {
+      default = { inherit config options; };
+      type = types.unspecified;
+      internal = true;
+      description = ''
+        Provides <literal>config</literal> and <literal>options</literal>
+        computed by the module system and given as argument to all
+        modules. These are used for introspection of options and
+        configuration by tools such as <literal>nixos-option</literal>.
+      '';
+    };
+  };
+
+  config = mkMerge [
+    (mkIf (config.nixos.path != null) (mkForce {
+      system.build.toplevel = nixosReentry.system;
+      system.build.vm = nixosReentry.vm;
+      nixos.reflect = { inherit (nixosReentry) config options; };
+    }))
+
+    { meta.maintainers = singleton lib.maintainers.pierron;
+      meta.doc = ./nixos.xml;
+    }
+  ];
+}
diff --git a/nixos/modules/misc/nixos.xml b/nixos/modules/misc/nixos.xml
new file mode 100644
index 000000000000..f8d3b4bc6e33
--- /dev/null
+++ b/nixos/modules/misc/nixos.xml
@@ -0,0 +1,84 @@
+<chapter xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         version="5.0"
+         xml:id="module-misc-nixos">
+
+<title>NixOS Reentry</title>
+
+<!-- FIXME: render nicely -->
+
+<!-- FIXME: source can be added automatically -->
+<para><emphasis>Source:</emphasis> <filename>modules/misc/nixos.nix</filename></para>
+
+<!-- FIXME: more stuff, like maintainer? -->
+
+<para>NixOS reentry can be used for both pinning the evaluation to a
+specific version of NixOS, and to dynamically add additional modules into
+the Module evaluation.</para>
+
+<section><title>NixOS Version Pinning</title>
+
+<para>To pin a specific version of NixOS, you need a version that you can
+either clone localy, or that you can fetch remotely.</para>
+
+<para>If you already have a cloned version of NixOS in the directory
+<filename>/etc/nixos/nixpkgs-16-03</filename>, then you can specify the
+<option>nixos.path</option> with either the path or the relative path of
+your NixOS clone. For example, you can add the following to your
+<filename>/etc/nixos/configuration.nix</filename> file:
+
+<programlisting>
+nixos.path = ./nixpkgs-16-03/nixos;
+</programlisting>
+</para>
+
+<para>Another option is to fetch a specific version of NixOS, with either
+the <literal>fetchTarball</literal> builtin, or the
+<literal>pkgs.fetchFromGithub</literal> function and use the result as an
+input.
+
+<programlisting>
+nixos.path = "${builtins.fetchTarball https://github.com/NixOS/nixpkgs/archive/1f27976e03c15183191d1b4aa1a40d1f14666cd2.tar.gz}/nixos";
+</programlisting>
+</para>
+
+</section>
+
+
+<section><title>Adding Module Dynamically</title>
+
+<para>To add additional module, the recommended way is to use statically
+known modules in the list of imported arguments as described in <xref
+linkend="sec-modularity" />.  Unfortunately, this recommended method has
+limitation, such that the list of imported files cannot be selected based on
+the content of the configuration.
+
+Fortunately, NixOS reentry system can be used as an alternative to register
+new imported modules based on the content of the configuration. To do so,
+one should define both <option>nixos.path</option> and
+<option>nixos.extraModules</option> options.
+
+<programlisting>
+nixos.path = &lt;nixos&gt;;
+nixos.extraModules =
+  if config.networking.hostName == "server" then
+    [ ./server.nix ] else [ ./client.nix ];
+</programlisting>
+
+Also note, that the above can be reimplemented in a different way which is
+not as expensive, by using <literal>mkIf</literal> at the top each
+configuration if both modules are present on the file system (see <xref
+linkend="sec-option-definitions" />) and by always inmporting both
+modules.</para>
+
+</section>
+
+<section><title>Options</title>
+
+<para>FIXME: auto-generated list of module options.</para>
+
+</section>
+
+
+</chapter>
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 9fcb01beaf0f..a8cf38f1c8fe 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -52,6 +52,7 @@
   ./misc/lib.nix
   ./misc/locate.nix
   ./misc/meta.nix
+  ./misc/nixos.nix
   ./misc/nixpkgs.nix
   ./misc/passthru.nix
   ./misc/version.nix
@@ -118,6 +119,7 @@
   ./services/computing/slurm/slurm.nix
   ./services/continuous-integration/jenkins/default.nix
   ./services/continuous-integration/jenkins/slave.nix
+  ./services/continuous-integration/jenkins/job-builder.nix
   ./services/databases/4store-endpoint.nix
   ./services/databases/4store.nix
   ./services/databases/couchdb.nix
@@ -187,7 +189,8 @@
   ./services/mail/postfix.nix
   ./services/mail/spamassassin.nix
   ./services/misc/apache-kafka.nix
-  #./services/misc/autofs.nix
+  ./services/misc/autofs.nix
+  ./services/misc/bepasty.nix
   ./services/misc/canto-daemon.nix
   ./services/misc/calibre-server.nix
   ./services/misc/cpuminer-cryptonight.nix
@@ -237,6 +240,8 @@
   ./services/monitoring/dd-agent.nix
   ./services/monitoring/grafana.nix
   ./services/monitoring/graphite.nix
+  ./services/monitoring/heapster.nix
+  ./services/monitoring/longview.nix
   ./services/monitoring/monit.nix
   ./services/monitoring/munin.nix
   ./services/monitoring/nagios.nix
@@ -440,6 +445,7 @@
   ./system/activation/top-level.nix
   ./system/boot/coredump.nix
   ./system/boot/emergency-mode.nix
+  ./system/boot/initrd-network.nix
   ./system/boot/kernel.nix
   ./system/boot/kexec.nix
   ./system/boot/loader/efi.nix
diff --git a/nixos/modules/profiles/base.nix b/nixos/modules/profiles/base.nix
index 9aa0034783fa..b8057cadce25 100644
--- a/nixos/modules/profiles/base.nix
+++ b/nixos/modules/profiles/base.nix
@@ -1,7 +1,7 @@
 # This module defines the software packages included in the "minimal"
 # installation CD.  It might be useful elsewhere.
 
-{ config, pkgs, ... }:
+{ config, lib, pkgs, ... }:
 
 {
   # Include some utilities that are useful for installing or repairing
@@ -50,5 +50,5 @@
   boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "zfs" "ntfs" "cifs" ];
 
   # Configure host id for ZFS to work
-  networking.hostId = "8425e349";
+  networking.hostId = lib.mkDefault "8425e349";
 }
diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix
index 75efd5e29039..1c3c07a1c210 100644
--- a/nixos/modules/programs/bash/bash.nix
+++ b/nixos/modules/programs/bash/bash.nix
@@ -90,8 +90,8 @@ in
 
       promptInit = mkOption {
         default = ''
-          if test "$TERM" != "dumb"; then
-            # Provide a nice prompt.
+          # Provide a nice prompt if the terminal supports it.
+          if [ "$TERM" != "dumb" -o -n "$INSIDE_EMACS" ]; then
             PROMPT_COLOR="1;31m"
             let $UID && PROMPT_COLOR="1;32m"
             PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index 52f6cc221119..a35b5cc9513e 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -38,9 +38,7 @@ in
         PERL5LIB = [ "/lib/perl5/site_perl" ];
         KDEDIRS = [ "" ];
         STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
-        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" "/lib/qt5/plugins" ];
-        QML_IMPORT_PATH = [ "/lib/qt5/imports" ];
-        QML2_IMPORT_PATH = [ "/lib/qt5/qml" ];
+        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
         QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
         GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
         XDG_CONFIG_DIRS = [ "/etc/xdg" ];
diff --git a/nixos/modules/programs/ibus.nix b/nixos/modules/programs/ibus.nix
index b8702a743d8a..a42753a292b2 100644
--- a/nixos/modules/programs/ibus.nix
+++ b/nixos/modules/programs/ibus.nix
@@ -27,7 +27,7 @@ in
   };
 
   config = mkIf cfg.enable {
-    environment.systemPackages = [ pkgs.ibus ];
+    environment.systemPackages = [ pkgs.ibus pkgs.gnome3.dconf ];
 
     gtkPlugins = [ pkgs.ibus ];
     qtPlugins = [ pkgs.ibus-qt ];
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index 74dd6af0bdde..dae7e446b4cf 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -25,7 +25,7 @@ in
       enable = mkOption {
         default = false;
         description = ''
-          Whenever to configure Zsh as an interactive shell.
+          Whether to configure zsh as an interactive shell.
         '';
         type = types.bool;
       };
@@ -73,6 +73,14 @@ in
         type = types.lines;
       };
 
+      enableCompletion = mkOption {
+        default = true;
+        description = ''
+          Enable zsh completion for all interactive zsh shells.
+        '';
+        type = types.bool;
+      };
+
     };
 
   };
@@ -101,6 +109,13 @@ in
         export HISTFILE=$HOME/.zsh_history
 
         setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
+
+        # Tell zsh how to find installed completions
+        for p in ''${(z)NIX_PROFILES}; do
+          fpath+=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions)
+        done
+
+        ${if cfg.enableCompletion then "autoload -U compinit && compinit" else ""}
       '';
 
     };
@@ -161,7 +176,10 @@ in
 
     environment.etc."zinputrc".source = ./zinputrc;
 
-    environment.systemPackages = [ pkgs.zsh ];
+    environment.systemPackages = [ pkgs.zsh ]
+      ++ optional cfg.enableCompletion pkgs.nix-zsh-completions;
+
+    environment.pathsToLink = optional cfg.enableCompletion "/share/zsh";
 
     #users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh";
 
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
index a06384e27139..42efde36678f 100644
--- a/nixos/modules/services/cluster/kubernetes.nix
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -512,6 +512,7 @@ in {
         wantedBy = [ "multi-user.target" ];
         requires = ["kubernetes-setup.service"];
         after = [ "network-interfaces.target" "etcd.service" "docker.service" ];
+        path = [ pkgs.gitMinimal pkgs.openssh ];
         script = ''
           export PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH"
           exec ${cfg.package}/bin/kubelet \
diff --git a/nixos/modules/services/continuous-integration/jenkins/job-builder.nix b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
new file mode 100644
index 000000000000..ec15a6a3d706
--- /dev/null
+++ b/nixos/modules/services/continuous-integration/jenkins/job-builder.nix
@@ -0,0 +1,155 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  jenkinsCfg = config.services.jenkins;
+  cfg = config.services.jenkins.jobBuilder;
+
+in {
+  options = {
+    services.jenkins.jobBuilder = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether or not to enable the Jenkins Job Builder (JJB) service. It
+          allows defining jobs for Jenkins in a declarative manner.
+
+          Jobs managed through the Jenkins WebUI (or by other means) are left
+          unchanged.
+
+          Note that it really is declarative configuration; if you remove a
+          previously defined job, the corresponding job directory will be
+          deleted.
+
+          Please see the Jenkins Job Builder documentation for more info:
+          <link xlink:href="http://docs.openstack.org/infra/jenkins-job-builder/">
+          http://docs.openstack.org/infra/jenkins-job-builder/</link>
+        '';
+      };
+
+      yamlJobs = mkOption {
+        default = "";
+        type = types.lines;
+        example = ''
+          - job:
+              name: jenkins-job-test-1
+              builders:
+                - shell: echo 'Hello world!'
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in YAML format.
+        '';
+      };
+
+      jsonJobs = mkOption {
+        default = [ ];
+        type = types.listOf types.str;
+        example = literalExample ''
+          [
+            '''
+              [ { "job":
+                  { "name": "jenkins-job-test-2",
+                    "builders": [ "shell": "echo 'Hello world!'" ]
+                  }
+                }
+              ]
+            '''
+          ]
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in JSON format.
+        '';
+      };
+
+      nixJobs = mkOption {
+        default = [ ];
+        type = types.listOf types.attrs;
+        example = literalExample ''
+          [ { job =
+              { name = "jenkins-job-test-3";
+                builders = [
+                  { shell = "echo 'Hello world!'"; }
+                ];
+              };
+            }
+          ];
+        '';
+        description = ''
+          Job descriptions for Jenkins Job Builder in Nix format.
+
+          This is a trivial wrapper around jsonJobs, using builtins.toJSON
+          behind the scene.
+        '';
+      };
+    };
+  };
+
+  config = mkIf (jenkinsCfg.enable && cfg.enable) {
+    systemd.services.jenkins-job-builder = {
+      description = "Jenkins Job Builder Service";
+      # JJB can run either before or after jenkins. We chose after, so we can
+      # always use curl to notify (running) jenkins to reload its config.
+      after = [ "jenkins.service" ];
+      wantedBy = [ "multi-user.target" ];
+
+      path = with pkgs; [ jenkins-job-builder curl ];
+
+      # Q: Why manipulate files directly instead of using "jenkins-jobs upload [...]"?
+      # A: Because this module is for administering a local jenkins install,
+      #    and using local file copy allows us to not worry about
+      #    authentication.
+      script =
+        let
+          yamlJobsFile = builtins.toFile "jobs.yaml" cfg.yamlJobs;
+          jsonJobsFiles =
+            map (x: (builtins.toFile "jobs.json" x))
+              (cfg.jsonJobs ++ [(builtins.toJSON cfg.nixJobs)]);
+          jobBuilderOutputDir = "/run/jenkins-job-builder/output";
+          # Stamp file is placed in $JENKINS_HOME/jobs/$JOB_NAME/ to indicate
+          # ownership. Enables tracking and removal of stale jobs.
+          ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder";
+        in
+          ''
+            rm -rf ${jobBuilderOutputDir}
+            cur_decl_jobs=/run/jenkins-job-builder/declarative-jobs
+            rm -f "$cur_decl_jobs"
+
+            # Create / update jobs
+            mkdir -p ${jobBuilderOutputDir}
+            for inputFile in ${yamlJobsFile} ${concatStringsSep " " jsonJobsFiles}; do
+                HOME="${jenkinsCfg.home}" "${pkgs.jenkins-job-builder}/bin/jenkins-jobs" --ignore-cache test -o "${jobBuilderOutputDir}" "$inputFile"
+            done
+
+            for file in "${jobBuilderOutputDir}/"*; do
+                test -f "$file" || continue
+                jobname="$(basename $file)"
+                jobdir="${jenkinsCfg.home}/jobs/$jobname"
+                echo "Creating / updating job \"$jobname\""
+                mkdir -p "$jobdir"
+                touch "$jobdir/${ownerStamp}"
+                cp "$file" "$jobdir/config.xml"
+                echo "$jobname" >> "$cur_decl_jobs"
+            done
+
+            # Remove stale jobs
+            for file in "${jenkinsCfg.home}"/jobs/*/${ownerStamp}; do
+                test -f "$file" || continue
+                jobdir="$(dirname $file)"
+                jobname="$(basename "$jobdir")"
+                grep --quiet --line-regexp "$jobname" "$cur_decl_jobs" 2>/dev/null && continue
+                echo "Deleting stale job \"$jobname\""
+                rm -rf "$jobdir"
+            done
+
+            echo "Asking Jenkins to reload config"
+            curl --silent -X POST http://localhost:${toString jenkinsCfg.port}/reload
+          '';
+      serviceConfig = {
+        User = jenkinsCfg.user;
+        RuntimeDirectory = "jenkins-job-builder";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/databases/influxdb.nix b/nixos/modules/services/databases/influxdb.nix
index 08963f7aab7f..8d63f14c67b5 100644
--- a/nixos/modules/services/databases/influxdb.nix
+++ b/nixos/modules/services/databases/influxdb.nix
@@ -5,43 +5,103 @@ with lib;
 let
   cfg = config.services.influxdb;
 
-  influxdbConfig = pkgs.writeText "config.toml" ''
-    bind-address = "${cfg.bindAddress}"
+  configOptions = recursiveUpdate {
+    meta = {
+      bind-address = ":8088";
+      commit-timeout = "50ms";
+      dir = "${cfg.dataDir}/meta";
+      election-timeout = "1s";
+      heartbeat-timeout = "1s";
+      hostname = "localhost";
+      leader-lease-timeout = "500ms";
+      retention-autocreate = true;
+    };
+
+    data = {
+      dir = "${cfg.dataDir}/data";
+      wal-dir = "${cfg.dataDir}/wal";
+      max-wal-size = 104857600;
+      wal-enable-logging = true;
+      wal-flush-interval = "10m";
+      wal-partition-flush-delay = "2s";
+    };
+
+    cluster = {
+      shard-writer-timeout = "5s";
+      write-timeout = "5s";
+    };
 
-    [logging]
-    level  = "info"
-    file   = "stdout"
+    retention = {
+      enabled = true;
+      check-interval = "30m";
+    };
 
-    [admin]
-    port   = ${toString cfg.adminPort}
-    assets = "${pkgs.influxdb}/share/influxdb/admin"
+    http = {
+      enabled = true;
+      auth-enabled = false;
+      bind-address = ":8086";
+      https-enabled = false;
+      log-enabled = true;
+      pprof-enabled = false;
+      write-tracing = false;
+    };
 
-    [api]
-    port   = ${toString cfg.apiPort}
-    ${cfg.apiExtraConfig}
+    monitor = {
+      store-enabled = false;
+      store-database = "_internal";
+      store-interval = "10s";
+    };
 
-    [input_plugins]
-      ${cfg.inputPluginsConfig}
+    admin = {
+      enabled = true;
+      bind-address = ":8083";
+      https-enabled = false;
+    };
 
-    [raft]
-    dir = "${cfg.dataDir}/raft"
-    ${cfg.raftConfig}
+    graphite = [{
+      enabled = false;
+    }];
 
-    [storage]
-    dir = "${cfg.dataDir}/db"
-    ${cfg.storageConfig}
+    udp = [{
+      enabled = false;
+    }];
 
-    [cluster]
-    ${cfg.clusterConfig}
+    collectd = {
+      enabled = false;
+      typesdb = "${pkgs.collectd}/share/collectd/types.db";
+      database = "collectd_db";
+      port = 25826;
+    };
 
-    [sharding]
-      ${cfg.shardingConfig}
+    opentsdb = {
+      enabled = false;
+    };
 
-    [wal]
-    dir = "${cfg.dataDir}/wal"
-    ${cfg.walConfig}
+    continuous_queries = {
+      enabled = true;
+      log-enabled = true;
+      recompute-previous-n = 2;
+      recompute-no-older-than = "10m";
+      compute-runs-per-interval = 10;
+      compute-no-more-than = "2m";
+    };
 
-    ${cfg.extraConfig}
+    hinted-handoff = {
+      enabled = true;
+      dir = "${cfg.dataDir}/hh";
+      max-size = 1073741824;
+      max-age = "168h";
+      retry-rate-limit = 0;
+      retry-interval = "1s";
+    };
+  } cfg.extraConfig;
+
+  configFile = pkgs.runCommand "config.toml" {
+    buildInputs = [ pkgs.remarshal ];
+  } ''
+    remarshal -if json -of toml \
+      < ${pkgs.writeText "config.json" (builtins.toJSON configOptions)} \
+      > $out
   '';
 in
 {
@@ -82,124 +142,10 @@ in
         type = types.path;
       };
 
-      bindAddress = mkOption {
-        default = "127.0.0.1";
-        description = "Address where influxdb listens";
-        type = types.str;
-      };
-
-      adminPort = mkOption {
-        default = 8083;
-        description = "The port where influxdb admin listens";
-        type = types.int;
-      };
-
-      apiPort = mkOption {
-        default = 8086;
-        description = "The port where influxdb api listens";
-        type = types.int;
-      };
-
-      apiExtraConfig = mkOption {
-        default = ''
-          read-timeout = "5s"
-        '';
-        description = "Extra influxdb api configuration";
-        example = ''
-          ssl-port = 8084
-          ssl-cert = /path/to/cert.pem
-          read-timeout = "5s"
-        '';
-        type = types.lines;
-      };
-
-      inputPluginsConfig = mkOption {
-        default = "";
-        description = "Configuration of influxdb extra plugins";
-        example = ''
-          [input_plugins.graphite]
-          enabled = true
-          port = 2003
-          database = "graphite"
-        '';
-      };
-
-      raftConfig = mkOption {
-        default = ''
-          port = 8090
-        '';
-        description = "Influxdb raft configuration";
-        type = types.lines;
-      };
-
-      storageConfig = mkOption {
-        default = ''
-          write-buffer-size = 10000
-        '';
-        description = "Influxdb raft configuration";
-        type = types.lines;
-      };
-
-      clusterConfig = mkOption {
-        default = ''
-          protobuf_port = 8099
-          protobuf_timeout = "2s"
-          protobuf_heartbeat = "200ms"
-          protobuf_min_backoff = "1s"
-          protobuf_max_backoff = "10s"
-
-          write-buffer-size = 10000
-          max-response-buffer-size = 100
-
-          concurrent-shard-query-limit = 10
-        '';
-        description = "Influxdb cluster configuration";
-        type = types.lines;
-      };
-
-      leveldbConfig = mkOption {
-        default = ''
-          max-open-files = 40
-          lru-cache-size = "200m"
-          max-open-shards = 0
-          point-batch-size = 100
-          write-batch-size = 5000000
-        '';
-        description = "Influxdb leveldb configuration";
-        type = types.lines;
-      };
-
-      shardingConfig = mkOption {
-        default = ''
-          replication-factor = 1
-
-          [sharding.short-term]
-          duration = "7d"
-          split = 1
-
-          [sharding.long-term]
-          duration = "30d"
-          split = 1
-        '';
-        description = "Influxdb sharding configuration";
-        type = types.lines;
-      };
-
-      walConfig = mkOption {
-        default = ''
-          flush-after = 1000
-          bookmark-after = 1000
-          index-after = 1000
-          requests-per-logfile = 10000
-        '';
-        description = "Influxdb write-ahead log configuration";
-        type = types.lines;
-      };
-
       extraConfig = mkOption {
-        default = "";
+        default = {};
         description = "Extra configuration options for influxdb";
-        type = types.string;
+        type = types.attrs;
       };
     };
 
@@ -215,7 +161,7 @@ in
       wantedBy = [ "multi-user.target" ];
       after = [ "network-interfaces.target" ];
       serviceConfig = {
-        ExecStart = ''${cfg.package}/bin/influxdb -config "${influxdbConfig}"'';
+        ExecStart = ''${cfg.package}/bin/influxd -config "${configFile}"'';
         User = "${cfg.user}";
         Group = "${cfg.group}";
         PermissionsStartOnly = true;
@@ -224,11 +170,6 @@ in
         mkdir -m 0770 -p ${cfg.dataDir}
         if [ "$(id -u)" = 0 ]; then chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}; fi
       '';
-      postStart = mkBefore ''
-        until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.bindAddress}:${toString cfg.apiPort}/'; do
-          sleep 1;
-        done
-      '';
     };
 
     users.extraUsers = optional (cfg.user == "influxdb") {
diff --git a/nixos/modules/services/hardware/actkbd.nix b/nixos/modules/services/hardware/actkbd.nix
index 82de362c371b..b16a8f50a3d8 100644
--- a/nixos/modules/services/hardware/actkbd.nix
+++ b/nixos/modules/services/hardware/actkbd.nix
@@ -125,6 +125,9 @@ in
       };
     };
 
+    # For testing
+    environment.systemPackages = [ pkgs.actkbd ];
+
   };
 
 }
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
index f221c82e2eda..23b6edcefd1a 100644
--- a/nixos/modules/services/hardware/tlp.nix
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -6,9 +6,23 @@ let
 
 cfg = config.services.tlp;
 
-tlp = pkgs.tlp.override { kmod = config.system.sbin.modprobe; };
-
-confFile = pkgs.writeText "tlp" (builtins.readFile "${tlp}/etc/default/tlp" + cfg.extraConfig);
+enableRDW = config.networking.networkmanager.enable;
+
+tlp = pkgs.tlp.override {
+  inherit enableRDW;
+  kmod = config.system.sbin.modprobe;
+};
+
+# XXX: We can't use writeTextFile + readFile here because it triggers
+# TLP build to get the .drv (even on --dry-run).
+confFile = pkgs.runCommand "tlp"
+  { config = cfg.extraConfig;
+    passAsFile = [ "config" ];
+  }
+  ''
+    cat ${tlp}/etc/default/tlp > $out
+    cat $configPath >> $out
+  '';
 
 in
 
@@ -81,13 +95,15 @@ in
     environment.etc = [{ source = confFile;
                          target = "default/tlp";
                        }
-                      ] ++ optional tlp.enableRDW {
+                      ] ++ optional enableRDW {
                         source = "${tlp}/etc/NetworkManager/dispatcher.d/99tlp-rdw-nm";
                         target = "NetworkManager/dispatcher.d/99tlp-rdw-nm";
                       };
 
     environment.systemPackages = [ tlp ];
 
+    boot.kernelModules = [ "msr" ];
+
   };
 
 }
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index d1aaebdfdf24..3a9e62a02052 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -11,6 +11,8 @@ let
 
   mainCf =
     ''
+      compatibility_level = 2
+
       queue_directory = /var/postfix/queue
       command_directory = ${pkgs.postfix}/sbin
       daemon_directory = ${pkgs.postfix}/libexec/postfix
@@ -31,10 +33,7 @@ let
           mynetworks_style = ${cfg.networksStyle}
         ''
       else
-        # Postfix default is subnet, but let's play safe
-        ''
-          mynetworks_style = host
-        '')
+        "")
     + optionalString (cfg.hostname != "") ''
       myhostname = ${cfg.hostname}
     ''
@@ -89,7 +88,7 @@ let
   masterCf = ''
     # ==========================================================================
     # service type  private unpriv  chroot  wakeup  maxproc command + args
-    #               (yes)   (yes)   (yes)   (never) (100)
+    #               (yes)   (yes)   (no)    (never) (100)
     # ==========================================================================
     smtp      inet  n       -       n       -       -       smtpd
     #submission inet n       -       n       -       -       smtpd
@@ -232,8 +231,7 @@ in
         default = null;
         example = ["localdomain"];
         description = "
-          List of domains we agree to relay to. Default is the same as
-          destination.
+          List of domains we agree to relay to. Default is empty.
         ";
       };
 
@@ -357,23 +355,20 @@ in
         }
       ];
 
-    jobs.postfix =
-      # I copy _lots_ of shipped configuration filed
-      # that can be left as is. I am afraid the exact
-      # will list slightly change in next Postfix
-      # release, so listing them all one-by-one in an
-      # accurate way is unlikely to be better.
+    systemd.services.postfix =
       { description = "Postfix mail server";
 
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
 
-        daemonType = "fork";
+        serviceConfig = {
+          Type = "forking";
+          Restart = "always";
+          PIDFile = "/var/postfix/queue/pid/master.pid";
+        };
 
         preStart = ''
-          if ! [ -d /var/spool/postfix ]; then
-            ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
-          fi
+          ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
 
           ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix
           ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue
@@ -382,7 +377,7 @@ in
           ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail
           ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/
 
-          ln -sf "${pkgs.postfix}/etc/postfix/"* /var/postfix/conf
+          ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf
 
           ln -sf ${aliasesFile} /var/postfix/conf/aliases
           ln -sf ${virtualFile} /var/postfix/conf/virtual
@@ -391,12 +386,18 @@ in
 
           ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
           ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual
+        '';
 
+        script = ''
           ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
         '';
 
+        reload = ''
+          ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload
+        '';
+
         preStop = ''
-            ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
+          ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
         '';
 
       };
diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix
index f4a1059d09f0..b4dae79cf8a9 100644
--- a/nixos/modules/services/misc/autofs.nix
+++ b/nixos/modules/services/misc/autofs.nix
@@ -71,48 +71,17 @@ in
 
   config = mkIf cfg.enable {
 
-    environment.etc = singleton
-      { target = "auto.master";
-        source = pkgs.writeText "auto.master" cfg.autoMaster;
-      };
-
     boot.kernelModules = [ "autofs4" ];
 
-    jobs.autofs =
+    systemd.services.autofs =
       { description = "Filesystem automounter";
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
 
-        startOn = "started network-interfaces";
-        stopOn = "stopping network-interfaces";
-
-        path = [ pkgs.nfs-utils pkgs.sshfsFuse ];
-
-        preStop =
-          ''
-            set -e; while :; do pkill -TERM automount; sleep 1; done
-          '';
-
-        # automount doesn't clean up when receiving SIGKILL.
-        # umount -l should unmount the directories recursively when they are no longer used
-        # It does, but traces are left in /etc/mtab. So unmount recursively..
-        postStop =
-          ''
-          PATH=${pkgs.gnused}/bin:${pkgs.coreutils}/bin
-          exec &> /tmp/logss
-          # double quote for sed:
-          escapeSpaces(){ sed 's/ /\\\\040/g'; }
-          unescapeSpaces(){ sed 's/\\040/ /g'; }
-          sed -n 's@^\s*\(\([^\\ ]\|\\ \)*\)\s.*@\1@p' ${autoMaster} | sed 's/[\\]//' | while read mountPoint; do
-            sed -n "s@[^ ]\+\s\+\($(echo "$mountPoint"| escapeSpaces)[^ ]*\).*@\1@p" /proc/mounts | sort -r | unescapeSpaces| while read smountP; do
-              ${pkgs.utillinux}/bin/umount -l "$smountP" || true
-            done
-          done
-          '';
-
-        script =
-          ''
-            ${if cfg.debug then "exec &> /var/log/autofs" else ""}
-            exec ${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} "${autoMaster}" ${if cfg.debug then "-l7" else ""}
-          '';
+        serviceConfig = {
+          ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}";
+          ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+        };
       };
 
   };
diff --git a/nixos/modules/services/misc/bepasty.nix b/nixos/modules/services/misc/bepasty.nix
new file mode 100644
index 000000000000..12671cb1b6cd
--- /dev/null
+++ b/nixos/modules/services/misc/bepasty.nix
@@ -0,0 +1,151 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  gunicorn = pkgs.pythonPackages.gunicorn;
+  bepasty = pkgs.pythonPackages.bepasty-server;
+  gevent = pkgs.pythonPackages.gevent;
+  python = pkgs.pythonPackages.python;
+  cfg = config.services.bepasty;
+  user = "bepasty";
+  group = "bepasty";
+  default_home = "/var/lib/bepasty";
+in
+{
+  options.services.bepasty = {
+    enable = mkEnableOption "Bepasty servers";
+
+    servers = mkOption {
+      default = {};
+      description = ''
+        configure a number of bepasty servers which will be started with
+        gunicorn.
+        '';
+      type = with types ; attrsOf (submodule ({
+
+        options = {
+
+          bind = mkOption {
+            type = types.str;
+            description = ''
+              Bind address to be used for this server.
+              '';
+            example = "0.0.0.0:8000";
+            default = "127.0.0.1:8000";
+          };
+
+
+          dataDir = mkOption {
+            type = types.str;
+            description = ''
+              Path to the directory where the pastes will be saved to
+              '';
+            default = default_home+"/data";
+          };
+
+          defaultPermissions = mkOption {
+            type = types.str;
+            description = ''
+              default permissions for all unauthenticated accesses.
+              '';
+            example = "read,create,delete";
+            default = "read";
+          };
+
+          extraConfig = mkOption {
+            type = types.str;
+            description = ''
+              Extra configuration for bepasty server to be appended on the
+              configuration.
+              see https://bepasty-server.readthedocs.org/en/latest/quickstart.html#configuring-bepasty
+              for all options.
+              '';
+            default = "";
+            example = ''
+              PERMISSIONS = {
+                'myadminsecret': 'admin,list,create,read,delete',
+              }
+              MAX_ALLOWED_FILE_SIZE = 5 * 1000 * 1000
+              '';
+          };
+
+          secretKey = mkOption {
+            type = types.str;
+            description = ''
+              server secret for safe session cookies, must be set.
+              '';
+            default = "";
+          };
+
+          workDir = mkOption {
+            type = types.str;
+            description = ''
+              Path to the working directory (used for config and pidfile).
+              Defaults to the users home directory.
+              '';
+            default = default_home;
+          };
+
+        };
+      }));
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ bepasty ];
+
+    # creates gunicorn systemd service for each configured server
+    systemd.services = mapAttrs' (name: server:
+      nameValuePair ("bepasty-server-${name}-gunicorn")
+        ({
+          description = "Bepasty Server ${name}";
+          wantedBy = [ "multi-user.target" ];
+          after = [ "network.target" ];
+          restartIfChanged = true;
+
+          environment = {
+            BEPASTY_CONFIG = "${server.workDir}/bepasty-${name}.conf";
+            PYTHONPATH= "${bepasty}/lib/${python.libPrefix}/site-packages:${gevent}/lib/${python.libPrefix}/site-packages";
+          };
+
+          serviceConfig = {
+            Type = "simple";
+            PrivateTmp = true;
+            ExecStartPre = assert server.secretKey != ""; pkgs.writeScript "bepasty-server.${name}-init" ''
+              #!/bin/sh
+              mkdir -p "${server.workDir}"
+              mkdir -p "${server.dataDir}"
+              chown ${user}:${group} "${server.workDir}" "${server.dataDir}"
+              cat > ${server.workDir}/bepasty-${name}.conf <<EOF
+              SITENAME="${name}"
+              STORAGE_FILESYSTEM_DIRECTORY="${server.dataDir}"
+              SECRET_KEY="${server.secretKey}"
+              DEFAULT_PERMISSIONS="${server.defaultPermissions}"
+              ${server.extraConfig}
+              EOF
+            '';
+            ExecStart = ''${gunicorn}/bin/gunicorn bepasty.wsgi --name ${name} \
+              -u ${user} \
+              -g ${group} \
+              --workers 3 --log-level=info \
+              --bind=${server.bind} \
+              --pid ${server.workDir}/gunicorn-${name}.pid \
+              -k gevent
+            '';
+          };
+        })
+    ) cfg.servers;
+
+    users.extraUsers = [{
+      uid = config.ids.uids.bepasty;
+      name = user;
+      group = group;
+      home = default_home;
+    }];
+
+    users.extraGroups = [{
+      name = group;
+      gid = config.ids.gids.bepasty;
+    }];
+  };
+}
diff --git a/nixos/modules/services/misc/devmon.nix b/nixos/modules/services/misc/devmon.nix
index 7a1f7c2e079e..9dc8fee2964b 100644
--- a/nixos/modules/services/misc/devmon.nix
+++ b/nixos/modules/services/misc/devmon.nix
@@ -18,11 +18,13 @@ in {
   };
 
   config = mkIf cfg.enable {
-    systemd.services.devmon = {
+    systemd.user.services.devmon = {
       description = "devmon automatic device mounting daemon";
-      wantedBy = [ "multi-user.target" ];
-      path = [ pkgs.udevil ];
+      wantedBy = [ "default.target" ];
+      path = [ pkgs.udevil pkgs.procps pkgs.udisks2 pkgs.which ];
       serviceConfig.ExecStart = "${pkgs.udevil}/bin/devmon";
     };
+
+    services.udisks2.enable = true;
   };
 }
diff --git a/nixos/modules/services/misc/ihaskell.nix b/nixos/modules/services/misc/ihaskell.nix
index 7f7f981de498..13c41466eab2 100644
--- a/nixos/modules/services/misc/ihaskell.nix
+++ b/nixos/modules/services/misc/ihaskell.nix
@@ -22,9 +22,9 @@ in
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellngPackages;
-        defaultText = "pkgs.haskellngPackages";
-        example = literalExample "pkgs.haskell-ng.packages.ghc784";
+        default = pkgs.haskellPackages;
+        defaultText = "pkgs.haskellPackages";
+        example = literalExample "pkgs.haskell.packages.ghc784";
         description = ''
           haskellPackages used to build IHaskell and other packages.
           This can be used to change the GHC version used to build
diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix
index 7e8dea4ec024..214a19d9483f 100644
--- a/nixos/modules/services/monitoring/bosun.nix
+++ b/nixos/modules/services/monitoring/bosun.nix
@@ -6,10 +6,12 @@ let
   cfg = config.services.bosun;
 
   configFile = pkgs.writeText "bosun.conf" ''
-    tsdbHost = ${cfg.opentsdbHost}
+    ${optionalString (cfg.opentsdbHost !=null) "tsdbHost = ${cfg.opentsdbHost}"}
+    ${optionalString (cfg.influxHost !=null) "influxHost = ${cfg.influxHost}"}
     httpListen = ${cfg.listenAddress}
     stateFile = ${cfg.stateFile}
-    checkFrequency = 5m
+    ledisDir = ${cfg.ledisDir}
+    checkFrequency = ${cfg.checkFrequency}
 
     ${cfg.extraConfig}
   '';
@@ -54,10 +56,20 @@ in {
       };
 
       opentsdbHost = mkOption {
-        type = types.string;
+        type = types.nullOr types.string;
         default = "localhost:4242";
         description = ''
           Host and port of the OpenTSDB database that stores bosun data.
+          To disable opentsdb you can pass null as parameter.
+        '';
+      };
+
+      influxHost = mkOption {
+        type = types.nullOr types.string;
+        default = null;
+        example = "localhost:8086";
+        description = ''
+           Host and port of the influxdb database.
         '';
       };
 
@@ -70,13 +82,29 @@ in {
       };
 
       stateFile = mkOption {
-        type = types.string;
+        type = types.path;
         default = "/var/lib/bosun/bosun.state";
         description = ''
           Path to bosun's state file.
         '';
       };
 
+      ledisDir = mkOption {
+        type = types.path;
+        default = "/var/lib/bosun/ledis_data";
+        description = ''
+          Path to bosun's ledis data dir
+        '';
+      };
+
+      checkFrequency = mkOption {
+        type = types.str;
+        default = "5m";
+        description = ''
+          Bosun's check frequency
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.string;
         default = "";
@@ -95,7 +123,7 @@ in {
   };
 
   config = mkIf cfg.enable {
-  
+
     systemd.services.bosun = {
       description = "bosun metrics collector (part of Bosun)";
       wantedBy = [ "multi-user.target" ];
diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix
index 5302728eae91..6053990e8d3b 100644
--- a/nixos/modules/services/monitoring/grafana.nix
+++ b/nixos/modules/services/monitoring/grafana.nix
@@ -7,150 +7,37 @@ let
 
   b2s = val: if val then "true" else "false";
 
-  cfgFile = pkgs.writeText "grafana.ini" ''
-    app_name = grafana
-    app_mode = production
-
-    [server]
-    ; protocol (http or https)
-    protocol = ${cfg.protocol}
-    ; the ip address to bind to, empty will bind to all interfaces
-    http_addr = ${cfg.addr}
-    ; the http port  to use
-    http_port = ${toString cfg.port}
-    ; The public facing domain name used to access grafana from a browser
-    domain = ${cfg.domain}
-    ; the full public facing url
-    root_url = ${cfg.rootUrl}
-    router_logging = false
-    ; the path relative to the binary where the static (html/js/css) files are placed
-    static_root_path = ${cfg.staticRootPath}
-    ; enable gzip
-    enable_gzip = false
-    ; https certs & key file
-    cert_file = ${cfg.certFile}
-    cert_key = ${cfg.certKey}
-
-    [analytics]
-    # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
-    # No ip addresses are being tracked, only simple counters to track
-    # running instances, dashboard and error counts. It is very helpful to us.
-    # Change this option to false to disable reporting.
-    reporting_enabled = true
-    ; Google Analytics universal tracking code, only enabled if you specify an id here
-    google_analytics_ua_id =
-
-    [database]
-    ; Either "mysql", "postgres" or "sqlite3", it's your choice
-    type = ${cfg.database.type}
-    host = ${cfg.database.host}
-    name = ${cfg.database.name}
-    user = ${cfg.database.user}
-    password = ${cfg.database.password}
-    ; For "postgres" only, either "disable", "require" or "verify-full"
-    ssl_mode = disable
-    ; For "sqlite3" only
-    path = ${cfg.database.path}
-
-    [session]
-    ; Either "memory", "file", "redis", "mysql", default is "memory"
-    provider = file
-    ; Provider config options
-    ; memory: not have any config yet
-    ; file: session file path, e.g. `data/sessions`
-    ; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,grafana`
-    ; mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1)/database_name`
-    provider_config = data/sessions
-    ; Session cookie name
-    cookie_name = grafana_sess
-    ; If you use session in https only, default is false
-    cookie_secure = false
-    ; Session life time, default is 86400
-    session_life_time = 86400
-    ; session id hash func, Either "sha1", "sha256" or "md5" default is sha1
-    session_id_hashfunc = sha1
-    ; Session hash key, default is use random string
-    session_id_hashkey =
-
-    [security]
-    ; default admin user, created on startup
-    admin_user = ${cfg.security.adminUser}
-    ; default admin password, can be changed before first start of grafana,  or in profile settings
-    admin_password = ${cfg.security.adminPassword}
-    ; used for signing
-    secret_key = ${cfg.security.secretKey}
-    ; Auto-login remember days
-    login_remember_days = 7
-    cookie_username = grafana_user
-    cookie_remember_name = grafana_remember
-
-    [users]
-    ; disable user signup / registration
-    allow_sign_up = ${b2s cfg.users.allowSignUp}
-    ; Allow non admin users to create organizations
-    allow_org_create = ${b2s cfg.users.allowOrgCreate}
-    # Set to true to automatically assign new users to the default organization (id 1)
-    auto_assign_org = ${b2s cfg.users.autoAssignOrg}
-    ; Default role new users will be automatically assigned (if disabled above is set to true)
-    auto_assign_org_role = ${cfg.users.autoAssignOrgRole}
-
-    [auth.anonymous]
-    ; enable anonymous access
-    enabled = ${b2s cfg.auth.anonymous.enable}
-    ; specify organization name that should be used for unauthenticated users
-    org_name = Main Org.
-    ; specify role for unauthenticated users
-    org_role = Viewer
-
-    [auth.github]
-    enabled = false
-    client_id = some_id
-    client_secret = some_secret
-    scopes = user:email
-    auth_url = https://github.com/login/oauth/authorize
-    token_url = https://github.com/login/oauth/access_token
-
-    [auth.google]
-    enabled = false
-    client_id = some_client_id
-    client_secret = some_client_secret
-    scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
-    auth_url = https://accounts.google.com/o/oauth2/auth
-    token_url = https://accounts.google.com/o/oauth2/token
-
-    [log]
-    root_path = data/log
-    ; Either "console", "file", default is "console"
-    ; Use comma to separate multiple modes, e.g. "console, file"
-    mode = console
-    ; Buffer length of channel, keep it as it is if you don't know what it is.
-    buffer_len = 10000
-    ; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
-    level = Info
-
-    ; For "console" mode only
-    [log.console]
-    level =
-
-    ; For "file" mode only
-    [log.file]
-    level =
-    ; This enables automated log rotate(switch of following options), default is true
-    log_rotate = true
-    ; Max line number of single file, default is 1000000
-    max_lines = 1000000
-    ; Max size shift of single file, default is 28 means 1 << 28, 256MB
-    max_lines_shift = 28
-    ; Segment log daily, default is true
-    daily_rotate = true
-    ; Expired days of log file(delete after max days), default is 7
-    max_days = 7
-
-    [event_publisher]
-    enabled = false
-    rabbitmq_url = amqp://localhost/
-    exchange = grafana_events
-  '';
+  envOptions = {
+    PATHS_DATA = cfg.dataDir;
+    PATHS_LOGS = "${cfg.dataDir}/log";
+
+    SERVER_PROTOCOL = cfg.protocol;
+    SERVER_HTTP_ADDR = cfg.addr;
+    SERVER_HTTP_PORT = cfg.port;
+    SERVER_DOMAIN = cfg.domain;
+    SERVER_ROOT_URL = cfg.rootUrl;
+    SERVER_STATIC_ROOT_PATH = cfg.staticRootPath;
+    SERVER_CERT_FILE = cfg.certFile;
+    SERVER_CERT_KEY = cfg.certKey;
+
+    DATABASE_TYPE = cfg.database.type;
+    DATABASE_HOST = cfg.database.host;
+    DATABASE_NAME = cfg.database.name;
+    DATABASE_USER = cfg.database.user;
+    DATABASE_PASSWORD = cfg.database.password;
+    DATABASE_PATH = cfg.database.path;
+
+    SECURITY_ADMIN_USER = cfg.security.adminUser;
+    SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword;
+    SECURITY_SECRET_KEY = cfg.security.secretKey;
+
+    USERS_ALLOW_SIGN_UP = b2s cfg.users.allowSignUp;
+    USERS_ALLOW_ORG_CREATE = b2s cfg.users.allowOrgCreate;
+    USERS_AUTO_ASSIGN_ORG = b2s cfg.users.autoAssignOrg;
+    USERS_AUTO_ASSIGN_ORG_ROLE = cfg.users.autoAssignOrgRole;
+
+    AUTH_ANONYMOUS_ENABLE = b2s cfg.auth.anonymous.enable;
+  } // cfg.extraOptions;
 
 in {
   options.services.grafana = {
@@ -306,6 +193,16 @@ in {
         type = types.bool;
       };
     };
+
+    extraOptions = mkOption {
+      description = ''
+        Extra configuration options passed as env variables as specified in
+        <link xlink:href="http://docs.grafana.org/installation/configuration/">documentation</link>,
+        but without GF_ prefix
+      '';
+      default = {};
+      type = types.attrsOf types.str;
+    };
   };
 
   config = mkIf cfg.enable {
@@ -317,11 +214,15 @@ in {
       description = "Grafana Service Daemon";
       wantedBy = ["multi-user.target"];
       after = ["networking.target"];
+      environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
       serviceConfig = {
-        ExecStart = "${cfg.package}/bin/grafana --config ${cfgFile} web";
+        ExecStart = "${cfg.package}/bin/grafana -homepath ${cfg.dataDir}";
         WorkingDirectory = cfg.dataDir;
         User = "grafana";
       };
+      preStart = ''
+        ln -fs ${cfg.package}/share/grafana/conf ${cfg.dataDir}
+      '';
     };
 
     users.extraUsers.grafana = {
@@ -331,7 +232,7 @@ in {
       createHome = true;
     };
 
-    services.grafana.staticRootPath = mkDefault "${cfg.package.out}/share/go/src/github.com/grafana/grafana/public";
+    services.grafana.staticRootPath = mkDefault "${cfg.package}/share/grafana/public";
 
   };
 }
diff --git a/nixos/modules/services/monitoring/heapster.nix b/nixos/modules/services/monitoring/heapster.nix
new file mode 100644
index 000000000000..74b8c9ccd3ed
--- /dev/null
+++ b/nixos/modules/services/monitoring/heapster.nix
@@ -0,0 +1,57 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.heapster;
+in {
+  options.services.heapster = {
+    enable = mkOption {
+      description = "Whether to enable heapster monitoring";
+      default = false;
+      type = types.bool;
+    };
+
+    source = mkOption {
+      description = "Heapster metric source";
+      example = "kubernetes:https://kubernetes.default";
+      type = types.string;
+    };
+
+    sink = mkOption {
+      description = "Heapster metic sink";
+      example = "influxdb:http://localhost:8086";
+      type = types.string;
+    };
+
+    extraOpts = mkOption {
+      description = "Heapster extra options";
+      default = "";
+      type = types.string;
+    };
+
+    package = mkOption {
+      description = "Package to use by heapster";
+      default = pkgs.heapster;
+      type = types.package;
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.heapster = {
+      wantedBy = ["multi-user.target"];
+      after = ["cadvisor.service" "kube-apiserver.service"];
+
+      serviceConfig = {
+        ExecStart = "${cfg.package}/bin/heapster --source=${cfg.source} --sink=${cfg.sink} ${cfg.extraOpts}";
+        User = "heapster";
+      };
+    };
+
+    users.extraUsers = singleton {
+      name = "heapster";
+      uid = config.ids.uids.heapster;
+      description = "Heapster user";
+    };
+  };
+}
diff --git a/nixos/modules/services/monitoring/longview.nix b/nixos/modules/services/monitoring/longview.nix
new file mode 100644
index 000000000000..770d56e60efb
--- /dev/null
+++ b/nixos/modules/services/monitoring/longview.nix
@@ -0,0 +1,118 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.longview;
+
+  pidFile = "/run/longview.pid";
+
+  apacheConf = optionalString (cfg.apacheStatusUrl != "") ''
+    location ${cfg.apacheStatusUrl}?auto
+  '';
+  mysqlConf = optionalString (cfg.mysqlUser != "") ''
+    username ${cfg.mysqlUser}
+    password ${cfg.mysqlPassword}
+  '';
+  nginxConf = optionalString (cfg.nginxStatusUrl != "") ''
+    location ${cfg.nginxStatusUrl}
+  '';
+
+in
+
+{
+  options = {
+
+    services.longview = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          If enabled, system metrics will be sent to Linode LongView.
+        '';
+      };
+
+      apiKey = mkOption {
+        type = types.str;
+        example = "01234567-89AB-CDEF-0123456789ABCDEF";
+        description = ''
+          Longview API key. To get this, look in Longview settings which
+          are found at https://manager.linode.com/longview/.
+        '';
+      };
+
+      apacheStatusUrl = mkOption {
+        type = types.str;
+        default = "";
+        example = "http://127.0.0.1/server-status";
+        description = ''
+          The Apache status page URL. If provided, Longview will
+          gather statistics from this location. This requires Apache
+          mod_status to be loaded and enabled.
+        '';
+      };
+
+      nginxStatusUrl = mkOption {
+        type = types.str;
+        default = "";
+        example = "http://127.0.0.1/nginx_status";
+        description = ''
+          The Nginx status page URL. Longview will gather statistics
+          from this URL. This requires the Nginx stub_status module to
+          be enabled and configured at the given location.
+        '';
+      };
+
+      mysqlUser = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          The user for connecting to the MySQL database. If provided,
+          Longview will connect to MySQL and collect statistics about
+          queries, etc. This user does not need to have been granted
+          any extra privileges.
+        '';
+      };
+
+      mysqlPassword = mkOption {
+        type = types.str;
+        description = ''
+          The password corresponding to mysqlUser.  Warning: this is
+          stored in cleartext in the Nix store!
+        '';
+      };
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.longview =
+      { description = "Longview Metrics Collection";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig.Type = "forking";
+        serviceConfig.ExecStop = "-${pkgs.coreutils}/bin/kill -TERM $MAINPID";
+        serviceConfig.ExecReload = "-${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+        serviceConfig.PIDFile = pidFile;
+        serviceConfig.ExecStart = "${pkgs.longview}/bin/longview";
+      };
+
+    environment.etc."linode/longview.key" = {
+      mode = "0400";
+      text = cfg.apiKey;
+    };
+    environment.etc."linode/longview.d/Apache.conf" = {
+      mode = "0400";
+      text = apacheConf;
+    };
+    environment.etc."linode/longview.d/MySQL.conf" = {
+      mode = "0400";
+      text = mysqlConf;
+    };
+    environment.etc."linode/longview.d/Nginx.conf" = {
+      mode = "0400";
+      text = nginxConf;
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
index 7ee78f01d497..af9424ecfeaf 100644
--- a/nixos/modules/services/networking/i2pd.nix
+++ b/nixos/modules/services/networking/i2pd.nix
@@ -10,23 +10,59 @@ let
 
   extip = "EXTIP=\$(${pkgs.curl}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
 
-  i2pSh = pkgs.writeScriptBin "i2pd" ''
+  toOneZero = b: if b then "1" else "0";
+
+  i2pdConf = pkgs.writeText "i2pd.conf" ''
+      v6 = ${toOneZero cfg.enableIPv6}
+      unreachable = ${toOneZero cfg.unreachable}
+      floodfill = ${toOneZero cfg.floodfill}
+      ${if isNull cfg.port then "" else "port = ${toString cfg.port}"}
+      httpproxyport = ${toString cfg.proxy.httpPort}
+      socksproxyport = ${toString cfg.proxy.socksPort}
+      ircaddress = ${cfg.irc.host}
+      ircport = ${toString cfg.irc.port}
+      ircdest = ${cfg.irc.dest}
+      irckeys = ${cfg.irc.keyFile}
+      eepport = ${toString cfg.eep.port}
+      ${if isNull cfg.sam.port then "" else "--samport=${toString cfg.sam.port}"}
+      eephost = ${cfg.eep.host}
+      eepkeys = ${cfg.eep.keyFile}
+  '';
+
+  i2pdTunnelConf = pkgs.writeText "i2pd-tunnels.conf" ''
+  ${flip concatMapStrings
+    (collect (tun: tun ? port && tun ? destination) cfg.outTunnels)
+    (tun: let portStr = toString tun.port; in ''
+  [${tun.name}]
+  type = client
+  destination = ${tun.destination}
+  keys = ${tun.keys}
+  address = ${tun.address}
+  port = ${toString tun.port}
+  '')
+  }
+  ${flip concatMapStrings
+    (collect (tun: tun ? port && tun ? host) cfg.outTunnels)
+    (tun: let portStr = toString tun.port; in ''
+  [${tun.name}]
+  type = server
+  destination = ${tun.destination}
+  keys = ${tun.keys}
+  host = ${tun.address}
+  port = ${tun.port}
+  inport = ${tun.inPort}
+  accesslist = ${concatStringSep "," tun.accessList}
+  '')
+  }
+  '';
+
+  i2pdSh = pkgs.writeScriptBin "i2pd" ''
     #!/bin/sh
     ${if isNull cfg.extIp then extip else ""}
-    ${pkgs.i2pd}/bin/i2p --log=1 --daemon=0 --service=0 \
-      --v6=${if cfg.enableIPv6 then "1" else "0"} \
-      --unreachable=${if cfg.unreachable then "1" else "0"} \
+    ${pkgs.i2pd}/bin/i2pd --log=1 --daemon=0 --service=0 \
       --host=${if isNull cfg.extIp then "$EXTIP" else cfg.extIp} \
-      ${if isNull cfg.port then "" else "--port=${toString cfg.port}"} \
-      --httpproxyport=${toString cfg.proxy.httpPort} \
-      --socksproxyport=${toString cfg.proxy.socksPort} \
-      --ircport=${toString cfg.irc.port} \
-      --ircdest=${cfg.irc.dest} \
-      --irckeys=${cfg.irc.keyFile} \
-      --eepport=${toString cfg.eep.port} \
-      ${if isNull cfg.sam.port then "" else "--samport=${toString cfg.sam.port}"} \
-      --eephost=${cfg.eep.host} \
-      --eepkeys=${cfg.eep.keyFile}
+      --conf=${i2pdConf} \
+      --tunnelscfg=${i2pdTunnelConf}
   '';
 
 in
@@ -63,11 +99,19 @@ in
         '';
       };
 
+      floodfill = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          If the router is declared to be unreachable and needs introduction nodes.
+        '';
+      };
+
       port = mkOption {
         type = with types; nullOr int;
         default = null;
         description = ''
-          I2P listen port. If no one is given the router will pick between 9111 and 30777.
+	        I2P listen port. If no one is given the router will pick between 9111 and 30777.
         '';
       };
 
@@ -107,6 +151,13 @@ in
       };
 
       irc = {
+        host = mkOption {
+          type = types.str;
+          default = "127.0.0.1";
+          description = ''
+            Address to forward incoming traffic to. 127.0.0.1 by default.
+          '';
+        };
         dest = mkOption {
           type = types.str;
           default = "irc.postman.i2p";
@@ -163,6 +214,94 @@ in
           '';
         };
       };
+
+      outTunnels = mkOption {
+        default = {};
+	      type = with types; loaOf optionSet;
+	      description = ''
+	      '';
+	      options = [ ({ name, config, ... }: {
+
+	        options = {
+	          name = mkOption {
+	            type = types.str;
+	            description = "The name of the tunnel.";
+	          };
+	          destination = mkOption {
+	            type = types.str;
+	            description = "Remote endpoint, I2P hostname or b32.i2p address.";
+	          };
+	          keys = mkOption {
+	            type = types.str;
+	            default = name + "-keys.dat";
+	            description = "Keyset used for tunnel identity.";
+	          };
+	          address = mkOption {
+	            type = types.str;
+	            default = "127.0.0.1";
+	            description = "Local bind address for tunnel.";
+	          };
+	          port = mkOption {
+	            type = types.int;
+	            default = 0;
+	            description = "Local tunnel listen port.";
+	          };
+	        };
+
+	        config = {
+	          name = mkDefault name;
+	        };
+
+	      }) ];
+      };
+
+      inTunnels = mkOption {
+        default = {};
+	      type = with types; loaOf optionSet;
+	      description = ''
+	      '';
+	      options = [ ({ name, config, ... }: {
+
+	        options = {
+
+	          name = mkOption {
+	            type = types.str;
+	            description = "The name of the tunnel.";
+	          };
+	          keys = mkOption {
+	            type = types.path;
+	            default = name + "-keys.dat";
+	            description = "Keyset used for tunnel identity.";
+	          };
+	          address = mkOption {
+	            type = types.str;
+	            default = "127.0.0.1";
+	            description = "Local service IP address.";
+	          };
+	          port = mkOption {
+	            type = types.int;
+	            default = 0;
+	            description = "Local tunnel listen port.";
+	          };
+	          inPort = mkOption {
+	            type = types.int;
+	            default = 0;
+	            description = "I2P service port. Default to the tunnel's listen port.";
+	          };
+	          accessList = mkOption {
+	            type = with types; listOf str;
+	            default = [];
+	            description = "I2P nodes that are allowed to connect to this service.";
+	          };
+
+	        };
+
+	        config = {
+	          name = mkDefault name;
+	        };
+
+	      }) ];
+      };
     };
   };
 
@@ -190,9 +329,8 @@ in
         User = "i2pd";
         WorkingDirectory = homeDir;
         Restart = "on-abort";
-        ExecStart = "${i2pSh}/bin/i2pd";
+        ExecStart = "${i2pdSh}/bin/i2pd";
       };
     };
   };
 }
-#
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 1c824b6bbfc3..7df194fa419b 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -6,16 +6,18 @@ with lib;
 let
   cfg = config.networking.networkmanager;
 
-  stateDirs = "/var/lib/NetworkManager /var/lib/dhclient";
+  # /var/lib/misc is for dnsmasq.leases.
+  stateDirs = "/var/lib/NetworkManager /var/lib/dhclient /var/lib/misc";
 
   configFile = writeText "NetworkManager.conf" ''
     [main]
     plugins=keyfile
 
     [keyfile]
-    ${optionalString (config.networking.hostName != "") ''
-      hostname=${config.networking.hostName}
-    ''}
+    ${optionalString (config.networking.hostName != "")
+      ''hostname=${config.networking.hostName}''}
+    ${optionalString (cfg.unmanaged != [])
+      ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''}
 
     [logging]
     level=WARN
@@ -96,6 +98,16 @@ in {
         '';
       };
 
+      unmanaged = mkOption {
+        type = types.listOf types.string;
+        default = [];
+        description = ''
+          List of interfaces that will not be managed by NetworkManager.
+          Interface name can be specified here, but if you need more fidelity
+          see "Device List Format" in NetworkManager.conf man page.
+        '';
+      };
+
       # Ugly hack for using the correct gnome3 packageSet
       basePackages = mkOption {
         type = types.attrsOf types.path;
diff --git a/nixos/modules/services/networking/nix-serve.nix b/nixos/modules/services/networking/nix-serve.nix
index 4f8b9357a828..880a1d361dfe 100644
--- a/nixos/modules/services/networking/nix-serve.nix
+++ b/nixos/modules/services/networking/nix-serve.nix
@@ -56,7 +56,7 @@ in
 
       serviceConfig = {
         ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
-          "--port ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
+          "--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
         User = "nix-serve";
         Group = "nogroup";
       };
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index 005eb7bd7614..52c7ac8e6893 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -23,11 +23,11 @@ in
         '';
       };
 
-      interface = mkOption {
-        default = "127.0.0.1";
+      interfaces = mkOption {
+        default = [ "127.0.0.1" ];
         description = ''
-          The interface the Quassel daemon will be listening to.  If `127.0.0.1',
-          only clients on the local host can connect to it; if `0.0.0.0', clients
+          The interfaces the Quassel daemon will be listening to.  If `[ 127.0.0.1 ]',
+          only clients on the local host can connect to it; if `[ 0.0.0.0 ]', clients
           can access it from any network interface.
         '';
       };
@@ -78,7 +78,8 @@ in
       { description = "Quassel IRC client daemon";
 
         wantedBy = [ "multi-user.target" ];
-        after = [ "network.target" ];
+        after = [ "network.target" ] ++ optional config.services.postgresql.enable "postgresql.service"
+                                     ++ optional config.services.mysql.enable "mysql.service";
 
         preStart = ''
           mkdir -p ${cfg.dataDir}
@@ -87,7 +88,7 @@ in
 
         serviceConfig =
         {
-          ExecStart = "${quassel}/bin/quasselcore --listen=${cfg.interface} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}";
+          ExecStart = "${quassel}/bin/quasselcore --listen=${concatStringsSep '','' cfg.interfaces} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}";
           User = user;
           PermissionsStartOnly = true;
         };
diff --git a/nixos/modules/services/networking/tlsdated.nix b/nixos/modules/services/networking/tlsdated.nix
index f2d0c9f35c9c..ff7d0178a81a 100644
--- a/nixos/modules/services/networking/tlsdated.nix
+++ b/nixos/modules/services/networking/tlsdated.nix
@@ -63,7 +63,7 @@ in
         });
         default = [
           {
-            host = "www.ptb.de";
+            host = "encrypted.google.com";
             port = 443;
             proxy = null;
           }
diff --git a/nixos/modules/services/networking/wakeonlan.nix b/nixos/modules/services/networking/wakeonlan.nix
index 11bb7e925255..ebfba263cd8f 100644
--- a/nixos/modules/services/networking/wakeonlan.nix
+++ b/nixos/modules/services/networking/wakeonlan.nix
@@ -40,7 +40,7 @@ in
       ];
       description = ''
         Interfaces where to enable Wake-On-LAN, and how. Two methods available:
-        "magickey" and "password". The password has the shape of six bytes
+        "magicpacket" and "password". The password has the shape of six bytes
         in hexadecimal separated by a colon each. For more information,
         check the ethtool manual.
       '';
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 1b5e83173e8f..f5e132fd77d8 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -39,7 +39,7 @@ in
 
       enable = mkOption {
         type = types.bool;
-        default = true;
+        example = true;
         description = "Whether to enable the Vixie cron daemon.";
       };
 
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index cf548bc696ca..1c9149224049 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -9,7 +9,7 @@ let
   homeDir = "/var/lib/transmission";
   downloadDir = "${homeDir}/Downloads";
   incompleteDir = "${homeDir}/.incomplete";
-  
+
   settingsDir = "${homeDir}/.config/transmission-daemon";
   settingsFile = pkgs.writeText "settings.json" (builtins.toJSON fullSettings);
 
@@ -21,7 +21,7 @@ let
     else toString ''"${x}"'';
 
   # for users in group "transmission" to have access to torrents
-  fullSettings = cfg.settings // { umask = 2; };
+  fullSettings = { download-dir = downloadDir; incomplete-dir = incompleteDir; } // cfg.settings // { umask = 2; };
 in
 {
   options = {
@@ -35,7 +35,7 @@ in
           Transmission daemon can be controlled via the RPC interface using
           transmission-remote or the WebUI (http://localhost:9091/ by default).
 
-          Torrents are downloaded to ${homeDir}/Downloads/ by default and are
+          Torrents are downloaded to ${downloadDir} by default and are
           accessible to users in the "transmission" group.
         '';
       };
@@ -83,7 +83,7 @@ in
       # 1) Only the "transmission" user and group have access to torrents.
       # 2) Optionally update/force specific fields into the configuration file.
       serviceConfig.ExecStartPre = ''
-          ${pkgs.stdenv.shell} -c "chmod 770 ${homeDir} && mkdir -p ${settingsDir} ${downloadDir} ${incompleteDir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json"
+          ${pkgs.stdenv.shell} -c "mkdir -p ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && chmod 770 ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json"
       '';
       serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port}";
       serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index 921f774bcaa0..7a0314027a3d 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -17,10 +17,10 @@ let
     define('DB_HOST',     '${config.dbHost}');
     define('DB_CHARSET',  'utf8');
     $table_prefix  = '${config.tablePrefix}';
+    ${config.extraConfig}
     if ( !defined('ABSPATH') )
     	define('ABSPATH', dirname(__FILE__) . '/');
     require_once(ABSPATH . 'wp-settings.php');
-    ${config.extraConfig}
   '';
 
   # .htaccess to support pretty URLs
diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix
index 2c662c0aead9..171503db4eec 100644
--- a/nixos/modules/services/web-servers/lighttpd/default.nix
+++ b/nixos/modules/services/web-servers/lighttpd/default.nix
@@ -44,7 +44,6 @@ let
     "mod_flv_streaming"
     "mod_magnet"
     "mod_mysql_vhost"
-    "mod_rewrite"
     "mod_scgi"
     "mod_setenv"
     "mod_trigger_b4_dl"
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 5061d59b7c7f..dc6aa137cbd3 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -8,38 +8,9 @@ let
   cfg = xcfg.desktopManager.kde5;
   xorg = pkgs.xorg;
 
-  phononBackends = {
-    gstreamer = [
-      pkgs.phonon_backend_gstreamer
-      pkgs.gst_all.gstreamer
-      pkgs.gst_all.gstPluginsBase
-      pkgs.gst_all.gstPluginsGood
-      pkgs.gst_all.gstPluginsUgly
-      pkgs.gst_all.gstPluginsBad
-      pkgs.gst_all.gstFfmpeg # for mp3 playback
-      pkgs.phonon_qt5_backend_gstreamer
-      pkgs.gst_all_1.gstreamer
-      pkgs.gst_all_1.gst-plugins-base
-      pkgs.gst_all_1.gst-plugins-good
-      pkgs.gst_all_1.gst-plugins-ugly
-      pkgs.gst_all_1.gst-plugins-bad
-      pkgs.gst_all_1.gst-libav # for mp3 playback
-    ];
-
-    vlc = [
-      pkgs.phonon_qt5_backend_vlc
-      pkgs.phonon_backend_vlc
-    ];
-  };
-
-  phononBackendPackages = flip concatMap cfg.phononBackends
-    (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends);
-
   kf5 = pkgs.kf5_stable;
-
-  plasma5 = pkgs.plasma5_stable.override { inherit kf5; };
-
-  kdeApps = pkgs.kdeApps_stable.override { inherit kf5; };
+  plasma5 = pkgs.plasma5_stable;
+  kdeApps = pkgs.kdeApps_stable;
 
 in
 
@@ -53,14 +24,24 @@ in
         description = "Enable the Plasma 5 (KDE 5) desktop environment.";
       };
 
-      phononBackends = mkOption {
-        type = types.listOf types.str;
-        default = ["gstreamer"];
-        example = ["gstreamer" "vlc"];
-        description = ''
-          Phonon backends to use in KDE. Only the VLC and GStreamer backends are
-          available. The GStreamer backend is preferred by upstream.
-        '';
+      phonon = {
+
+        gstreamer = {
+          enable = mkOption {
+            type = types.bool;
+            default = true;
+            description = "Enable the GStreamer Phonon backend (recommended).";
+          };
+        };
+
+        vlc = {
+          enable = mkOption {
+            type = types.bool;
+            default = false;
+            description = "Enable the VLC Phonon backend.";
+          };
+        };
+
       };
 
     };
@@ -88,23 +69,77 @@ in
     };
 
     environment.systemPackages =
-      filter isDerivation (builtins.attrValues plasma5)
-      ++ filter isDerivation (builtins.attrValues kf5)
-      ++ [
+      [
         pkgs.qt4 # qtconfig is the only way to set Qt 4 theme
 
-        kdeApps.kde-baseapps
-        kdeApps.kde-base-artwork
-        kdeApps.kmix
+        kf5.frameworkintegration
+        kf5.kinit
+
+        plasma5.breeze
+        plasma5.kde-cli-tools
+        plasma5.kdeplasma-addons
+        plasma5.kgamma5
+        plasma5.khelpcenter
+        plasma5.khotkeys
+        plasma5.kinfocenter
+        plasma5.kmenuedit
+        plasma5.kscreen
+        plasma5.ksysguard
+        plasma5.kwayland
+        plasma5.kwin
+        plasma5.kwrited
+        plasma5.milou
+        plasma5.oxygen
+        plasma5.polkit-kde-agent
+        plasma5.systemsettings
+
+        plasma5.plasma-desktop
+        plasma5.plasma-workspace
+        plasma5.plasma-workspace-wallpapers
+
+        kdeApps.ark
+        kdeApps.dolphin
+        kdeApps.dolphin-plugins
+        kdeApps.ffmpegthumbs
+        kdeApps.gwenview
+        kdeApps.kate
+        kdeApps.kdegraphics-thumbnailers
         kdeApps.konsole
-        kdeApps.oxygen-icons
-
-        kdeApps.kde-runtime
+        kdeApps.okular
+        kdeApps.print-manager
 
+        (kdeApps.oxygen-icons or kf5.oxygen-icons5)
         pkgs.hicolor_icon_theme
 
+        plasma5.kde-gtk-config
         pkgs.orion # GTK theme, nearly identical to Breeze
-      ] ++ phononBackendPackages;
+      ]
+      ++ lib.optional config.hardware.bluetooth.enable plasma5.bluedevil
+      ++ lib.optional config.networking.networkmanager.enable plasma5.plasma-nm
+      ++ lib.optional config.hardware.pulseaudio.enable plasma5.plasma-pa
+      ++ lib.optional config.powerManagement.enable plasma5.powerdevil
+      ++ lib.optionals cfg.phonon.gstreamer.enable
+        [
+          pkgs.phonon_backend_gstreamer
+          pkgs.gst_all.gstreamer
+          pkgs.gst_all.gstPluginsBase
+          pkgs.gst_all.gstPluginsGood
+          pkgs.gst_all.gstPluginsUgly
+          pkgs.gst_all.gstPluginsBad
+          pkgs.gst_all.gstFfmpeg # for mp3 playback
+          pkgs.phonon_qt5_backend_gstreamer
+          pkgs.gst_all_1.gstreamer
+          pkgs.gst_all_1.gst-plugins-base
+          pkgs.gst_all_1.gst-plugins-good
+          pkgs.gst_all_1.gst-plugins-ugly
+          pkgs.gst_all_1.gst-plugins-bad
+          pkgs.gst_all_1.gst-libav # for mp3 playback
+        ]
+      ++ lib.optionals cfg.phonon.vlc.enable
+        [
+          pkgs.phonon_qt5_backend_vlc
+          pkgs.phonon_backend_vlc
+        ];
 
     environment.pathsToLink = [ "/share" ];
 
@@ -114,13 +149,13 @@ in
     };
 
     environment.profileRelativeEnvVars =
-      mkIf (lib.elem "gstreamer" cfg.phononBackends)
+      mkIf cfg.phonon.gstreamer.enable
       {
         GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ];
         GST_PLUGIN_SYSTEM_PATH_1_0 = [ "/lib/gstreamer-1.0" ];
       };
 
-    fonts.fonts = [ plasma5.oxygen-fonts ];
+    fonts.fonts = [ (plasma5.oxygen-fonts or pkgs.noto-fonts) ];
 
     programs.ssh.askPassword = "${plasma5.ksshaskpass}/bin/ksshaskpass";
 
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index 88eefa13de35..33b6dd32c193 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -18,6 +18,14 @@ in
       description = "Enable the Xfce desktop environment.";
     };
 
+    services.xserver.desktopManager.xfce.thunarPlugins = mkOption {
+      default = [];
+      type = types.listOf types.package;
+      example = literalExample "[ pkgs.xfce.thunar-archive-plugin ]";
+      description = ''
+        A list of plugin that should be installed with Thunar.
+      '';
+    };
   };
 
 
@@ -49,7 +57,7 @@ in
         pkgs.xfce.mousepad
         pkgs.xfce.ristretto
         pkgs.xfce.terminal
-        pkgs.xfce.thunar
+       (pkgs.xfce.thunar.override { thunarPlugins = cfg.thunarPlugins; })
         pkgs.xfce.xfce4icontheme
         pkgs.xfce.xfce4panel
         pkgs.xfce.xfce4session
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index c9a563768323..52847d2f8d2c 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -20,7 +20,9 @@ in
 
       enable = mkEnableOption ''
         GDM as the display manager.
-        <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+        <emphasis>GDM in NixOS is not well-tested with desktops other
+        than GNOME, so use with caution, as it could render the
+        system unusable.</emphasis>
       '';
 
       debug = mkEnableOption ''
@@ -160,7 +162,7 @@ in
 
       gdm.text = ''
         auth     requisite      pam_nologin.so
-        auth     required       pam_env.so
+        auth     required       pam_env.so envfile=${config.system.build.pamEnvironment}
 
         auth     required       pam_succeed_if.so uid >= 1000 quiet
         auth     optional       ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index 11e21c9d917f..8452b1ec33cd 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -150,7 +150,7 @@ in
       allowNullPassword = true;
       startSession = true;
       text = ''
-        auth     required pam_env.so
+        auth     required pam_env.so envfile=${config.system.build.pamEnvironment}
         auth     required pam_permit.so
 
         account  required pam_permit.so
diff --git a/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix
index 545f4283828a..e3db0230d3b7 100644
--- a/nixos/modules/services/x11/display-managers/slim.nix
+++ b/nixos/modules/services/x11/display-managers/slim.nix
@@ -18,6 +18,7 @@ let
       halt_cmd ${config.systemd.package}/sbin/shutdown -h now
       reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
       ${optionalString (cfg.defaultUser != null) ("default_user " + cfg.defaultUser)}
+      ${optionalString (cfg.defaultUser != null) ("focus_password yes")}
       ${optionalString cfg.autoLogin "auto_login yes"}
       ${cfg.extraConfig}
     '';
@@ -57,8 +58,8 @@ in
       theme = mkOption {
         type = types.nullOr types.path;
         default = pkgs.fetchurl {
-          url    = https://github.com/jagajaga/nixos-slim-theme/archive/1.1.tar.gz;
-          sha256 = "66c3020a6716130a20c3898567339b990fbd7888a3b7bbcb688f6544d1c05c31";
+          url = "https://github.com/jagajaga/nixos-slim-theme/archive/2.0.tar.gz";
+          sha256 = "0lldizhigx7bjhxkipii87y432hlf5wdvamnfxrryf9z7zkfypc8";
         };
         example = literalExample ''
           pkgs.fetchurl {
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index ffae22d2d670..d40373ec2e55 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -22,14 +22,16 @@ in {
     latitude = mkOption {
       type = types.str;
       description = ''
-        Your current latitude.
+        Your current latitude, between
+        <literal>-90.0</literal> and <literal>90.0</literal>.
       '';
     };
 
     longitude = mkOption {
       type = types.str;
       description = ''
-        Your current longitude.
+        Your current longitude, between
+        between <literal>-180.0</literal> and <literal>180.0</literal>.
       '';
     };
 
@@ -38,14 +40,16 @@ in {
         type = types.int;
         default = 5500;
         description = ''
-          Colour temperature to use during the day.
+          Colour temperature to use during the day, between
+          <literal>1000</literal> and <literal>25000</literal> K.
         '';
       };
       night = mkOption {
         type = types.int;
         default = 3700;
         description = ''
-          Colour temperature to use at night.
+          Colour temperature to use at night, between
+          <literal>1000</literal> and <literal>25000</literal> K.
         '';
       };
     };
diff --git a/nixos/modules/services/x11/window-managers/clfswm.nix b/nixos/modules/services/x11/window-managers/clfswm.nix
new file mode 100644
index 000000000000..9d8eecb56c77
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/clfswm.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.clfswm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.clfswm = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        example = true;
+        description = "Enable the clfswm tiling window manager.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "clfswm";
+      start = ''
+        ${pkgs.clfswm}/bin/clfswm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.clfswm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index 4751de07a15d..31f42f5ffb9f 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -10,6 +10,7 @@ in
   imports = [
     ./afterstep.nix
     ./bspwm.nix
+    ./clfswm.nix
     ./compiz.nix
     ./fluxbox.nix
     ./herbstluftwm.nix
diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix
index c922ca7848d1..288800d514d3 100644
--- a/nixos/modules/services/x11/window-managers/xmonad.nix
+++ b/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -20,9 +20,9 @@ in
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellngPackages;
-        defaultText = "pkgs.haskellngPackages";
-        example = literalExample "pkgs.haskell-ng.packages.ghc784";
+        default = pkgs.haskellPackages;
+        defaultText = "pkgs.haskellPackages";
+        example = literalExample "pkgs.haskell.packages.ghc784";
         description = ''
           haskellPackages used to build Xmonad and other packages.
           This can be used to change the GHC version used to build
diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
new file mode 100644
index 000000000000..6c6e2fafad43
--- /dev/null
+++ b/nixos/modules/system/boot/initrd-network.nix
@@ -0,0 +1,149 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.boot.initrd.network;
+
+in
+{
+
+  options = {
+
+    boot.initrd.network.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Add network connectivity support to initrd.
+
+        Network options are configured via <literal>ip</literal> kernel
+        option, according to the kernel documentation.
+      '';
+    };
+
+    boot.initrd.network.ssh.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Start SSH service during initrd boot. It can be used to debug failing
+        boot on a remote server, enter pasphrase for an encrypted partition etc.
+        Service is killed when stage-1 boot is finished.
+      '';
+    };
+
+    boot.initrd.network.ssh.port = mkOption {
+      type = types.int;
+      default = 22;
+      description = ''
+        Port on which SSH initrd service should listen.
+      '';
+    };
+
+    boot.initrd.network.ssh.shell = mkOption {
+      type = types.str;
+      default = "/bin/ash";
+      description = ''
+        Login shell of the remote user. Can be used to limit actions user can do.
+      '';
+    };
+
+    boot.initrd.network.ssh.hostRSAKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        RSA SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.hostDSSKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        DSS SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.hostECDSAKey = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        ECDSA SSH private key file in the Dropbear format.
+
+        WARNING: This key is contained insecurely in the global Nix store. Do NOT
+        use your regular SSH host private keys for this purpose or you'll expose
+        them to regular users!
+      '';
+    };
+
+    boot.initrd.network.ssh.authorizedKeys = mkOption {
+      type = types.listOf types.str;
+      default = config.users.extraUsers.root.openssh.authorizedKeys.keys;
+      description = ''
+        Authorized keys for the root user on initrd.
+      '';
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    boot.initrd.kernelModules = [ "af_packet" ];
+
+    boot.initrd.extraUtilsCommands = ''
+      copy_bin_and_libs ${pkgs.mkinitcpio-nfs-utils}/bin/ipconfig
+    '' + optionalString cfg.ssh.enable ''
+      copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear
+
+      cp -pv ${pkgs.glibc}/lib/libnss_files.so.* $out/lib
+    '';
+
+    boot.initrd.extraUtilsCommandsTest = optionalString cfg.ssh.enable ''
+      $out/bin/dropbear -V
+    '';
+
+    boot.initrd.postEarlyDeviceCommands = ''
+      # Search for interface definitions in command line
+      for o in $(cat /proc/cmdline); do
+        case $o in
+          ip=*)
+            ipconfig $o && hasNetwork=1
+            ;;
+        esac
+      done
+    '' + optionalString cfg.ssh.enable ''
+      if [ -n "$hasNetwork" ]; then
+        mkdir /dev/pts
+        mount -t devpts devpts /dev/pts
+
+        mkdir -p /etc
+        echo 'root:x:0:0:root:/root:${cfg.ssh.shell}' > /etc/passwd
+        echo '${cfg.ssh.shell}' > /etc/shells
+        echo 'passwd: files' > /etc/nsswitch.conf
+
+        mkdir -p /var/log
+        touch /var/log/lastlog
+
+        mkdir -p /etc/dropbear
+        ${optionalString (cfg.ssh.hostRSAKey != null) "ln -s ${cfg.ssh.hostRSAKey} /etc/dropbear/dropbear_rsa_host_key"}
+        ${optionalString (cfg.ssh.hostDSSKey != null) "ln -s ${cfg.ssh.hostDSSKey} /etc/dropbear/dropbear_dss_host_key"}
+        ${optionalString (cfg.ssh.hostECDSAKey != null) "ln -s ${cfg.ssh.hostECDSAKey} /etc/dropbear/dropbear_ecdsa_host_key"}
+
+        mkdir -p /root/.ssh
+        ${concatStrings (map (key: ''
+          echo -n ${escapeShellArg key} >> /root/.ssh/authorized_keys
+        '') cfg.ssh.authorizedKeys)}
+
+        dropbear -s -j -k -E -m -p ${toString cfg.ssh.port}
+      fi
+    '';
+
+  };
+}
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 4a14ff1879c9..763703205630 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -32,9 +32,12 @@ let
     ''}
 
     open_normally() {
-        cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
+        echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
           ${optionalString (header != null) "--header=${header}"} \
-          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"}
+          ${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \
+          > /.luksopen_args
+        cryptsetup-askpass
+        rm /.luksopen_args
     }
 
     ${optionalString (luks.yubikeySupport && (yubikey != null)) ''
@@ -418,6 +421,18 @@ in
     boot.initrd.extraUtilsCommands = ''
       copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
 
+      cat > $out/bin/cryptsetup-askpass <<EOF
+      #!$out/bin/sh -e
+      if [ -e /.luksopen_args ]; then
+        cryptsetup \$(cat /.luksopen_args)
+        killall cryptsetup
+      else
+        echo "Passphrase is not requested now"
+        exit 1
+      fi
+      EOF
+      chmod +x $out/bin/cryptsetup-askpass
+
       ${optionalString luks.yubikeySupport ''
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
         copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
@@ -432,6 +447,8 @@ in
 
         cat > $out/bin/openssl-wrap <<EOF
         #!$out/bin/sh
+        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
+        $out/bin/openssl "\$@"
         EOF
         chmod +x $out/bin/openssl-wrap
       ''}
@@ -442,11 +459,6 @@ in
       ${optionalString luks.yubikeySupport ''
         $out/bin/ykchalresp -V
         $out/bin/ykinfo -V
-        cat > $out/bin/openssl-wrap <<EOF
-        #!$out/bin/sh
-        export OPENSSL_CONF=$out/etc/ssl/openssl.cnf
-        $out/bin/openssl "\$@"
-        EOF
         $out/bin/openssl-wrap version
       ''}
     '';
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 51828c5c090b..2b5d547353f8 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -149,6 +149,10 @@ udevadm trigger --action=add
 udevadm settle
 
 
+# Additional devices initialization.
+@postEarlyDeviceCommands@
+
+
 # Load boot-time keymap before any LVM/LUKS initialization
 @extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@"
 
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index fe34e8227289..58a0749c74e2 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -104,7 +104,7 @@ let
       stripDirs "lib bin" "-s"
 
       # Run patchelf to make the programs refer to the copied libraries.
-      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done
+      for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs -e $out $i; fi; done
 
       for i in $out/bin/*; do
           if ! test -L $i; then
@@ -203,7 +203,7 @@ let
     inherit (config.boot) resumeDevice devSize runSize;
 
     inherit (config.boot.initrd) checkJournalingFS
-      preLVMCommands postDeviceCommands postMountCommands kernelModules;
+      postEarlyDeviceCommands preLVMCommands postDeviceCommands postMountCommands kernelModules;
 
     resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
                     (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices);
@@ -313,6 +313,14 @@ in
       '';
     };
 
+    boot.initrd.postEarlyDeviceCommands = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        Shell commands to be executed early after creation of device nodes.
+      '';
+    };
+
     boot.initrd.postMountCommands = mkOption {
       default = "";
       type = types.lines;
diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index a7a334dec285..d4cab93b26b8 100644
--- a/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixos/modules/system/boot/systemd-unit-options.nix
@@ -170,6 +170,15 @@ in rec {
       '';
     };
 
+    onFailure = mkOption {
+      default = [];
+      type = types.listOf types.str;
+      description = ''
+        A list of one or more units that are activated when
+        this unit enters the "failed" state.
+      '';
+    };
+
   };
 
 
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 4704b3981e46..d145baeebe93 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -69,6 +69,7 @@ let
       "systemd-journal-flush.service"
       "systemd-journal-gatewayd.socket"
       "systemd-journal-gatewayd.service"
+      "systemd-journald-audit.socket"
       "systemd-journald-dev-log.socket"
       "syslog.socket"
 
@@ -99,7 +100,7 @@ let
       # Maintaining state across reboots.
       "systemd-random-seed.service"
       "systemd-backlight@.service"
-      "systemd-rfkill@.service"
+      "systemd-rfkill.service"
 
       # Hibernate / suspend.
       "hibernate.target"
@@ -109,8 +110,6 @@ let
       "systemd-hibernate.service"
       "systemd-suspend.service"
       "systemd-hybrid-sleep.service"
-      "systemd-shutdownd.socket"
-      "systemd-shutdownd.service"
 
       # Reboot stuff.
       "reboot.target"
@@ -200,6 +199,8 @@ let
           { X-Restart-Triggers = toString config.restartTriggers; }
         // optionalAttrs (config.description != "") {
           Description = config.description;
+        } // optionalAttrs (config.onFailure != []) {
+          OnFailure = toString config.onFailure;
         };
     };
   };
@@ -758,7 +759,6 @@ in
     systemd.services."systemd-rfkill@".restartIfChanged = false;
     systemd.services."user@".restartIfChanged = false;
     systemd.services.systemd-journal-flush.restartIfChanged = false;
-    systemd.services.systemd-journald.restartIfChanged = false; # FIXME: shouldn't be necessary with systemd 219
     systemd.services.systemd-random-seed.restartIfChanged = false;
     systemd.services.systemd-remount-fs.restartIfChanged = false;
     systemd.services.systemd-update-utmp.restartIfChanged = false;
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index dbe0c9c6e03a..d0dd7670157e 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -58,6 +58,15 @@ let
         '';
       };
 
+      formatOptions = mkOption {
+        default = "";
+        type = types.str;
+        description = ''
+          If <option>autoFormat</option> option is set specifies
+          extra options passed to mkfs.
+        '';
+      };
+
       autoResize = mkOption {
         default = false;
         type = types.bool;
@@ -81,6 +90,9 @@ let
       mountPoint = mkDefault name;
       device = mkIf (config.fsType == "tmpfs") (mkDefault config.fsType);
       options = mkIf config.autoResize "x-nixos.autoresize";
+
+      # -F needed to allow bare block device without partitions
+      formatOptions = mkIf ((builtins.substring 0 3 config.fsType) == "ext") (mkDefault "-F");
     };
 
   };
@@ -192,8 +204,6 @@ in
           let
             mountPoint' = escapeSystemdPath fs.mountPoint;
             device' = escapeSystemdPath fs.device;
-            # -F needed to allow bare block device without partitions
-            mkfsOpts = optional ((builtins.substring 0 3 fs.fsType) == "ext") "-F";
           in nameValuePair "mkfs-${device'}"
           { description = "Initialisation of Filesystem ${fs.device}";
             wantedBy = [ "${mountPoint'}.mount" ];
@@ -208,7 +218,7 @@ in
                 type=$(blkid -p -s TYPE -o value "${fs.device}" || true)
                 if [ -z "$type" ]; then
                   echo "creating ${fs.fsType} filesystem on ${fs.device}..."
-                  mkfs.${fs.fsType} ${concatStringsSep " " mkfsOpts} "${fs.device}"
+                  mkfs.${fs.fsType} ${fs.formatOptions} "${fs.device}"
                 fi
               '';
             unitConfig.RequiresMountsFor = [ "${dirOf fs.device}" ];
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index 69f004888f55..5969da7062b6 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -4,11 +4,13 @@ with lib;
 
 let
 
+  makeColor = n: value: "COLOR_${toString n}=${value}";
+
   vconsoleConf = pkgs.writeText "vconsole.conf"
     ''
       KEYMAP=${config.i18n.consoleKeyMap}
       FONT=${config.i18n.consoleFont}
-    '';
+    '' + concatImapStringsSep "\n" makeColor config.i18n.consoleColors;
 
 in
 
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 2d6522a1bf9d..ee21d735f959 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -46,6 +46,51 @@ let
     '';
   });
 
+  # Collect all interfaces that are defined for a device
+  # as device:interface key:value pairs.
+  wlanDeviceInterfaces =
+    let
+      allDevices = unique (mapAttrsToList (_: v: v.device) cfg.wlanInterfaces);
+      interfacesOfDevice = d: filterAttrs (_: v: v.device == d) cfg.wlanInterfaces;
+    in
+      genAttrs allDevices (d: interfacesOfDevice d);
+
+  # Convert device:interface key:value pairs into a list, and if it exists,
+  # place the interface which is named after the device at the beginning.
+  wlanListDeviceFirst = device: interfaces:
+    if hasAttr device interfaces
+    then mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n==device) interfaces) ++ mapAttrsToList (n: v: v//{_iName=n;}) (filterAttrs (n: _: n!=device) interfaces)
+    else mapAttrsToList (n: v: v // {_iName = n;}) interfaces;
+
+  # udev script that configures a physical wlan device and adds virtual interfaces
+  wlanDeviceUdevScript = device: interfaceList: pkgs.writeScript "wlan-${device}-udev-script" ''
+    #!${pkgs.stdenv.shell}
+
+    # Change the wireless phy device to a predictable name.
+    if [ -e "/sys/class/net/${device}/phy80211/name" ]; then
+      ${pkgs.iw}/bin/iw phy `${pkgs.coreutils}/bin/cat /sys/class/net/${device}/phy80211/name` set name ${device} || true
+    fi
+
+    # Crate new, virtual interfaces and configure them at the same time
+    ${flip concatMapStrings (drop 1 interfaceList) (i: ''
+    ${pkgs.iw}/bin/iw dev ${device} interface add ${i._iName} type ${i.type} \
+      ${optionalString (i.type == "mesh" && i.meshID != null) "mesh_id ${i.meshID}"} \
+      ${optionalString (i.type == "monitor" && i.flags != null) "flags ${i.flags}"} \
+      ${optionalString (i.type == "managed" && i.fourAddr != null) "4addr ${if i.fourAddr then "on" else "off"}"} \
+      ${optionalString (i.mac != null) "addr ${i.mac}"}
+    '')}
+
+    # Reconfigure and rename the default interface that already exists
+    ${flip concatMapStrings (take 1 interfaceList) (i: ''
+      ${pkgs.iw}/bin/iw dev ${device} set type ${i.type}
+      ${optionalString (i.type == "mesh" && i.meshID != null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${i.meshID}"}
+      ${optionalString (i.type == "monitor" && i.flags != null) "${pkgs.iw}/bin/iw dev ${device} set monitor ${i.flags}"}
+      ${optionalString (i.type == "managed" && i.fourAddr != null) "${pkgs.iw}/bin/iw dev ${device} set 4addr ${if i.fourAddr then "on" else "off"}"}
+      ${optionalString (i.mac != null) "${pkgs.iproute}/bin/ip link set dev ${device} address ${i.mac}"}
+      ${optionalString (device != i._iName) "${pkgs.iproute}/bin/ip link set dev ${device} name ${i._iName}"}
+    '')}
+  '';
+
   # We must escape interfaces due to the systemd interpretation
   subsystemDevice = interface:
     "sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
diff --git a/nixos/modules/tasks/scsi-link-power-management.nix b/nixos/modules/tasks/scsi-link-power-management.nix
index a74023dec21a..484c0a0186d7 100644
--- a/nixos/modules/tasks/scsi-link-power-management.nix
+++ b/nixos/modules/tasks/scsi-link-power-management.nix
@@ -2,18 +2,19 @@
 
 with lib;
 
+let cfg = config.powerManagement.scsiLinkPolicy; in
+
 {
   ###### interface
 
   options = {
 
     powerManagement.scsiLinkPolicy = mkOption {
-      default = "";
-      example = "min_power";
-      type = types.str;
+      default = null;
+      type = types.nullOr (types.enum [ "min_power" "max_performance" "medium_power" ]);
       description = ''
-        Configure the SCSI link power management policy. By default,
-        the kernel configures "max_performance".
+        SCSI link power management policy. The kernel default is
+        "max_performance".
       '';
     };
 
@@ -22,25 +23,10 @@ with lib;
 
   ###### implementation
 
-  config = mkIf (config.powerManagement.scsiLinkPolicy != "") {
-
-    jobs."scsi-link-pm" =
-      { description = "SCSI Link Power Management Policy";
-
-        startOn = "stopped udevtrigger";
-
-        task = true;
-
-        unitConfig.ConditionPathIsReadWrite = "/sys/class/scsi_host";
-
-        script = ''
-          shopt -s nullglob
-          for x in /sys/class/scsi_host/host*/link_power_management_policy; do
-            echo ${config.powerManagement.scsiLinkPolicy} > $x
-          done
-        '';
-      };
-
+  config = mkIf (cfg != null) {
+    services.udev.extraRules = ''
+      SUBSYSTEM=="scsi_host", ACTION=="add", KERNEL=="host*", ATTR{link_power_management_policy}="${cfg}"
+    '';
   };
 
 }
diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix
index 0c642bf3b816..718ca0851477 100644
--- a/nixos/modules/virtualisation/docker.nix
+++ b/nixos/modules/virtualisation/docker.nix
@@ -31,16 +31,11 @@ in
     socketActivation =
       mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description =
           ''
             This option enables docker with socket activation. I.e. docker will
             start when first called by client.
-
-            Note: This is false by default because systemd lower than 214 that
-            nixos uses so far, doesn't support SocketGroup option, so socket
-            created by docker has root group now. This will likely be changed
-            in future.  So set this option explicitly to false if you wish.
           '';
       };
     storageDriver =
diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix
index 00486df5c4ba..5fb472ebfc32 100644
--- a/nixos/modules/virtualisation/virtualbox-host.nix
+++ b/nixos/modules/virtualisation/virtualbox-host.nix
@@ -111,5 +111,8 @@ in
       };
 
     networking.interfaces.vboxnet0.ip4 = [ { address = "192.168.56.1"; prefixLength = 24; } ];
+    # Make sure NetworkManager won't assume this interface being up
+    # means we have internet access.
+    networking.networkmanager.unmanaged = ["vboxnet0"];
   })]);
 }
diff --git a/nixos/release.nix b/nixos/release.nix
index 1a1ed4bca410..f0df3fe3e1ef 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -276,6 +276,7 @@ in rec {
   tests.networkingProxy = callTest tests/networking-proxy.nix {};
   tests.nfs3 = callTest tests/nfs.nix { version = 3; };
   tests.nfs4 = callTest tests/nfs.nix { version = 4; };
+  tests.nixosPinVersion = callTest tests/nixos-pin-version.nix {};
   tests.nsd = callTest tests/nsd.nix {};
   tests.openssh = callTest tests/openssh.nix {};
   tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; });
@@ -284,6 +285,7 @@ in rec {
   tests.proxy = callTest tests/proxy.nix {};
   tests.quake3 = callTest tests/quake3.nix {};
   tests.runInMachine = callTest tests/run-in-machine.nix {};
+  tests.sddm = callTest tests/sddm.nix {};
   tests.simple = callTest tests/simple.nix {};
   tests.tomcat = callTest tests/tomcat.nix {};
   tests.udisks2 = callTest tests/udisks2.nix {};
diff --git a/nixos/tests/gnome3_18.nix b/nixos/tests/gnome3_18.nix
new file mode 100644
index 000000000000..971fd48b1868
--- /dev/null
+++ b/nixos/tests/gnome3_18.nix
@@ -0,0 +1,36 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "gnome3";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ iElectric eelco chaoflow lethalman ];
+  };
+
+  machine =
+    { config, pkgs, ... }:
+
+    { imports = [ ./common/user-account.nix ];
+
+      services.xserver.enable = true;
+
+      services.xserver.displayManager.auto.enable = true;
+      services.xserver.displayManager.auto.user = "alice";
+      services.xserver.desktopManager.gnome3.enable = true;
+
+      environment.gnome3.packageSet = pkgs.gnome3_18;
+
+      virtualisation.memorySize = 512;
+    };
+
+  testScript =
+    ''
+      $machine->waitForX;
+      $machine->sleep(15);
+
+      # Check that logging in has given the user ownership of devices.
+      $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
+
+      $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
+      $machine->waitForWindow(qr/Terminal/);
+      $machine->sleep(20);
+      $machine->screenshot("screen");
+    '';
+})
diff --git a/nixos/tests/nixos-pin-version.nix b/nixos/tests/nixos-pin-version.nix
new file mode 100644
index 000000000000..91fba2e759d2
--- /dev/null
+++ b/nixos/tests/nixos-pin-version.nix
@@ -0,0 +1,57 @@
+{ system ? builtins.currentSystem }:
+
+with import ../lib/testing.nix { inherit system; };
+let
+in
+
+pkgs.stdenv.mkDerivation rec {
+  name = "nixos-pin-version";
+  src = ../..;
+  buildInputs = with pkgs; [ nix gnugrep ];
+
+    withoutPath = pkgs.writeText "configuration.nix" ''
+    {
+      nixos.extraModules = [ ({lib, ...}: { system.nixosRevision = lib.mkForce "ABCDEF"; }) ];
+    }
+  '';
+
+  withPath = pkgs.writeText "configuration.nix" ''
+    {
+      nixos.path = ${src}/nixos ;
+      nixos.extraModules = [ ({lib, ...}: { system.nixosRevision = lib.mkForce "ABCDEF"; }) ];
+    }
+  '';
+
+  phases = "buildPhase";
+  buildPhase = ''
+    datadir="${pkgs.nix}/share"
+    export TEST_ROOT=$(pwd)/test-tmp
+    export NIX_STORE_DIR=$TEST_ROOT/store
+    export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
+    export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
+    export NIX_STATE_DIR=$TEST_ROOT/var/nix
+    export NIX_DB_DIR=$TEST_ROOT/db
+    export NIX_CONF_DIR=$TEST_ROOT/etc
+    export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
+    export NIX_BUILD_HOOK=
+    export PAGER=cat
+    cacheDir=$TEST_ROOT/binary-cache
+    nix-store --init
+
+    export NIX_PATH="nixpkgs=$src:nixos=$src/nixos:nixos-config=${withoutPath}" ;
+    if test $(nix-instantiate $src/nixos -A config.system.nixosRevision --eval-only) != '"ABCDEF"' ; then :;
+    else
+      echo "Unexpected re-entry without the nixos.path option defined.";
+      exit 1;
+    fi;
+
+    export NIX_PATH="nixpkgs=$src:nixos=$src/nixos:nixos-config=${withPath}" ;
+    if test $(nix-instantiate $src/nixos -A config.system.nixosRevision --eval-only) = '"ABCDEF"' ; then :;
+    else
+      echo "Expected a re-entry when the nixos.path option is defined.";
+      exit 1;
+    fi;
+
+    touch $out;
+  '';
+}
diff --git a/nixos/tests/sddm.nix b/nixos/tests/sddm.nix
new file mode 100644
index 000000000000..e11b5714d5c2
--- /dev/null
+++ b/nixos/tests/sddm.nix
@@ -0,0 +1,28 @@
+import ./make-test.nix ({ pkgs, ...} : {
+  name = "sddm";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ ttuegel ];
+  };
+
+  machine = { lib, ... }: {
+    imports = [ ./common/user-account.nix ];
+    services.xserver.enable = true;
+    services.xserver.displayManager.sddm = {
+      enable = true;
+      autoLogin = {
+        enable = true;
+        user = "alice";
+      };
+    };
+    services.xserver.windowManager.default = "icewm";
+    services.xserver.windowManager.icewm.enable = true;
+    services.xserver.desktopManager.default = "none";
+  };
+
+  enableOCR = true;
+
+  testScript = { nodes, ... }: ''
+    startAll;
+    $machine->waitForWindow("^IceWM ");
+  '';
+})