about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/installation/installing.xml5
-rw-r--r--nixos/doc/manual/release-notes/rl-1603.xml15
-rw-r--r--nixos/lib/make-iso9660-image.nix2
-rw-r--r--nixos/modules/config/krb5.nix2
-rw-r--r--nixos/modules/hardware/video/nvidia.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/security/grsecurity.nix28
-rw-r--r--nixos/modules/services/logging/awstats.nix123
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix12
-rw-r--r--nixos/modules/services/monitoring/grafana.nix2
-rw-r--r--nixos/modules/services/networking/bird.nix4
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.nix5
-rw-r--r--nixos/modules/services/networking/nsd.nix12
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix2
-rw-r--r--nixos/modules/services/networking/unbound.nix2
-rw-r--r--nixos/modules/services/networking/vsftpd.nix9
-rw-r--r--nixos/modules/services/printing/cupsd.nix3
-rw-r--r--nixos/modules/services/system/kerberos.nix4
-rw-r--r--nixos/modules/services/torrent/transmission.nix1
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/foswiki.nix78
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix2
-rw-r--r--nixos/modules/services/x11/window-managers/exwm.nix55
-rw-r--r--nixos/modules/services/x11/window-managers/jwm.nix25
-rw-r--r--nixos/modules/system/boot/stage-1.nix1
-rw-r--r--nixos/modules/tasks/swraid.nix41
-rw-r--r--nixos/modules/virtualisation/amazon-image.nix1
26 files changed, 389 insertions, 48 deletions
diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml
index 9aec57fb6d5a..7e71df28cdb3 100644
--- a/nixos/doc/manual/installation/installing.xml
+++ b/nixos/doc/manual/installation/installing.xml
@@ -22,7 +22,10 @@
   (with empty password).</para></listitem>
 
   <listitem><para>If you downloaded the graphical ISO image, you can
-  run <command>start display-manager</command> to start KDE.</para></listitem>
+  run <command>start display-manager</command> to start KDE. If you
+  want to continue on the terminal, you can use
+  <command>loadkeys</command> to switch to your preferred keyboard layout.
+  (We even provide neo2 via <command>loadkeys de neo</command>!)</para></listitem>
 
   <listitem><para>The boot process should have brought up networking (check
   <command>ip a</command>).  Networking is necessary for the
diff --git a/nixos/doc/manual/release-notes/rl-1603.xml b/nixos/doc/manual/release-notes/rl-1603.xml
index 0ede1a9ce8ed..83057a44d0ae 100644
--- a/nixos/doc/manual/release-notes/rl-1603.xml
+++ b/nixos/doc/manual/release-notes/rl-1603.xml
@@ -247,6 +247,21 @@ $TTL 1800
     </programlisting>
   </listitem>
 
+  <listitem>
+    <para>
+    <literal>service.syncthing.dataDir</literal> options now has to point
+    to exact folder where syncthing is writing to. Example configuration should
+    loook something like:
+    </para>
+    <programlisting>
+services.syncthing = {
+    enable = true;
+    dataDir = "/home/somebody/.syncthing";
+    user = "somebody";
+};
+    </programlisting>
+  </listitem>
+
 </itemizedlist>
 
 
diff --git a/nixos/lib/make-iso9660-image.nix b/nixos/lib/make-iso9660-image.nix
index b2409c6006bc..21c9cca316d1 100644
--- a/nixos/lib/make-iso9660-image.nix
+++ b/nixos/lib/make-iso9660-image.nix
@@ -22,7 +22,7 @@
 , # Whether this should be an efi-bootable El-Torito CD.
   efiBootable ? false
 
-, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
+, # Whether this should be an hybrid CD (bootable from USB as well as CD).
   usbBootable ? false
 
 , # The path (in the ISO file system) of the boot image.
