summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-1703.xml8
-rw-r--r--nixos/modules/config/networking.nix2
-rw-r--r--nixos/modules/hardware/opengl.nix2
-rw-r--r--nixos/modules/i18n/input-method/default.nix2
-rw-r--r--nixos/modules/misc/ids.nix4
-rw-r--r--nixos/modules/module-list.nix6
-rw-r--r--nixos/modules/programs/bash/bash.nix2
-rw-r--r--nixos/modules/programs/zsh/zsh.nix6
-rw-r--r--nixos/modules/rename.nix3
-rw-r--r--nixos/modules/services/backup/rsnapshot.nix3
-rw-r--r--nixos/modules/services/continuous-integration/gitlab-runner.nix51
-rw-r--r--nixos/modules/services/mail/offlineimap.nix (renamed from nixos/modules/services/networking/offlineimap.nix)2
-rw-r--r--nixos/modules/services/misc/gitlab.nix18
-rw-r--r--nixos/modules/services/misc/nix-optimise.nix49
-rw-r--r--nixos/modules/services/networking/connman.nix12
-rw-r--r--nixos/modules/services/networking/htpdate.nix80
-rw-r--r--nixos/modules/services/networking/murmur.nix4
-rw-r--r--nixos/modules/services/networking/nsd.nix58
-rw-r--r--nixos/modules/services/networking/radicale.nix4
-rw-r--r--nixos/modules/services/web-apps/selfoss.nix166
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/mediawiki.nix6
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/moodle.nix4
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/wordpress.nix11
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix19
-rw-r--r--nixos/modules/system/activation/activation-script.nix9
-rw-r--r--nixos/modules/system/boot/loader/grub/grub.nix2
-rw-r--r--nixos/modules/system/boot/stage-1.nix7
-rw-r--r--nixos/modules/system/boot/stage-2-init.sh10
-rw-r--r--nixos/modules/tasks/filesystems.nix5
-rw-r--r--nixos/modules/virtualisation/containers.nix2
-rw-r--r--nixos/tests/wordpress.nix60
31 files changed, 562 insertions, 55 deletions
diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml
index 2eda8a56b202..9bc42edb49bc 100644
--- a/nixos/doc/manual/release-notes/rl-1703.xml
+++ b/nixos/doc/manual/release-notes/rl-1703.xml
@@ -35,6 +35,14 @@ following incompatible changes:</para>
       Now you need to use versioned attributes, like <literal>gnome3</literal>.
     </para>
   </listitem>
+
+  <listitem>
+    <para>
+      The attribute name of the Radicale daemon has been changed from
+      <literal>pythonPackages.radicale</literal> to
+      <literal>radicale</literal>.
+    </para>
+  </listitem>
 </itemizedlist>
 
 
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index aab5523c6848..952f62569c93 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -232,7 +232,7 @@ in
     # and other configurations. If the file is destroyed by an environment
     # activation then it must be rebuilt so that applications which interface
     # with /etc/resolv.conf directly don't break.
-    system.activationScripts.resolvconf = stringAfter [ "etc" "tmpfs" "var" ]
+    system.activationScripts.resolvconf = stringAfter [ "etc" "specialfs" "var" ]
       ''
         # Systemd resolved controls its own resolv.conf
         rm -f /run/resolvconf/interfaces/systemd
diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix
index 0bc574d48190..bef500e30c0b 100644
--- a/nixos/modules/hardware/opengl.nix
+++ b/nixos/modules/hardware/opengl.nix
@@ -14,7 +14,7 @@ let
     name = "mesa-drivers+txc-${p.mesa_drivers.version}";
     paths =
       [ p.mesa_drivers
-        p.mesa_noglu # mainly for libGL
+        p.mesa_drivers.out # mainly for libGL
         (if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
       ];
   };
diff --git a/nixos/modules/i18n/input-method/default.nix b/nixos/modules/i18n/input-method/default.nix
index f3e568f1dde3..693e1df66c6c 100644
--- a/nixos/modules/i18n/input-method/default.nix
+++ b/nixos/modules/i18n/input-method/default.nix
@@ -7,7 +7,7 @@ let
     preferLocalBuild = true; 
     allowSubstitutes = false;
     name = "gtk2-immodule.cache";
-    buildInputs = [ pkgs.gtk cfg.package ];
+    buildInputs = [ pkgs.gtk2 cfg.package ];
     buildCommand = ''
       mkdir -p $out/etc/gtk-2.0/
       GTK_PATH=${cfg.package}/lib/gtk-2.0/ gtk-query-immodules-2.0 > $out/etc/gtk-2.0/immodules.cache
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 13a7323e858e..e005c0465042 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -119,7 +119,6 @@
       minidlna = 91;
       elasticsearch = 92;
       tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice.
-      #connman = 94; # unused
       firebird = 95;
       #keys = 96; # unused
       haproxy = 97;
