summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
authorParnell Springmeyer <parnell@digitalmentat.com>2017-01-26 02:00:04 -0800
committerParnell Springmeyer <parnell@digitalmentat.com>2017-01-26 02:00:04 -0800
commita26a796d5c7fa305e007c2b5229e0521c8b3fb0f (patch)
tree6c35defae305b0da581f757b72b461a8f6052620 /nixos/modules
parentad8fde5e5d9bc25a54ac238f485e28b37d6d185a (diff)
parent142696de884213e01cc518af813a20d2e2ece3cc (diff)
downloadnixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar.gz
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar.bz2
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar.lz
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar.xz
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.tar.zst
nixpkgs-a26a796d5c7fa305e007c2b5229e0521c8b3fb0f.zip
Merging against master - updating smokingpig, rebase was going to be messy
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/networking.nix2
-rw-r--r--nixos/modules/config/pulseaudio.nix18
-rw-r--r--nixos/modules/hardware/ckb.nix40
-rw-r--r--nixos/modules/hardware/opengl.nix4
-rw-r--r--nixos/modules/i18n/input-method/ibus.nix13
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-minimal.nix5
-rw-r--r--nixos/modules/installer/tools/nix-fallback-paths.nix6
-rw-r--r--nixos/modules/misc/ids.nix7
-rw-r--r--nixos/modules/misc/nixpkgs.nix48
-rw-r--r--nixos/modules/module-list.nix11
-rw-r--r--nixos/modules/profiles/installation-device.nix15
-rw-r--r--nixos/modules/programs/chromium.nix85
-rw-r--r--nixos/modules/programs/man.nix1
-rw-r--r--nixos/modules/programs/nano.nix12
-rw-r--r--nixos/modules/programs/zsh/zsh.nix11
-rw-r--r--nixos/modules/rename.nix4
-rw-r--r--nixos/modules/security/acme.nix2
-rw-r--r--nixos/modules/services/cluster/kubernetes.nix2
-rw-r--r--nixos/modules/services/games/factorio.nix87
-rw-r--r--nixos/modules/services/hardware/udev.nix5
-rw-r--r--nixos/modules/services/logging/journalbeat.nix76
-rw-r--r--nixos/modules/services/logging/logstash.nix14
-rw-r--r--nixos/modules/services/mail/dovecot.nix9
-rw-r--r--nixos/modules/services/misc/apache-kafka.nix2
-rw-r--r--nixos/modules/services/misc/couchpotato.nix50
-rw-r--r--nixos/modules/services/misc/gogs.nix215
-rw-r--r--nixos/modules/services/misc/mesos-master.nix21
-rw-r--r--nixos/modules/services/misc/mesos-slave.nix98
-rw-r--r--nixos/modules/services/monitoring/arbtt.nix63
-rw-r--r--nixos/modules/services/monitoring/netdata.nix78
-rw-r--r--nixos/modules/services/monitoring/prometheus/alertmanager.nix17
-rw-r--r--nixos/modules/services/monitoring/vnstat.nix43
-rw-r--r--nixos/modules/services/network-filesystems/ipfs.nix29
-rw-r--r--nixos/modules/services/network-filesystems/tahoe.nix2
-rw-r--r--nixos/modules/services/networking/ddclient.nix3
-rw-r--r--nixos/modules/services/networking/dhcpd.nix250
-rw-r--r--nixos/modules/services/networking/dnscrypt-wrapper.nix187
-rw-r--r--nixos/modules/services/networking/firewall.nix127
-rw-r--r--nixos/modules/services/networking/flannel.nix2
-rw-r--r--nixos/modules/services/networking/kresd.nix119
-rw-r--r--nixos/modules/services/networking/miredo.nix1
-rw-r--r--nixos/modules/services/networking/networkmanager.nix5
-rw-r--r--nixos/modules/services/networking/pdns-recursor.nix168
-rw-r--r--nixos/modules/services/networking/smokeping.nix9
-rw-r--r--nixos/modules/services/security/clamav.nix1
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix4
-rw-r--r--nixos/modules/services/web-servers/caddy.nix9
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix40
-rw-r--r--nixos/modules/services/web-servers/nginx/vhost-options.nix9
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix7
-rw-r--r--nixos/modules/services/x11/display-managers/slim.nix13
-rw-r--r--nixos/modules/services/x11/terminal-server.nix2
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py2
-rw-r--r--nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix16
-rw-r--r--nixos/modules/virtualisation/ec2-amis.nix98
55 files changed, 1872 insertions, 295 deletions
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index 9e7cfbd686c..426aaa34885 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -13,7 +13,7 @@ let
 
   resolvconfOptions = cfg.resolvconfOptions
     ++ optional cfg.dnsSingleRequest "single-request"
-    ++ optional cfg.dnsExtensionMechanism "ends0";
+    ++ optional cfg.dnsExtensionMechanism "edns0";
 in
 
 {
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index 742167fbf69..d5cb4fce0f9 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -160,6 +160,13 @@ in {
             if activated.
           '';
         };
+
+        config = mkOption {
+          type = types.attrsOf types.unspecified;
+          default = {};
+          description = ''Config of the pulse daemon. See <literal>man pulse-daemon.conf</literal>.'';
+          example = literalExample ''{ flat-volumes = "no"; }'';
+        };
       };
 
       zeroconf = {
@@ -204,10 +211,13 @@ in {
     (mkIf cfg.enable {
       environment.systemPackages = [ overriddenPackage ];
 
-      environment.etc = singleton {
-        target = "asound.conf";
-        source = alsaConf;
-      };
+      environment.etc = [
+        { target = "asound.conf";
+          source = alsaConf; }
+
+        { target = "pulse/daemon.conf";
+          source = writeText "daemon.conf" (lib.generators.toKeyValue {} cfg.daemon.config); }
+      ];
 
       # Allow PulseAudio to get realtime priority using rtkit.
       security.rtkit.enable = true;
diff --git a/nixos/modules/hardware/ckb.nix b/nixos/modules/hardware/ckb.nix
new file mode 100644
index 00000000000..8429572a882
--- /dev/null
+++ b/nixos/modules/hardware/ckb.nix
@@ -0,0 +1,40 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.ckb;
+
+in
+  {
+    options.hardware.ckb = {
+      enable = mkEnableOption "the Corsair keyboard/mouse driver";
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.ckb;
+        defaultText = "pkgs.ckb";
+        description = ''
+          The package implementing the Corsair keyboard/mouse driver.
+        '';
+      };
+    };
+
+    config = mkIf cfg.enable {
+      environment.systemPackages = [ cfg.package ];
+
+      systemd.services.ckb = {
+        description = "Corsair Keyboard Daemon";
+        wantedBy = ["multi-user.target"];
+        script = "${cfg.package}/bin/ckb-daemon";
+        serviceConfig = {
+          Restart = "always";
+          StandardOutput = "syslog";
+        };
+      };
+    };
+
+    meta = {
+      maintainers = with lib.maintainers; [ kierdavis ];
+    };
+  }
diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix
index c4fad9a6672..5e38a988096 100644
--- a/nixos/modules/hardware/opengl.nix
+++ b/nixos/modules/hardware/opengl.nix
@@ -96,7 +96,7 @@ in
       example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]";
       description = ''
         Additional packages to add to OpenGL drivers. This can be used
-        to add additional VA-API/VDPAU drivers.
+        to add OpenCL drivers, VA-API/VDPAU drivers etc.
       '';
     };
 
@@ -107,7 +107,7 @@ in
       description = ''
         Additional packages to add to 32-bit OpenGL drivers on
         64-bit systems. Used when <option>driSupport32Bit</option> is
-        set. This can be used to add additional VA-API/VDPAU drivers.
+        set. This can be used to add OpenCL drivers, VA-API/VDPAU drivers etc.
       '';
     };
 
diff --git a/nixos/modules/i18n/input-method/ibus.nix b/nixos/modules/i18n/input-method/ibus.nix
index e23e28aa25e..a5bbe6bcb55 100644
--- a/nixos/modules/i18n/input-method/ibus.nix
+++ b/nixos/modules/i18n/input-method/ibus.nix
@@ -10,6 +10,11 @@ let
     check = x: (lib.types.package.check x) && (attrByPath ["meta" "isIbusEngine"] false x);
   };
 
+  impanel =
+    if cfg.panel != null
+    then "--panel=${cfg.panel}"
+    else "";
+
   ibusAutostart = pkgs.writeTextFile {
     name = "autostart-ibus-daemon";
     destination = "/etc/xdg/autostart/ibus-daemon.desktop";
@@ -17,7 +22,7 @@ let
       [Desktop Entry]
       Name=IBus
       Type=Application
-      Exec=${ibusPackage}/bin/ibus-daemon --daemonize --xim
+      Exec=${ibusPackage}/bin/ibus-daemon --daemonize --xim ${impanel}
     '';
   };
 in
@@ -36,6 +41,12 @@ in
           in
             "Enabled IBus engines. Available engines are: ${engines}.";
       };
+      panel = mkOption {
+        type = with types; nullOr path;
+        default = null;
+        example = literalExample "''${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
+        description = "Replace the IBus panel with another panel.";
+      };
     };
   };
 
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix b/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
index f4122ab0e51..7ec55f159d0 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
@@ -7,9 +7,4 @@
   imports =
     [ ./installation-cd-base.nix
     ];
-
-  environment.systemPackages =
-    [
-      pkgs.vim
-    ];
 }
diff --git a/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixos/modules/installer/tools/nix-fallback-paths.nix
index ddc624a77de..d73d67ef472 100644
--- a/nixos/modules/installer/tools/nix-fallback-paths.nix
+++ b/nixos/modules/installer/tools/nix-fallback-paths.nix
@@ -1,5 +1,5 @@
 {
-  x86_64-linux = "/nix/store/m8z91vpfxyszhjpq4wl8m1zwlqik4fkn-nix-1.11.5";
-  i686-linux = "/nix/store/vk71likl32igqg6apqsj52ln3vhkq1pa-nix-1.11.5";
-  x86_64-darwin = "/nix/store/qfwm0b5qkr8v8gsv9dh2z3arky9p1myg-nix-1.11.5";
+  x86_64-linux = "/nix/store/qdkzm17csr24snk247a1s0c47ikq5sl6-nix-1.11.6";
+  i686-linux = "/nix/store/hiwp53747lxlniqy5wpbql5izjrs8z0z-nix-1.11.6";
+  x86_64-darwin = "/nix/store/hca2hqcvwncf23hiqyqgwbsdy8vvl9xv-nix-1.11.6";
 }
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 6ab4b24a349..2005f2518ba 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -282,6 +282,10 @@
       infinoted = 264;
       keystone = 265;
       glance = 266;
+      couchpotato = 267;
+      gogs = 268;
+      pdns-recursor = 269;
+      kresd = 270;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -534,6 +538,9 @@
       infinoted = 264;
       keystone = 265;
       glance = 266;
+      couchpotato = 267;
+      gogs = 268;
+      kresd = 270;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index 7d50b8025bd..7451888484f 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -29,11 +29,19 @@ let
     };
 
   configType = mkOptionType {
-    name = "nixpkgs config";
+    name = "nixpkgs-config";
+    description = "nixpkgs config";
     check = traceValIfNot isConfig;
     merge = args: fold (def: mergeConfig def.value) {};
   };
 
+  overlayType = mkOptionType {
+    name = "nixpkgs-overlay";
+    description = "nixpkgs overlay";
+    check = builtins.isFunction;
+    merge = lib.mergeOneOption;
+  };
+
 in
 
 {
@@ -43,23 +51,37 @@ in
       default = {};
       example = literalExample
         ''
-          { firefox.enableGeckoMediaPlayer = true;
-            packageOverrides = pkgs: {
-              firefox60Pkgs = pkgs.firefox60Pkgs.override {
-                enableOfficialBranding = true;
-              };
-            };
-          }
+          { firefox.enableGeckoMediaPlayer = true; }
         '';
       type = configType;
       description = ''
         The configuration of the Nix Packages collection.  (For
         details, see the Nixpkgs documentation.)  It allows you to set
-        package configuration options, and to override packages
-        globally through the <varname>packageOverrides</varname>
-        option.  The latter is a function that takes as an argument
-        the <emphasis>original</emphasis> Nixpkgs, and must evaluate
-        to a set of new or overridden packages.
+        package configuration options.
+      '';
+    };
+
+    nixpkgs.overlays = mkOption {
+      default = [];
+      example = literalExample
+        ''
+          [ (self: super: {
+              openssh = super.openssh.override {
+                hpnSupport = true;
+                withKerberos = true;
+                kerberos = self.libkrb5;
+              };
+            };
+          ) ]
+        '';
+      type = types.listOf overlayType;
+      description = ''
+        List of overlays to use with the Nix Packages collection.
+        (For details, see the Nixpkgs documentation.)  It allows
+        you to override packages globally. This is a function that
+        takes as an argument the <emphasis>original</emphasis> Nixpkgs.
+        The first argument should be used for finding dependencies, and
+        the second should be used for overriding recipes.
       '';
     };
 
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 7607af2ae92..f7206ea931b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -26,6 +26,7 @@
   ./config/vpnc.nix
   ./config/zram.nix
   ./hardware/all-firmware.nix
+  ./hardware/ckb.nix
   ./hardware/cpu/amd-microcode.nix
   ./hardware/cpu/intel-microcode.nix
   ./hardware/ksm.nix
@@ -66,6 +67,7 @@
   ./programs/bash/bash.nix
   ./programs/blcr.nix
   ./programs/cdemu.nix
+  ./programs/chromium.nix
   ./programs/command-not-found/command-not-found.nix
   ./programs/dconf.nix
   ./programs/environment.nix