diff --git a/nixos/modules/config/krb5.nix b/nixos/modules/config/krb5.nix
index d2198e4ac1ae..b845ef69a753 100644
--- a/nixos/modules/config/krb5.nix
+++ b/nixos/modules/config/krb5.nix
@@ -32,7 +32,7 @@ in
 
       kdc = mkOption {
         default = "kerberos.mit.edu";
-        description = "Kerberos Domain Controller.";
+        description = "Key Distribution Center";
       };
 
       kerberosAdminServer = mkOption {
diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix
index 711576982ec3..8514f765e610 100644
--- a/nixos/modules/hardware/video/nvidia.nix
+++ b/nixos/modules/hardware/video/nvidia.nix
@@ -14,6 +14,8 @@ let
   nvidiaForKernel = kernelPackages:
     if elem "nvidia" drivers then
         kernelPackages.nvidia_x11
+    else if elem "nvidiaBeta" drivers then
+        kernelPackages.nvidia_x11_beta
     else if elem "nvidiaLegacy173" drivers then
       kernelPackages.nvidia_x11_legacy173
     else if elem "nvidiaLegacy304" drivers then
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 640e8ae5c19d..86cd87efdbeb 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -176,6 +176,7 @@
   ./services/hardware/udisks2.nix
   ./services/hardware/upower.nix
   ./services/hardware/thermald.nix
+  ./services/logging/awstats.nix
   ./services/logging/fluentd.nix
   ./services/logging/klogd.nix
   ./services/logging/logcheck.nix
diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix
index 40942644868a..3aabbc8fe1bc 100644
--- a/nixos/modules/security/grsecurity.nix
+++ b/nixos/modules/security/grsecurity.nix
@@ -26,19 +26,12 @@ in
         '';
       };
 
-      stable = mkOption {
-        type = types.bool;
-        default = false;
+      kernelPatch = mkOption {
+        type = types.attrs;
+        default = pkgs.kernelPatches.grsecurity_latest;
+        example = pkgs.kernelPatches.grsecurity_4_1;
         description = ''
-          Enable the stable grsecurity patch, based on Linux 3.14.
-        '';
-      };
-
-      testing = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Enable the testing grsecurity patch, based on Linux 4.0.
+          Grsecurity patch to use.
         '';
       };
 
@@ -219,16 +212,7 @@ in
 
   config = mkIf cfg.enable {
     assertions =
-      [ { assertion = cfg.stable || cfg.testing;
-          message   = ''
-            If grsecurity is enabled, you must select either the
-            stable patch (with kernel 3.14), or the testing patch (with
-            kernel 4.0) to continue.
-          '';
-        }
-        { assertion = !(cfg.stable && cfg.testing);
-          message   = "Select either one of the stable or testing patch";
-        }
+      [
         { assertion = (cfg.config.restrictProc -> !cfg.config.restrictProcWithGroup) ||
                       (cfg.config.restrictProcWithGroup -> !cfg.config.restrictProc);
           message   = "You cannot enable both restrictProc and restrictProcWithGroup";
diff --git a/nixos/modules/services/logging/awstats.nix b/nixos/modules/services/logging/awstats.nix
new file mode 100644
index 000000000000..8ab7e6acd98e
--- /dev/null
+++ b/nixos/modules/services/logging/awstats.nix
@@ -0,0 +1,123 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.awstats;
+  package = pkgs.awstats;
+in
+
+{
+  options.services.awstats = {
+    enable = mkOption {
+      type = types.bool;
+      default = cfg.service.enable;
+      description = ''
+        Enable the awstats program (but not service).
+        Currently only simple httpd (Apache) configs are supported,
+        and awstats plugins may not work correctly.
+      '';
+    };
+    vardir = mkOption {
+      type = types.path;
+      default = "/var/lib/awstats";
+      description = "The directory where variable awstats data will be stored.";
+    };
+
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = "Extra configuration to be appendend to awstats.conf.";
+    };
+
+    updateAt = mkOption {
+      type = types.nullOr types.string;
+      default = null;
+      example = "hourly";
+      description = ''
+        Specification of the time at which awstats will get updated.
+        (in the format described by <citerefentry>
+          <refentrytitle>systemd.time</refentrytitle>
+          <manvolnum>5</manvolnum></citerefentry>)
+      '';
+    };
+
+    service = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''Enable the awstats web service. This switches on httpd.'';
+      };
+      urlPrefix = mkOption {
+        type = types.string;
+        default = "/awstats";
+        description = "The URL prefix under which the awstats service appears.";
+      };
+    };
+  };
+
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ package.bin ];
+    /* TODO:
+      - heed config.services.httpd.logPerVirtualHost, etc.
+      - Can't AllowToUpdateStatsFromBrowser, as CGI scripts don't have permission
+        to read the logs, and our httpd config apparently doesn't an option for that.
+    */
+    environment.etc."awstats/awstats.conf".source = pkgs.runCommand "awstats.conf"
+      { preferLocalBuild = true; }
+      ( let
+          cfg-httpd = config.services.httpd;
+          logFormat =
+            if cfg-httpd.logFormat == "combined" then "1" else
+            if cfg-httpd.logFormat == "common" then "4" else
+            throw "awstats service doesn't support Apache log format `${cfg-httpd.logFormat}`";
+        in
+        ''
+          sed \
+            -e 's|^\(DirData\)=.*$|\1="${cfg.vardir}"|' \
+            -e 's|^\(DirIcons\)=.*$|\1="icons"|' \
+            -e 's|^\(CreateDirDataIfNotExists\)=.*$|\1=1|' \
+            -e 's|^\(SiteDomain\)=.*$|\1="${cfg-httpd.hostName}"|' \
+            -e 's|^\(LogFile\)=.*$|\1="${cfg-httpd.logDir}/access_log"|' \
+            -e 's|^\(LogFormat\)=.*$|\1=${logFormat}|' \
+            < '${package.out}/wwwroot/cgi-bin/awstats.model.conf' > "$out"
+          echo '${cfg.extraConfig}' >> "$out"
+        '');
+
+    # The httpd sub-service showing awstats.
+    services.httpd.enable = mkIf cfg.service.enable true;
+    services.httpd.extraSubservices = mkIf cfg.service.enable [ { function = { serverInfo, ... }: {
+      extraConfig =
+        ''
+          Alias ${cfg.service.urlPrefix}/classes "${package.out}/wwwroot/classes/"
+          Alias ${cfg.service.urlPrefix}/css "${package.out}/wwwroot/css/"
+          Alias ${cfg.service.urlPrefix}/icons "${package.out}/wwwroot/icon/"
+          ScriptAlias ${cfg.service.urlPrefix}/ "${package.out}/wwwroot/cgi-bin/"
+
+          <Directory "${package.out}/wwwroot">
+            Options None
+            AllowOverride None
+            Order allow,deny
+            Allow from all
+          </Directory>
+        '';
+      startupScript =
+        let
+          inherit (serverInfo.serverConfig) user group;
+        in pkgs.writeScript "awstats_startup.sh"
+          ''
+            mkdir -p '${cfg.vardir}'
+            chown '${user}:${group}' '${cfg.vardir}'
+          '';
+    };}];
+
+    systemd.services.awstats-update = mkIf (cfg.updateAt != null) {
+      description = "awstats log collector";
+      script = "exec '${package.bin}/bin/awstats' -update -config=awstats.conf";
+      startAt = cfg.updateAt;
+    };
+  };
+
+}
+
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index cf2ee20801ab..78f0cd18040d 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -257,13 +257,11 @@ in
         type = types.bool;
         default = true;
         description = ''
