about summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/fonts/fontconfig.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-rebuild.sh4
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--[-rwxr-xr-x]nixos/modules/module-list.nix5
-rw-r--r--nixos/modules/programs/environment.nix4
-rw-r--r--nixos/modules/rename.nix7
-rw-r--r--nixos/modules/security/grsecurity.nix18
-rw-r--r--nixos/modules/services/amqp/rabbitmq.nix32
-rw-r--r--nixos/modules/services/databases/openldap.nix44
-rw-r--r--nixos/modules/services/hardware/freefall.nix62
-rw-r--r--nixos/modules/services/hardware/tlp.nix93
-rw-r--r--nixos/modules/services/misc/apache-kafka.nix156
-rw-r--r--nixos/modules/services/misc/gitlab.nix19
-rw-r--r--nixos/modules/services/misc/gitolite.nix1
-rw-r--r--nixos/modules/services/misc/redmine.nix3
-rw-r--r--nixos/modules/services/monitoring/riemann-dash.nix2
-rw-r--r--nixos/modules/services/networking/firewall.nix2
-rw-r--r--nixos/modules/services/networking/ntpd.nix3
-rw-r--r--nixos/modules/services/networking/openntpd.nix24
-rw-r--r--nixos/modules/services/networking/tftpd.nix6
-rw-r--r--nixos/modules/services/networking/tlsdated.nix110
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/default.nix1
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/owncloud.nix577
-rw-r--r--nixos/modules/services/x11/desktop-managers/default.nix4
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde4.nix8
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix143
-rw-r--r--nixos/modules/services/x11/desktop-managers/kodi.nix31
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix2
-rw-r--r--nixos/modules/services/x11/display-managers/kdm.nix3
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/loader/gummiboot/gummiboot.nix2
-rw-r--r--nixos/modules/system/boot/loader/loader.nix15
-rw-r--r--nixos/modules/system/boot/modprobe.nix15
-rw-r--r--nixos/modules/tasks/filesystems.nix7
-rw-r--r--nixos/modules/virtualisation/containers.nix10
-rw-r--r--nixos/modules/virtualisation/nixos-container.pl4
36 files changed, 1359 insertions, 64 deletions
diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
index 793b0a250acd..6f17bd396a0b 100644
--- a/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixos/modules/config/fonts/fontconfig.nix
@@ -204,7 +204,7 @@ with lib;
             ${optionalString (fontconfig.dpi != 0) ''
             <match target="pattern">
               <edit name="dpi" mode="assign">
-                <double>${fontconfig.dpi}</double>
+                <double>${toString fontconfig.dpi}</double>
               </edit>
             </match>
             ''}
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index 93f258f54e3e..8157f8fc7da5 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -148,9 +148,9 @@ if [ -n "$buildNix" ]; then
             if ! nix-build '<nixpkgs>' -A nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
                 machine="$(uname -m)"
                 if [ "$machine" = x86_64 ]; then
-                    nixStorePath=/nix/store/d34q3q2zj9nriq4ifhn3dnnngqvinjb3-nix-1.7
+                    nixStorePath=/nix/store/ffig6yaggbh12dh9y5pnf1grf5lqyipz-nix-1.8
                 elif [[ "$machine" =~ i.86 ]]; then
-                    nixStorePath=/nix/store/qlah0darpcn6sf3lr2226rl04l1gn4xz-nix-1.7
+                    nixStorePath=/nix/store/lglhfp4mimfa5wzjjf1kqz6f5wlsj2mn-nix-1.8
                 else
                     echo "$0: unsupported platform"
                     exit 1
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 7bfbefb348f0..7415af8ab6af 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -176,7 +176,7 @@
       tox-bootstrapd = 166;
       cadvisor = 167;
       nylon = 168;
-
+      apache-kafka = 169;
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
       nixbld = 30000; # start of range of uids
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 2a2a7b004163..b949fef6bab7 100755..100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -144,11 +144,13 @@
   ./services/hardware/acpid.nix
   ./services/hardware/amd-hybrid-graphics.nix
   ./services/hardware/bluetooth.nix
+  ./services/hardware/freefall.nix
   ./services/hardware/nvidia-optimus.nix
   ./services/hardware/pcscd.nix
   ./services/hardware/pommed.nix
   ./services/hardware/sane.nix
   ./services/hardware/tcsd.nix
+  ./services/hardware/tlp.nix
   ./services/hardware/thinkfan.nix
   ./services/hardware/udev.nix
   ./services/hardware/udisks2.nix
@@ -168,6 +170,7 @@
   ./services/mail/opensmtpd.nix
   ./services/mail/postfix.nix
   ./services/mail/spamassassin.nix
+  ./services/misc/apache-kafka.nix
   #./services/misc/autofs.nix
   ./services/misc/cpuminer-cryptonight.nix
   ./services/misc/cgminer.nix
@@ -290,6 +293,7 @@
   ./services/networking/tcpcrypt.nix
   ./services/networking/teamspeak3.nix
   ./services/networking/tftpd.nix
+  ./services/networking/tlsdated.nix
   ./services/networking/tox-bootstrapd.nix
   ./services/networking/unbound.nix
   ./services/networking/unifi.nix
@@ -369,6 +373,7 @@
   ./system/boot/kernel.nix
   ./system/boot/kexec.nix
   ./system/boot/loader/efi.nix
+  ./system/boot/loader/loader.nix
   ./system/boot/loader/generations-dir/generations-dir.nix
   ./system/boot/loader/grub/grub.nix
   ./system/boot/loader/grub/ipxe.nix
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index a5ec387df647..4d93d2d35b46 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -46,12 +46,14 @@ in
         PERL5LIB = [ "/lib/perl5/site_perl" ];
         KDEDIRS = [ "" ];
         STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
-        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
+        QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" "/lib/qt5/plugins" ];
+        QML2_IMPORT_PATH = [ "/lib/qml" ];
         QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
         GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
         XDG_CONFIG_DIRS = [ "/etc/xdg" ];
         XDG_DATA_DIRS = [ "/share" ];
         MOZ_PLUGIN_PATH = [ "/lib/mozilla/plugins" ];
+        LIBEXEC_PATH = [ "/lib/libexec" ];
       };
 
     environment.extraInit =
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 20fd76855d96..1efc278aeb22 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -33,7 +33,8 @@ let
   zipModules = list:
     zipAttrsWith (n: v:
       if tail v != [] then
-        if n == "_type" then (head v)
+        if all (o: isAttrs o && o ? _type) v then mkMerge v
+        else if n == "_type" then head v
         else if n == "warnings" then concatLists v
         else if n == "description" || n == "apply" then
           abort "Cannot rename an option to multiple options."
@@ -115,8 +116,8 @@ in zipModules ([]
 ++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ]
 
 # KDE
-++ deprecated [ "kde" "extraPackages" ] [ "environment" "kdePackages" ]
-# ++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] # !!! doesn't work!
+++ deprecated [ "kde" "extraPackages" ] [ "environment" "systemPackages" ]
+++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ]
 
 # Multiple efi bootloaders now
 ++ obsolete [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ]
diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix
index 5c8c49939510..d0c7fa6ec288 100644
--- a/nixos/modules/security/grsecurity.nix
+++ b/nixos/modules/security/grsecurity.nix
@@ -156,6 +156,24 @@ in
           '';
         };
 