@@ -210,6 +212,7 @@
   ./services/logging/awstats.nix
   ./services/logging/fluentd.nix
   ./services/logging/graylog.nix
+  ./services/logging/journalbeat.nix
   ./services/logging/klogd.nix
   ./services/logging/logcheck.nix
   ./services/logging/logrotate.nix
@@ -241,6 +244,7 @@
   ./services/misc/cpuminer-cryptonight.nix
   ./services/misc/cgminer.nix
   ./services/misc/confd.nix
+  ./services/misc/couchpotato.nix
   ./services/misc/devmon.nix
   ./services/misc/dictd.nix
   ./services/misc/dysnomia.nix
@@ -255,6 +259,7 @@
   #./services/misc/gitit.nix
   ./services/misc/gitlab.nix
   ./services/misc/gitolite.nix
+  ./services/misc/gogs.nix
   ./services/misc/gpsd.nix
   ./services/misc/ihaskell.nix
   ./services/misc/leaps.nix
@@ -294,6 +299,7 @@
   ./services/misc/uhub.nix
   ./services/misc/zookeeper.nix
   ./services/monitoring/apcupsd.nix
+  ./services/monitoring/arbtt.nix
   ./services/monitoring/bosun.nix
   ./services/monitoring/cadvisor.nix
   ./services/monitoring/collectd.nix
@@ -307,6 +313,7 @@
   ./services/monitoring/monit.nix
   ./services/monitoring/munin.nix
   ./services/monitoring/nagios.nix
+  ./services/monitoring/netdata.nix
   ./services/monitoring/prometheus/default.nix
   ./services/monitoring/prometheus/alertmanager.nix
   ./services/monitoring/prometheus/blackbox-exporter.nix
@@ -326,6 +333,7 @@
   ./services/monitoring/telegraf.nix
   ./services/monitoring/ups.nix
   ./services/monitoring/uptime.nix
+  ./services/monitoring/vnstat.nix
   ./services/monitoring/zabbix-agent.nix
   ./services/monitoring/zabbix-server.nix
   ./services/network-filesystems/cachefilesd.nix
@@ -364,6 +372,7 @@
   ./services/networking/dhcpd.nix
   ./services/networking/dnschain.nix
   ./services/networking/dnscrypt-proxy.nix
+  ./services/networking/dnscrypt-wrapper.nix
   ./services/networking/dnsmasq.nix
   ./services/networking/ejabberd.nix
   ./services/networking/fan.nix
@@ -390,6 +399,7 @@
   ./services/networking/iodine.nix
   ./services/networking/ircd-hybrid/default.nix
   ./services/networking/kippo.nix
+  ./services/networking/kresd.nix
   ./services/networking/lambdabot.nix
   ./services/networking/libreswan.nix
   ./services/networking/logmein-hamachi.nix
@@ -420,6 +430,7 @@
   ./services/networking/pdnsd.nix
   ./services/networking/polipo.nix
   ./services/networking/powerdns.nix
+  ./services/networking/pdns-recursor.nix
   ./services/networking/pptpd.nix
   ./services/networking/prayer.nix
   ./services/networking/privoxy.nix
diff --git a/nixos/modules/profiles/installation-device.nix b/nixos/modules/profiles/installation-device.nix
index 7949e600f86..a24fa75e01d 100644
--- a/nixos/modules/profiles/installation-device.nix
+++ b/nixos/modules/profiles/installation-device.nix
@@ -45,8 +45,13 @@ with lib;
             "Type `systemctl start display-manager' to\nstart the graphical user interface."}
       '';
 
-    # Allow sshd to be started manually through "start sshd".
-    services.openssh.enable = true;
+    # Allow sshd to be started manually through "systemctl start sshd".
+    services.openssh = {
+      enable = true;
+      # Allow password login to the installation, if the user sets a password via "passwd"
+      # It is safe as root doesn't have a password by default and SSH is disabled by default
+      permitRootLogin = "yes";
+    };
     systemd.services.sshd.wantedBy = mkOverride 50 [];
 
     # Enable wpa_supplicant, but don't start it by default.
@@ -66,9 +71,8 @@ with lib;
     boot.kernel.sysctl."vm.overcommit_memory" = "1";
 
     # To speed up installation a little bit, include the complete
-    # stdenv in the Nix store on the CD.  Archive::Cpio is needed for
-    # the initrd builder.
-    system.extraDependencies = [ pkgs.stdenv pkgs.busybox pkgs.perlPackages.ArchiveCpio ];
+    # stdenv in the Nix store on the CD.
+    system.extraDependencies = with pkgs; [ stdenv stdenvNoCC busybox ];
 
     # Show all debug messages from the kernel but don't log refused packets
     # because we have the firewall enabled. This makes installs from the
@@ -76,5 +80,6 @@ with lib;
     boot.consoleLogLevel = mkDefault 7;
     networking.firewall.logRefusedConnections = mkDefault false;
 
+    environment.systemPackages = [ pkgs.vim ];
   };
 }
diff --git a/nixos/modules/programs/chromium.nix b/nixos/modules/programs/chromium.nix
new file mode 100644
index 00000000000..54739feab97
--- /dev/null
+++ b/nixos/modules/programs/chromium.nix
@@ -0,0 +1,85 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.chromium;
+
+  defaultProfile = filterAttrs (k: v: v != null) {
+    HomepageLocation = cfg.homepageLocation;
+    DefaultSearchProviderSearchURL = cfg.defaultSearchProviderSearchURL;
+    DefaultSearchProviderSuggestURL = cfg.defaultSearchProviderSuggestURL;
+    ExtensionInstallForcelist = map (extension:
+      "${extension};https://clients2.google.com/service/update2/crx"
+    ) cfg.extensions;
+  };
+in
+
+{
+  ###### interface
+
+  options = {
+    programs.chromium = {
+      enable = mkEnableOption "<command>chromium</command> policies";
+
+      extensions = mkOption {
+        type = types.listOf types.str;
+        description = ''
+          List of chromium extensions to install.
+          For list of plugins ids see id in url of extensions on
+          <link xlink:href="https://chrome.google.com/webstore/category/extensions">chrome web store</link>
+          page.
+        '';
+        default = [];
+        example = literalExample ''
+          [
+            "chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
+            "mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
+            "gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
+          ]
+        '';
+      };
+
+      homepageLocation = mkOption {
+        type = types.nullOr types.str;
+        description = "Chromium default homepage";
+        default = null;
+        example = "https://nixos.org";
+      };
+
+      defaultSearchProviderSearchURL = mkOption {
+        type = types.nullOr types.str;
+        description = "Chromium default search provider url.";
+        default = null;
+        example =
+          "https://encrypted.google.com/search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:
+        ↪searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}ie={inputEncoding}";
+      };
+
+      defaultSearchProviderSuggestURL = mkOption {
+        type = types.nullOr types.str;
+        description = "Chromium default search provider url for suggestions.";
+        default = null;
+        example =
+          "https://encrypted.google.com/complete/search?output=chrome&q={searchTerms}";
+      };
+
+      extraOpts = mkOption {
+        type = types.attrs;
+        description = ''
+          Extra chromium policy options, see
+          <link xlink:href="https://www.chromium.org/administrators/policy-list-3">https://www.chromium.org/administrators/policy-list-3</link>
+          for a list of avalible options
+        '';
+        default = {};
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = lib.mkIf cfg.enable {
+    environment.etc."chromium/policies/managed/default.json".text = builtins.toJSON defaultProfile;
+    environment.etc."chromium/policies/managed/extra.json".text = builtins.toJSON cfg.extraOpts;
+  };
+}
diff --git a/nixos/modules/programs/man.nix b/nixos/modules/programs/man.nix
index e59ffd6f936..5b20a38d885 100644
--- a/nixos/modules/programs/man.nix
+++ b/nixos/modules/programs/man.nix
@@ -11,6 +11,7 @@ with lib;
       default = true;
       description = ''
         Whether to enable manual pages and the <command>man</command> command.
+        This also includes "man" outputs of all <literal>systemPackages</literal>.
       '';
     };
 
diff --git a/nixos/modules/programs/nano.nix b/nixos/modules/programs/nano.nix
index b8803eec7be..27b6d446c75 100644
--- a/nixos/modules/programs/nano.nix
+++ b/nixos/modules/programs/nano.nix
@@ -1,4 +1,4 @@
-{ config, lib, ... }:
+{ config, lib, pkgs, ... }:
 
 let
   cfg = config.programs.nano;
@@ -20,16 +20,22 @@ in
         example = ''
           set nowrap
           set tabstospaces
-          set tabsize 4
+          set tabsize 2
         '';
       };
+      syntaxHighlight = lib.mkOption {
+        type = lib.types.bool;
+        default = true;
+        description = "Whether to enable syntax highlight for various languages.";
+      };
     };
   };
 
   ###### implementation
 
   config = lib.mkIf (cfg.nanorc != "") {
-    environment.etc."nanorc".text = cfg.nanorc;
+    environment.etc."nanorc".text = lib.concatStrings [ cfg.nanorc
+      (lib.optionalString cfg.syntaxHighlight ''include "${pkgs.nano}/share/nano/*.nanorc"'') ];
   };
 
 }
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index b4d941a7770..990e6648e82 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -123,11 +123,6 @@ in
 
         setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
 
-        ${cfge.interactiveShellInit}
-
-        ${cfg.promptInit}
-        ${zshAliases}
-
         # Tell zsh how to find installed completions
         for p in ''${(z)NIX_PROFILES}; do
           fpath+=($p/share/zsh/site-functions $p/share/zsh/$ZSH_VERSION/functions)
@@ -143,6 +138,12 @@ in
           "source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
         }
 
+        ${zshAliases}
+        ${cfg.promptInit}
+
+        ${cfge.interactiveShellInit}
+
+
         HELPDIR="${pkgs.zsh}/share/zsh/$ZSH_VERSION/help"
       '';
 
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 876e54a162c..be89d85ff3c 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -17,6 +17,7 @@ with lib;
     (mkRenamedOptionModule [ "services" "elasticsearch" "host" ] [ "services" "elasticsearch" "listenAddress" ])
     (mkRenamedOptionModule [ "services" "graphite" "api" "host" ] [ "services" "graphite" "api" "listenAddress" ])
     (mkRenamedOptionModule [ "services" "graphite" "web" "host" ] [ "services" "graphite" "web" "listenAddress" ])
+    (mkRenamedOptionModule [ "services" "logstash" "address" ] [ "services" "logstash" "listenAddress" ])
     (mkRenamedOptionModule [ "services" "kibana" "host" ] [ "services" "kibana" "listenAddress" ])
     (mkRenamedOptionModule [ "services" "mpd" "network" "host" ] [ "services" "mpd" "network" "listenAddress" ])
     (mkRenamedOptionModule [ "services" "neo4j" "host" ] [ "services" "neo4j" "listenAddress" ])
@@ -163,6 +164,9 @@ with lib;
         else { addr = value inetAddr; port = value inetPort; }
     ))
 
+    # dhcpd
+    (mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ])
+
     # Options that are obsolete and have no replacement.
     (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
     (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix
index 726e5471141..4e7c966a463 100644
--- a/nixos/modules/security/acme.nix
+++ b/nixos/modules/security/acme.nix
@@ -284,6 +284,8 @@ in
             OnCalendar = cfg.renewInterval;
             Unit = "acme-${cert}.service";
             Persistent = "yes";
+            AccuracySec = "5m";
+            RandomizedDelaySec = "1h";
           };
         })
       );
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
index fbf7412a6cd..029b11ad98b 100644
--- a/nixos/modules/services/cluster/kubernetes.nix
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -737,6 +737,8 @@ in {
         wantedBy = [ "multi-user.target" ];
         after = [ "kube-apiserver.service" ];
         serviceConfig = {
+          RestartSec = "30s";
+          Restart = "on-failure";
           ExecStart = ''${cfg.package}/bin/kube-controller-manager \
             --address=${cfg.controllerManager.address} \
             --port=${toString cfg.controllerManager.port} \
diff --git a/nixos/modules/services/games/factorio.nix b/nixos/modules/services/games/factorio.nix
index 0369752997a..e7f070d0877 100644
--- a/nixos/modules/services/games/factorio.nix
+++ b/nixos/modules/services/games/factorio.nix
@@ -14,6 +14,31 @@ let
     read-data=${factorio}/share/factorio/data
     write-data=${stateDir}
   '';
+  serverSettings = {
+    name = cfg.game-name;
+    description = cfg.description;
+    visibility = {
+      public = cfg.public;
+      lan = cfg.lan;
+    };
+    username = cfg.username;
+    password = cfg.password;
+    token = cfg.token;
+    game_password = cfg.game-password;
+    require_user_verification = true;
+    max_upload_in_kilobytes_per_second = 0;
+    minimum_latency_in_ticks = 0;
+    ignore_player_limit_for_returning_players = false;
+    allow_commands = "admins-only";
+    autosave_interval = cfg.autosave-interval;
+    autosave_slots = 5;
+    afk_autokick_interval = 0;
+    auto_pause = true;
+    only_admins_can_pause_the_game = true;
+    autosave_only_on_server = true;
+    admins = [];
+  };
+  serverSettingsFile = pkgs.writeText "server-settings.json" (builtins.toJSON (filterAttrsRecursive (n: v: v != null) serverSettings));
   modDir = pkgs.factorio-mkModDirDrv cfg.mods;
 in
 {
@@ -67,12 +92,68 @@ in
           derivations via nixos-channel. Until then, this is for experts only.
         '';
       };
+      game-name = mkOption {
+        type = types.nullOr types.string;
+        default = "Factorio Game";
+        description = ''
+          Name of the game as it will appear in the game listing.
+        '';
+      };
+      description = mkOption {
+        type = types.nullOr types.string;
+        default = "";
+        description = ''
+          Description of the game that will appear in the listing.
+        '';
+      };
+      public = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Game will be published on the official Factorio matching server.
+        '';
+      };
+      lan = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Game will be broadcast on LAN.
+        '';
+      };
+      username = mkOption {
+        type = types.nullOr types.string;
+        default = null;
+        description = ''
+          Your factorio.com login credentials. Required for games with visibility public.
+        '';
+      };
+      password = mkOption {
+        type = types.nullOr types.string;
+        default = null;
+        description = ''
+          Your factorio.com login credentials. Required for games with visibility public.
+        '';
+      };
+      token = mkOption {
+        type = types.nullOr types.string;
+        default = null;
+        description = ''
+          Authentication token. May be used instead of 'password' above.
+        '';
+      };
+      game-password = mkOption {
+        type = types.nullOr types.string;
+        default = null;
+        description = ''
+          Game password.
+        '';
+      };
       autosave-interval = mkOption {
         type = types.nullOr types.int;
         default = null;
-        example = 2;
+        example = 10;
         description = ''
-          The time, in minutes, between autosaves.
+          Autosave interval in minutes.
         '';
       };
     };