-          If enabled, Nix will only download binaries from binary
-          caches if they are cryptographically signed with any of the
-          keys listed in
-          <option>nix.binaryCachePublicKeys</option>. If disabled (the
-          default), signatures are neither required nor checked, so
-          it's strongly recommended that you use only trustworthy
-          caches and https to prevent man-in-the-middle attacks.
+          If enabled (the default), Nix will only download binaries from binary caches if
+          they are cryptographically signed with any of the keys listed in
+          <option>nix.binaryCachePublicKeys</option>. If disabled, signatures are neither
+          required nor checked, so it's strongly recommended that you use only
+          trustworthy caches and https to prevent man-in-the-middle attacks.
         '';
       };
 
diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix
index 1dec528b5a2c..5c6f063b1493 100644
--- a/nixos/modules/services/monitoring/grafana.nix
+++ b/nixos/modules/services/monitoring/grafana.nix
@@ -87,7 +87,7 @@ in {
 
     staticRootPath = mkOption {
       description = "Root path for static assets.";
-      default = "${cfg.package.out}/share/grafana/public";
+      default = "${cfg.package}/share/grafana/public";
       type = types.str;
     };
 
diff --git a/nixos/modules/services/networking/bird.nix b/nixos/modules/services/networking/bird.nix
index e7e1db191529..e76cdac14ca8 100644
--- a/nixos/modules/services/networking/bird.nix
+++ b/nixos/modules/services/networking/bird.nix
@@ -30,7 +30,7 @@ in
 
       user = mkOption {
         type = types.string;
-        default = "ircd";
+        default = "bird";
         description = ''
           BIRD Internet Routing Daemon user.
         '';
@@ -38,7 +38,7 @@ in
 
       group = mkOption {
         type = types.string;
-        default = "ircd";
+        default = "bird";
         description = ''
           BIRD Internet Routing Daemon group.
         '';
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix
index c724ee979c2d..9bb28838878f 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy.nix
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -49,7 +49,7 @@ in
         '';
       };
       resolverName = mkOption {
-        default = "opendns";
+        default = "cisco";
         type = types.nullOr types.string;
         description = ''
           The name of the upstream DNSCrypt resolver to use. See
@@ -130,6 +130,9 @@ in
         ${pkgs.xz}/lib/liblzma.so.* mr,
         ${pkgs.libgcrypt}/lib/libgcrypt.so.* mr,
         ${pkgs.libgpgerror}/lib/libgpg-error.so.* mr,
+        ${pkgs.libcap}/lib/libcap.so.* mr,
+        ${pkgs.lz4}/lib/liblz4.so.* mr,
+        ${pkgs.attr}/lib/libattr.so.* mr,
 
         ${resolverListFile} r,
       }
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index ca08bb57895a..333a3378c4cc 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -346,7 +346,7 @@ in
       type = types.bool;
       default = true;
       description = ''
-        Wheter NSD should answer VERSION.BIND and VERSION.SERVER CHAOS class queries.
+        Whether NSD should answer VERSION.BIND and VERSION.SERVER CHAOS class queries.
       '';
     };
 
@@ -378,7 +378,7 @@ in
       type = types.bool;
       default = true;
       description = ''
-        Wheter to listen on IPv4 connections.
+        Whether to listen on IPv4 connections.
       '';
     };
 