@@ -275,6 +274,7 @@
       mattermost = 254;
       prometheus = 255;
       telegraf = 256;
+      gitlab-runner = 257;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -376,7 +376,6 @@
       minidlna = 91;
       elasticsearch = 92;
       #tcpcryptd = 93; # unused
-      connman = 94;
       firebird = 95;
       keys = 96;
       haproxy = 97;
@@ -520,6 +519,7 @@
       mattermost = 254;
       prometheus = 255;
       #telegraf = 256; # unused
+      gitlab-runner = 257;
 
       # 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/module-list.nix b/nixos/modules/module-list.nix
index 7064dcd968ae..ad3edd6fbd5b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -133,6 +133,7 @@
   ./services/computing/slurm/slurm.nix
   ./services/continuous-integration/buildkite-agent.nix
   ./services/continuous-integration/hydra/default.nix
+  ./services/continuous-integration/gitlab-runner.nix
   ./services/continuous-integration/gocd-agent/default.nix
   ./services/continuous-integration/gocd-server/default.nix
   ./services/continuous-integration/jenkins/default.nix
@@ -210,6 +211,7 @@
   ./services/mail/freepops.nix
   ./services/mail/mail.nix
   ./services/mail/mlmmj.nix
+  ./services/mail/offlineimap.nix
   ./services/mail/opendkim.nix
   ./services/mail/opensmtpd.nix
   ./services/mail/postfix.nix
@@ -250,6 +252,7 @@
   ./services/misc/mwlib.nix
   ./services/misc/nix-daemon.nix
   ./services/misc/nix-gc.nix
+  ./services/misc/nix-optimise.nix
   ./services/misc/nixos-manual.nix
   ./services/misc/nix-ssh-serve.nix
   ./services/misc/nzbget.nix
@@ -354,6 +357,7 @@
   ./services/networking/haproxy.nix
   ./services/networking/heyefi.nix
   ./services/networking/hostapd.nix
+  ./services/networking/htpdate.nix
   ./services/networking/i2pd.nix
   ./services/networking/i2p.nix
   ./services/networking/iodine.nix
@@ -380,7 +384,6 @@
   ./services/networking/ntopng.nix
   ./services/networking/ntpd.nix
   ./services/networking/nylon.nix
-  ./services/networking/offlineimap.nix
   ./services/networking/oidentd.nix
   ./services/networking/openfire.nix
   ./services/networking/openntpd.nix
@@ -475,6 +478,7 @@
   ./services/web-apps/mattermost.nix
   ./services/web-apps/pump.io.nix
   ./services/web-apps/tt-rss.nix
+  ./services/web-apps/selfoss.nix
   ./services/web-servers/apache-httpd/default.nix
   ./services/web-servers/caddy.nix
   ./services/web-servers/fcgiwrap.nix
diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix
index c09bcfb70e24..e23849d350b4 100644
--- a/nixos/modules/programs/bash/bash.nix
+++ b/nixos/modules/programs/bash/bash.nix
@@ -16,7 +16,7 @@ let
     # programmable completion. If we do, enable all modules installed in
     # the system (and user profile).
     if shopt -q progcomp &>/dev/null; then
-      . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh"
+      . "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
       nullglobStatus=$(shopt -p nullglob)
       shopt -s nullglob
       for p in $NIX_PROFILES; do
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index 91cd84416921..d81f63c2acca 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -102,9 +102,9 @@ in
 
       interactiveShellInit = ''
         # history defaults
-        export SAVEHIST=2000
-        export HISTSIZE=2000
-        export HISTFILE=$HOME/.zsh_history
+        SAVEHIST=2000
+        HISTSIZE=2000
+        HISTFILE=$HOME/.zsh_history
 
         setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
 
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 34b9724442eb..e597cec6b32d 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -139,6 +139,9 @@ with lib;
     # fontconfig-ultimate
     (mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "rendering" ] [ "fonts" "fontconfig" "ultimate" "preset" ])
 