@@ -120,8 +201,8 @@ in
           "--config=${cfg.configFile}"
           "--port=${toString cfg.port}"
           "--start-server=${mkSavePath cfg.saveName}"
+          "--server-settings=${serverSettingsFile}"
           (optionalString (cfg.mods != []) "--mod-directory=${modDir}")
-          (optionalString (cfg.autosave-interval != null) "--autosave-interval ${toString cfg.autosave-interval}")
         ];
       };
     };
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index 14d65978c32..028907693a5 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -143,7 +143,10 @@ let
       done
 
       echo "Generating hwdb database..."
-      ${udev}/bin/udevadm hwdb --update --root=$(pwd)
+      # hwdb --update doesn't return error code even on errors!
+      res="$(${udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)"
+      echo "$res"
+      [ -z "$(echo "$res" | egrep '^Error')" ]
       mv etc/udev/hwdb.bin $out
     '';
 
diff --git a/nixos/modules/services/logging/journalbeat.nix b/nixos/modules/services/logging/journalbeat.nix
new file mode 100644
index 00000000000..8186a3b02c3
--- /dev/null
+++ b/nixos/modules/services/logging/journalbeat.nix
@@ -0,0 +1,76 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.journalbeat;
+
+  journalbeatYml = pkgs.writeText "journalbeat.yml" ''
+    name: ${cfg.name}
+    tags: ${builtins.toJSON cfg.tags}
+
+    journalbeat.cursor_state_file: ${cfg.stateDir}/cursor-state
+
+    ${cfg.extraConfig}
+  '';
+
+in
+{
+  options = {
+
+    services.journalbeat = {
+
+      enable = mkEnableOption "journalbeat";
+
+      name = mkOption {
+        type = types.str;
+        default = "journalbeat";
+        description = "Name of the beat";
+      };
+
+      tags = mkOption {
+        type = types.listOf types.str;
+        default = [];
+        description = "Tags to place on the shipped log messages";
+      };
+
+      stateDir = mkOption {
+        type = types.str;
+        default = "/var/lib/journalbeat";
+        description = "The state directory. Journalbeat's own logs and other data are stored here.";
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = ''
+          journalbeat:
+            seek_position: cursor
+            cursor_seek_fallback: tail
+            write_cursor_state: true
+            cursor_flush_period: 5s
+            clean_field_names: true
+            convert_to_numbers: false
+            move_metadata_to_field: journal
+            default_type: journal
+        '';
+        description = "Any other configuration options you want to add";
+      };
+
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    systemd.services.journalbeat = with pkgs; {
+      description = "Journalbeat log shipper";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -p ${cfg.stateDir}/data
+        mkdir -p ${cfg.stateDir}/logs
+      '';
+      serviceConfig = {
+        ExecStart = "${pkgs.journalbeat}/bin/journalbeat -c ${journalbeatYml} -path.data ${cfg.stateDir}/data -path.logs ${cfg.stateDir}/logs";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/logging/logstash.nix b/nixos/modules/services/logging/logstash.nix
index 62f6e187ea0..c9477b9e3ab 100644
--- a/nixos/modules/services/logging/logstash.nix
+++ b/nixos/modules/services/logging/logstash.nix
@@ -63,7 +63,7 @@ in
         description = "Enable the logstash web interface.";
       };
 
-      address = mkOption {
+      listenAddress = mkOption {
         type = types.str;
         default = "0.0.0.0";
         description = "Address on which to start webserver.";
@@ -77,7 +77,7 @@ in
 
       inputConfig = mkOption {
         type = types.lines;
-        default = ''stdin { type => "example" }'';
+        default = ''generator { }'';
         description = "Logstash input configuration.";
         example = ''
           # Read from journal
@@ -90,7 +90,7 @@ in
 
       filterConfig = mkOption {
         type = types.lines;
-        default = ''noop {}'';
+        default = "";
         description = "logstash filter configuration.";
         example = ''
           if [type] == "syslog" {
@@ -108,11 +108,11 @@ in
 
       outputConfig = mkOption {
         type = types.lines;
-        default = ''stdout { debug => true debug_format => "json"}'';
+        default = ''stdout { codec => rubydebug }'';
         description = "Logstash output configuration.";
         example = ''
-          redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
-          elasticsearch { embedded => true }
+          redis { host => ["localhost"] data_type => "list" key => "logstash" codec => json }
+          elasticsearch { }
         '';
       };
 
@@ -147,7 +147,7 @@ in
               ${cfg.outputConfig}
             }
           ''} " +
-          ops cfg.enableWeb "-- web -a ${cfg.address} -p ${cfg.port}";
+          ops cfg.enableWeb "-- web -a ${cfg.listenAddress} -p ${cfg.port}";
       };
     };
   };
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 1d427429b9c..6b37a8a4ea2 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -241,6 +241,9 @@ in
         RuntimeDirectory = [ "dovecot2" ];
       };
 
+      # When copying sieve scripts preserve the original time stamp
+      # (should be 0) so that the compiled sieve script is newer than
+      # the source file and Dovecot won't try to compile it.
       preStart = ''
         rm -rf ${stateDir}/sieve
       '' + optionalString (cfg.sieveScripts != {}) ''
@@ -248,11 +251,11 @@ in
         ${concatStringsSep "\n" (mapAttrsToList (to: from: ''
           if [ -d '${from}' ]; then
             mkdir '${stateDir}/sieve/${to}'
-            cp "${from}/"*.sieve '${stateDir}/sieve/${to}'
+            cp -p "${from}/"*.sieve '${stateDir}/sieve/${to}'
           else
-            cp '${from}' '${stateDir}/sieve/${to}'
+            cp -p '${from}' '${stateDir}/sieve/${to}'
           fi
-           ${pkgs.dovecot_pigeonhole}/bin/sievec '${stateDir}/sieve/${to}'
+          ${pkgs.dovecot_pigeonhole}/bin/sievec '${stateDir}/sieve/${to}'
         '') cfg.sieveScripts)}
         chown -R '${cfg.mailUser}:${cfg.mailGroup}' '${stateDir}/sieve'
       '';
diff --git a/nixos/modules/services/misc/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix
index c856d3294c0..cff05339688 100644
--- a/nixos/modules/services/misc/apache-kafka.nix
+++ b/nixos/modules/services/misc/apache-kafka.nix
@@ -38,7 +38,7 @@ in {
 
     brokerId = mkOption {
       description = "Broker ID.";
-      default = 0;
+      default = -1;
       type = types.int;
     };
 
diff --git a/nixos/modules/services/misc/couchpotato.nix b/nixos/modules/services/misc/couchpotato.nix
new file mode 100644
index 00000000000..49648762235
--- /dev/null
+++ b/nixos/modules/services/misc/couchpotato.nix
@@ -0,0 +1,50 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.couchpotato;
+
+in
+{
+  options = {
+    services.couchpotato = {
+      enable = mkEnableOption "CouchPotato Server";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.couchpotato = {
+      description = "CouchPotato Server";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+
+      preStart = ''
+        mkdir -p /var/lib/couchpotato
+        chown -R couchpotato:couchpotato /var/lib/couchpotato
+      '';
+
+      serviceConfig = {
+        Type = "simple";
+        User = "couchpotato";
+        Group = "couchpotato";
+        PermissionsStartOnly = "true";
+        ExecStart = "${pkgs.couchpotato}/bin/couchpotato";
+        Restart = "on-failure";
+      };
+    };
+
+    users.extraUsers = singleton
+      { name = "couchpotato";
+        group = "couchpotato";
+        home = "/var/lib/couchpotato/";
+        description = "CouchPotato daemon user";
+        uid = config.ids.uids.couchpotato;
+      };
+
+    users.extraGroups = singleton
+      { name = "couchpotato";
+        gid = config.ids.gids.couchpotato;
+      };
+  };
+}
diff --git a/nixos/modules/services/misc/gogs.nix b/nixos/modules/services/misc/gogs.nix
new file mode 100644
index 00000000000..09e5c4fe1ff
--- /dev/null
+++ b/nixos/modules/services/misc/gogs.nix
@@ -0,0 +1,215 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.gogs;
+  configFile = pkgs.writeText "app.ini" ''
+    APP_NAME = ${cfg.appName}
+    RUN_USER = ${cfg.user}
+    RUN_MODE = prod
+
+    [database]
+    DB_TYPE = ${cfg.database.type}
+    HOST = ${cfg.database.host}:${toString cfg.database.port}
+    NAME = ${cfg.database.name}
+    USER = ${cfg.database.user}
+    PASSWD = ${cfg.database.password}
+    PATH = ${cfg.database.path}
+
+    [repository]
+    ROOT = ${cfg.repositoryRoot}
+
+    [server]
+    DOMAIN = ${cfg.domain}
+    HTTP_ADDR = ${cfg.httpAddress}
+    HTTP_PORT = ${toString cfg.httpPort}
+    ROOT_URL = ${cfg.rootUrl}
+
+    [security]
+    SECRET_KEY = #secretkey#
+    INSTALL_LOCK = true
+
+    ${cfg.extraConfig}
+  '';
+in
+
+{
+  options = {
+    services.gogs = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Enable Go Git Service.";
+      };
+
+      useWizard = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator.";
+      };
+
+      stateDir = mkOption {
+        default = "/var/lib/gogs";
+        type = types.str;
+        description = "Gogs data directory.";
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "gogs";
+        description = "User account under which Gogs runs.";
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "gogs";
+        description = "Group account under which Gogs runs.";
+      };
+
+      database = {
+        type = mkOption {
+          type = types.enum [ "sqlite3" "mysql" "postgres" ];
+          example = "mysql";
+          default = "sqlite3";
+          description = "Database engine to use.";
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "127.0.0.1";
+          description = "Database host address.";
+        };
+
+        port = mkOption {
+          type = types.int;
+          default = 3306;
+          description = "Database host port.";
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "gogs";
+          description = "Database name.";
+        };
+
+        user = mkOption {
+          type = types.str;
+          default = "gogs";
+          description = "Database user.";
+        };
+
+        password = mkOption {
+          type = types.str;
+          default = "";
+          description = "Database password.";
+        };
+
+        path = mkOption {
+          type = types.str;
+          default = "${cfg.stateDir}/data/gogs.db";
+          description = "Path to the sqlite3 database file.";
+        };
+      };
+
+      appName = mkOption {
+        type = types.str;
+        default = "Gogs: Go Git Service";
+        description = "Application name.";
+      };
+
+      repositoryRoot = mkOption {
+        type = types.str;
+        default = "${cfg.stateDir}/repositories";
+        description = "Path to the git repositories.";
+      };
+
+      domain = mkOption {
+        type = types.str;
+        default = "localhost";
+        description = "Domain name of your server.";
+      };
+
+      rootUrl = mkOption {
+        type = types.str;
+        default = "http://localhost:3000/";
+        description = "Full public URL of Gogs server.";
+      };
+
+      httpAddress = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        description = "HTTP listen address.";
+      };
+
+      httpPort = mkOption {
+        type = types.int;
+        default = 3000;
+        description = "HTTP listen port.";
+      };
+
+      extraConfig = mkOption {
+        type = types.str;
+        default = "";
+        description = "Configuration lines appended to the generated Gogs configuration file.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    systemd.services.gogs = {
+      description = "Gogs (Go Git Service)";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path = [ pkgs.gogs.bin ];
+
+      preStart = ''
+        # copy custom configuration and generate a random secret key if needed
+        ${optionalString (cfg.useWizard == false) ''
+          mkdir -p ${cfg.stateDir}/custom/conf
+          cp -f ${configFile} ${cfg.stateDir}/custom/conf/app.ini
+          KEY=$(head -c 16 /dev/urandom | tr -dc A-Za-z0-9)
+          sed -i "s,#secretkey#,$KEY,g" ${cfg.stateDir}/custom/conf/app.ini
+        ''}
+
+        mkdir -p ${cfg.repositoryRoot}
+        # update all hooks' binary paths
+        HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*")
+        if [ "$HOOKS" ]
+        then
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gogs,${pkgs.gogs.bin}/bin/gogs,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
+          sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
+        fi
+      '';
+
+      serviceConfig = {
+        Type = "simple";
+        User = cfg.user;
+        Group = cfg.group;
+        WorkingDirectory = cfg.stateDir;
+        ExecStart = "${pkgs.gogs.bin}/bin/gogs web";
+        Restart = "always";
+      };
+
+      environment = {
+        USER = cfg.user;
+        HOME = cfg.stateDir;
+        GOGS_WORK_DIR = cfg.stateDir;
+      };
+    };
+
+    users = {
+      extraUsers.gogs = {
+        description = "Go Git Service";
+        uid = config.ids.uids.gogs;
+        group = "gogs";
+        home = cfg.stateDir;
+        createHome = true;
+      };
+      extraGroups.gogs.gid = config.ids.gids.gogs;
+    };
+  };
+}
diff --git a/nixos/modules/services/misc/mesos-master.nix b/nixos/modules/services/misc/mesos-master.nix
index 99583ebeebd..0523c6549ed 100644
--- a/nixos/modules/services/misc/mesos-master.nix
+++ b/nixos/modules/services/misc/mesos-master.nix
@@ -16,12 +16,30 @@ in {
         type = types.bool;
       };
 
+      ip = mkOption {
+        description = "IP address to listen on.";
+        default = "0.0.0.0";
+        type = types.str;
+      };
+
       port = mkOption {
         description = "Mesos Master port";
         default = 5050;
         type = types.int;
       };
 
+      advertiseIp = mkOption {
+        description = "IP address advertised to reach this master.";
+        default = null;
+        type = types.nullOr types.str;
+      };
+
+      advertisePort = mkOption {
+        description = "Port advertised to reach this Mesos master.";
+        default = null;
+        type = types.nullOr types.int;
+      };
+
       zk = mkOption {
         description = ''
           ZooKeeper URL (used for leader election amongst masters).
@@ -84,7 +102,10 @@ in {
       serviceConfig = {
         ExecStart = ''
           ${pkgs.mesos}/bin/mesos-master \
+            --ip=${cfg.ip} \
             --port=${toString cfg.port} \
+            ${optionalString (cfg.advertiseIp != null) "--advertise_ip=${cfg.advertiseIp}"} \
+            ${optionalString (cfg.advertisePort  != null) "--advertise_port=${toString cfg.advertisePort}"} \
             ${if cfg.quorum == 0
               then "--registry=in_memory"
               else "--zk=${cfg.zk} --registry=replicated_log --quorum=${toString cfg.quorum}"} \
diff --git a/nixos/modules/services/misc/mesos-slave.nix b/nixos/modules/services/misc/mesos-slave.nix
index 9ddecb6fe30..47be10274d3 100644
--- a/nixos/modules/services/misc/mesos-slave.nix
+++ b/nixos/modules/services/misc/mesos-slave.nix
@@ -12,7 +12,23 @@ let
   attribsArg = optionalString (cfg.attributes != {})
                               "--attributes=${mkAttributes cfg.attributes}";
 
-  containerizers = [ "mesos" ] ++ (optional cfg.withDocker "docker");
+  containerizersArg = concatStringsSep "," (
+    lib.unique (
+      cfg.containerizers ++ (optional cfg.withDocker "docker")
+    )
+  );
+
+  imageProvidersArg = concatStringsSep "," (
+    lib.unique (
+      cfg.imageProviders ++ (optional cfg.withDocker "docker")
+    )
+  );
+
+  isolationArg = concatStringsSep "," (
+    lib.unique (
+      cfg.isolation ++ (optionals cfg.withDocker [ "filesystem/linux" "docker/runtime"])
+    )
+  );
 
 in {
 
@@ -27,7 +43,7 @@ in {
       ip = mkOption {
         description = "IP address to listen on.";
         default = "0.0.0.0";
-        type = types.string;
+        type = types.str;
       };
 
       port = mkOption {
@@ -36,6 +52,53 @@ in {
         type = types.int;
       };
 
+      advertiseIp = mkOption {
+        description = "IP address advertised to reach this agent.";
+        default = null;
+        type = types.nullOr types.str;
+      };
+
+      advertisePort = mkOption {
+        description = "Port advertised to reach this agent.";
+        default = null;
+        type = types.nullOr types.int;
+      };
+
+      containerizers = mkOption {
+        description = ''
+          List of containerizer implementations to compose in order to provide
+          containerization. Available options are mesos and docker.
+          The order the containerizers are specified is the order they are tried.
+        '';
+        default = [ "mesos" ];
+        type = types.listOf types.str;
+      };
+
+      imageProviders = mkOption {
+        description = "List of supported image providers, e.g., APPC,DOCKER.";
+        default = [ ];
+        type = types.listOf types.str;
+      };
+
+      imageProvisionerBackend = mkOption {
+        description = ''
+          Strategy for provisioning container rootfs from images,
+          e.g., aufs, bind, copy, overlay.
+        '';
+        default = "copy";
+        type = types.str;
+      };
+
+      isolation = mkOption {
+        description = ''
+          Isolation mechanisms to use, e.g., posix/cpu,posix/mem, or
+          cgroups/cpu,cgroups/mem, or network/port_mapping, or `gpu/nvidia` for nvidia
+          specific gpu isolation.
+        '';
+        default = [ "posix/cpu" "posix/mem" ];
+        type = types.listOf types.str;
+      };
+
       master = mkOption {
         description = ''
           May be one of:
@@ -57,6 +120,16 @@ in {
         type = types.bool;
       };
 
+      dockerRegistry = mkOption {
+        description = ''
+          The default url for pulling Docker images.
+          It could either be a Docker registry server url,
+          or a local path in which Docker image archives are stored.
+        '';
+        default = null;
+        type = types.nullOr (types.either types.str types.path);
+      };
+
       workDir = mkOption {
         description = "The Mesos work directory.";
         default = "/var/lib/mesos/slave";
@@ -96,28 +169,45 @@ in {
                     host = "aabc123";
                     os = "nixos"; };
       };
+
+      executorEnvironmentVariables = mkOption {
+        description = ''
+          The environment variables that should be passed to the executor, and thus subsequently task(s).
+        '';
+        default = {
+          PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
+        };
+        type = types.attrsOf types.str;
+      };
     };
 
   };
 
-
   config = mkIf cfg.enable {
     systemd.services.mesos-slave = {
       description = "Mesos Slave";
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" ];
-      environment.MESOS_CONTAINERIZERS = concatStringsSep "," containerizers;
+      path = [ pkgs.stdenv.shellPackage ];
       serviceConfig = {
         ExecStart = ''
           ${pkgs.mesos}/bin/mesos-slave \
+            --containerizers=${containerizersArg} \
+            --image_providers=${imageProvidersArg} \
+            --image_provisioner_backend=${cfg.imageProvisionerBackend} \
+            --isolation=${isolationArg} \
             --ip=${cfg.ip} \
             --port=${toString cfg.port} \
+            ${optionalString (cfg.advertiseIp != null) "--advertise_ip=${cfg.advertiseIp}"} \
+            ${optionalString (cfg.advertisePort  != null) "--advertise_port=${toString cfg.advertisePort}"} \
             --master=${cfg.master} \
             --work_dir=${cfg.workDir} \
             --logging_level=${cfg.logLevel} \
             ${attribsArg} \
             ${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \
             ${optionalString cfg.withDocker "--docker=${pkgs.docker}/libexec/docker/docker"} \
+            ${optionalString (cfg.dockerRegistry != null) "--docker_registry=${cfg.dockerRegistry}"} \
+            --executor_environment_variables=${lib.escapeShellArg (builtins.toJSON cfg.executorEnvironmentVariables)} \
             ${toString cfg.extraCmdLineOptions}
         '';
         PermissionsStartOnly = true;
diff --git a/nixos/modules/services/monitoring/arbtt.nix b/nixos/modules/services/monitoring/arbtt.nix
new file mode 100644
index 00000000000..27d59e367d5
--- /dev/null
+++ b/nixos/modules/services/monitoring/arbtt.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.arbtt;
+in {
+  options = {
+    services.arbtt = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        example = true;
+        description = ''
+          Enable the arbtt statistics capture service.
+        '';
+      };
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.haskellPackages.arbtt;
+        defaultText = "pkgs.haskellPackages.arbtt";
+        example = literalExample "pkgs.haskellPackages.arbtt";
+        description = ''
+          The package to use for the arbtt binaries.
+        '';
+      };
+
+      logFile = mkOption {
+        type = types.str;
+        default = "%h/.arbtt/capture.log";
+        example = "/home/username/.arbtt-capture.log";
+        description = ''
+          The log file for captured samples.
+        '';
+      };
+
+      sampleRate = mkOption {
+        type = types.int;
+        default = 60;
+        example = 120;
+        description = ''
+          The sampling interval in seconds.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.user.services.arbtt = {
+      description = "arbtt statistics capture service";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        Type = "simple";
+        ExecStart = "${cfg.package}/bin/arbtt-capture --logfile=${cfg.logFile} --sample-rate=${toString cfg.sampleRate}";
+        Restart = "always";
+      };
+    };
+  };
+
+  meta.maintainers = [ maintainers.michaelpj ];
+}
diff --git a/nixos/modules/services/monitoring/netdata.nix b/nixos/modules/services/monitoring/netdata.nix
new file mode 100644
index 00000000000..e1fde4fc950
--- /dev/null
+++ b/nixos/modules/services/monitoring/netdata.nix
@@ -0,0 +1,78 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.netdata;
+
+  configFile = pkgs.writeText "netdata.conf" cfg.configText;
+
+  defaultUser = "netdata";
+
+in {
+  options = {
+    services.netdata = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Whether to enable netdata monitoring.";
+      };
+
+      user = mkOption {
+        type = types.str;
+        default = "netdata";
+        description = "User account under which netdata runs.";
+      };
+
+      group = mkOption {
+        type = types.str;
+        default = "netdata";
+        description = "Group under which netdata runs.";
+      };
+
+      configText = mkOption {
+        type = types.lines;
+        default = "";
+        description = "netdata.conf configuration.";
+        example = ''
+          [global]
+          debug log = syslog
+          access log = syslog
+          error log = syslog
+        '';
+      };
+
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.netdata = {
+      description = "Real time performance monitoring";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      preStart = concatStringsSep "\n" (map (dir: ''
+        mkdir -vp ${dir}
+        chmod 750 ${dir}
+        chown -R ${cfg.user}:${cfg.group} ${dir}
+        '') [ "/var/cache/netdata"
+              "/var/log/netdata"
+              "/var/lib/netdata" ]);
+      serviceConfig = {
+        User = cfg.user;
+        Group = cfg.group;
+        PermissionsStartOnly = true;
+        ExecStart = "${pkgs.netdata}/bin/netdata -D -c ${configFile}";
+        TimeoutStopSec = 60;
+      };
+    };
+
+    users.extraUsers = optional (cfg.user == defaultUser) {
+      name = defaultUser;
+    };
+
+    users.extraGroups = optional (cfg.group == defaultUser) {
+      name = defaultUser;
+    };
+
+  };
+}
diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix
index da2cd02eaa3..cf761edad92 100644
--- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix
+++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix
@@ -5,6 +5,10 @@ with lib;
 let
   cfg = config.services.prometheus.alertmanager;
   mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration);
+  alertmanagerYml =
+    if cfg.configText != null then
+      pkgs.writeText "alertmanager.yml" cfg.configText
+    else mkConfigFile;
 in {
   options = {
     services.prometheus.alertmanager = {
@@ -34,6 +38,17 @@ in {
         '';
       };
 
+      configText = mkOption {
+        type = types.nullOr types.lines;
+        default = null;
+        description = ''
+          Alertmanager configuration as YAML text. If non-null, this option
+          defines the text that is written to alertmanager.yml. If null, the
+          contents of alertmanager.yml is generated from the structured config
+          options.
+        '';
+      };
+
       logFormat = mkOption {
         type = types.nullOr types.str;
         default = null;
@@ -96,7 +111,7 @@ in {
       after    = [ "network.target" ];
       script = ''
         ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \
-        -config.file ${mkConfigFile} \
+        -config.file ${alertmanagerYml} \
         -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
         -log.level ${cfg.logLevel} \
         ${optionalString (cfg.webExternalUrl != null) ''-web.external-url ${cfg.webExternalUrl} \''}
diff --git a/nixos/modules/services/monitoring/vnstat.nix b/nixos/modules/services/monitoring/vnstat.nix
new file mode 100644
index 00000000000..f6be7c7fd34
--- /dev/null
+++ b/nixos/modules/services/monitoring/vnstat.nix
@@ -0,0 +1,43 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.vnstat;
+in {
+  options.services.vnstat = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to enable update of network usage statistics via vnstatd.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.extraUsers.vnstatd = {
+      isSystemUser = true;
+      description = "vnstat daemon user";
+      home = "/var/lib/vnstat";
+      createHome = true;
+    };
+
+    systemd.services.vnstat = {
+      description = "vnStat network traffic monitor";
+      path = [ pkgs.coreutils ];
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      unitConfig.documentation = "man:vnstatd(1) man:vnstat(1) man:vnstat.conf(5)";
+      preStart = "chmod 755 /var/lib/vnstat";
+      serviceConfig = {
+        ExecStart = "${pkgs.vnstat}/bin/vnstatd -n";
+        ExecReload = "kill -HUP $MAINPID";
+        ProtectHome = true;
+        PrivateDevices = true;
+        PrivateTmp = true;
+        User = "vnstatd";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/network-filesystems/ipfs.nix b/nixos/modules/services/network-filesystems/ipfs.nix
index 104b5b92620..d43147a16f3 100644
--- a/nixos/modules/services/network-filesystems/ipfs.nix
+++ b/nixos/modules/services/network-filesystems/ipfs.nix
@@ -67,6 +67,14 @@ in
         '';
       };
 
+      emptyRepo = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          If set to true, the repo won't be initialized with help files
+        '';
+      };
+
       extraFlags = mkOption {
         type = types.listOf types.str;
         description = "Extra flags passed to the IPFS daemon";
@@ -103,16 +111,17 @@ in
       after = [ "network.target" "local-fs.target" ];
       path  = [ pkgs.ipfs pkgs.su pkgs.bash ];
 
-      preStart =
-        ''
-          install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}
-          if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then
-            cd ${cfg.dataDir}
-            ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs init"
-          fi
-          ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.API ${cfg.apiAddress}"
-          ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c "${ipfs}/bin/ipfs config Addresses.Gateway ${cfg.gatewayAddress}"
-        '';
+      preStart = ''
+        install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}
+        if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then
+          cd ${cfg.dataDir}
+          ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \
+             "${ipfs}/bin/ipfs init ${if cfg.emptyRepo then "-e" else ""}"
+        fi
+        ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \
+           "${ipfs}/bin/ipfs --local config Addresses.API ${cfg.apiAddress} && \
+            ${ipfs}/bin/ipfs --local config Addresses.Gateway ${cfg.gatewayAddress}"
+      '';
 
       serviceConfig = {
         ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags}";
diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix
index ab9eac3829f..f63f641d00b 100644
--- a/nixos/modules/services/network-filesystems/tahoe.nix
+++ b/nixos/modules/services/network-filesystems/tahoe.nix
@@ -343,7 +343,7 @@ in
             preStart = ''
               if [ \! -d ${nodedir} ]; then
                 mkdir -p /var/db/tahoe-lafs
-                tahoe create-node ${nodedir}
+                tahoe create-node --hostname=localhost ${nodedir}
               fi
 
               # Tahoe has created a predefined tahoe.cfg which we must now
diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix
index d1900deceaf..5928203368d 100644
--- a/nixos/modules/services/networking/ddclient.nix
+++ b/nixos/modules/services/networking/ddclient.nix
@@ -132,7 +132,8 @@ in
         login=${config.services.ddclient.username}
         password=${config.services.ddclient.password}
         protocol=${config.services.ddclient.protocol}
-        server=${config.services.ddclient.server}
+        ${let server = config.services.ddclient.server; in
+          lib.optionalString (server != "") "server=${server}"}
         ssl=${if config.services.ddclient.ssl then "yes" else "no"}
         wildcard=YES
         ${config.services.ddclient.domain}
diff --git a/nixos/modules/services/networking/dhcpd.nix b/nixos/modules/services/networking/dhcpd.nix
index d2cd00e74a1..86bcaa96f34 100644
--- a/nixos/modules/services/networking/dhcpd.nix
+++ b/nixos/modules/services/networking/dhcpd.nix
@@ -4,11 +4,10 @@ with lib;
 
 let
 
-  cfg = config.services.dhcpd;
+  cfg4 = config.services.dhcpd4;
+  cfg6 = config.services.dhcpd6;
 
-  stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant.
-
-  configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf"
+  writeConfig = cfg: pkgs.writeText "dhcpd.conf"
     ''
       default-lease-time 600;
       max-lease-time 7200;
@@ -29,131 +28,180 @@ let
       }
     '';
 
-in
-
-{
-
-  ###### interface
-
-  options = {
+  dhcpdService = postfix: cfg: optionalAttrs cfg.enable {
+    "dhcpd${postfix}" = {
+      description = "DHCPv${postfix} server";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+
+      preStart = ''
+        mkdir -m 755 -p ${cfg.stateDir}
+        touch ${cfg.stateDir}/dhcpd.leases
+      '';
+
+      serviceConfig =
+        let
+          configFile = if cfg.configFile != null then cfg.configFile else writeConfig cfg;
+          args = [ "@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
+                   "-pf" "/run/dhcpd${postfix}/dhcpd.pid"
+                   "-cf" "${configFile}"
+                   "-lf" "${cfg.stateDir}/dhcpd.leases"
+                   "-user" "dhcpd" "-group" "nogroup"
+                 ] ++ cfg.extraFlags
+                   ++ cfg.interfaces;
+
+        in {
+          ExecStart = concatMapStringsSep " " escapeShellArg args;
+          Type = "forking";
+          Restart = "always";
+          RuntimeDirectory = [ "dhcpd${postfix}" ];
+          PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
+        };
+    };
+  };
 
-    services.dhcpd = {
+  machineOpts = {...}: {
+    config = {
 
-      enable = mkOption {
-        default = false;
-        description = "
-          Whether to enable the DHCP server.
-        ";
+      hostName = mkOption {
+        type = types.str;
+        example = "foo";
+        description = ''
+          Hostname which is assigned statically to the machine.
+        '';
       };
 
-      extraConfig = mkOption {
-        type = types.lines;
-        default = "";
-        example = ''
-          option subnet-mask 255.255.255.0;
-          option broadcast-address 192.168.1.255;
-          option routers 192.168.1.5;
-          option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1;
-          option domain-name "example.org";
-          subnet 192.168.1.0 netmask 255.255.255.0 {
-            range 192.168.1.100 192.168.1.200;
-          }
+      ethernetAddress = mkOption {
+        type = types.str;
+        example = "00:16:76:9a:32:1d";
+        description = ''
+          MAC address of the machine.
         '';
-        description = "
-          Extra text to be appended to the DHCP server configuration
-          file.  Currently, you almost certainly need to specify
-          something here, such as the options specifying the subnet
-          mask, DNS servers, etc.
-        ";
       };
 
-      extraFlags = mkOption {
-        default = "";
-        example = "-6";
-        description = "
-          Additional command line flags to be passed to the dhcpd daemon.
-        ";
+      ipAddress = mkOption {
+        type = types.str;
+        example = "192.168.1.10";
+        description = ''
+          IP address of the machine.
+        '';
       };
 
-      configFile = mkOption {
-        default = null;
-        description = "
-          The path of the DHCP server configuration file.  If no file
-          is specified, a file is generated using the other options.
-        ";
-      };
+    };
+  };
 
-      interfaces = mkOption {
-        default = ["eth0"];
-        description = "
-          The interfaces on which the DHCP server should listen.
-        ";
-      };
+  dhcpConfig = postfix: {
 
-      machines = mkOption {
-        default = [];
-        example = [
-          { hostName = "foo";
-            ethernetAddress = "00:16:76:9a:32:1d";
-            ipAddress = "192.168.1.10";
-          }
-          { hostName = "bar";
-            ethernetAddress = "00:19:d1:1d:c4:9a";
-            ipAddress = "192.168.1.11";
-          }
-        ];
-        description = "
-          A list mapping ethernet addresses to IP addresses for the
-          DHCP server.
-        ";
-      };
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to enable the DHCPv${postfix} server.
+      '';
+    };
 
+    stateDir = mkOption {
+      type = types.path;
+      # We use /var/lib/dhcp for DHCPv4 to save backwards compatibility.
+      default = "/var/lib/dhcp${if postfix == "4" then "" else postfix}";
+      description = ''
+        State directory for the DHCP server.
+      '';
     };
 
-  };
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      example = ''
+        option subnet-mask 255.255.255.0;
+        option broadcast-address 192.168.1.255;
+        option routers 192.168.1.5;
+        option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1;
+        option domain-name "example.org";
+        subnet 192.168.1.0 netmask 255.255.255.0 {
+          range 192.168.1.100 192.168.1.200;
+        }
+      '';
+      description = ''
+        Extra text to be appended to the DHCP server configuration
+        file. Currently, you almost certainly need to specify something
+        there, such as the options specifying the subnet mask, DNS servers,
+        etc.
+      '';
+    };
 
+    extraFlags = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      description = ''
+        Additional command line flags to be passed to the dhcpd daemon.
+      '';
+    };
 
-  ###### implementation
+    configFile = mkOption {
+      type = types.nullOr types.path;
+      default = null;
+      description = ''
+        The path of the DHCP server configuration file.  If no file
+        is specified, a file is generated using the other options.
+      '';
+    };
 
-  config = mkIf config.services.dhcpd.enable {
+    interfaces = mkOption {
+      type = types.listOf types.str;
+      default = ["eth0"];
+      description = ''
+        The interfaces on which the DHCP server should listen.
+      '';
+    };
 
-    users = {
-      extraUsers.dhcpd = {
-        uid = config.ids.uids.dhcpd;
-        description = "DHCP daemon user";
-      };
+    machines = mkOption {
+      type = types.listOf (types.submodule machineOpts);
+      default = [];
+      example = [
+        { hostName = "foo";
+          ethernetAddress = "00:16:76:9a:32:1d";
+          ipAddress = "192.168.1.10";
+        }
+        { hostName = "bar";
+          ethernetAddress = "00:19:d1:1d:c4:9a";
+          ipAddress = "192.168.1.11";
+        }
+      ];
+      description = ''
+        A list mapping Ethernet addresses to IPv${postfix} addresses for the
+        DHCP server.
+      '';
     };
 
-    systemd.services.dhcpd =
-      { description = "DHCP server";
+  };
+
+in
+
+{
+
+  ###### interface
 
-        wantedBy = [ "multi-user.target" ];
+  options = {
 
-        after = [ "network.target" ];
+    services.dhcpd4 = dhcpConfig "4";
+    services.dhcpd6 = dhcpConfig "6";
 
-        path = [ pkgs.dhcp ];
+  };
 
-        preStart =
-          ''
-            mkdir -m 755 -p ${stateDir}
 
-            touch ${stateDir}/dhcpd.leases
+  ###### implementation
 
-            mkdir -m 755 -p /run/dhcpd
-            chown dhcpd /run/dhcpd
-          '';
+  config = mkIf (cfg4.enable || cfg6.enable) {
 
-        serviceConfig =
-          { ExecStart = "@${pkgs.dhcp}/sbin/dhcpd dhcpd"
-              + " -pf /run/dhcpd/dhcpd.pid -cf ${configFile}"
-              + " -lf ${stateDir}/dhcpd.leases -user dhcpd -group nogroup"
-              + " ${cfg.extraFlags}"
-              + " ${toString cfg.interfaces}";
-            Restart = "always";
-            Type = "forking";
-            PIDFile = "/run/dhcpd/dhcpd.pid";
-          };
+    users = {
+      extraUsers.dhcpd = {
+        uid = config.ids.uids.dhcpd;
+        description = "DHCP daemon user";
       };
+    };
+
+    systemd.services = dhcpdService "4" cfg4 // dhcpdService "6" cfg6;
 
   };
 
diff --git a/nixos/modules/services/networking/dnscrypt-wrapper.nix b/nixos/modules/services/networking/dnscrypt-wrapper.nix
new file mode 100644
index 00000000000..85fac660d52
--- /dev/null
+++ b/nixos/modules/services/networking/dnscrypt-wrapper.nix
@@ -0,0 +1,187 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+  cfg     = config.services.dnscrypt-wrapper;
+  dataDir = "/var/lib/dnscrypt-wrapper";
+
+  daemonArgs = with cfg; [
+    "--listen-address=${address}:${toString port}"
+    "--resolver-address=${upstream.address}:${toString upstream.port}"
+    "--provider-name=${providerName}"
+    "--provider-publickey-file=public.key"
+    "--provider-secretkey-file=secret.key"
+    "--provider-cert-file=${providerName}.crt"
+    "--crypt-secretkey-file=${providerName}.key"
+  ];
+
+  genKeys = ''
+    # generates time-limited keypairs
+    keyGen() {
+      dnscrypt-wrapper --gen-crypt-keypair \
+        --crypt-secretkey-file=${cfg.providerName}.key
+
+      dnscrypt-wrapper --gen-cert-file \
+        --crypt-secretkey-file=${cfg.providerName}.key \
+        --provider-cert-file=${cfg.providerName}.crt \
+        --provider-publickey-file=public.key \
+        --provider-secretkey-file=secret.key \
+        --cert-file-expire-days=${toString cfg.keys.expiration}
+    }
+
+    cd ${dataDir}
+
+    # generate provider keypair (first run only)
+    if [ ! -f public.key ] || [ ! -f secret.key ]; then
+      dnscrypt-wrapper --gen-provider-keypair
+    fi
+
+    # generate new keys for rotation
+    if [ ! -f ${cfg.providerName}.key ] || [ ! -f ${cfg.providerName}.crt ]; then
+      keyGen
+    fi
+  '';
+
+  rotateKeys = ''
+    # check if keys are not expired
+    keyValid() {
+      fingerprint=$(dnscrypt-wrapper --show-provider-publickey-fingerprint | awk '{print $(NF)}')
+      dnscrypt-proxy --test=${toString (cfg.keys.checkInterval + 1)} \
+        --resolver-address=127.0.0.1:${toString cfg.port} \
+        --provider-name=${cfg.providerName} \
+        --provider-key=$fingerprint
+    }
+
+    cd ${dataDir}
+
+    # archive old keys and restart the service
+    if ! keyValid; then
+      mkdir -p oldkeys
+      mv ${cfg.providerName}.key oldkeys/${cfg.providerName}-$(date +%F-%T).key
+      mv ${cfg.providerName}.crt oldkeys/${cfg.providerName}-$(date +%F-%T).crt
+      systemctl restart dnscrypt-wrapper
+    fi
+  '';
+
+in {
+
+
+  ###### interface
+
+  options.services.dnscrypt-wrapper = {
+    enable = mkEnableOption "DNSCrypt wrapper";
+
+    address = mkOption {
+      type = types.str;
+      default = "127.0.0.1";
+      description = ''
+        The DNSCrypt wrapper will bind to this IP address.
+      '';
+    };
+
+    port = mkOption {
+      type = types.int;
+      default = 5353;
+      description = ''
+        The DNSCrypt wrapper will listen for DNS queries on this port.
+      '';
+    };
+
+    providerName = mkOption {
+      type = types.str;
+      default = "2.dnscrypt-cert.${config.networking.hostName}";
+      example = "2.dnscrypt-cert.myresolver";
+      description = ''
+        The name that will be given to this DNSCrypt resolver.
+        Note: the resolver name must start with <literal>2.dnscrypt-cert.</literal>.
+      '';
+    };
+
+    upstream.address = mkOption {
+      type = types.str;
+      default = "127.0.0.1";
+      description = ''
+        The IP address of the upstream DNS server DNSCrypt will "wrap".
+      '';
+    };
+
+    upstream.port = mkOption {
+      type = types.int;
+      default = 53;
+      description = ''
+        The port of the upstream DNS server DNSCrypt will "wrap".
+      '';
+    };
+
+    keys.expiration = mkOption {
+      type = types.int;
+      default = 30;
+      description = ''
+        The duration (in days) of the time-limited secret key.
+        This will be automatically rotated before expiration.
+      '';
+    };
+
+    keys.checkInterval = mkOption {
+      type = types.int;
+      default = 1440;
+      description = ''
+        The time interval (in minutes) between key expiration checks.
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    users.users.dnscrypt-wrapper = {
+      description = "dnscrypt-wrapper daemon user";
+      home = "${dataDir}";
+      createHome = true;
+    };
+    users.groups.dnscrypt-wrapper = { };
+
+
+    systemd.services.dnscrypt-wrapper = {
+      description = "dnscrypt-wrapper daemon";
+      after    = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path     = [ pkgs.dnscrypt-wrapper ];
+
+      serviceConfig = {
+        User = "dnscrypt-wrapper";
+        WorkingDirectory = dataDir;
+        Restart   = "on-failure";
+        ExecStart = "${pkgs.dnscrypt-wrapper}/bin/dnscrypt-wrapper ${toString daemonArgs}";
+      };
+
+      preStart = genKeys;
+    };
+
+
+    systemd.services.dnscrypt-wrapper-rotate = {
+      after    = [ "network.target" ];
+      requires = [ "dnscrypt-wrapper.service" ];
+      description = "Rotates DNSCrypt wrapper keys if soon to expire";
+
+      path   = with pkgs; [ dnscrypt-wrapper dnscrypt-proxy gawk ];
+      script = rotateKeys;
+    };
+
+
+    systemd.timers.dnscrypt-wrapper-rotate = {
+      description = "Periodically check DNSCrypt wrapper keys for expiration";
+      wantedBy = [ "multi-user.target" ];
+
+      timerConfig = {
+        Unit = "dnscrypt-wrapper-rotate.service";
+        OnBootSec = "1min";
+        OnUnitActiveSec = cfg.keys.checkInterval * 60;
+      };
+    };
+
+  };
+}
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 1c0ea5034df..34b731ad35c 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -4,17 +4,29 @@
    ‘networking.firewall.extraCommands’.  For modularity, the firewall
    uses several chains:
 
-   - ‘nixos-fw-input’ is the main chain for input packet processing.
+   - ‘nixos-fw’ is the main chain for input packet processing.
+
+   - ‘nixos-fw-accept’ is called for accepted packets.  If you want
+     additional logging, or want to reject certain packets anyway, you
+     can insert rules at the start of this chain.
 
    - ‘nixos-fw-log-refuse’ and ‘nixos-fw-refuse’ are called for
      refused packets.  (The former jumps to the latter after logging
      the packet.)  If you want additional logging, or want to accept
      certain packets anyway, you can insert rules at the start of
-     these chain.
+     this chain.
 
-   - ‘nixos-fw-accept’ is called for accepted packets.  If you want
-     additional logging, or want to reject certain packets anyway, you
-     can insert rules at the start of this chain.
+   - ‘nixos-fw-rpfilter’ is used as the main chain in the raw table,
+     called from the built-in ‘PREROUTING’ chain.  If the kernel
+     supports it and `cfg.checkReversePath` is set this chain will
+     perform a reverse path filter test.
+
+   - ‘nixos-drop’ is used while reloading the firewall in order to drop
+     all traffic.  Since reloading isn't implemented in an atomic way
+     this'll prevent any traffic from leaking through while reloading
+     the firewall.  However, if the reloading fails, the ‘firewall-stop’
+     script will be called which in return will effectively disable the
+     complete firewall (in the default configuration).
 
 */
 
@@ -26,6 +38,10 @@ let
 
   cfg = config.networking.firewall;
 
+  kernelPackages = config.boot.kernelPackages;
+
+  kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
+
   helpers =
     ''
       # Helper command to manipulate both the IPv4 and IPv6 tables.
@@ -49,7 +65,7 @@ let
     # firewall would be atomic.  Apparently that's possible
     # with iptables-restore.
     ip46tables -D INPUT -j nixos-fw 2> /dev/null || true
-    for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do
+    for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse; do
       ip46tables -F "$chain" 2> /dev/null || true
       ip46tables -X "$chain" 2> /dev/null || true
     done
@@ -172,13 +188,16 @@ let
       }-j nixos-fw-accept
     ''}
 
-    # Accept all ICMPv6 messages except redirects and node
-    # information queries (type 139).  See RFC 4890, section
-    # 4.4.
     ${optionalString config.networking.enableIPv6 ''
+      # Accept all ICMPv6 messages except redirects and node
+      # information queries (type 139).  See RFC 4890, section
+      # 4.4.
       ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
       ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
       ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
+
+      # Allow this host to act as a DHCPv6 client
+      ip6tables -A nixos-fw -d fe80::/64 -p udp --dport 546 -j nixos-fw-accept
     ''}
 
     ${cfg.extraCommands}
@@ -228,11 +247,6 @@ let
     fi
   '';
 
-  kernelPackages = config.boot.kernelPackages;
-
-  kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
-  kernelCanDisableHelpers = kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers or false;
-
 in
 
 {
@@ -290,26 +304,30 @@ in
       default = false;
       description =
         ''
-          If set, forbidden packets are rejected rather than dropped
+          If set, refused packets are rejected rather than dropped
           (ignored).  This means that an ICMP "port unreachable" error
-          message is sent back to the client.  Rejecting packets makes
+          message is sent back to the client (or a TCP RST packet in
+          case of an existing connection).  Rejecting packets makes
           port scanning somewhat easier.
         '';
     };
 
     networking.firewall.trustedInterfaces = mkOption {
       type = types.listOf types.str;
+      default = [ ];
+      example = [ "enp0s2" ];
       description =
         ''
           Traffic coming in from these interfaces will be accepted
-          unconditionally.
+          unconditionally.  Traffic from the loopback (lo) interface
+          will always be accepted.
         '';
     };
 
     networking.firewall.allowedTCPPorts = mkOption {
-      default = [];
-      example = [ 22 80 ];
       type = types.listOf types.int;
+      default = [ ];
+      example = [ 22 80 ];
       description =
         ''
           List of TCP ports on which incoming connections are
@@ -318,9 +336,9 @@ in
     };
 
     networking.firewall.allowedTCPPortRanges = mkOption {
-      default = [];
-      example = [ { from = 8999; to = 9003; } ];
       type = types.listOf (types.attrsOf types.int);
+      default = [ ];
+      example = [ { from = 8999; to = 9003; } ];
       description =
         ''
           A range of TCP ports on which incoming connections are
@@ -329,9 +347,9 @@ in
     };
 
     networking.firewall.allowedUDPPorts = mkOption {
-      default = [];
-      example = [ 53 ];
       type = types.listOf types.int;
+      default = [ ];
+      example = [ 53 ];
       description =
         ''
           List of open UDP ports.
@@ -339,9 +357,9 @@ in
     };
 
     networking.firewall.allowedUDPPortRanges = mkOption {
-      default = [];
-      example = [ { from = 60000; to = 61000; } ];
       type = types.listOf (types.attrsOf types.int);
+      default = [ ];
+      example = [ { from = 60000; to = 61000; } ];
       description =
         ''
           Range of open UDP ports.
@@ -349,8 +367,8 @@ in
     };
 
     networking.firewall.allowPing = mkOption {
-      default = true;
       type = types.bool;
+      default = true;
       description =
         ''
           Whether to respond to incoming ICMPv4 echo requests
@@ -361,36 +379,43 @@ in
     };
 
     networking.firewall.pingLimit = mkOption {
-      default = null;
       type = types.nullOr (types.separatedString " ");
+      default = null;
+      example = "--limit 1/minute --limit-burst 5";
       description =
         ''
           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"
+          on them.  If non-null, this option should be in the form of
+          flags like "--limit 1/minute --limit-burst 5"
         '';
     };
 
     networking.firewall.checkReversePath = mkOption {
-      default = kernelHasRPFilter;
       type = types.either types.bool (types.enum ["strict" "loose"]);
+      default = kernelHasRPFilter;
+      example = "loose";
       description =
         ''
-          Performs a reverse path filter test on a packet.
-          If a reply to the packet would not be sent via the same interface
-          that the packet arrived on, it is refused.
+          Performs a reverse path filter test on a packet.  If a reply
+          to the packet would not be sent via the same interface that
+          the packet arrived on, it is refused.
 
-          If using asymmetric routing or other complicated routing,
-          set this option to loose mode or disable it and setup your
-          own counter-measures.
+          If using asymmetric routing or other complicated routing, set
+          this option to loose mode or disable it and setup your own
+          counter-measures.
+
+          This option can be either true (or "strict"), "loose" (only
+          drop the packet if the source address is not reachable via any
+          interface) or false.  Defaults to the value of
+          kernelHasRPFilter.
 
           (needs kernel 3.3+)
         '';
     };
 
     networking.firewall.logReversePathDrops = mkOption {
-      default = false;
       type = types.bool;
+      default = false;
       description =
         ''
           Logs dropped packets failing the reverse path filter test if
@@ -399,9 +424,9 @@ in
     };
 
     networking.firewall.connectionTrackingModules = mkOption {
-      default = [ "ftp" ];
-      example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
       type = types.listOf types.str;
+      default = [ ];
+      example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
       description =
         ''
           List of connection-tracking helpers that are auto-loaded.
@@ -409,17 +434,19 @@ in
 
           As helpers can pose as a security risk, it is advised to
           set this to an empty list and disable the setting
-          networking.firewall.autoLoadConntrackHelpers
+          networking.firewall.autoLoadConntrackHelpers unless you
+          know what you are doing. Connection tracking is disabled
+          by default.
 
-          Loading of helpers is recommended to be done through the new
-          CT target. More info:
+          Loading of helpers is recommended to be done through the
+          CT target.  More info:
           https://home.regit.org/netfilter-en/secure-use-of-helpers/
         '';
     };
 
     networking.firewall.autoLoadConntrackHelpers = mkOption {
-      default = true;
       type = types.bool;
+      default = false;
       description =
         ''
           Whether to auto-load connection-tracking helpers.
@@ -461,7 +488,8 @@ in
         ''
           Additional shell commands executed as part of the firewall
           shutdown script.  These are executed just after the removal
-          of the nixos input rule, or if the service enters a failed state.
+          of the NixOS input rule, or if the service enters a failed
+          state.
         '';
     };
 
@@ -478,15 +506,14 @@ in
 
     environment.systemPackages = [ pkgs.iptables ] ++ cfg.extraPackages;
 
-    boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
-    boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
-      options nf_conntrack nf_conntrack_helper=0
+    boot.kernelModules = (optional cfg.autoLoadConntrackHelpers "nf_conntrack")
+      ++ map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
+    boot.extraModprobeConfig = optionalString cfg.autoLoadConntrackHelpers ''
+      options nf_conntrack nf_conntrack_helper=1
     '';
 
     assertions = [ { assertion = (cfg.checkReversePath != false) || kernelHasRPFilter;
                      message = "This kernel does not support rpfilter"; }
-                   { assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers;
-                     message = "This kernel does not support disabling conntrack helpers"; }
                  ];
 
     systemd.services.firewall = {
@@ -499,7 +526,7 @@ in
       path = [ pkgs.iptables ] ++ cfg.extraPackages;
 
       # FIXME: this module may also try to load kernel modules, but
-      # containers don't have CAP_SYS_MODULE. So the host system had
+      # containers don't have CAP_SYS_MODULE.  So the host system had
       # better have all necessary modules already loaded.
       unitConfig.ConditionCapability = "CAP_NET_ADMIN";
       unitConfig.DefaultDependencies = false;
diff --git a/nixos/modules/services/networking/flannel.nix b/nixos/modules/services/networking/flannel.nix
index ca47a18bc1f..b93e28e34ef 100644
--- a/nixos/modules/services/networking/flannel.nix
+++ b/nixos/modules/services/networking/flannel.nix
@@ -149,6 +149,6 @@ in {
       serviceConfig.ExecStart = "${cfg.package}/bin/flannel";
     };
 
-    services.etcd.enable = mkDefault cfg.etcd.endpoints == ["http://127.0.0.1:2379"];
+    services.etcd.enable = mkDefault (cfg.etcd.endpoints == ["http://127.0.0.1:2379"]);
   };
 }
diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix
new file mode 100644
index 00000000000..18e2ab9aebf
--- /dev/null
+++ b/nixos/modules/services/networking/kresd.nix
@@ -0,0 +1,119 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.kresd;
+  package = pkgs.knot-resolver;
+
+  configFile = pkgs.writeText "kresd.conf" cfg.extraConfig;
+in
+
+{
+  meta.maintainers = [ maintainers.vcunat /* upstream developer */ ];
+
+  ###### interface
+  options.services.kresd = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to enable knot-resolver domain name server.
+        DNSSEC validation is turned on by default.
+        You can run <literal>sudo nc -U /run/kresd/control</literal>
+        and give commands interactively to kresd.
+      '';
+    };
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = ''
+        Extra lines to be added verbatim to the generated configuration file.
+      '';
+    };
+    cacheDir = mkOption {
+      type = types.path;
+      default = "/var/cache/kresd";
+      description = ''
+        Directory for caches.  They are intended to survive reboots.
+      '';
+    };
+    interfaces = mkOption {
+      type = with types; listOf str;
+      default = [ "::1" "127.0.0.1" ];
+      description = ''
+        What addresses the server should listen on.
+      '';
+    };
+    # TODO: perhaps options for more common stuff like cache size or forwarding
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    environment.etc."kresd.conf".source = configFile; # not required
+
+    users.extraUsers = singleton
+      { name = "kresd";
+        uid = config.ids.uids.kresd;
+        group = "kresd";
+        description = "Knot-resolver daemon user";
+      };
+    users.extraGroups = singleton
+      { name = "kresd";
+        gid = config.ids.gids.kresd;
+      };
+
+    systemd.sockets.kresd = rec {
+      wantedBy = [ "sockets.target" ];
+      before = wantedBy;
+      listenStreams = map
+        # Syntax depends on being IPv6 or IPv4.
+        (iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53")
+        cfg.interfaces;
+      socketConfig.ListenDatagram = listenStreams;
+    };
+
+    systemd.sockets.kresd-control = rec {
+      wantedBy = [ "sockets.target" ];
+      before = wantedBy;
+      partOf = [ "kresd.socket" ];
+      listenStreams = [ "/run/kresd/control" ];
+      socketConfig = {
+        FileDescriptorName = "control";
+        Service = "kresd.service";
+        SocketMode = "0660"; # only root user/group may connect
+      };
+    };
+
+    # Create the cacheDir; tmpfiles don't work on nixos-rebuild switch.
+    systemd.services.kresd-cachedir = {
+      serviceConfig.Type = "oneshot";
+      script = ''
+        if [ ! -d '${cfg.cacheDir}' ]; then
+          mkdir -p '${cfg.cacheDir}'
+          chown kresd:kresd '${cfg.cacheDir}'
+        fi
+      '';
+    };
+
+    systemd.services.kresd = {
+      description = "Knot-resolver daemon";
+
+      serviceConfig = {
+        User = "kresd";
+        Type = "notify";
+        WorkingDirectory = cfg.cacheDir;
+      };
+
+      script = ''
+        exec '${package}/bin/kresd' --config '${configFile}' \
+          -k '${cfg.cacheDir}/root.key'
+      '';
+
+      after = [ "kresd-cachedir.service" ];
+      requires = [ "kresd.socket" "kresd-cachedir.service" ];
+      wantedBy = [ "sockets.target" ];
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/miredo.nix b/nixos/modules/services/networking/miredo.nix
index 932d6cf2903..3d560338e2c 100644
--- a/nixos/modules/services/networking/miredo.nix
+++ b/nixos/modules/services/networking/miredo.nix
@@ -82,7 +82,6 @@ in
       serviceConfig = {
         Restart = "always";
         RestartSec = "5s";
-        ExecStartPre = "${cfg.package}/bin/miredo-checkconf -f ${miredoConf}";
         ExecStart = "${cfg.package}/bin/miredo -c ${miredoConf} -p ${pidFile} -f";
         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
       };
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 8f353979d3f..c11d4434c20 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -174,7 +174,7 @@ in {
 
     assertions = [{
       assertion = config.networking.wireless.enable == false;
-      message = "You can not use networking.networkmanager with services.networking.wireless";
+      message = "You can not use networking.networkmanager with networking.wireless";
     }];
 
     boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections.
@@ -239,7 +239,8 @@ in {
     # Turn off NixOS' network management
     networking = {
       useDHCP = false;
-      wireless.enable = false;
+      # use mkDefault to trigger the assertion about the conflict above
+      wireless.enable = lib.mkDefault false;
     };
 
     powerManagement.resumeCommands = ''
diff --git a/nixos/modules/services/networking/pdns-recursor.nix b/nixos/modules/services/networking/pdns-recursor.nix
new file mode 100644
index 00000000000..26be72d2a61
--- /dev/null
+++ b/nixos/modules/services/networking/pdns-recursor.nix
@@ -0,0 +1,168 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  dataDir  = "/var/lib/pdns-recursor";
+  username = "pdns-recursor";
+
+  cfg   = config.services.pdns-recursor;
+  zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
+
+  configFile = pkgs.writeText "recursor.conf" ''
+    local-address=${cfg.dns.address}
+    local-port=${toString cfg.dns.port}
+    allow-from=${concatStringsSep "," cfg.dns.allowFrom}
+
+    webserver-address=${cfg.api.address}
+    webserver-port=${toString cfg.api.port}
+    webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom}
+
+    forward-zones=${concatStringsSep "," zones}
+    export-etc-hosts=${if cfg.exportHosts then "yes" else "no"}
+    dnssec=${cfg.dnssecValidation}
+    serve-rfc1918=${if cfg.serveRFC1918 then "yes" else "no"}
+
+    ${cfg.extraConfig}
+  '';
+
+in {
+  options.services.pdns-recursor = {
+    enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server";
+
+    dns.address = mkOption {
+      type = types.str;
+      default = "0.0.0.0";
+      description = ''
+        IP address Recursor DNS server will bind to.
+      '';
+    };
+
+    dns.port = mkOption {
+      type = types.int;
+      default = 53;
+      description = ''
+        Port number Recursor DNS server will bind to.
+      '';
+    };
+
+    dns.allowFrom = mkOption {
+      type = types.listOf types.str;
+      default = [ "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" ];
+      example = [ "0.0.0.0/0" ];
+      description = ''
+        IP address ranges of clients allowed to make DNS queries.
+      '';
+    };
+
+    api.address = mkOption {
+      type = types.str;
+      default = "0.0.0.0";
+      description = ''
+        IP address Recursor REST API server will bind to.
+      '';
+    };
+
+    api.port = mkOption {
+      type = types.int;
+      default = 8082;
+      description = ''
+        Port number Recursor REST API server will bind to.
+      '';
+    };
+
+    api.allowFrom = mkOption {
+      type = types.listOf types.str;
+      default = [ "0.0.0.0/0" ];
+      description = ''
+        IP address ranges of clients allowed to make API requests.
+      '';
+    };
+
+    exportHosts = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+       Whether to export names and IP addresses defined in /etc/hosts.
+      '';
+    };
+
+    forwardZones = mkOption {
+      type = types.attrs;
+      example = { eth = "127.0.0.1:5353"; };
+      default = {};
+      description = ''
+        DNS zones to be forwarded to other servers.
+      '';
+    };
+
+    dnssecValidation = mkOption {
+      type = types.enum ["off" "process-no-validate" "process" "log-fail" "validate"];
+      default = "validate";
+      description = ''
+        Controls the level of DNSSEC processing done by the PowerDNS Recursor.
+        See https://doc.powerdns.com/md/recursor/dnssec/ for a detailed explanation.
+      '';
+    };
+
+    serveRFC1918 = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether to directly resolve the RFC1918 reverse-mapping domains:
+        <literal>10.in-addr.arpa</literal>,
+        <literal>168.192.in-addr.arpa</literal>,
+        <literal>16-31.172.in-addr.arpa</literal>
+        This saves load on the AS112 servers.
+      '';
+    };
+
+    extraConfig = mkOption {
+      type = types.lines;
+      default = "";
+      description = ''
+        Extra options to be appended to the configuration file.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    users.extraUsers."${username}" = {
+      home = dataDir;
+      createHome = true;
+      uid = config.ids.uids.pdns-recursor;
+      description = "PowerDNS Recursor daemon user";
+    };
+
+    systemd.services.pdns-recursor = {
+      unitConfig.Documentation = "man:pdns_recursor(1) man:rec_control(1)";
+      description = "PowerDNS recursive server";
+      wantedBy = [ "multi-user.target" ];
+      after    = [ "network.target" ];
+
+      serviceConfig = {
+        User = username;
+        Restart    ="on-failure";
+        RestartSec = "5";
+        PrivateTmp = true;
+        PrivateDevices = true;
+        AmbientCapabilities = "cap_net_bind_service";
+        ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \
+          --config-dir=${dataDir} \
+          --socket-dir=${dataDir} \
+          --disable-syslog
+        '';
+      };
+
+      preStart = ''
+        # Link configuration file into recursor home directory
+        configPath=${dataDir}/recursor.conf
+        if [ "$(realpath $configPath)" != "${configFile}" ]; then
+          rm -f $configPath
+          ln -s ${configFile} $configPath
+        fi
+      '';
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix
index 6d2f5f8d41f..67aa313c860 100644
--- a/nixos/modules/services/networking/smokeping.nix
+++ b/nixos/modules/services/networking/smokeping.nix
@@ -275,7 +275,14 @@ in
     ];
     security.permissionsWrappers.setuid = [
       { program = "fping";
-        source  = "${e.enlightenment.out}/bin/fping";
+        source  = "${pkgs.fping}/bin/fping";
+        owner   = "root";
+        group   = "root";
+        setuid  = true;
+      }
+
+      { program = "fping";
+        source  = "${pkgs.fping}/bin/fping6";
         owner   = "root";
         group   = "root";
         setuid  = true;
diff --git a/nixos/modules/services/security/clamav.nix b/nixos/modules/services/security/clamav.nix
index b045e140546..f71f30fee97 100644
--- a/nixos/modules/services/security/clamav.nix
+++ b/nixos/modules/services/security/clamav.nix
@@ -81,6 +81,7 @@ in
     users.extraUsers = singleton {
       name = clamavUser;
       uid = config.ids.uids.clamav;
+      group = clamavGroup;
       description = "ClamAV daemon user";
       home = stateDir;
     };
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index 32dd4439675..26f0bdec655 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -6,7 +6,7 @@ with lib;
 let
 
   # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix
-  version = "4.6.1";
+  version = "4.7.1";
   fullversion = "${version}";
 
   # Our bare-bones wp-config.php file using the above settings
@@ -75,7 +75,7 @@ let
       owner = "WordPress";
       repo = "WordPress";
       rev = "${fullversion}";
-      sha256 = "0n82xgjg1ry2p73hhgpslnkdzrma5n6hxxq76s7qskkzj0qjfvpn";
+      sha256 = "1wb4f4zn55d23qi0whsfpbpcd4sjvzswgmni6f5rzrmlawq9ssgr";
     };
     installPhase = ''
       mkdir -p $out
diff --git a/nixos/modules/services/web-servers/caddy.nix b/nixos/modules/services/web-servers/caddy.nix
index 0666dfddaff..619e0f90b12 100644
--- a/nixos/modules/services/web-servers/caddy.nix
+++ b/nixos/modules/services/web-servers/caddy.nix
@@ -39,6 +39,13 @@ in
       type = types.path;
       description = "The data directory, for storing certificates.";
     };
+
+    package = mkOption {
+      default = pkgs.caddy;
+      defaultText = "pkgs.caddy";
+      type = types.package;
+      description = "Caddy package to use.";
+    };
   };
 
   config = mkIf cfg.enable {
@@ -47,7 +54,7 @@ in
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
-        ExecStart = ''${pkgs.caddy.bin}/bin/caddy -conf=${configFile} \
+        ExecStart = ''${cfg.package.bin}/bin/caddy -conf=${configFile} \
           -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
         '';
         Type = "simple";
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 68a672c42c9..c9eacdd85dc 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -5,7 +5,11 @@ with lib;
 let
   cfg = config.services.nginx;
   virtualHosts = mapAttrs (vhostName: vhostConfig:
-    vhostConfig // (optionalAttrs vhostConfig.enableACME {
+    vhostConfig // {
+      serverName = if vhostConfig.serverName != null
+        then vhostConfig.serverName
+        else vhostName;
+    } // (optionalAttrs vhostConfig.enableACME {
       sslCertificate = "/var/lib/acme/${vhostName}/fullchain.pem";
       sslCertificateKey = "/var/lib/acme/${vhostName}/key.pem";
     })
@@ -112,8 +116,9 @@ let
     ${cfg.appendConfig}
   '';
 
-  vhosts = concatStringsSep "\n" (mapAttrsToList (serverName: vhost:
+  vhosts = concatStringsSep "\n" (mapAttrsToList (vhostName: vhost:
       let
+        serverName = vhost.serverName;
         ssl = vhost.enableSSL || vhost.forceSSL;
         port = if vhost.port != null then vhost.port else (if ssl then 443 else 80);
         listenString = toString port + optionalString ssl " ssl http2"
@@ -161,7 +166,7 @@ let
             ssl_certificate_key ${vhost.sslCertificateKey};
           ''}
 
-          ${optionalString (vhost.basicAuth != {}) (mkBasicAuth serverName vhost.basicAuth)}
+          ${optionalString (vhost.basicAuth != {}) (mkBasicAuth vhostName vhost.basicAuth)}
 
           ${mkLocations vhost.locations}
 
@@ -178,8 +183,8 @@ let
       ${config.extraConfig}
     }
   '') locations);
-  mkBasicAuth = serverName: authDef: let
-    htpasswdFile = pkgs.writeText "${serverName}.htpasswd" (
+  mkBasicAuth = vhostName: authDef: let
+    htpasswdFile = pkgs.writeText "${vhostName}.htpasswd" (
       concatStringsSep "\n" (mapAttrsToList (user: password: ''
         ${user}:{PLAIN}${password}
       '') authDef)
@@ -393,17 +398,20 @@ in
     };
 
     security.acme.certs = filterAttrs (n: v: v != {}) (
-      mapAttrs (vhostName: vhostConfig:
-        optionalAttrs vhostConfig.enableACME {
-          user = cfg.user;
-          group = cfg.group;
-          webroot = vhostConfig.acmeRoot;
-          extraDomains = genAttrs vhostConfig.serverAliases (alias: null);
-          postRun = ''
-            systemctl reload nginx
-          '';
-        }
-      ) virtualHosts
+      let
+        vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts;
+        acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs;
+        acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = {
+            user = cfg.user;
+            group = cfg.group;
+            webroot = vhostConfig.acmeRoot;
+            extraDomains = genAttrs vhostConfig.serverAliases (alias: null);
+            postRun = ''
+              systemctl reload nginx
+            '';
+          }; }) acmeEnabledVhosts;
+      in
+        listToAttrs acmePairs
     );
 
     users.extraUsers = optionalAttrs (cfg.user == "nginx") (singleton
diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix
index dcebbc9229f..c0ea645b3df 100644
--- a/nixos/modules/services/web-servers/nginx/vhost-options.nix
+++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix
@@ -8,6 +8,15 @@
 with lib;
 {
   options = {
+    serverName = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Name of this virtual host. Defaults to attribute name in virtualHosts.
+      '';
+      example = "example.org";
+    };
+
     serverAliases = mkOption {
       type = types.listOf types.str;
       default = [];
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 3037f949cbf..f886c60793d 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -228,6 +228,8 @@ in
       # Enable helpful DBus services.
       services.udisks2.enable = true;
       services.upower.enable = config.powerManagement.enable;
+      services.dbus.packages =
+        mkIf config.services.printing.enable [ pkgs.system-config-printer ];
 
       # Extra UDEV rules used by Solid
       services.udev.packages = [
@@ -246,6 +248,11 @@ in
 
       security.pam.services.kde = { allowNullPassword = true; };
 
+      # use kimpanel as the default IBus panel
+      i18n.inputMethod.ibus.panel =
+        lib.mkDefault
+        "${pkgs.kde5.plasma-desktop}/lib/libexec/kimpanel-ibus-panel";
+
     })
   ];
 
diff --git a/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix
index 68acde85b5d..05b979eef47 100644
--- a/nixos/modules/services/x11/display-managers/slim.nix
+++ b/nixos/modules/services/x11/display-managers/slim.nix
@@ -20,6 +20,7 @@ let
       ${optionalString (cfg.defaultUser != null) ("default_user " + cfg.defaultUser)}
       ${optionalString (cfg.defaultUser != null) ("focus_password yes")}
       ${optionalString cfg.autoLogin "auto_login yes"}
+      ${optionalString (cfg.consoleCmd != null) "console_cmd ${cfg.consoleCmd}"}
       ${cfg.extraConfig}
     '';
 
@@ -105,6 +106,18 @@ in
         '';
       };
 
+      consoleCmd = mkOption {
+        type = types.nullOr types.str;
+        default = ''
+          ${pkgs.xterm}/bin/xterm -C -fg white -bg black +sb -T "Console login" -e ${pkgs.shadow}/bin/login
+        '';
+        defaultText = ''
+          ''${pkgs.xterm}/bin/xterm -C -fg white -bg black +sb -T "Console login" -e ''${pkgs.shadow}/bin/login
+        '';
+        description = ''
+          The command to run when "console" is given as the username.
+        '';
+      };
     };
 
   };
diff --git a/nixos/modules/services/x11/terminal-server.nix b/nixos/modules/services/x11/terminal-server.nix
index 09d0ab07751..785394d9648 100644
--- a/nixos/modules/services/x11/terminal-server.nix
+++ b/nixos/modules/services/x11/terminal-server.nix
@@ -41,7 +41,7 @@ with lib;
       { description = "Terminal Server";
 
         path =
-          [ pkgs.xorgserver.out pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth
+          [ pkgs.xorg.xorgserver.out pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth
             pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash
           ];
 
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index 515136c904c..b91d64bb0a7 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -28,6 +28,8 @@ def write_loader_conf(generation):
         if "@timeout@" != "":
             f.write("timeout @timeout@\n")
         f.write("default nixos-generation-%d\n" % generation)
+        if not @editor@:
+            f.write("editor 0");
     os.rename("@efiSysMountPoint@/loader/loader.conf.tmp", "@efiSysMountPoint@/loader/loader.conf")
 
 def copy_from_profile(generation, name, dry_run=False):
diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index cc43fb8bab4..ec02f73cada 100644
--- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -20,6 +20,8 @@ let
 
     timeout = if config.boot.loader.timeout != null then config.boot.loader.timeout else "";
 
+    editor = if cfg.editor then "True" else "False";
+
     inherit (efi) efiSysMountPoint canTouchEfiVariables;
   };
 in {
@@ -36,6 +38,20 @@ in {
 
       description = "Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager";
     };
+
+    editor = mkOption {
+      default = true;
+
+      type = types.bool;
+
+      description = ''
+        Whether to allow editing the kernel command-line before
+        boot. It is recommended to set this to false, as it allows
+        gaining root access by passing init=/bin/sh as a kernel
+        parameter. However, it is enabled by default for backwards
+        compatibility.
+      '';
+    };
   };
 
   config = mkIf cfg.enable {
diff --git a/nixos/modules/virtualisation/ec2-amis.nix b/nixos/modules/virtualisation/ec2-amis.nix
index ffd1cbec3ce..0753e2ce994 100644
--- a/nixos/modules/virtualisation/ec2-amis.nix
+++ b/nixos/modules/virtualisation/ec2-amis.nix
@@ -135,51 +135,59 @@ let self = {
   "16.03".us-west-2.pv-ebs = "ami-5e61a23e";
   "16.03".us-west-2.pv-s3 = "ami-734c8f13";
 
-  # 16.09.666.3738950
-  "16.09".ap-northeast-1.hvm-ebs = "ami-35578954";
-  "16.09".ap-northeast-1.hvm-s3 = "ami-d6528cb7";
-  "16.09".ap-northeast-1.pv-ebs = "ami-07548a66";
-  "16.09".ap-northeast-1.pv-s3 = "ami-f1548a90";
-  "16.09".ap-northeast-2.hvm-ebs = "ami-d48753ba";
-  "16.09".ap-northeast-2.hvm-s3 = "ami-4c865222";
-  "16.09".ap-northeast-2.pv-ebs = "ami-ca8551a4";
-  "16.09".ap-northeast-2.pv-s3 = "ami-9c8551f2";
-  "16.09".ap-south-1.hvm-ebs = "ami-922450fd";
-  "16.09".ap-south-1.hvm-s3 = "ami-6d3a4e02";
-  "16.09".ap-south-1.pv-ebs = "ami-4d394d22";
-  "16.09".ap-south-1.pv-s3 = "ami-17384c78";
-  "16.09".ap-southeast-1.hvm-ebs = "ami-f824809b";
-  "16.09".ap-southeast-1.hvm-s3 = "ami-f924809a";
-  "16.09".ap-southeast-1.pv-ebs = "ami-af2480cc";
-  "16.09".ap-southeast-1.pv-s3 = "ami-5826823b";
-  "16.09".ap-southeast-2.hvm-ebs = "ami-40fecd23";
-  "16.09".ap-southeast-2.hvm-s3 = "ami-48fecd2b";
-  "16.09".ap-southeast-2.pv-ebs = "ami-dffecdbc";
-  "16.09".ap-southeast-2.pv-s3 = "ami-e0fccf83";
-  "16.09".eu-central-1.hvm-ebs = "ami-1d8b7472";
-  "16.09".eu-central-1.hvm-s3 = "ami-1c8b7473";
-  "16.09".eu-central-1.pv-ebs = "ami-8c8d72e3";
-  "16.09".eu-central-1.pv-s3 = "ami-3488775b";
-  "16.09".eu-west-1.hvm-ebs = "ami-15662766";
-  "16.09".eu-west-1.hvm-s3 = "ami-476b2a34";
-  "16.09".eu-west-1.pv-ebs = "ami-876928f4";
-  "16.09".eu-west-1.pv-s3 = "ami-70682903";
-  "16.09".sa-east-1.hvm-ebs = "ami-27bc2e4b";
-  "16.09".sa-east-1.hvm-s3 = "ami-e4b92b88";
-  "16.09".sa-east-1.pv-ebs = "ami-4dbe2c21";
-  "16.09".sa-east-1.pv-s3 = "ami-77fc6e1b";
-  "16.09".us-east-1.hvm-ebs = "ami-93347684";
-  "16.09".us-east-1.hvm-s3 = "ami-5e347649";
-  "16.09".us-east-1.pv-ebs = "ami-b0387aa7";
-  "16.09".us-east-1.pv-s3 = "ami-51357746";
-  "16.09".us-west-1.hvm-ebs = "ami-06337a66";
-  "16.09".us-west-1.hvm-s3 = "ami-76307916";
-  "16.09".us-west-1.pv-ebs = "ami-fd327b9d";
-  "16.09".us-west-1.pv-s3 = "ami-cc347dac";
-  "16.09".us-west-2.hvm-ebs = "ami-49fe2729";
-  "16.09".us-west-2.hvm-s3 = "ami-93fc25f3";
-  "16.09".us-west-2.pv-ebs = "ami-14fe2774";
-  "16.09".us-west-2.pv-s3 = "ami-74f12814";
+  # 16.09.1508.3909827
+  "16.09".ap-northeast-1.hvm-ebs = "ami-68453b0f";
+  "16.09".ap-northeast-1.hvm-s3 = "ami-f9bec09e";
+  "16.09".ap-northeast-1.pv-ebs = "ami-254a3442";
+  "16.09".ap-northeast-1.pv-s3 = "ami-ef473988";
+  "16.09".ap-northeast-2.hvm-ebs = "ami-18ae7f76";
+  "16.09".ap-northeast-2.hvm-s3 = "ami-9eac7df0";
+  "16.09".ap-northeast-2.pv-ebs = "ami-57aa7b39";
+  "16.09".ap-northeast-2.pv-s3 = "ami-5cae7f32";
+  "16.09".ap-south-1.hvm-ebs = "ami-b3f98fdc";
+  "16.09".ap-south-1.hvm-s3 = "ami-98e690f7";
+  "16.09".ap-south-1.pv-ebs = "ami-aef98fc1";
+  "16.09".ap-south-1.pv-s3 = "ami-caf88ea5";
+  "16.09".ap-southeast-1.hvm-ebs = "ami-80fb51e3";
+  "16.09".ap-southeast-1.hvm-s3 = "ami-2df3594e";
+  "16.09".ap-southeast-1.pv-ebs = "ami-37f05a54";
+  "16.09".ap-southeast-1.pv-s3 = "ami-27f35944";
+  "16.09".ap-southeast-2.hvm-ebs = "ami-57ece834";
+  "16.09".ap-southeast-2.hvm-s3 = "ami-87f4f0e4";
+  "16.09".ap-southeast-2.pv-ebs = "ami-d8ede9bb";
+  "16.09".ap-southeast-2.pv-s3 = "ami-a6ebefc5";
+  "16.09".eu-central-1.hvm-ebs = "ami-1b884774";
+  "16.09".eu-central-1.hvm-s3 = "ami-b08c43df";
+  "16.09".eu-central-1.pv-ebs = "ami-888946e7";
+  "16.09".eu-central-1.pv-s3 = "ami-06874869";
+  "16.09".eu-west-1.hvm-ebs = "ami-1ed3e76d";
+  "16.09".eu-west-1.hvm-s3 = "ami-73d1e500";
+  "16.09".eu-west-1.pv-ebs = "ami-44c0f437";
+  "16.09".eu-west-1.pv-s3 = "ami-f3d8ec80";
+  "16.09".eu-west-2.hvm-ebs = "ami-2c9c9648";
+  "16.09".eu-west-2.hvm-s3 = "ami-6b9e940f";
+  "16.09".eu-west-2.pv-ebs = "ami-f1999395";
+  "16.09".eu-west-2.pv-s3 = "ami-bb9f95df";
+  "16.09".sa-east-1.hvm-ebs = "ami-a11882cd";
+  "16.09".sa-east-1.hvm-s3 = "ami-7726bc1b";
+  "16.09".sa-east-1.pv-ebs = "ami-9725bffb";
+  "16.09".sa-east-1.pv-s3 = "ami-b027bddc";
+  "16.09".us-east-1.hvm-ebs = "ami-854ca593";
+  "16.09".us-east-1.hvm-s3 = "ami-2241a834";
+  "16.09".us-east-1.pv-ebs = "ami-a441a8b2";
+  "16.09".us-east-1.pv-s3 = "ami-e841a8fe";
+  "16.09".us-east-2.hvm-ebs = "ami-3f41645a";
+  "16.09".us-east-2.hvm-s3 = "ami-804065e5";
+  "16.09".us-east-2.pv-ebs = "ami-f1466394";
+  "16.09".us-east-2.pv-s3 = "ami-05426760";
+  "16.09".us-west-1.hvm-ebs = "ami-c2efbca2";
+  "16.09".us-west-1.hvm-s3 = "ami-d71042b7";
+  "16.09".us-west-1.pv-ebs = "ami-04e8bb64";
+  "16.09".us-west-1.pv-s3 = "ami-31e9ba51";
+  "16.09".us-west-2.hvm-ebs = "ami-6449f504";
+  "16.09".us-west-2.hvm-s3 = "ami-344af654";
+  "16.09".us-west-2.pv-ebs = "ami-6d4af60d";
+  "16.09".us-west-2.pv-s3 = "ami-de48f4be";
 
   latest = self."16.09";
 }; in self