@@ -394,7 +394,7 @@ in
       type = types.bool;
       default = true;
       description = ''
-        Wheter to listen on IPv6 connections.
+        Whether to listen on IPv6 connections.
       '';
     };
 
@@ -434,7 +434,7 @@ in
       type = types.bool;
       default = pkgs.stdenv.isLinux;
       description = ''
-        Wheter to enable SO_REUSEPORT on all used sockets. This lets multiple
+        Whether to enable SO_REUSEPORT on all used sockets. This lets multiple
         processes bind to the same port. This speeds up operation especially
         if the server count is greater than one and makes fast restarts less
         prone to fail
@@ -445,7 +445,7 @@ in
       type = types.bool;
       default = false;
       description = ''
-        Wheter if this server will be a root server (a DNS root server, you
+        Whether this server will be a root server (a DNS root server, you
         usually don't want that).
       '';
     };
@@ -524,7 +524,7 @@ in
       type = types.bool;
       default = true;
       description = ''
-        Wheter to check mtime of all zone files on start and sighup.
+        Whether to check mtime of all zone files on start and sighup.
       '';
     };
 
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 20a1777f3ccb..5971a5a250d3 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -263,7 +263,7 @@ in
 
             serviceConfig =
               { ExecStart =
-                  "${cfgc.package}/sbin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
+                  "${cfgc.package}/bin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
                   "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
                 KillMode = "process";
               } // (if cfg.startWhenNeeded then {
diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix
index e154aed0843a..89762fe52488 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -113,7 +113,7 @@ in
       '';
 
       serviceConfig = {
-        ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${stateDir}/unbound.conf";
+        ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf";
         ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random";
       };
     };
diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix
index e7301e9ef5f5..7ec484941ede 100644
--- a/nixos/modules/services/networking/vsftpd.nix
+++ b/nixos/modules/services/networking/vsftpd.nix
@@ -85,6 +85,9 @@ let
         ssl_enable=YES
         rsa_cert_file=${cfg.rsaCertFile}
       ''}
+      ${optionalString (cfg.rsaKeyFile != null) ''
+        rsa_private_key_file=${cfg.rsaKeyFile}
+      ''}
       ${optionalString (cfg.userlistFile != null) ''
         userlist_file=${cfg.userlistFile}
       ''}
@@ -147,6 +150,12 @@ in
         description = "RSA certificate file.";
       };
 
+      rsaKeyFile = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        description = "RSA private key file.";
+      };
+
       anonymousUmask = mkOption {
         type = types.string;
         default = "077";
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index 80d11565e47d..9fb854e50cfb 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -238,7 +238,8 @@ in
         example = literalExample "[ pkgs.splix ]";
         description = ''
           CUPS drivers to use. Drivers provided by CUPS, cups-filters, Ghostscript
-          and Samba are added unconditionally.
+          and Samba are added unconditionally. For adding Gutenprint, see
+          <literal>gutenprint</literal>.
         '';
       };
 