+    # murmur
+    (mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ])
+
     # Options that are obsolete and have no replacement.
     (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
     (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
diff --git a/nixos/modules/services/backup/rsnapshot.nix b/nixos/modules/services/backup/rsnapshot.nix
index ce628a720363..16815bcc8605 100644
--- a/nixos/modules/services/backup/rsnapshot.nix
+++ b/nixos/modules/services/backup/rsnapshot.nix
@@ -7,11 +7,14 @@ let
   cfgfile = pkgs.writeText "rsnapshot.conf" ''
     config_version	1.2
     cmd_cp	${pkgs.coreutils}/bin/cp
+    cmd_rm	${pkgs.coreutils}/bin/rm
     cmd_rsync	${pkgs.rsync}/bin/rsync
     cmd_ssh	${pkgs.openssh}/bin/ssh
     cmd_logger	${pkgs.inetutils}/bin/logger
     cmd_du	${pkgs.coreutils}/bin/du
+    cmd_rsnapshot_diff	${pkgs.rsnapshot}/bin/rsnapshot-diff
     lockfile	/run/rsnapshot.pid
+    link_dest	1
 
     ${cfg.extraConfig}
   '';
diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix
new file mode 100644
index 000000000000..1fe4d28f9f35
--- /dev/null
+++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix
@@ -0,0 +1,51 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.gitlab-runner;
+  configFile = pkgs.writeText "config.toml" cfg.configText;
+in
+{
+  options.services.gitlab-runner = {
+    enable = mkEnableOption "Gitlab Runner";
+
+    configText = mkOption {
+      description = "Verbatim config.toml to use";
+    };
+
+    workDir = mkOption {
+      default = "/var/lib/gitlab-runner";
+      type = types.path;
+      description = "The working directory used";
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.gitlab-runner = {
+      description = "Gitlab Runner";
+      after = [ "network.target" "docker.service" ];
+      requires = [ "docker.service" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = ''${pkgs.gitlab-runner.bin}/bin/gitlab-runner run \
+          --working-directory ${cfg.workDir} \
+          --config ${configFile} \
+          --service gitlab-runner \
+          --user gitlab-runner \
+        '';
+      };
+    };
+
+    users.extraUsers.gitlab-runner = {
+      group = "gitlab-runner";
+      extraGroups = [ "docker" ];
+      uid = config.ids.uids.gitlab-runner;
+      home = cfg.workDir;
+      createHome = true;
+    };
+
+    users.extraGroups.gitlab-runner.gid = config.ids.gids.gitlab-runner;
+  };
+}
diff --git a/nixos/modules/services/networking/offlineimap.nix b/nixos/modules/services/mail/offlineimap.nix
index daf6196d3706..85ece020905b 100644
--- a/nixos/modules/services/networking/offlineimap.nix
+++ b/nixos/modules/services/mail/offlineimap.nix
@@ -59,7 +59,7 @@ in {
       };
       path = cfg.path;
     };
-    environment.systemPackages = [ "${cfg.package}" ];
+    environment.systemPackages = [ cfg.package ];
     systemd.user.timers.offlineimap = {
       description = "offlineimap timer";
       timerConfig               = {
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index de90d461f527..f8881233dceb 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -449,13 +449,15 @@ in {
         Group = cfg.group;
         TimeoutSec = "300";
         Restart = "on-failure";
+        WorkingDirectory = gitlabEnv.HOME;
         ExecStart =
           "${cfg.packages.gitlab-workhorse}/bin/gitlab-workhorse "
           + "-listenUmask 0 "
           + "-listenNetwork unix "
           + "-listenAddr /run/gitlab/gitlab-workhorse.socket "
           + "-authSocket ${gitlabSocket} "
-          + "-documentRoot ${cfg.packages.gitlab}/share/gitlab/public";
+          + "-documentRoot ${cfg.packages.gitlab}/share/gitlab/public "
+          + "-secretPath ${cfg.packages.gitlab}/share/gitlab/.gitlab_workhorse_secret";
       };
     };
 
@@ -525,11 +527,6 @@ in {
             psql postgres -c "CREATE ROLE gitlab WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'"
             ${config.services.postgresql.package}/bin/createdb --owner gitlab gitlab || true
             touch "${cfg.statePath}/db-created"
-
-            # The gitlab:setup task is horribly broken somehow, these two tasks will do the same for setting up the initial database
-            ${gitlab-rake}/bin/gitlab-rake db:migrate RAILS_ENV=production
-            ${gitlab-rake}/bin/gitlab-rake db:seed_fu RAILS_ENV=production \
-              GITLAB_ROOT_PASSWORD="${cfg.initialRootPassword}" GITLAB_ROOT_EMAIL="${cfg.initialRootEmail}";
           fi
         fi
 
@@ -538,6 +535,15 @@ in {
         # Always do the db migrations just to be sure the database is up-to-date
         ${gitlab-rake}/bin/gitlab-rake db:migrate RAILS_ENV=production
 
+        # The gitlab:setup task is horribly broken somehow, the db:migrate
+        # task above and the db:seed_fu below will do the same for setting
+        # up the initial database
+        if ! test -e "${cfg.statePath}/db-seeded"; then
+          ${gitlab-rake}/bin/gitlab-rake db:seed_fu RAILS_ENV=production \
+            GITLAB_ROOT_PASSWORD="${cfg.initialRootPassword}" GITLAB_ROOT_EMAIL="${cfg.initialRootEmail}"
+          touch "${cfg.statePath}/db-seeded"
+        fi
+
         # Change permissions in the last step because some of the
         # intermediary scripts like to create directories as root.
         chown -R ${cfg.user}:${cfg.group} ${cfg.statePath}
diff --git a/nixos/modules/services/misc/nix-optimise.nix b/nixos/modules/services/misc/nix-optimise.nix
new file mode 100644
index 000000000000..fea322a68f8e
--- /dev/null
+++ b/nixos/modules/services/misc/nix-optimise.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.nix.optimise;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    nix.optimise = {
+
+      automatic = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Automatically run the nix store optimiser at a specific time.";
+      };
+
+      dates = mkOption {
+        default = "03:45";
+        type = types.listOf types.str;
+        description = ''
+          Specification (in the format described by
+          <citerefentry><refentrytitle>systemd.time</refentrytitle>
+          <manvolnum>5</manvolnum></citerefentry>) of the time at
+          which the optimiser will run.
+        '';
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = {
+
+    systemd.services.nix-optimise =
+      { description = "Nix Store Optimiser";
+        serviceConfig.ExecStart = "${config.nix.package}/bin/nix-store --optimise";
+        startAt = optional cfg.automatic cfg.dates;
+      };
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix
index 3fecfbb13a04..d0683b877801 100644
--- a/nixos/modules/services/networking/connman.nix
+++ b/nixos/modules/services/networking/connman.nix
@@ -27,6 +27,14 @@ in {
         '';
       };
 
+      enableVPN = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable ConnMan VPN service.
+        '';
+      };
+
       extraConfig = mkOption {
         type = types.lines;
         default = ''
@@ -78,7 +86,7 @@ in {
       };
     };
 
-    systemd.services."connman-vpn" = {
+    systemd.services."connman-vpn" = mkIf cfg.enableVPN {
       description = "ConnMan VPN service";
       wantedBy = [ "multi-user.target" ];
       after = [ "syslog.target" ];
@@ -91,7 +99,7 @@ in {
       };
     };
 
-    systemd.services."net-connman-vpn" = {
+    systemd.services."net-connman-vpn" = mkIf cfg.enableVPN {
       description = "D-BUS Service";
       serviceConfig = {
         Name = "net.connman.vpn";
diff --git a/nixos/modules/services/networking/htpdate.nix b/nixos/modules/services/networking/htpdate.nix
new file mode 100644
index 000000000000..f5d512c7cd5a
--- /dev/null
+++ b/nixos/modules/services/networking/htpdate.nix
@@ -0,0 +1,80 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  inherit (pkgs) htpdate;
+
+  cfg = config.services.htpdate;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.htpdate = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable htpdate daemon.
+        '';
+      };
+
+      extraOptions = mkOption {
+        type = types.str;
+        default = "";
+        description = ''
+          Additional command line arguments to pass to htpdate.
+        '';
+      };
+
+      servers = mkOption {
+        type = types.listOf types.str;
+        default = [ "www.google.com" ];
+        description = ''
+          HTTP servers to use for time synchronization.
+        '';
+      };
+
+      proxy = mkOption {
+        type = types.str;
+        default = "";
+        example = "127.0.0.1:8118";
+        description = ''
+          HTTP proxy used for requests.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.htpdate = {
+      description = "htpdate daemon";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        Type = "forking";
+        PIDFile = "/var/run/htpdate.pid";
+        ExecStart = concatStringsSep " " [
+          "${htpdate}/bin/htpdate"
+          "-D -u nobody"
+          "-a -s"
+          "-l"
+          "${optionalString (cfg.proxy != "") "-P ${cfg.proxy}"}"
+          "${cfg.extraOptions}"
+          "${concatStringsSep " " cfg.servers}"
+        ];
+      };
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix
index 1cc19a2c9e09..134544cda681 100644
--- a/nixos/modules/services/networking/murmur.nix
+++ b/nixos/modules/services/networking/murmur.nix
@@ -15,7 +15,7 @@ let
     logfile=/var/log/murmur/murmurd.log
     pidfile=${cfg.pidfile}
 
-    welcome="${cfg.welcome}"
+    welcometext="${cfg.welcometext}"
     port=${toString cfg.port}
 
     ${if cfg.hostName == "" then "" else "host="+cfg.hostName}
@@ -84,7 +84,7 @@ in
         description = "Path to PID file for Murmur daemon.";
       };
 
-      welcome = mkOption {
+      welcometext = mkOption {
         type = types.str;
         default = "";
         description = "Welcome message for connected clients.";
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index 333a3378c4cc..6af1dd736431 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -71,6 +71,7 @@ let
       # interfaces
     ${forEach "  ip-address: " cfg.interfaces}
 
+      ip-freebind:         ${yesOrNo  cfg.ipFreebind}
       hide-version:        ${yesOrNo  cfg.hideVersion}
       identity:            "${cfg.identity}"
       ip-transparent:      ${yesOrNo  cfg.ipTransparent}
@@ -84,7 +85,7 @@ let
       reuseport:           ${yesOrNo  cfg.reuseport}
       round-robin:         ${yesOrNo  cfg.roundRobin}
       server-count:        ${toString cfg.serverCount}
-      ${if cfg.statistics == null then "" else "statistics:          ${toString cfg.statistics}"}
+      ${maybeToString "statistics: " cfg.statistics}
       tcp-count:           ${toString cfg.tcpCount}
       tcp-query-count:     ${toString cfg.tcpQueryCount}
       tcp-timeout:         ${toString cfg.tcpTimeout}
@@ -117,7 +118,8 @@ let
   '';
 
   yesOrNo = b: if b then "yes" else "no";
-  maybeString = pre: s: if s == null then "" else ''${pre} "${s}"'';
+  maybeString = prefix: x: if x == null then "" else ''${prefix} "${s}"'';
+  maybeToString = prefix: x: if x == null then "" else ''${prefix} ${toString s}'';
   forEach = pre: l: concatMapStrings (x: pre + x + "\n") l;
 
 
@@ -146,6 +148,11 @@ let
     ${forEach     "  rrl-whitelist: "      zone.rrlWhitelist}
       ${maybeString "zonestats: "          zone.zoneStats}
 
+      ${maybeToString "max-refresh-time: " zone.maxRefreshSecs}
+      ${maybeToString "min-refresh-time: " zone.minRefreshSecs}
+      ${maybeToString "max-retry-time:   " zone.maxRetrySecs}
+      ${maybeToString "min-retry-time:   " zone.minRetrySecs}
+
       allow-axfr-fallback: ${yesOrNo       zone.allowAXFRFallback}
     ${forEach     "  allow-notify: "       zone.allowNotify}
     ${forEach     "  request-xfr: "        zone.requestXFR}
@@ -241,6 +248,44 @@ let
         '';
       };
 
+      maxRefreshSecs = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        description = ''
+          Limit refresh time for secondary zones. This is the timer which
+          checks to see if the zone has to be refetched when it expires.
+          Normally the value from the SOA record is used, but this  option
+          restricts that value.
+        '';
+      };
+
+      minRefreshSecs = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        description = ''
+          Limit refresh time for secondary zones.
+        '';
+      };
+
+      maxRetrySecs = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        description = ''
+          Limit retry time for secondary zones. This is the timeout after
+          a failed fetch attempt for the zone. Normally the value from
+          the SOA record is used, but this option restricts that value.
+        '';
+      };
+
+      minRetrySecs = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        description = ''
+          Limit retry time for secondary zones.
+        '';
+      };
+
+
       notify = mkOption {
         type = types.listOf types.str;
         default = [];
@@ -366,6 +411,15 @@ in
       '';
     };
 
+    ipFreebind = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to bind to nonlocal addresses and interfaces that are down.
+        Similar to ip-transparent.
+      '';
+    };
+
     ipTransparent = mkOption {
       type = types.bool;
       default = false;
diff --git a/nixos/modules/services/networking/radicale.nix b/nixos/modules/services/networking/radicale.nix
index d5e2e3041b49..e52c90227d3d 100644
--- a/nixos/modules/services/networking/radicale.nix
+++ b/nixos/modules/services/networking/radicale.nix
@@ -33,7 +33,7 @@ in
   };
 
   config = mkIf cfg.enable {
-    environment.systemPackages = [ pkgs.pythonPackages.radicale ];
+    environment.systemPackages = [ pkgs.radicale ];
 
     users.extraUsers = singleton
       { name = "radicale";
@@ -52,7 +52,7 @@ in
       description = "A Simple Calendar and Contact Server";
       after = [ "network-interfaces.target" ];
       wantedBy = [ "multi-user.target" ];
-      script = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -f";
+      script = "${pkgs.radicale}/bin/radicale -C ${confFile} -f";
       serviceConfig.User = "radicale";
       serviceConfig.Group = "radicale";
     };
diff --git a/nixos/modules/services/web-apps/selfoss.nix b/nixos/modules/services/web-apps/selfoss.nix
new file mode 100644
index 000000000000..5571f77334cc
--- /dev/null
+++ b/nixos/modules/services/web-apps/selfoss.nix
@@ -0,0 +1,166 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+  cfg = config.services.selfoss;
+
+  poolName = "selfoss_pool";
+  phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock";
+
+  dataDir = "/var/lib/selfoss";
+
+  selfoss-config =
+  let
+    db_type = cfg.database.type;
+    default_port = if (db_type == "mysql") then 3306 else 5342;
+  in
+  pkgs.writeText "selfoss-config.ini" ''
+    [globals]
+    ${lib.optionalString (db_type != "sqlite") ''
+      db_type=${db_type}
+      db_host=${cfg.database.host}
+      db_database=${cfg.database.name}
+      db_username=${cfg.database.user}
+      db_password=${cfg.database.password}
+      db_port=${if (cfg.database.port != null) then cfg.database.port
+                    else default_port}
+    ''
+    }
+    ${cfg.extraConfig}
+  '';
+in
+  {
+    options = {
+      services.selfoss = {
+        enable = mkEnableOption "selfoss";
+
+        user = mkOption {
+          type = types.str;
+          default = "nginx";
+          example = "nginx";
+          description = ''
+            User account under which both the service and the web-application run.
+          '';
+        };
+
+        pool = mkOption {
+          type = types.str;
+          default = "${poolName}";
+          description = ''
+            Name of existing phpfpm pool that is used to run web-application.
+            If not specified a pool will be created automatically with
+            default values.
+          '';
+        };
+
+      database = {
+        type = mkOption {
+          type = types.enum ["pgsql" "mysql" "sqlite"];
+          default = "sqlite";
+          description = ''
+            Database to store feeds. Supported are sqlite, pgsql and mysql.
+          '';
+        };
+
+        host = mkOption {
+          type = types.str;
+          default = "localhost";
+          description = ''
+            Host of the database (has no effect if type is "sqlite").
+          '';
+        };
+
+        name = mkOption {
+          type = types.str;
+          default = "tt_rss";
+          description = ''
+            Name of the existing database (has no effect if type is "sqlite").
+          '';
+        };
+
+        user = mkOption {
+          type = types.str;
+          default = "tt_rss";
+          description = ''
+            The database user. The user must exist and has access to
+            the specified database (has no effect if type is "sqlite").
+          '';
+        };
+
+        password = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = ''
+            The database user's password (has no effect if type is "sqlite").
+          '';
+        };
+
+        port = mkOption {
+          type = types.nullOr types.int;
+          default = null;
+          description = ''
+            The database's port. If not set, the default ports will be
+            provided (5432 and 3306 for pgsql and mysql respectively)
+            (has no effect if type is "sqlite").
+          '';
+        };
+      };
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Extra configuration added to config.ini
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") {
+      "${poolName}" = ''
+        listen = "${phpfpmSocketName}";
+        listen.owner = nginx
+        listen.group = nginx
+        listen.mode = 0600
+        user = nginx
+        pm = dynamic
+        pm.max_children = 75
+        pm.start_servers = 10
+        pm.min_spare_servers = 5
+        pm.max_spare_servers = 20
+        pm.max_requests = 500
+        catch_workers_output = 1
+      '';
+    };
+
+    systemd.services.selfoss-config = {
+      serviceConfig.Type = "oneshot";
+      script = ''
+        mkdir -m 755 -p ${dataDir}
+        cd ${dataDir}
+
+        # Delete all but the "data" folder
+        ls | grep -v data | while read line; do rm -rf $line; done || true
+
+        # Create the files
+        cp -r "${pkgs.selfoss}/"* "${dataDir}"
+        ln -sf "${selfoss-config}" "${dataDir}/config.ini"
+        chown -R "${cfg.user}" "${dataDir}"
+        chmod -R 755 "${dataDir}"
+      '';
+      wantedBy = [ "multi-user.target" ];
+    };
+
+    systemd.services.selfoss-update = {
+      serviceConfig = {
+        ExecStart = "${pkgs.php}/bin/php ${dataDir}/cliupdate.php";
+        User = "${cfg.user}";
+      };
+      startAt = "hourly";
+      after = [ "selfoss-config.service" ];
+      wantedBy = [ "multi-user.target" ];
+
+    };
+
+  };
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
index b4b5a6fdc07e..4f9e9f52f9e0 100644
--- a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
@@ -83,11 +83,11 @@ let
 
   # Unpack Mediawiki and put the config file in its root directory.
   mediawikiRoot = pkgs.stdenv.mkDerivation rec {
-    name= "mediawiki-1.23.13";
+    name= "mediawiki-1.27.1";
 
     src = pkgs.fetchurl {
-      url = "http://download.wikimedia.org/mediawiki/1.23/${name}.tar.gz";
-      sha256 = "168wpf53n4ksj2g5q5r0hxapx6238dvsfng5ff9ixk6axsn0j5d0";
+      url = "http://download.wikimedia.org/mediawiki/1.27/${name}.tar.gz";
+      sha256 = "0sm3ymz93qragbwhzzbwq7f127mbj29inv0afg2z6p32jb1pd9h8";
     };
 
     skins = config.skins;
diff --git a/nixos/modules/services/web-servers/apache-httpd/moodle.nix b/nixos/modules/services/web-servers/apache-httpd/moodle.nix
index 87b1fba5aa10..aa00e89967db 100644
--- a/nixos/modules/services/web-servers/apache-httpd/moodle.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/moodle.nix
@@ -63,6 +63,10 @@ let
         cp -r * $out
         cp ${moodleConfig} $out/config.php
       '';
+    # Marked as broken due to needing an update for security issues.
+    # See: https://github.com/NixOS/nixpkgs/issues/18856
+    meta.broken = true;
+
   };
 
 in
diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
index 937b2698ce9b..007c7669d8ac 100644
--- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix
@@ -5,7 +5,8 @@ with lib;
 
 let
 
-  version = "4.3.1";
+  # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix
+  version = "4.6.1";
   fullversion = "${version}";
 
   # Our bare-bones wp-config.php file using the above settings
@@ -74,7 +75,7 @@ let
       owner = "WordPress";
       repo = "WordPress";
       rev = "${fullversion}";
-      sha256 = "1rk10vcv4z9p04hfzc0wkbilrgx7m9ssyr6c3w6vw3vl1bcgqxza";
+      sha256 = "0n82xgjg1ry2p73hhgpslnkdzrma5n6hxxq76s7qskkzj0qjfvpn";
     };
     installPhase = ''
       mkdir -p $out
@@ -98,7 +99,7 @@ let
       # symlink additional plugin(s)
       ${concatMapStrings (plugin: "ln -s ${plugin} $out/wp-content/plugins/${plugin.name}\n") (config.plugins) }
 
-      # symlink additional translation(s) 
+      # symlink additional translation(s)
       mkdir -p $out/wp-content/languages
       ${concatMapStrings (language: "ln -s ${language}/*.mo ${language}/*.po $out/wp-content/languages/\n") (selectedLanguages) }
     '';
@@ -123,7 +124,7 @@ in
   options = {
     dbHost = mkOption {
       default = "localhost";
-      description = "The location of the database server.";  
+      description = "The location of the database server.";
       example = "localhost";
     };
     dbName = mkOption {
@@ -253,7 +254,7 @@ in
       done
       ${pkgs.mysql}/bin/mysql -e 'CREATE DATABASE ${config.dbName};'
       ${pkgs.mysql}/bin/mysql -e 'GRANT ALL ON ${config.dbName}.* TO ${config.dbUser}@localhost IDENTIFIED BY "${config.dbPassword}";'
-    else 
+    else
       echo "Good, no need to do anything database related."
     fi
   '';
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 94c442e165b7..443bd8c10000 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -18,9 +18,13 @@ let
 
     ${cfg.config}
 
-    ${optionalString (cfg.httpConfig == "" && cfg.config == "") ''
-    events {}
+    ${optionalString (cfg.eventsConfig != "" || cfg.config == "") ''
+    events {
+      ${cfg.eventsConfig}
+    }
+    ''}
 
+    ${optionalString (cfg.httpConfig == "" && cfg.config == "") ''
     http {
       include ${cfg.package}/conf/mime.types;
       include ${cfg.package}/conf/fastcgi.conf;
@@ -98,7 +102,6 @@ let
     }''}
 
     ${optionalString (cfg.httpConfig != "") ''
-    events {}
     http {
       include ${cfg.package}/conf/mime.types;
       include ${cfg.package}/conf/fastcgi.conf;
@@ -272,12 +275,20 @@ in
         ";
       };
 
+      eventsConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Configuration lines to be set inside the events block.
+        '';
+      };
+
       appendHttpConfig = mkOption {
         type = types.lines;
         default = "";
         description = "
           Configuration lines to be appended to the generated http block.
-          This is mutually exclusive with using config and httpConfig for 
+          This is mutually exclusive with using config and httpConfig for
           specifying the whole http block verbatim.
         ";
       };
diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix
index 4c3d30e346c5..4a16a6762935 100644
--- a/nixos/modules/system/activation/activation-script.nix
+++ b/nixos/modules/system/activation/activation-script.nix
@@ -159,7 +159,7 @@ in
         rmdir --ignore-fail-on-non-empty /usr/bin /usr
       '';
 
-    system.activationScripts.tmpfs =
+    system.activationScripts.specialfs =
       ''
         specialMount() {
           local device="$1"
@@ -167,7 +167,12 @@ in
           local options="$3"
           local fsType="$4"
 
-          ${pkgs.utillinux}/bin/mount -t "$fsType" -o "remount,$options" "$device" "$mountPoint"
+          if ${pkgs.utillinux}/bin/mountpoint -q "$mountPoint"; then
+            local options="remount,$options"
+          else
+            mkdir -m 0755 -p "$mountPoint"
+          fi
+          ${pkgs.utillinux}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint"
         }
         source ${config.system.build.earlyMountScript}
       '';
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index e84cdb3212ce..cae045f78c37 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -503,7 +503,7 @@ in
             + "'boot.loader.grub.mirroredBoots' to make the system bootable.";
         }
         {
-          assertion = all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters);
+          assertion = cfg.efiSupport || all (c: c < 2) (mapAttrsToList (_: c: c) bootDeviceCounters);
           message = "You cannot have duplicated devices in mirroredBoots";
         }
         {
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 513c121347b1..40e67fa5f8d2 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -198,9 +198,10 @@ let
       preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
 
     resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
-                    (filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption 
-                    # Don't include zram devices
-                    && !(hasPrefix "/dev/zram" sd.device)) config.swapDevices);
+                    (filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption
+                             # Don't include zram devices
+                             && !(hasPrefix "/dev/zram" sd.device)
+                            ) config.swapDevices);
 
     fsInfo =
       let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType (builtins.concatStringsSep "," fs.options) ];
diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh
index ae88222f2780..f827e530f877 100644
--- a/nixos/modules/system/boot/stage-2-init.sh
+++ b/nixos/modules/system/boot/stage-2-init.sh
@@ -111,16 +111,6 @@ rm -f /etc/{group,passwd,shadow}.lock
 rm -rf /nix/var/nix/gcroots/tmp /nix/var/nix/temproots
 
 
-# Create a ramfs on /run/keys to hold secrets that shouldn't be
-# written to disk (generally used for NixOps, harmless elsewhere).
-if ! mountpoint -q /run/keys; then
-    rm -rf /run/keys
-    mkdir /run/keys
-    mount -t ramfs ramfs /run/keys
-    chown 0:96 /run/keys
-    chmod 0750 /run/keys
-fi
-
 mkdir -m 0755 -p /run/lock
 
 
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 3c822c8716d0..d47f6854e338 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -18,7 +18,7 @@ let
 
   prioOption = prio: optionalString (prio != null) " pri=${toString prio}";
 
-  specialFSTypes = [ "proc" "sysfs" "tmpfs" "devtmpfs" "devpts" ];
+  specialFSTypes = [ "proc" "sysfs" "tmpfs" "ramfs" "devtmpfs" "devpts" ];
 
   coreFileSystemOpts = { name, config, ... }: {
 
@@ -290,6 +290,9 @@ in
       "/dev" = { fsType = "devtmpfs"; options = [ "nosuid" "strictatime" "mode=755" "size=${config.boot.devSize}" ]; };
       "/dev/shm" = { fsType = "tmpfs"; options = [ "nosuid" "nodev" "strictatime" "mode=1777" "size=${config.boot.devShmSize}" ]; };
       "/dev/pts" = { fsType = "devpts"; options = [ "nosuid" "noexec" "mode=620" "gid=${toString config.ids.gids.tty}" ]; };
+
+      # To hold secrets that shouldn't be written to disk (generally used for NixOps, harmless elsewhere)
+      "/run/keys" = { fsType = "ramfs"; options = [ "nosuid" "nodev" "mode=750" "gid=${toString config.ids.gids.keys}" ]; };
     } // optionalAttrs (!config.boot.isContainer) {
       # systemd-nspawn populates /sys by itself, and remounting it causes all
       # kinds of weird issues (most noticeably, waiting for host disk device
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index eaa4d828afb6..f570813805cf 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -159,7 +159,7 @@ let
             fi
           ''
         else
-          ''${ipcmd} add ${cfg.attribute} dev $ifaceHost'';
+          ''${ipcmd} add ${cfg.${attribute}} dev $ifaceHost'';
       renderExtraVeth = name: cfg:
         if cfg.hostBridge != null then
           ''
diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix
new file mode 100644
index 000000000000..afee1f7f6dd4
--- /dev/null
+++ b/nixos/tests/wordpress.nix
@@ -0,0 +1,60 @@
+import ./make-test.nix ({ pkgs, ... }:
+
+{
+  name = "wordpress";
+  meta = with pkgs.stdenv.lib.maintainers; {
+    maintainers = [ grahamc ]; # under duress!
+  };
+
+  nodes =
+    { web =
+        { config, pkgs, ... }:
+        {
+          services.mysql.enable = true;
+          services.mysql.package = pkgs.mysql;
+          services.mysql.initialScript = pkgs.writeText "start.sql" ''
+            CREATE DATABASE wordpress;
+	    CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress';
+            GRANT ALL on wordpress.* TO 'wordpress'@'localhost';
+          '';
+
+          services.httpd = {
+            enable = true;
+            logPerVirtualHost = true;
+            adminAddr="js@lastlog.de";
+            extraModules = [
+              { name = "php7"; path = "${pkgs.php}/modules/libphp7.so"; }
+            ];
+
+            virtualHosts = [
+              {
+                hostName = "wordpress";
+                extraSubservices =
+                  [
+                    {
+                      serviceType = "wordpress";
+                      dbPassword = "wordpress";
+                      wordpressUploads = "/data/uploads";
+                      languages = [ "de_DE" "en_GB" ];
+                    }
+                  ];
+              }
+            ];
+          };
+        };
+    };
+
+  testScript =
+    { nodes, ... }:
+    ''
+      startAll;
+
+      $web->waitForUnit("mysql");
+      $web->waitForUnit("httpd");
+
+      $web->succeed("curl -L 127.0.0.1:80 | grep 'Welcome to the famous'");
+
+
+    '';
+
+})