+        denyUSB = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            If true, then set <literal>GRKERNSEC_DENYUSB y</literal>.
+
+            This enables a sysctl with name
+            <literal>kernel.grsecurity.deny_new_usb</literal>. Setting
+            its value to <literal>1</literal> will prevent any new USB
+            devices from being recognized by the OS.  Any attempted
+            USB device insertion will be logged.
+
+            This option is intended to be used against custom USB
+            devices designed to exploit vulnerabilities in various USB
+            device drivers.
+          '';
+        };
+
         restrictProc = mkOption {
           type = types.bool;
           default = false;
diff --git a/nixos/modules/services/amqp/rabbitmq.nix b/nixos/modules/services/amqp/rabbitmq.nix
index 77487ec1ab91..780d5daded92 100644
--- a/nixos/modules/services/amqp/rabbitmq.nix
+++ b/nixos/modules/services/amqp/rabbitmq.nix
@@ -31,6 +31,15 @@ in {
           <literal>guest</literal> by default, so you should delete
           this user if you intend to allow external access.
         '';
+        type = types.str;
+      };
+
+      port = mkOption {
+        default = 5672;
+        description = ''
+          Port on which RabbitMQ will listen for AMQP connections.
+        '';
+        type = types.int;
       };
 
       dataDir = mkOption {
@@ -77,6 +86,7 @@ in {
     users.extraUsers.rabbitmq = {
       description = "RabbitMQ server user";
       home = "${cfg.dataDir}";
+      createHome = true;
       group = "rabbitmq";
       uid = config.ids.uids.rabbitmq;
     };
@@ -87,14 +97,16 @@ in {
       description = "RabbitMQ Server";
 
       wantedBy = [ "multi-user.target" ];
-      after = [ "network-interfaces.target" ];
+      after = [ "network.target" ];
 
-      path = [ pkgs.rabbitmq_server ];
+      path = [ pkgs.rabbitmq_server pkgs.procps ];
 
       environment = {
         RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia";
         RABBITMQ_NODE_IP_ADDRESS = cfg.listenAddress;
+        RABBITMQ_NODE_PORT = toString cfg.port;
         RABBITMQ_SERVER_START_ARGS = "-rabbit error_logger tty -rabbit sasl_error_logger false";
+        RABBITMQ_PID_FILE = "${cfg.dataDir}/pid";
         SYS_PREFIX = "";
         RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" ''
           [ ${concatStringsSep "," cfg.plugins} ].
@@ -103,26 +115,22 @@ in {
 
       serviceConfig = {
         ExecStart = "${pkgs.rabbitmq_server}/sbin/rabbitmq-server";
+        ExecStop = "${pkgs.rabbitmq_server}/sbin/rabbitmqctl stop";
         User = "rabbitmq";
         Group = "rabbitmq";
-        PermissionsStartOnly = true;
+        WorkingDirectory = cfg.dataDir;
       };
 
+      postStart = ''
+        rabbitmqctl wait ${cfg.dataDir}/pid
+      '';
+
       preStart = ''
-        mkdir -p ${cfg.dataDir} && chmod 0700 ${cfg.dataDir}
-        if [ "$(id -u)" = 0 ]; then chown rabbitmq:rabbitmq ${cfg.dataDir}; fi
-        
         ${optionalString (cfg.cookie != "") ''
             echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
             chmod 400 ${cfg.dataDir}/.erlang.cookie
-            chown rabbitmq:rabbitmq ${cfg.dataDir}/.erlang.cookie
         ''}
-
-        mkdir -p /var/log/rabbitmq && chmod 0700 /var/log/rabbitmq
-        chown rabbitmq:rabbitmq /var/log/rabbitmq
       '';
-
-      postStart = mkBefore "until rabbitmqctl status; do sleep 1; done";
     };
 
   };
diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix
index eae4c114fc12..29bdb2017523 100644
--- a/nixos/modules/services/databases/openldap.nix
+++ b/nixos/modules/services/databases/openldap.nix
@@ -20,23 +20,49 @@ in
     services.openldap = {
 
       enable = mkOption {
+        type = types.bool;
         default = false;
         description = "
           Whether to enable the ldap server.
         ";
+        example = literalExample ''
+          openldap.enable = true;
+          openldap.extraConfig = '''
+            include ''${pkgs.openldap}/etc/openldap/schema/core.schema
+            include ''${pkgs.openldap}/etc/openldap/schema/cosine.schema
+            include ''${pkgs.openldap}/etc/openldap/schema/inetorgperson.schema
+            include ''${pkgs.openldap}/etc/openldap/schema/nis.schema
+
+            database bdb 
+            suffix dc=example,dc=org 
+            rootdn cn=admin,dc=example,dc=org 
+            # NOTE: change after first start
+            rootpw secret
+            directory /var/db/openldap
+          ''';
+        '';
       };
 
       user = mkOption {
+        type = types.string;
         default = "openldap";
         description = "User account under which slapd runs.";
       };
 
       group = mkOption {
+        type = types.string;
         default = "openldap";
         description = "Group account under which slapd runs.";
       };
 
+      dataDir = mkOption {
+        type = types.string;
+        default = "/var/db/openldap";
+        description = "The database directory.";
+      };
+
       extraConfig = mkOption {
+        type = types.lines;
         default = "";
         description = "
           sldapd.conf configuration
@@ -60,22 +86,22 @@ in
       preStart = ''
         mkdir -p /var/run/slapd
         chown -R ${cfg.user}:${cfg.group} /var/run/slapd
-        mkdir -p /var/db/openldap
-        chown -R ${cfg.user}:${cfg.group} /var/db/openldap
+        mkdir -p ${cfg.dataDir}
+        chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
       '';
-      serviceConfig.ExecStart = "${openldap}/libexec/slapd -u openldap -g openldap -d 0 -f ${configFile}";
+      serviceConfig.ExecStart = "${openldap}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -f ${configFile}";
     };
 
-    users.extraUsers = optionalAttrs (cfg.user == "openldap") (singleton
-      { name = "openldap";
+    users.extraUsers.openldap =
+      { name = cfg.user;
         group = cfg.group;
         uid = config.ids.uids.openldap;
-      });
+      };
 
-    users.extraGroups = optionalAttrs (cfg.group == "openldap") (singleton
-      { name = "openldap";
+    users.extraGroups.openldap =
+      { name = cfg.group;
         gid = config.ids.gids.openldap;
-     });
+      };
 
   };
 }
diff --git a/nixos/modules/services/hardware/freefall.nix b/nixos/modules/services/hardware/freefall.nix
new file mode 100644
index 000000000000..6e6960bac491
--- /dev/null
+++ b/nixos/modules/services/hardware/freefall.nix
@@ -0,0 +1,62 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+{
+
+  ###### interface
+
+  options = with types; {
+
+    services.freefall = {
+
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to protect HP/Dell laptop hard drives (not SSDs) in free fall.
+        '';
+        type = bool;
+      };
+
+      devices = mkOption {
+        default = [ "/dev/sda" ];
+        description = ''
+          Device paths to all internal spinning hard drives.
+        '';
+        type = listOf string;
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = let
+
+    cfg = config.services.freefall;
+
+    mkService = dev:
+      assert dev != "";
+      let dev' = utils.escapeSystemdPath dev; in
+      nameValuePair "freefall-${dev'}"
+        { description = "Free-fall protection for ${dev}";
+        after = [ "${dev'}.device" ];
+        wantedBy = [ "${dev'}.device" ];
+        path = [ pkgs.freefall ];
+        serviceConfig = {
+          ExecStart = "${pkgs.freefall}/bin/freefall ${dev}";
+          Restart = "on-failure";
+          Type = "forking";
+        };
+      };
+
+  in mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.freefall ];
+
+    systemd.services = listToAttrs (map mkService cfg.devices);
+
+  };
+
+}
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
new file mode 100644
index 000000000000..f221c82e2eda
--- /dev/null
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+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);
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.tlp = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to enable the TLP daemon.";
+      };
+
+      extraConfig = mkOption {
+        type = types.str;
+        default = "";
+        description = "Additional configuration variables for TLP";
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services = {
+      tlp = {
+        description = "TLP system startup/shutdown";
+
+        after = [ "multi-user.target" ];
+        wantedBy = [ "multi-user.target" ];
+        before = [ "shutdown.target" ];
+
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = true;
+          ExecStart = "${tlp}/bin/tlp init start";
+          ExecStop = "${tlp}/bin/tlp init stop";
+        };
+      };
+
+      tlp-sleep = {
+        description = "TLP suspend/resume";
+
+        wantedBy = [ "sleep.target" ];
+        before = [ "sleep.target" ];
+
+        unitConfig = {
+          StopWhenUnneeded = true;
+        };
+
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = true;
+          ExecStart = "${tlp}/bin/tlp suspend";
+          ExecStop = "${tlp}/bin/tlp resume";
+        };
+      };
+    };
+
+    services.udev.packages = [ tlp ];
+
+    environment.etc = [{ source = confFile;
+                         target = "default/tlp";
+                       }
+                      ] ++ optional tlp.enableRDW {
+                        source = "${tlp}/etc/NetworkManager/dispatcher.d/99tlp-rdw-nm";
+                        target = "NetworkManager/dispatcher.d/99tlp-rdw-nm";
+                      };
+
+    environment.systemPackages = [ tlp ];
+
+  };
+
+}
diff --git a/nixos/modules/services/misc/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix
new file mode 100644
index 000000000000..168615153fed
--- /dev/null
+++ b/nixos/modules/services/misc/apache-kafka.nix
@@ -0,0 +1,156 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.apache-kafka;
+
+  serverProperties =
+    if cfg.serverProperties != null then
+      cfg.serverProperties
+    else
+      ''
+        # Generated by nixos
+        broker.id=${toString cfg.brokerId}
+        port=${toString cfg.port}
+        host.name=${cfg.hostname}
+        log.dirs=${concatStringsSep "," cfg.logDirs}
+        zookeeper.connect=${cfg.zookeeper}
+        ${toString cfg.extraProperties}
+      '';
+
+  configDir = pkgs.buildEnv {
+    name = "apache-kafka-conf";
+    paths = [
+      (pkgs.writeTextDir "server.properties" serverProperties)
+      (pkgs.writeTextDir "log4j.properties" cfg.log4jProperties)
+    ];
+  };
+
+in {
+
+  options.services.apache-kafka = {
+    enable = mkOption {
+      description = "Whether to enable Apache Kafka.";
+      default = false;
+      type = types.uniq types.bool;
+    };
+
+    brokerId = mkOption {
+      description = "Broker ID.";
+      default = 0;
+      type = types.int;
+    };
+
+    port = mkOption {
+      description = "Port number the broker should listen on.";
+      default = 9092;
+      type = types.int;
+    };
+
+    hostname = mkOption {
+      description = "Hostname the broker should bind to.";
+      default = "localhost";
+      type = types.string;
+    };
+
+    logDirs = mkOption {
+      description = "Log file directories";
+      default = [ "/tmp/kafka-logs" ];
+      type = types.listOf types.path;
+    };
+    
+    zookeeper = mkOption {
+      description = "Zookeeper connection string";
+      default = "localhost:2181";
+      type = types.string;
+    };
+ 
+    extraProperties = mkOption {
+      description = "Extra properties for server.properties.";
+      type = types.nullOr types.lines;
+      default = null;
+    };
+
+    serverProperties = mkOption {
+      description = ''
+        Complete server.properties content. Other server.properties config
+        options will be ignored if this option is used.
+      '';
+      type = types.nullOr types.lines;
+      default = null;
+    };
+
+    log4jProperties = mkOption {
+      description = "Kafka log4j property configuration.";
+      default = ''
+        log4j.rootLogger=INFO, stdout 
+        
+        log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+        log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+        log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n
+      '';
+      type = types.lines;
+    };
+
+    jvmOptions = mkOption {
+      description = "Extra command line options for the JVM running Kafka.";
+      default = [
+        "-server"
+        "-Xmx1G"
+        "-Xms1G"
+        "-XX:+UseCompressedOops"
+        "-XX:+UseParNewGC"
+        "-XX:+UseConcMarkSweepGC"
+        "-XX:+CMSClassUnloadingEnabled"
+        "-XX:+CMSScavengeBeforeRemark"
+        "-XX:+DisableExplicitGC"
+        "-Djava.awt.headless=true"
+        "-Djava.net.preferIPv4Stack=true"
+      ];
+      type = types.listOf types.string;
+      example = [
+        "-Djava.net.preferIPv4Stack=true"
+        "-Dcom.sun.management.jmxremote"
+        "-Dcom.sun.management.jmxremote.local.only=true"
+      ];
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [pkgs.apacheKafka];
+
+    users.extraUsers = singleton {
+      name = "apache-kafka";
+      uid = config.ids.uids.apache-kafka;
+      description = "Apache Kafka daemon user";
+      home = head cfg.logDirs;
+    };
+
+    systemd.services.apache-kafka = {
+      description = "Apache Kafka Daemon";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-interfaces.target" ];
+      serviceConfig = {
+        ExecStart = ''
+          ${pkgs.jre}/bin/java \
+            -cp "${pkgs.apacheKafka}/libs/*:${configDir}" \
+            ${toString cfg.jvmOptions} \
+            kafka.Kafka \
+            ${configDir}/server.properties
+        '';
+        User = "apache-kafka";
+        PermissionsStartOnly = true;
+      };
+      preStart = ''
+        mkdir -m 0700 -p ${concatStringsSep " " cfg.logDirs}
+        if [ "$(id -u)" = 0 ]; then
+           chown apache-kafka ${concatStringsSep " " cfg.logDirs};
+        fi
+      '';
+    };
+
+  };
+}
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index efa139c8dfd2..ddb0bd671dd1 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -7,8 +7,10 @@ with lib;
 let
   cfg = config.services.gitlab;
 
-  ruby = pkgs.ruby;
-  rubyLibs = pkgs.rubyLibs;
+  ruby = pkgs.gitlab.ruby;
+  bundler = pkgs.bundler;
+
+  gemHome = "${pkgs.gitlab.env}/${ruby.gemPath}";
 
   databaseYml = ''
     production:
@@ -38,13 +40,14 @@ let
 
   gitlab-runner = pkgs.stdenv.mkDerivation rec {
     name = "gitlab-runner";
-    buildInputs = [ pkgs.gitlab pkgs.rubyLibs.bundler pkgs.makeWrapper ];
+    buildInputs = [ pkgs.gitlab pkgs.bundler pkgs.makeWrapper ];
     phases = "installPhase fixupPhase";
     buildPhase = "";
     installPhase = ''
       mkdir -p $out/bin
-      makeWrapper ${rubyLibs.bundler}/bin/bundle $out/bin/gitlab-runner\
+      makeWrapper ${bundler}/bin/bundle $out/bin/gitlab-runner\
           --set RAKEOPT '"-f ${pkgs.gitlab}/share/gitlab/Rakefile"'\
+          --set GEM_HOME '${gemHome}'\
           --set UNICORN_PATH "${cfg.stateDir}/"\
           --set GITLAB_PATH "${pkgs.gitlab}/share/gitlab/"\
           --set GITLAB_APPLICATION_LOG_PATH "${cfg.stateDir}/log/application.log"\
@@ -172,6 +175,7 @@ in {
       after = [ "network.target" "redis.service" ];
       wantedBy = [ "multi-user.target" ];
       environment.HOME = "${cfg.stateDir}/home";
+      environment.GEM_HOME = gemHome;
       environment.UNICORN_PATH = "${cfg.stateDir}/";
       environment.GITLAB_PATH = "${pkgs.gitlab}/share/gitlab/";
       environment.GITLAB_APPLICATION_LOG_PATH = "${cfg.stateDir}/log/application.log";
@@ -201,7 +205,7 @@ in {
         Group = "gitlab";
         TimeoutSec = "300";
         WorkingDirectory = "${pkgs.gitlab}/share/gitlab";
-        ExecStart="${rubyLibs.bundler}/bin/bundle exec \"sidekiq -q post_receive -q mailer -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.stateDir}/tmp/sidekiq.pid\"";
+        ExecStart="${bundler}/bin/bundle exec \"sidekiq -q post_receive -q mailer -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.stateDir}/tmp/sidekiq.pid\"";
       };
     };
 
@@ -209,6 +213,7 @@ in {
       after = [ "network.target" "postgresql.service" "redis.service" ];
       wantedBy = [ "multi-user.target" ];
       environment.HOME = "${cfg.stateDir}/home";
+      environment.GEM_HOME = gemHome;
       environment.UNICORN_PATH = "${cfg.stateDir}/";
       environment.GITLAB_PATH = "${pkgs.gitlab}/share/gitlab/";
       environment.GITLAB_APPLICATION_LOG_PATH = "${cfg.stateDir}/log/application.log";
@@ -263,7 +268,7 @@ in {
 
             # force=yes disables the manual-interaction yes/no prompt
             # which breaks without an stdin.
-            force=yes ${rubyLibs.bundler}/bin/bundle exec rake -f ${pkgs.gitlab}/share/gitlab/Rakefile gitlab:setup RAILS_ENV=production
+            force=yes ${bundler}/bin/bundle exec rake -f ${pkgs.gitlab}/share/gitlab/Rakefile gitlab:setup RAILS_ENV=production
           fi
         fi
 
@@ -285,7 +290,7 @@ in {
         Group = "gitlab";
         TimeoutSec = "300";
         WorkingDirectory = "${pkgs.gitlab}/share/gitlab";
-        ExecStart="${rubyLibs.bundler}/bin/bundle exec \"unicorn -c ${cfg.stateDir}/config/unicorn.rb -E production\"";
+        ExecStart="${bundler}/bin/bundle exec \"unicorn -c ${cfg.stateDir}/config/unicorn.rb -E production\"";
       };
 
     };
diff --git a/nixos/modules/services/misc/gitolite.nix b/nixos/modules/services/misc/gitolite.nix
index 66e19d13d72e..16335c8aca73 100644
--- a/nixos/modules/services/misc/gitolite.nix
+++ b/nixos/modules/services/misc/gitolite.nix
@@ -36,6 +36,7 @@ in
           Initial administrative public key for Gitolite. This should
           be an SSH Public Key. Note that this key will only be used
           once, upon the first initialization of the Gitolite user.
+          The key string cannot have any line breaks in it.
         '';
       };
 
diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix
index d7e64590f503..059cc18733bb 100644
--- a/nixos/modules/services/misc/redmine.nix
+++ b/nixos/modules/services/misc/redmine.nix
@@ -8,7 +8,6 @@ let
   cfg = config.services.redmine;
 
   ruby = pkgs.ruby;
-  rubyLibs = pkgs.rubyLibs;
 
   databaseYml = ''
     production:
@@ -155,7 +154,7 @@ in {
       environment.HOME = "${pkgs.redmine}/share/redmine";
       environment.REDMINE_LANG = "en";
       environment.GEM_HOME = "${pkgs.redmine}/share/redmine/vendor/bundle/ruby/1.9.1";
-      environment.GEM_PATH = "${rubyLibs.bundler}/lib/ruby/gems/1.9";
+      environment.GEM_PATH = "${bundler}/${bundler.ruby.gemPath}";
       path = with pkgs; [
         imagemagickBig
         subversion
diff --git a/nixos/modules/services/monitoring/riemann-dash.nix b/nixos/modules/services/monitoring/riemann-dash.nix
index 148dc0468059..523f74cb72b9 100644
--- a/nixos/modules/services/monitoring/riemann-dash.nix
+++ b/nixos/modules/services/monitoring/riemann-dash.nix
@@ -15,7 +15,7 @@ let
 
   launcher = writeScriptBin "riemann-dash" ''
     #!/bin/sh
-    exec ${rubyLibs.riemann_dash}/bin/riemann-dash ${conf}
+    exec ${pkgs.riemann-dash}/bin/riemann-dash ${conf}
   '';
 
 in {
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 1f17661c9f08..b05a640e11fd 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -356,7 +356,7 @@ in
         ''
           If pings are allowed, this allows setting rate limits
           on them. If non-null, this option should be in the form
-          of flags like "-limit 1/minute -limit-burst 5"
+          of flags like "--limit 1/minute --limit-burst 5"
         '';
     };
 
diff --git a/nixos/modules/services/networking/ntpd.nix b/nixos/modules/services/networking/ntpd.nix
index 1988c7140d34..a9183577d0a2 100644
--- a/nixos/modules/services/networking/ntpd.nix
+++ b/nixos/modules/services/networking/ntpd.nix
@@ -82,7 +82,8 @@ in
           '';
 
         serviceConfig = {
-          ExecStart = "@${ntp}/bin/ntpd ntpd -g -n ${ntpFlags}";
+          ExecStart = "@${ntp}/bin/ntpd ntpd -g ${ntpFlags}";
+          Type = "forking";
         };
       };
 
diff --git a/nixos/modules/services/networking/openntpd.nix b/nixos/modules/services/networking/openntpd.nix
index 2f9031481d1d..d1c32db49c4c 100644
--- a/nixos/modules/services/networking/openntpd.nix
+++ b/nixos/modules/services/networking/openntpd.nix
@@ -12,6 +12,7 @@ let
 
   cfgFile = pkgs.writeText "openntpd.conf" ''
     ${concatStringsSep "\n" (map (s: "server ${s}") cfg.servers)}
+    ${cfg.extraConfig}
   '';
 in
 {
@@ -25,6 +26,27 @@ in
       type = types.listOf types.str;
       inherit (options.services.ntp.servers) description;
     };
+
+    extraConfig = mkOption {
+      type = with types; lines;
+      default = "";
+      example = ''
+        listen on 127.0.0.1 
+        listen on ::1 
+      '';
+      description = ''
+        Additional text appended to <filename>openntpd.conf</filename>.
+      '';
+    };
+
+    extraOptions = mkOption {
+      type = with types; string;
+      default = "";
+      example = "-s";
+      description = ''
+        Extra options used when launching openntpd.
+      '';
+    };
   };
 
   ###### implementation
@@ -42,7 +64,7 @@ in
     systemd.services.openntpd = {
       description = "OpenNTP Server";
       wantedBy = [ "multi-user.target" ];
-      serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile}";
+      serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile} ${cfg.extraOptions}";
     };
   };
 }