diff --git a/nixos/modules/services/system/kerberos.nix b/nixos/modules/services/system/kerberos.nix
index e0c3f95c3ccc..347302c6090d 100644
--- a/nixos/modules/services/system/kerberos.nix
+++ b/nixos/modules/services/system/kerberos.nix
@@ -46,7 +46,7 @@ in
       };
 
     systemd.services.kdc = {
-      description = "Kerberos Domain Controller daemon";
+      description = "Key Distribution Center daemon";
       wantedBy = [ "multi-user.target" ];
       preStart = ''
         mkdir -m 0755 -p ${stateDir}
@@ -55,7 +55,7 @@ in
     };
 
     systemd.services.kpasswdd = {
-      description = "Kerberos Domain Controller daemon";
+      description = "Kerberos Password Changing daemon";
       wantedBy = [ "multi-user.target" ];
       script = "${heimdal}/sbin/kpasswdd";
     };
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index 5ae12ac1e953..7718a721763c 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -128,6 +128,7 @@ in
           ${pkgs.c-ares}/lib/libcares*.so*          mr,
           ${pkgs.libcap}/lib/libcap*.so*            mr,
           ${pkgs.attr}/lib/libattr*.so*             mr,
+          ${pkgs.lz4}/lib/liblz4*.so*               mr,
 
           @{PROC}/sys/kernel/random/uuid   r,
           @{PROC}/sys/vm/overcommit_memory r,
diff --git a/nixos/modules/services/web-servers/apache-httpd/foswiki.nix b/nixos/modules/services/web-servers/apache-httpd/foswiki.nix
new file mode 100644
index 000000000000..8c1ac8935a47
--- /dev/null
+++ b/nixos/modules/services/web-servers/apache-httpd/foswiki.nix
@@ -0,0 +1,78 @@
+{ config, pkgs, lib, serverInfo, ... }:
+let
+  inherit (pkgs) foswiki;
+  inherit (serverInfo.serverConfig) user group;
+  inherit (config) vardir;
+in
+{
+  options.vardir = lib.mkOption {
+    type = lib.types.path;
+    default = "/var/www/foswiki";
+    description = "The directory where variable foswiki data will be stored and served from.";
+  };
+
+  # TODO: this will probably need to be better customizable
+  extraConfig =
+    let httpd-conf = pkgs.runCommand "foswiki-httpd.conf"
+      { preferLocalBuild = true; }
+      ''
+        substitute '${foswiki}/foswiki_httpd_conf.txt' "$out" \
+          --replace /var/www/foswiki/ "${vardir}/"
+      '';
+    in
+      ''
+        RewriteEngine on
+        RewriteRule /foswiki/(.*) ${vardir}/$1
+
+        <Directory "${vardir}">
+          Require all granted
+        </Directory>
+
+        Include ${httpd-conf}
+        <Directory "${vardir}/pub">
+          Options FollowSymlinks
+        </Directory>
+      '';
+
+  /** This handles initial setup and updates.
+      It will probably need some tweaking, maybe per-site.  */
+  startupScript = pkgs.writeScript "foswiki_startup.sh" (
+    let storeLink = "${vardir}/package"; in
+    ''
+      [ -e '${storeLink}' ] || needs_setup=1
+      mkdir -p '${vardir}'
+      cd '${vardir}'
+      ln -sf -T '${foswiki}' '${storeLink}'
+
+      if [ -n "$needs_setup" ]; then # do initial setup
+        mkdir -p bin lib
+        # setup most of data/ as copies only
+        cp -r '${foswiki}'/data '${vardir}/'
+        rm -r '${vardir}'/data/{System,mime.types}
+        ln -sr -t '${vardir}/data/' '${storeLink}'/data/{System,mime.types}
+
+        ln -sr '${storeLink}/locale' .
+
+        mkdir pub
+        ln -sr '${storeLink}/pub/System' pub/
+
+        mkdir templates
+        ln -sr '${storeLink}'/templates/* templates/
+
+        ln -sr '${storeLink}/tools' .
+
+        mkdir -p '${vardir}'/working/{logs,tmp}
+        ln -sr '${storeLink}/working/README' working/ # used to check dir validity
+
+        chown -R '${user}:${group}' .
+        chmod +w -R .
+      fi
+
+      # bin/* and lib/* shall always be overwritten, in case files are added
+      ln -srf '${storeLink}'/bin/* '${vardir}/bin/'
+      ln -srf '${storeLink}'/lib/* '${vardir}/lib/'
+    ''
+    /* Symlinking bin/ one-by-one ensures that ${vardir}/lib/LocalSite.cfg
+        is used instead of ${foswiki}/... */
+  );
+}
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index 37d3348b8a32..63136beac710 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -13,9 +13,11 @@ in
     ./clfswm.nix
     ./compiz.nix
     ./dwm.nix
+    ./exwm.nix
     ./fluxbox.nix
     ./herbstluftwm.nix
     ./i3.nix
+    ./jwm.nix
     ./metacity.nix
     ./openbox.nix
     ./notion.nix
diff --git a/nixos/modules/services/x11/window-managers/exwm.nix b/nixos/modules/services/x11/window-managers/exwm.nix
new file mode 100644
index 000000000000..dbbd8a125d66
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/exwm.nix
@@ -0,0 +1,55 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.exwm;
+  loadScript = pkgs.writeText "emacs-exwm-load" ''
+    (require 'exwm)
+    ${optionalString cfg.enableDefaultConfig ''
+      (require 'exwm-config)
+      (exwm-config-default)
+    ''}
+  '';
+  packages = epkgs: cfg.extraPackages epkgs ++ [ epkgs.exwm ];
+  exwm-emacs = pkgs.emacsWithPackages packages;
+in
+
+{
+  options = {
+    services.xserver.windowManager.exwm = {
+      enable = mkEnableOption "exwm";
+      enableDefaultConfig = mkOption {
+        default = true;
+        example = false;
+        type = lib.types.bool;
+        description = "Enable an uncustomised exwm configuration.";
+      };
+      extraPackages = mkOption {
+        default = self: [];
+        example = literalExample ''
+          epkgs: [
+            epkgs.emms
+            epkgs.magit
+            epkgs.proofgeneral
+          ]
+        '';
+        description = ''
+          Extra packages available to Emacs. The value must be a
+          function which receives the attrset defined in
+          <varname>emacsPackages</varname> as the sole argument.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "exwm";
+      start = ''
+        ${exwm-emacs}/bin/emacs -l ${loadScript}
+      '';
+    };
+    environment.systemPackages = [ exwm-emacs ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/jwm.nix b/nixos/modules/services/x11/window-managers/jwm.nix
new file mode 100644
index 000000000000..0e8dab2e9224
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/jwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.jwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.jwm.enable = mkEnableOption "jwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "jwm";
+      start = ''
+        ${pkgs.jwm}/bin/jwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.jwm ];
+  };
+}
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index f31620df1d85..757d883373ac 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -58,6 +58,7 @@ let
 
       # Add RAID mdadm tool.
       copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm
+      copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
 
       # Copy udev.
       copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
diff --git a/nixos/modules/tasks/swraid.nix b/nixos/modules/tasks/swraid.nix
index 8e9728919718..d6cb1c96ef46 100644
--- a/nixos/modules/tasks/swraid.nix
+++ b/nixos/modules/tasks/swraid.nix
@@ -12,4 +12,45 @@
     cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
   '';
 
+  systemd.services.mdadm-shutdown = {
+    wantedBy = [ "final.target"];
+    after = [ "umount.target" ];
+
+    unitConfig = {
+      DefaultDependencies = false;
+    };
+
+    serviceConfig = {
+      Type = "oneshot";
+      ExecStart = ''${pkgs.mdadm}/bin/mdadm --wait-clean --scan'';
+    };
+  };
+
+  systemd.services."mdmon@" = {
+    description = "MD Metadata Monitor on /dev/%I";
+
+    unitConfig.DefaultDependencies = false;
+
+    serviceConfig = {
+      Type = "forking";
+      Environment = "IMSM_NO_PLATFORM=1";
+      ExecStart = ''${pkgs.mdadm}/bin/mdmon --offroot --takeover %I'';
+      KillMode = "none";
+    };
+  };
+
+  systemd.services."mdadm-grow-continue@" = {
+    description = "Manage MD Reshape on /dev/%I";
+
+    unitConfig.DefaultDependencies = false;
+
+    serviceConfig = {
+      ExecStart = ''${pkgs.mdadm}/bin/mdadm --grow --continue /dev/%I'';
+      StandardInput = "null";
+      StandardOutput = "null";
+      StandardError = "null";
+      KillMode = "none";
+    };
+  };
+ 
 }
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index a895f66db8ef..35af905bc628 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -40,7 +40,6 @@ let cfg = config.ec2; in
         # Force udev to exit to prevent random "Device or resource busy
         # while trying to open /dev/xvda" errors from fsck.
         udevadm control --exit || true
-        kill -9 -1
       '';
 
     boot.initrd.network.enable = true;