diff --git a/nixos/modules/services/networking/tftpd.nix b/nixos/modules/services/networking/tftpd.nix
index a2f7ff06ea61..9b3cc6b8ec4f 100644
--- a/nixos/modules/services/networking/tftpd.nix
+++ b/nixos/modules/services/networking/tftpd.nix
@@ -9,16 +9,18 @@ with lib;
   options = {
 
     services.tftpd.enable = mkOption {
+      type = types.bool;
       default = false;
       description = ''
-        Whether to enable the anonymous FTP user.
+        Whether to enable tftpd, a Trivial File Transfer Protocol server.
       '';
     };
 
     services.tftpd.path = mkOption {
+      type = types.path;
       default = "/home/tftp";
       description = ''
-        Where the tftp server files are stored
+        Where the tftp server files are stored.
       '';
     };
 
diff --git a/nixos/modules/services/networking/tlsdated.nix b/nixos/modules/services/networking/tlsdated.nix
new file mode 100644
index 000000000000..f2d0c9f35c9c
--- /dev/null
+++ b/nixos/modules/services/networking/tlsdated.nix
@@ -0,0 +1,110 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  inherit (pkgs) coreutils tlsdate;
+
+  cfg = config.services.tlsdated;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.tlsdated = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable tlsdated daemon.
+        '';
+      };
+
+      extraOptions = mkOption {
+        type = types.string;
+        description = ''
+          Additional command line arguments to pass to tlsdated.
+        '';
+      };
+
+      sources = mkOption {
+        type = types.listOf (types.submodule {
+          options = {
+            host = mkOption {
+              type = types.string;
+              description = ''
+                Remote hostname.
+              '';
+            };
+            port = mkOption {
+              type = types.int;
+              description = ''
+                Remote port.
+              '';
+            };
+            proxy = mkOption {
+              type = types.nullOr types.string;
+              default = null;
+              description = ''
+                The proxy argument expects HTTP, SOCKS4A or SOCKS5 formatted as followed:
+
+                 http://127.0.0.1:8118
+                 socks4a://127.0.0.1:9050
+                 socks5://127.0.0.1:9050
+
+                The proxy support should not leak DNS requests and is suitable for use with Tor.
+              '';
+            };
+          };
+        });
+        default = [
+          {
+            host = "www.ptb.de";
+            port = 443;
+            proxy = null;
+          }
+        ];
+        description = ''
+          You can list one or more sources to fetch time from.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    # Make tools such as tlsdate available in the system path
+    environment.systemPackages = [ tlsdate ];
+
+    systemd.services.tlsdated = {
+      description = "tlsdated daemon";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        # XXX because pkgs.tlsdate is compiled to run as nobody:nogroup, we
+        # hard-code base-path to /tmp and use PrivateTmp.
+        ExecStart = "${tlsdate}/bin/tlsdated -f ${pkgs.writeText "tlsdated.confg" ''
+          base-path /tmp
+
+          ${concatMapStrings (src: ''
+          source
+              host    ${src.host}
+              port    ${toString src.port}
+              proxy   ${if src.proxy == null then "none" else src.proxy}
+          end
+          '') cfg.sources}
+        ''} ${cfg.extraOptions}";
+        PrivateTmp = "yes";
+      };
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index d5a57eddd5e7..6a830827fd78 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -682,6 +682,7 @@ in
         serviceConfig.Type = "forking";
         serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid";
         serviceConfig.Restart = "always";
+        serviceConfig.RestartSec = "5s";
       };
 
   };
diff --git a/nixos/modules/services/web-servers/apache-httpd/owncloud.nix b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix
new file mode 100644
index 000000000000..3bea3c3ee1dd
--- /dev/null
+++ b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix
@@ -0,0 +1,577 @@
+{ config, lib, pkgs, serverInfo, php, ... }:
+
+with lib;
+
+let
+
+  httpd = serverInfo.serverConfig.package;
+
+  version24 = !versionOlder httpd.version "2.4";
+
+  allGranted = if version24 then ''
+    Require all granted
+  '' else ''
+    Order allow,deny
+    Allow from all
+  '';
+
+  owncloudConfig = pkgs.writeText "config.php"
+    ''
+      <?php
+
+      /* Only enable this for local development and not in productive environments */
+      /* This will disable the minifier and outputs some additional debug informations */
+      define("DEBUG", false);
+
+      $CONFIG = array(
+      /* Flag to indicate ownCloud is successfully installed (true = installed) */
+      "installed" => true,
+
+      /* Type of database, can be sqlite, mysql or pgsql */
+      "dbtype" => "${config.dbType}",
+
+      /* Name of the ownCloud database */
+      "dbname" => "${config.dbName}",
+
+      /* User to access the ownCloud database */
+      "dbuser" => "${config.dbUser}",
+
+      /* Password to access the ownCloud database */
+      "dbpassword" => "${config.dbPassword}",
+
+      /* Host running the ownCloud database. To specify a port use "HOSTNAME:####"; to specify a unix sockets use "localhost:/path/to/socket". */
+      "dbhost" => "${config.dbServer}",
+
+      /* Prefix for the ownCloud tables in the database */
+      "dbtableprefix" => "",
+
+      /* Force use of HTTPS connection (true = use HTTPS) */
+      "forcessl" => ${config.forceSSL},
+
+      /* Blacklist a specific file and disallow the upload of files with this name - WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING. */
+      "blacklisted_files" => array('.htaccess'),
+
+      /* The automatic hostname detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */
+      "overwritehost" => "${config.overwriteHost}",
+
+      /* The automatic protocol detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the protocol detection. For example "https" */
+      "overwriteprotocol" => "${config.overwriteProtocol}",
+
+      /* The automatic webroot detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. For example "/domain.tld/ownCloud". The value "/" can be used to remove the root. */
+      "overwritewebroot" => "${config.overwriteWebRoot}",
+
+      /* The automatic detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to define a manually override condition as regular expression for the remote ip address. For example "^10\.0\.0\.[1-3]$" */
+      "overwritecondaddr" => "",
+
+      /* A proxy to use to connect to the internet. For example "myproxy.org:88" */
+      "proxy" => "",
+
+      /* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */
+      "proxyuserpwd" => "",
+
+      /* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */
+      'trusted_domains' => array('${config.trustedDomain}'),
+
+      /* Theme to use for ownCloud */
+      "theme" => "",
+
+      /* Optional ownCloud default language - overrides automatic language detection on public pages like login or shared items. This has no effect on the user's language preference configured under "personal -> language" once they have logged in */
+      "default_language" => "${config.defaultLang}",
+
+      /* Path to the parent directory of the 3rdparty directory */
+      "3rdpartyroot" => "",
+
+      /* URL to the parent directory of the 3rdparty directory, as seen by the browser */
+      "3rdpartyurl" => "",
+
+      /* Default app to open on login.
+       * This can be a comma-separated list of app ids.
+       * If the first app is not enabled for the current user,
+       * it will try with the second one and so on. If no enabled app could be found,
+       * the "files" app will be displayed instead. */
+      "defaultapp" => "${config.defaultApp}",
+
+      /* Enable the help menu item in the settings */
+      "knowledgebaseenabled" => true,
+
+      /* Enable installing apps from the appstore */
+      "appstoreenabled" => ${config.appStoreEnable},
+
+      /* URL of the appstore to use, server should understand OCS */
+      "appstoreurl" => "https://api.owncloud.com/v1",
+
+      /* Domain name used by ownCloud for the sender mail address, e.g. no-reply@example.com */
+      "mail_domain" => "${config.mailFromDomain}",
+
+      /* FROM address used by ownCloud for the sender mail address, e.g. owncloud@example.com
+         This setting overwrites the built in 'sharing-noreply' and 'lostpassword-noreply'
+         FROM addresses, that ownCloud uses
+      */
+      "mail_from_address" => "${config.mailFrom}",
+
+      /* Enable SMTP class debugging */
+      "mail_smtpdebug" => false,
+
+      /* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
+      "mail_smtpmode" => "${config.SMTPMode}",
+
+      /* Host to use for sending mail, depends on mail_smtpmode if this is used */
+      "mail_smtphost" => "${config.SMTPHost}",
+
+      /* Port to use for sending mail, depends on mail_smtpmode if this is used */
+      "mail_smtpport" => ${config.SMTPPort},
+
+      /* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */
+      "mail_smtptimeout" => ${config.SMTPTimeout},
+
+      /* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used.
+         Can be "", ssl or tls */
+      "mail_smtpsecure" => "${config.SMTPSecure}",
+
+      /* authentication needed to send mail, depends on mail_smtpmode if this is used
+       * (false = disable authentication)
+       */
+      "mail_smtpauth" => ${config.SMTPAuth},
+
+      /* authentication type needed to send mail, depends on mail_smtpmode if this is used
+       * Can be LOGIN (default), PLAIN or NTLM */
+      "mail_smtpauthtype" => "${config.SMTPAuthType}",
+
+      /* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
+      "mail_smtpname" => "${config.SMTPUser}",
+
+      /* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
+      "mail_smtppassword" => "${config.SMTPPass}",
+
+      /* memcached servers (Only used when xCache, APC and APCu are absent.) */
+      "memcached_servers" => array(
+          // hostname, port and optional weight. Also see:
+          // http://www.php.net/manual/en/memcached.addservers.php
+          // http://www.php.net/manual/en/memcached.addserver.php
+          //array('localhost', 11211),
+          //array('other.host.local', 11211),
+      ),
+
+      /* How long should ownCloud keep deleted files in the trash bin, default value:  30 days */
+      'trashbin_retention_obligation' => 30,
+
+      /* Disable/Enable auto expire for the trash bin, by default auto expire is enabled */
+      'trashbin_auto_expire' => true,
+
+      /* allow user to change his display name, if it is supported by the back-end */
+      'allow_user_to_change_display_name' => true,
+
+      /* Check 3rdparty apps for malicious code fragments */
+      "appcodechecker" => true,
+
+      /* Check if ownCloud is up to date */
+      "updatechecker" => true,
+
+      /* Are we connected to the internet or are we running in a closed network? */
+      "has_internet_connection" => true,
+
+      /* Check if the ownCloud WebDAV server is working correctly. Can be disabled if not needed in special situations*/
+      "check_for_working_webdav" => true,
+
+      /* Check if .htaccess protection of data is working correctly. Can be disabled if not needed in special situations*/
+      "check_for_working_htaccess" => true,
+
+      /* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
+      "log_type" => "owncloud",
+
+      /* File for the owncloud logger to log to, (default is ownloud.log in the data dir) */
+      "logfile" => "${config.dataDir}/owncloud.log",
+
+      /* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
+      "loglevel" => "2",
+
+      /* date format to be used while writing to the owncloud logfile */
+      'logdateformat' => 'F d, Y H:i:s',
+
+      /* timezone used while writing to the owncloud logfile (default: UTC) */
+      'logtimezone' => '${serverInfo.fullConfig.time.timeZone}',
+
+      /* Append all database queries and parameters to the log file.
+       (watch out, this option can increase the size of your log file)*/
+      "log_query" => false,
+
+      /* Whether ownCloud should log the last successfull cron exec */
+      "cron_log" => true,
+
+      /*
+       * Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
+       * This rotates the current owncloud logfile to a new name, this way the total log usage
+       * will stay limited and older entries are available for a while longer. The
+       * total disk usage is twice the configured size.
+       * WARNING: When you use this, the log entries will eventually be lost.
+       */
+      'log_rotate_size' => "104857600", // 104857600, // 100 MiB
+
+      /* Lifetime of the remember login cookie, default is 15 days */
+      "remember_login_cookie_lifetime" => 1296000,
+
+      /* Life time of a session after inactivity */
+      "session_lifetime" => 86400,
+
+      /*
+       * Enable/disable session keep alive when a user is logged in in the Web UI.
+       * This is achieved by sending a "heartbeat" to the server to prevent
+       * the session timing out.
+       */
+      "session_keepalive" => true,
+
+      /* Custom CSP policy, changing this will overwrite the standard policy */
+      "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *",
+
+      /* Enable/disable X-Frame-Restriction */
+      /* HIGH SECURITY RISK IF DISABLED*/
+      "xframe_restriction" => true,
+
+      /* The directory where the user data is stored, default to data in the owncloud
+       * directory. The sqlite database is also stored here, when sqlite is used.
+       */
+      "datadirectory" => "${config.dataDir}/storage",
+
+      /* The directory where the skeleton files are located. These files will be copied to the data
+       * directory of new users. Leave empty to not copy any skeleton files.
+       */
+      // "skeletondirectory" => "",
+
+      /* Enable maintenance mode to disable ownCloud
+         If you want to prevent users to login to ownCloud before you start doing some maintenance work,
+         you need to set the value of the maintenance parameter to true.
+         Please keep in mind that users who are already logged-in are kicked out of ownCloud instantly.
+      */
+      "maintenance" => false,
+
+      "apps_paths" => array(
+
+      /* Set an array of path for your apps directories
+       key 'path' is for the fs path and the key 'url' is for the http path to your
+       applications paths. 'writable' indicates whether the user can install apps in this folder.
+       You must have at least 1 app folder writable or you must set the parameter 'appstoreenabled' to false
+      */
+          array(
+              'path'=> '${config.dataDir}/apps',
+              'url' => '/apps',
+              'writable' => true,
+          ),
+      ),
+      'user_backends'=>array(
+          /*
+          array(
+              'class'=>'OC_User_IMAP',
+              'arguments'=>array('{imap.gmail.com:993/imap/ssl}INBOX')
+          )
+          */
+      ),
+      //links to custom clients
+      'customclient_desktop' => ''', //http://owncloud.org/sync-clients/
+      'customclient_android' => ''', //https://play.google.com/store/apps/details?id=com.owncloud.android
+      'customclient_ios' => ''', //https://itunes.apple.com/us/app/owncloud/id543672169?mt=8
+
+      // PREVIEW
+      'enable_previews' => true,
+      /* the max width of a generated preview, if value is null, there is no limit */
+      'preview_max_x' => null,
+      /* the max height of a generated preview, if value is null, there is no limit */
+      'preview_max_y' => null,
+      /* the max factor to scale a preview, default is set to 10 */
+      'preview_max_scale_factor' => 10,
+      /* custom path for libreoffice / openoffice binary */
+      'preview_libreoffice_path' => '${config.libreofficePath}',
+      /* cl parameters for libreoffice / openoffice */
+      'preview_office_cl_parameters' => ''',
+
+      /* whether avatars should be enabled */
+      'enable_avatars' => true,
+
+      // Extra SSL options to be used for configuration
+      'openssl' => array(
+          'config' => '/etc/ssl/openssl.cnf',
+      ),
+
+      // default cipher used for file encryption, currently we support AES-128-CFB and AES-256-CFB
+      'cipher' => 'AES-256-CFB',
+
+      /* whether usage of the instance should be restricted to admin users only */
+      'singleuser' => false,
+
+      /* all css and js files will be served by the web server statically in one js file and ons css file*/
+      'asset-pipeline.enabled' => false,
+
+      /* where mount.json file should be stored, defaults to data/mount.json */
+      'mount_file' => ''',
+
+      /*
+       * Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user.
+       *
+       * When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured
+       * cache directory and "$user" is the user.
+       *
+       */
+      'cache_path' => ''',
+
+      /* EXPERIMENTAL: option whether to include external storage in quota calculation, defaults to false */
+      'quota_include_external_storage' => false,
+
+      /*
+       * specifies how often the filesystem is checked for changes made outside owncloud
+       * 0 -> never check the filesystem for outside changes, provides a performance increase when it's certain that no changes are made directly to the filesystem
+       * 1 -> check each file or folder at most once per request, recomended for general use if outside changes might happen
+       * 2 -> check every time the filesystem is used, causes a performance hit when using external storages, not recomended for regular use
+       */
+      'filesystem_check_changes' => 1,
+
+      /* If true, prevent owncloud from changing the cache due to changes in the filesystem for all storage */
+      'filesystem_cache_readonly' => false,
+
+      /**
+       * define default folder for shared files and folders
+       */
+      'share_folder' => '/',
+
+      'version' => '${pkgs.owncloud.version}',
+
+      'openssl' => '${pkgs.openssl}/bin/openssl'
+
+      );
+
+    '';
+
+in
+
+rec {
+
+  extraConfig =
+    ''
+      ServerName ${config.siteName}
+      ServerAdmin ${config.adminAddr}
+      DocumentRoot ${documentRoot}
+
+      RewriteEngine On
+      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
+      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
+
+      <Directory ${pkgs.owncloud}>
+        ${builtins.readFile "${pkgs.owncloud}/.htaccess"}
+      </Directory>
+    '';
+
+  globalEnvVars = [
+    { name = "OC_CONFIG_PATH"; value = "${config.dataDir}/config/"; }
+  ];
+
+  documentRoot = pkgs.owncloud;
+
+  enablePHP = true;
+
+  options = {
+
+    id = mkOption {
+      default = "main";
+      description = ''
+        A unique identifier necessary to keep multiple owncloud server
+        instances on the same machine apart.  This is used to
+        disambiguate the administrative scripts, which get names like
+        mediawiki-$id-change-password.
+      '';
+    };
+
+    adminUser = mkOption {
+      default = "owncloud";
+      description = "The admin user name for accessing owncloud.";
+    };
+
+    adminPassword = mkOption {
+      description = "The admin password for accessing owncloud.
+        Warning: this is stored in cleartext in the Nix store!";
+    };
+
+    dbType = mkOption {
+      default = "pgsql";
+      description = "Type of database, in NixOS, for now, only pgsql.";
+    };
+
+    dbName = mkOption {
+      default = "owncloud";
+      description = "Name of the database that holds the owncloud data.";
+    };
+
+    dbServer = mkOption {
+      default = "localhost:5432";
+      description = ''
+        The location of the database server.
+      '';
+    };
+
+    dbUser = mkOption {
+      default = "owncloud";
+      description = "The user name for accessing the database.";
+    };
+
+    dbPassword = mkOption {
+      example = "foobar";
+      description = ''
+        The password of the database user.  Warning: this is stored in
+        cleartext in the Nix store!
+      '';
+    };
+
+    forceSSL = mkOption {
+      default = "false";
+      description = "Force use of HTTPS connection.";
+    };
+
+    adminAddr = mkOption {
+      default = serverInfo.serverConfig.adminAddr;
+      example = "admin@example.com";
+      description = ''
+        Emergency contact e-mail address.  Defaults to the Apache
+        admin address.
+      '';
+    };
+
+    siteName = mkOption {
+      default = "owncloud";
+      example = "Foobar owncloud";
+      description = "Name of the owncloud";
+    };
+
+    trustedDomain = mkOption {
+      default = "";
+      description = "Trusted domain";
+    };
+
+    defaultLang = mkOption {
+      default = "";
+      description = "Default language";
+    };
+
+    defaultApp = mkOption {
+      default = "";
+      description = "Default application";
+    };
+
+    appStoreEnable = mkOption {
+      default = "true";
+      description = "Enable app store";
+    };
+
+    mailFrom = mkOption {
+      default = "no-reply";
+      description = "Mail from";
+    };
+
+    mailFromDomain = mkOption {
+      default = "example.xyz";
+      description = "Mail from domain";
+    };
+
+    SMTPMode = mkOption {
+      default = "smtp";
+      description = "Which mode to use for sending mail: sendmail, smtp, qmail or php.";
+    };
+
+    SMTPHost = mkOption {
+      default = "";
+      description = "SMTP host";
+    };
+
+    SMTPPort = mkOption {
+      default = "25";
+      description = "SMTP port";
+    };
+
+    SMTPTimeout = mkOption {
+      default = "10";
+      description = "SMTP mode";
+    };
+
+    SMTPSecure = mkOption {
+      default = "ssl";
+      description = "SMTP secure";
+    };
+
+    SMTPAuth = mkOption {
+      default = "true";
+      description = "SMTP auth";
+    };
+
+    SMTPAuthType = mkOption {
+      default = "LOGIN";
+      description = "SMTP auth type";
+    };
+
+    SMTPUser = mkOption {
+      default = "";
+      description = "SMTP user";
+    };
+
+    SMTPPass = mkOption {
+      default = "";
+      description = "SMTP pass";
+    };
+
+    dataDir = mkOption {
+      default = "/var/lib/owncloud";
+      description = "Data dir";
+    };
+
+    libreofficePath = mkOption {
+      default = "/usr/bin/libreoffice";
+      description = "Path for LibreOffice/OpenOffice binary.";
+    };
+
+    overwriteHost = mkOption {
+      default = "";
+      description = "The automatic hostname detection of ownCloud can fail in
+        certain reverse proxy and CLI/cron situations. This option allows to
+        manually override the automatic detection. You can also add a port.";
+    };
+
+    overwriteProtocol = mkOption {
+      default = "";
+      description = "The automatic protocol detection of ownCloud can fail in
+        certain reverse proxy and CLI/cron situations. This option allows to
+        manually override the protocol detection.";
+    };
+
+    overwriteWebRoot = mkOption {
+      default = "";
+      description = "The automatic webroot detection of ownCloud can fail in
+        certain reverse proxy and CLI/cron situations. This option allows to
+        manually override the automatic detection.";
+    };
+
+  };
+
+  startupScript = pkgs.writeScript "owncloud_startup.sh" ''
+
+    if [ ! -d ${config.dataDir}/config ]; then
+      mkdir -p ${config.dataDir}/config
+      cp ${owncloudConfig} ${config.dataDir}/config/config.php
+      mkdir -p ${config.dataDir}/storage
+      mkdir -p ${config.dataDir}/apps
+      cp -r ${pkgs.owncloud}/apps/* ${config.dataDir}/apps/
+      chmod -R ug+rw ${config.dataDir}
+      chmod -R o-rwx ${config.dataDir}
+      chown -R wwwrun:wwwrun ${config.dataDir}
+
+      ${pkgs.postgresql}/bin/createuser -s -r postgres
+      ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
+      ${pkgs.postgresql}/bin/createdb "${config.dbName}" -O "${config.dbUser}" || true
+      ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -U postgres -d postgres -c "alter user ${config.dbUser} with password '${config.dbPassword}';" || true
+
+      QUERY="CREATE TABLE appconfig (appid VARCHAR( 255 ) NOT NULL ,configkey VARCHAR( 255 ) NOT NULL ,configvalue VARCHAR( 255 ) NOT NULL); GRANT ALL ON appconfig TO ${config.dbUser}; ALTER TABLE appconfig OWNER TO ${config.dbUser};"
+      ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
+    fi
+
+    ${php}/bin/php ${pkgs.owncloud}/occ upgrade || true
+
+    chown wwwrun:wwwrun ${config.dataDir}/owncloud.log || true
+
+    QUERY="INSERT INTO groups (gid) values('admin'); INSERT INTO users (uid,password) values('${config.adminUser}','`echo -n "${config.adminPassword}" | ${pkgs.openssl}/bin/openssl dgst -sha1 | ${pkgs.gawk}/bin/awk '{print $2}'`'); INSERT INTO group_user (gid,uid) values('admin','${config.adminUser}');"
+    ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
+  '';
+}
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index bffbb56e6816..9165658a7be7 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -18,8 +18,8 @@ in
   # determines the default: later modules (if enabled) are preferred.
   # E.g., if KDE is enabled, it supersedes xterm.
   imports = [
-    ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix
-    ./e19.nix ./gnome3.nix ./xbmc.nix
+    ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix
+    ./e19.nix ./gnome3.nix ./xbmc.nix ./kodi.nix
   ];
 
   options = {
diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix
index 16c99862e9e0..21b6243ba188 100644
--- a/nixos/modules/services/x11/desktop-managers/kde4.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde4.nix
@@ -70,14 +70,6 @@ in
         description = "Custom kde-workspace, used for NixOS rebranding.";
       };
     };
-
-    environment.kdePackages = mkOption {
-      default = [];
-      example = literalExample "[ pkgs.kde4.kdesdk ]";
-      type = types.listOf types.package;
-      description = "This option is obsolete.  Please use <option>environment.systemPackages</option> instead.";
-    };
-
   };
 
 
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
new file mode 100644
index 000000000000..6d6479da2a1f
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -0,0 +1,143 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.kde5;
+  xorg = pkgs.xorg;
+
+  phononBackends = {
+    gstreamer = [
+      pkgs.phonon_backend_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.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;
+
+  kdeApps = pkgs.kdeApps_stable;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.kde5 = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        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 VLC backend is preferred by upstream.
+        '';
+      };
+
+    };
+
+  };
+
+
+  config = mkIf (xcfg.enable && cfg.enable) {
+
+    warnings = optional config.services.xserver.desktopManager.kde4.enable
+      "KDE 4 should not be enabled at the same time as KDE 5";
+
+    services.xserver.desktopManager.session = singleton {
+      name = "kde5";
+      bgSupport = true;
+      start = ''exec ${plasma5.startkde}/bin/startkde;'';
+    };
+
+    security.setuidOwners = singleton {
+      program = "kcheckpass";
+      source = "${plasma5.plasma-workspace}/lib/libexec/kcheckpass";
+      owner = "root";
+      group = "root";
+      setuid = true;
+    };
+
+    environment.systemPackages = with plasma5; with kf5;
+      (builtins.attrValues
+        (removeAttrs plasma5
+          [ "deepOverride" "override" "overrideDerivation"
+            "recurseForDerivations" "scope"
+          ]))
+      ++
+      (builtins.attrValues
+        (removeAttrs kf5
+          [ "deepOverride" "extra-cmake-modules" "mkDerivation" "override"
+            "overrideDerivation" "recurseForDerivations" "scope"
+          ]))
+      ++
+      [
+        pkgs.qt4 # qtconfig is the only way to set Qt 4 theme
+
+        kdeApps.kde-baseapps
+        kdeApps.kde-base-artwork
+        kdeApps.kde-workspace
+        kdeApps.kde-runtime
+        kdeApps.kmix
+        kdeApps.konsole
+        kdeApps.oxygen-icons
+
+        pkgs.hicolor_icon_theme
+
+        pkgs.orion # GTK theme, nearly identical to Breeze
+      ]
+      ++ (optional config.networking.networkmanager.enable plasma-nm)
+      ++ phononBackendPackages;
+
+    environment.pathsToLink = [ "/share" ];
+
+    environment.etc = singleton {
+      source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
+      target = "X11/xkb";
+    };
+
+    environment.profileRelativeEnvVars =
+      mkIf (lib.elem "gstreamer" cfg.phononBackends)
+      {
+        GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ];
+        GST_PLUGIN_SYSTEM_PATH_1_0 = [ "/lib/gstreamer-1.0" ];
+      };
+
+    fonts.fonts = [ plasma5.oxygen-fonts ];
+
+    # Enable helpful DBus services.
+    services.udisks2.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+
+    security.pam.services.kde = { allowNullPassword = true; };
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/kodi.nix b/nixos/modules/services/x11/desktop-managers/kodi.nix
new file mode 100644
index 000000000000..1e30308a5139
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.desktopManager.kodi;
+in
+
+{
+  options = {
+    services.xserver.desktopManager.kodi = {
+      enable = mkOption {
+        default = false;
+        example = true;
+        description = "Enable the kodi multimedia center.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.desktopManager.session = [{
+      name = "kodi";
+      start = ''
+        ${pkgs.kodi}/bin/kodi --lircdev /var/run/lirc/lircd --standalone &
+        waitPID=$!
+      '';
+    }];
+
+    environment.systemPackages = [ pkgs.kodi ];
+  };
+}
\ No newline at end of file
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index a1b5daa3336d..601971d27b69 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -25,7 +25,7 @@ let
 
   fontconfig = config.fonts.fontconfig;
   xresourcesXft = pkgs.writeText "Xresources-Xft" ''
-    ${optionalString (fontconfig.dpi != 0) ''Xft.dpi: ${fontconfig.dpi}''}
+    ${optionalString (fontconfig.dpi != 0) ''Xft.dpi: ${toString fontconfig.dpi}''}
     Xft.antialias: ${if fontconfig.antialias then "1" else "0"}
     Xft.rgba: ${fontconfig.subpixel.rgba}
     Xft.lcdfilter: lcd${fontconfig.subpixel.lcdfilter}
diff --git a/nixos/modules/services/x11/display-managers/kdm.nix b/nixos/modules/services/x11/display-managers/kdm.nix
index 7ec489ae3e73..42eaacfe84af 100644
--- a/nixos/modules/services/x11/display-managers/kdm.nix
+++ b/nixos/modules/services/x11/display-managers/kdm.nix
@@ -151,6 +151,9 @@ in
         description = "KDM user";
       };
 
+    environment.systemPackages =
+      [ pkgs.kde4.kde_wallpapers ]; # contains kdm's default background
+
   };
 
 }
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 3ea00e40c3b3..b16a725aba8e 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -196,7 +196,7 @@ in
       };
 
       timeout = mkOption {
-        default = 5;
+        default = if (config.boot.loader.timeout != null) then config.boot.loader.timeout else -1;
         type = types.int;
         description = ''
           Timeout (in seconds) until GRUB boots the default menu item.
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
index 003f72b37f9e..6c201eb8212f 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
+++ b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
@@ -31,7 +31,7 @@ in {
     };
 
     timeout = mkOption {
-      default = null;
+      default = if config.boot.loader.timeout == null then 10000 else config.boot.loader.timeout;
 
       example = 4;
 
diff --git a/nixos/modules/system/boot/loader/loader.nix b/nixos/modules/system/boot/loader/loader.nix
new file mode 100644
index 000000000000..28cceafea7ca
--- /dev/null
+++ b/nixos/modules/system/boot/loader/loader.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+    options = {
+        boot.loader.timeout =  mkOption {
+            default = 5;
+            type = types.nullOr types.int;
+            description = ''
+              Timeout (in seconds) until loader boots the default menu item. Use null if the loader menu should be displayed indefinitely.
+            '';
+        };
+    };
+}
\ No newline at end of file
diff --git a/nixos/modules/system/boot/modprobe.nix b/nixos/modules/system/boot/modprobe.nix
index eaf8cf1ecd6f..a1feaad6132d 100644
--- a/nixos/modules/system/boot/modprobe.nix
+++ b/nixos/modules/system/boot/modprobe.nix
@@ -10,10 +10,18 @@ with lib;
 
     system.sbin.modprobe = mkOption {
       internal = true;
-      default = pkgs.writeTextFile {
+      default = pkgs.stdenv.mkDerivation {
         name = "modprobe";
-        destination = "/sbin/modprobe";
-        executable = true;
+        buildCommand = ''
+          mkdir -p $out/bin
+          for i in ${pkgs.kmod}/sbin/*; do
+            name=$(basename $i)
+            echo "$text" > $out/bin/$name
+            echo 'exec '$i' "$@"' >> $out/bin/$name
+            chmod +x $out/bin/$name
+          done
+          ln -s bin $out/sbin
+        '';
         text =
           ''
             #! ${pkgs.stdenv.shell}
@@ -26,7 +34,6 @@ with lib;
                 MODULE_DIR=/run/booted-system/kernel-modules/lib/modules/
             fi
 
-            exec ${pkgs.kmod}/sbin/modprobe "$@"
           '';
       };
       description = ''
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 64a20034f3cc..c6f2f072352e 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -142,7 +142,10 @@ in
       ++ config.system.fsPackages;
 
     environment.etc.fstab.text =
-      ''
+      let
+        fsToSkipCheck = [ "none" "btrfs" "zfs" "tmpfs" "nfs" ];
+        skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
+      in ''
         # This is a generated file.  Do not edit!
 
         # Filesystems.
@@ -154,7 +157,7 @@ in
             + " " + fs.fsType
             + " " + fs.options
             + " 0"
-            + " " + (if fs.fsType == "none" || fs.device == "none" || fs.fsType == "btrfs" || fs.fsType == "tmpfs" || fs.noCheck then "0" else
+            + " " + (if skipCheck fs then "0" else
                      if fs.mountPoint == "/" then "1" else "2")
             + "\n"
         )}
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 075ec0ea2277..c461cf8c00cb 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -54,6 +54,14 @@ in
       '';
     };
 
+    boot.enableContainers = mkOption {
+      type = types.bool;
+      default = !config.boot.isContainer;
+      description = ''
+        Whether to enable support for nixos containers.
+      '';
+    };
+
     containers = mkOption {
       type = types.attrsOf (types.submodule (
         { config, options, name, ... }:
@@ -164,7 +172,7 @@ in
   };
 
 
-  config = mkIf (!config.boot.isContainer) {
+  config = mkIf (config.boot.enableContainers) {
 
     systemd.services."container@" =
       { description = "Container '%i'";
diff --git a/nixos/modules/virtualisation/nixos-container.pl b/nixos/modules/virtualisation/nixos-container.pl
index 9ae5331786cc..94edfb37948a 100644
--- a/nixos/modules/virtualisation/nixos-container.pl
+++ b/nixos/modules/virtualisation/nixos-container.pl
@@ -104,6 +104,10 @@ if ($action eq "create") {
 
     die "$0: container ‘$containerName’ already exists\n" if -e $confFile;
 
+    # Due to interface name length restrictions, container names must
+    # be restricted too.
+    die "$0: container name ‘$containerName’ is too long\n" if length $containerName > 11;
+
     # Get an unused IP address.
     my %usedIPs;
     foreach my $confFile2 (glob "/etc/containers/*.conf") {