about summary refs log tree commit diff
path: root/nixos/modules/services
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services')
-rw-r--r--nixos/modules/services/audio/alsa.nix10
-rw-r--r--nixos/modules/services/backup/crashplan-small-business.nix74
-rw-r--r--nixos/modules/services/continuous-integration/buildkite-agent.nix140
-rw-r--r--nixos/modules/services/databases/postgresql.nix2
-rw-r--r--nixos/modules/services/hardware/acpid.nix8
-rw-r--r--nixos/modules/services/misc/nixos-manual.nix6
-rw-r--r--nixos/modules/services/misc/novacomd.nix31
-rw-r--r--nixos/modules/services/misc/ssm-agent.nix2
-rw-r--r--nixos/modules/services/networking/dhcpcd.nix6
-rw-r--r--nixos/modules/services/networking/nat.nix33
-rw-r--r--nixos/modules/services/networking/nixops-dns.nix79
-rw-r--r--nixos/modules/services/networking/softether.nix33
-rw-r--r--nixos/modules/services/networking/tox-bootstrapd.nix2
-rw-r--r--nixos/modules/services/security/hologram-agent.nix7
-rw-r--r--nixos/modules/services/ttys/agetty.nix4
-rw-r--r--nixos/modules/services/web-servers/varnish/default.nix17
-rw-r--r--nixos/modules/services/x11/xautolock.nix28
17 files changed, 413 insertions, 69 deletions
diff --git a/nixos/modules/services/audio/alsa.nix b/nixos/modules/services/audio/alsa.nix
index acf48d3c3d03..161d873686a8 100644
--- a/nixos/modules/services/audio/alsa.nix
+++ b/nixos/modules/services/audio/alsa.nix
@@ -21,7 +21,7 @@ in
 
       enable = mkOption {
         type = types.bool;
-        default = true;
+        defaultText = "!versionAtLeast system.stateVersion \"18.03\"";
         description = ''
           Whether to enable ALSA sound.
         '';
@@ -78,7 +78,11 @@ in
 
   ###### implementation
 
-  config = mkIf config.sound.enable {
+  config = mkMerge [
+    ({
+      sound.enable = mkDefault (!versionAtLeast config.system.stateVersion "18.03");
+    })
+    (mkIf config.sound.enable {
 
     environment.systemPackages = [ alsaUtils ];
 
@@ -124,6 +128,6 @@ in
       ];
     };
 
-  };
+  })];
 
 }
diff --git a/nixos/modules/services/backup/crashplan-small-business.nix b/nixos/modules/services/backup/crashplan-small-business.nix
new file mode 100644
index 000000000000..9497d8c18bb7
--- /dev/null
+++ b/nixos/modules/services/backup/crashplan-small-business.nix
@@ -0,0 +1,74 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.services.crashplansb;
+  crashplansb = pkgs.crashplansb.override { maxRam = cfg.maxRam; };
+  varDir = "/var/lib/crashplan";
+in
+
+with lib;
+
+{
+  options = {
+    services.crashplansb = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Starts crashplan for small business background service.
+        '';
+      };
+      maxRam = mkOption {
+        default = "1024m";
+        example = "2G";
+        type = types.str;
+        description = ''
+          Maximum amount of ram that the crashplan engine should use.
+        '';
+      };
+      openPorts = mkOption {
+        description = "Open ports in the firewall for crashplan.";
+        default = true;
+        type = types.bool;
+      };
+      ports =  mkOption {
+        # https://support.code42.com/Administrator/6/Planning_and_installing/TCP_and_UDP_ports_used_by_the_Code42_platform
+        # used ports can also be checked in the desktop app console using the command connection.info
+        description = "which ports to open.";
+        default = [ 4242 4243 4244 4247 ];
+        type = types.listOf types.int;
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ crashplansb ];
+    networking.firewall.allowedTCPPorts = mkIf cfg.openPorts cfg.ports;
+
+    systemd.services.crashplansb = {
+      description = "CrashPlan Backup Engine";
+
+      wantedBy = [ "multi-user.target" ];
+      after    = [ "network.target" "local-fs.target" ];
+
+      preStart = ''
+        install -d -m 755 ${crashplansb.vardir}
+        install -d -m 700 ${crashplansb.vardir}/conf
+        install -d -m 700 ${crashplansb.manifestdir}
+        install -d -m 700 ${crashplansb.vardir}/cache
+        install -d -m 700 ${crashplansb.vardir}/backupArchives
+        install -d -m 777 ${crashplansb.vardir}/log
+        cp -avn ${crashplansb}/conf.template/* ${crashplansb.vardir}/conf
+      '';
+
+      serviceConfig = {
+        Type = "forking";
+        EnvironmentFile = "${crashplansb}/bin/run.conf";
+        ExecStart = "${crashplansb}/bin/CrashPlanEngine start";
+        ExecStop = "${crashplansb}/bin/CrashPlanEngine stop";
+        PIDFile = "${crashplansb.vardir}/CrashPlanEngine.pid";
+        WorkingDirectory = crashplansb;
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/continuous-integration/buildkite-agent.nix b/nixos/modules/services/continuous-integration/buildkite-agent.nix
index 1b0198ac93fe..0a0c9f665d25 100644
--- a/nixos/modules/services/continuous-integration/buildkite-agent.nix
+++ b/nixos/modules/services/continuous-integration/buildkite-agent.nix
@@ -4,6 +4,31 @@ with lib;
 
 let
   cfg = config.services.buildkite-agent;
+
+  mkHookOption = { name, description, example ? null }: {
+    inherit name;
+    value = mkOption {
+      default = null;
+      inherit description;
+      type = types.nullOr types.lines;
+    } // (if example == null then {} else { inherit example; });
+  };
+  mkHookOptions = hooks: listToAttrs (map mkHookOption hooks);
+
+  hooksDir = let
+    mkHookEntry = name: value: ''
+      cat > $out/${name} <<EOF
+      #! ${pkgs.stdenv.shell}
+      set -e
+      ${value}
+      EOF
+      chmod 755 $out/${name}
+    '';
+  in pkgs.runCommand "buildkite-agent-hooks" {} ''
+    mkdir $out
+    ${concatStringsSep "\n" (mapAttrsToList mkHookEntry (filterAttrs (n: v: v != null) cfg.hooks))}
+  '';
+
 in
 
 {
@@ -43,25 +68,28 @@ in
 
       name = mkOption {
         type = types.str;
+        default = "%hostname-%n";
         description = ''
           The name of the agent.
         '';
       };
 
-      hooksPath = mkOption {
-        type = types.path;
-        default = "${pkgs.buildkite-agent}/share/hooks";
-        defaultText = "${pkgs.buildkite-agent}/share/hooks";
+      meta-data = mkOption {
+        type = types.str;
+        default = "";
+        example = "queue=default,docker=true,ruby2=true";
         description = ''
-          Path to the directory storing the hooks.
+          Meta data for the agent. This is a comma-separated list of
+          <code>key=value</code> pairs.
         '';
       };
 
-      meta-data = mkOption {
-        type = types.str;
+      extraConfig = mkOption {
+        type = types.lines;
         default = "";
+        example = "debug=true";
         description = ''
-          Meta data for the agent.
+          Extra lines to be added verbatim to the configuration file.
         '';
       };
 
@@ -85,6 +113,74 @@ in
             '';
           };
         };
+
+      hooks = mkHookOptions [
+        { name = "checkout";
+          description = ''
+            The `checkout` hook script will replace the default checkout routine of the
+            bootstrap.sh script. You can use this hook to do your own SCM checkout
+            behaviour
+          ''; }
+        { name = "command";
+          description = ''
+            The `command` hook script will replace the default implementation of running
+            the build command.
+          ''; }
+        { name = "environment";
+          description = ''
+            The `environment` hook will run before all other commands, and can be used
+            to set up secrets, data, etc. Anything exported in hooks will be available
+            to the build script.
+
+            Note: the contents of this file will be copied to the world-readable
+            Nix store.
+          '';
+          example = ''
+            export SECRET_VAR=`head -1 /run/keys/secret`
+          ''; }
+        { name = "post-artifact";
+          description = ''
+            The `post-artifact` hook will run just after artifacts are uploaded
+          ''; }
+        { name = "post-checkout";
+          description = ''
+            The `post-checkout` hook will run after the bootstrap script has checked out
+            your projects source code.
+          ''; }
+        { name = "post-command";
+          description = ''
+            The `post-command` hook will run after the bootstrap script has run your
+            build commands
+          ''; }
+        { name = "pre-artifact";
+          description = ''
+            The `pre-artifact` hook will run just before artifacts are uploaded
+          ''; }
+        { name = "pre-checkout";
+          description = ''
+            The `pre-checkout` hook will run just before your projects source code is
+            checked out from your SCM provider
+          ''; }
+        { name = "pre-command";
+          description = ''
+            The `pre-command` hook will run just before your build command runs
+          ''; }
+        { name = "pre-exit";
+          description = ''
+            The `pre-exit` hook will run just before your build job finishes
+          ''; }
+      ];
+
+      hooksPath = mkOption {
+        type = types.path;
+        default = hooksDir;
+        defaultText = "generated from services.buildkite-agent.hooks";
+        description = ''
+          Path to the directory storing the hooks.
+          Consider using <option>services.buildkite-agent.hooks.&lt;name&gt;</option>
+          instead.
+        '';
+      };
     };
   };
 
@@ -100,13 +196,10 @@ in
     environment.systemPackages = [ cfg.package ];
 
     systemd.services.buildkite-agent =
-      let copy = x: target: perms:
-                 "cp -f ${x} ${target}; ${pkgs.coreutils}/bin/chmod ${toString perms} ${target}; ";
-      in
       { description = "Buildkite Agent";
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
-        path = cfg.runtimePackages;
+        path = cfg.runtimePackages ++ [ pkgs.coreutils ];
         environment = config.networking.proxy.envVars // {
           HOME = cfg.dataDir;
           NIX_REMOTE = "daemon";
@@ -114,10 +207,14 @@ in
 
         ## NB: maximum care is taken so that secrets (ssh keys and the CI token)
         ##     don't end up in the Nix store.
-        preStart = ''
-            ${pkgs.coreutils}/bin/mkdir -m 0700 -p ${cfg.dataDir}/.ssh
-            ${copy (toString cfg.openssh.privateKeyPath) "${cfg.dataDir}/.ssh/id_rsa"     600}
-            ${copy (toString cfg.openssh.publicKeyPath)  "${cfg.dataDir}/.ssh/id_rsa.pub" 600}
+        preStart = let
+          sshDir = "${cfg.dataDir}/.ssh";
+        in
+          ''
+            mkdir -m 0700 -p "${sshDir}"
+            cp -f "${toString cfg.openssh.privateKeyPath}" "${sshDir}/id_rsa"
+            cp -f "${toString cfg.openssh.publicKeyPath}"  "${sshDir}/id_rsa.pub"
+            chmod 600 "${sshDir}"/id_rsa*
 
             cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
             token="$(cat ${toString cfg.tokenPath})"
@@ -125,7 +222,7 @@ in
             meta-data="${cfg.meta-data}"
             build-path="${cfg.dataDir}/builds"
             hooks-path="${cfg.hooksPath}"
-            bootstrap-script="${pkgs.buildkite-agent}/share/bootstrap.sh"
+            ${cfg.extraConfig}
             EOF
           '';
 
@@ -137,6 +234,15 @@ in
             TimeoutSec = 10;
           };
       };
+
+    assertions = [
+      { assertion = cfg.hooksPath == hooksDir || all isNull (attrValues cfg.hooks);
+        message = ''
+          Options `services.buildkite-agent.hooksPath' and
+          `services.buildkite-agent.hooks.<name>' are mutually exclusive.
+        '';
+      }
+    ];
   };
   imports = [
     (mkRenamedOptionModule [ "services" "buildkite-agent" "token" ]                [ "services" "buildkite-agent" "tokenPath" ])
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 9b5e3735239f..0dcbfe2e47ac 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -122,7 +122,7 @@ in
       extraPlugins = mkOption {
         type = types.listOf types.path;
         default = [];
-        example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }).v_2_1_4 ]";
+        example = literalExample "[ (pkgs.postgis.override { postgresql = pkgs.postgresql94; }) ]";
         description = ''
           When this list contains elements a new store path is created.
           PostgreSQL and the elements are symlinked into it. Then pg_config,
diff --git a/nixos/modules/services/hardware/acpid.nix b/nixos/modules/services/hardware/acpid.nix
index f69706ebff34..0f05876aee32 100644
--- a/nixos/modules/services/hardware/acpid.nix
+++ b/nixos/modules/services/hardware/acpid.nix
@@ -53,6 +53,12 @@ in
         description = "Whether to enable the ACPI daemon.";
       };
 
+      logEvents = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Log all event activity.";
+      };
+
       handlers = mkOption {
         type = types.attrsOf (types.submodule {
           options = {
@@ -142,7 +148,7 @@ in
         ConditionPathExists = [ "/proc/acpi" ];
       };
 
-      script = "acpid --confdir ${acpiConfDir}";
+      script = "acpid ${optionalString config.services.acpid.logEvents "--logevents"} --confdir ${acpiConfDir}";
     };
 
   };
diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix
index 41cadb4a6de0..5d0f2abd13a9 100644
--- a/nixos/modules/services/misc/nixos-manual.nix
+++ b/nixos/modules/services/misc/nixos-manual.nix
@@ -16,10 +16,10 @@ let
     It isn't perfect, but it seems to cover a vast majority of use cases.
     Caveat: even if the package is reached by a different means,
     the path above will be shown and not e.g. `${config.services.foo.package}`. */
-  manual = import ../../../doc/manual {
+  manual = import ../../../doc/manual rec {
     inherit pkgs config;
-    version = config.system.nixosRelease;
-    revision = "release-${config.system.nixosRelease}";
+    version = config.system.nixos.release;
+    revision = "release-${version}";
     options =
       let
         scrubbedEval = evalModules {
diff --git a/nixos/modules/services/misc/novacomd.nix b/nixos/modules/services/misc/novacomd.nix
new file mode 100644
index 000000000000..7cfc68d2b673
--- /dev/null
+++ b/nixos/modules/services/misc/novacomd.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.novacomd;
+
+in {
+
+  options = {
+    services.novacomd = {
+      enable = mkEnableOption "Novacom service for connecting to WebOS devices";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.webos.novacom ];
+
+    systemd.services.novacomd = {
+      description = "Novacom WebOS daemon";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        ExecStart = "${pkgs.webos.novacomd}/sbin/novacomd";
+      };
+    };
+  };
+
+  meta.maintainers = with maintainers; [ dtzWill ];
+}
diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix
index c1e1f0903539..a57fbca86fb6 100644
--- a/nixos/modules/services/misc/ssm-agent.nix
+++ b/nixos/modules/services/misc/ssm-agent.nix
@@ -12,7 +12,7 @@ let
 
     case "$1" in
       -i) echo "nixos";;
-      -r) echo "${config.system.nixosVersion}";;
+      -r) echo "${config.system.nixos.version}";;
     esac
   '';
 in {
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index d283c7624335..de0aa1a2c2c3 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -16,7 +16,7 @@ let
   # Don't start dhcpcd on explicitly configured interfaces or on
   # interfaces that are part of a bridge, bond or sit device.
   ignoredInterfaces =
-    map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ip4 != [ ] || i.ipAddress != null) interfaces)
+    map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ipv4.addresses != [ ]) interfaces)
     ++ mapAttrsToList (i: _: i) config.networking.sits
     ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
     ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.vswitches))
@@ -156,11 +156,11 @@ in
     systemd.services.dhcpcd = let
       cfgN = config.networking;
       hasDefaultGatewaySet = (cfgN.defaultGateway != null && cfgN.defaultGateway.address != "")
-                          || (cfgN.defaultGateway6 != null && cfgN.defaultGateway6.address != "");
+                          && (!cfgN.enableIPv6 || (cfgN.defaultGateway6 != null && cfgN.defaultGateway6.address != ""));
     in
       { description = "DHCP Client";
 
-        wantedBy = optional (!hasDefaultGatewaySet) "network-online.target";
+        wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target";
         after = [ "network.target" ];
         wants = [ "network.target" ];
 
diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix
index df4246d216d8..da3827c35e63 100644
--- a/nixos/modules/services/networking/nat.nix
+++ b/nixos/modules/services/networking/nat.nix
@@ -53,12 +53,36 @@ let
         -i ${cfg.externalInterface} -p ${fwd.proto} \
         --dport ${builtins.toString fwd.sourcePort} \
         -j DNAT --to-destination ${fwd.destination}
+
+      ${concatMapStrings (loopbackip:
+        let
+          m                = builtins.match "([0-9.]+):([0-9-]+)" fwd.destination;
+          destinationIP    = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 0;
+          destinationPorts = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 1;
+        in ''
+          # Allow connections to ${loopbackip}:${toString fwd.sourcePort} from the host itself
+          iptables -w -t nat -A OUTPUT \
+            -d ${loopbackip} -p ${fwd.proto} \
+            --dport ${builtins.toString fwd.sourcePort} \
+            -j DNAT --to-destination ${fwd.destination}
+
+          # Allow connections to ${loopbackip}:${toString fwd.sourcePort} from other hosts behind NAT
+          iptables -w -t nat -A nixos-nat-pre \
+            -d ${loopbackip} -p ${fwd.proto} \
+            --dport ${builtins.toString fwd.sourcePort} \
+            -j DNAT --to-destination ${fwd.destination}
+
+          iptables -w -t nat -A nixos-nat-post \
+            -d ${destinationIP} -p ${fwd.proto} \
+            --dport ${destinationPorts} \
+            -j SNAT --to-source ${loopbackip}
+        '') fwd.loopbackIPs}
     '') cfg.forwardPorts}
 
     ${optionalString (cfg.dmzHost != null) ''
       iptables -w -t nat -A nixos-nat-pre \
         -i ${cfg.externalInterface} -j DNAT \
-	--to-destination ${cfg.dmzHost}
+        --to-destination ${cfg.dmzHost}
     ''}
 
     ${cfg.extraCommands}
@@ -152,6 +176,13 @@ in
             example = "udp";
             description = "Protocol of forwarded connection";
           };
+
+          loopbackIPs = mkOption {
+            type = types.listOf types.str;
+            default = [];
+            example = literalExample ''[ "55.1.2.3" ]'';
+            description = "Public IPs for NAT reflection; for connections to `loopbackip:sourcePort' from the host itself and from other hosts behind NAT";
+          };
         };
       });
       default = [];
diff --git a/nixos/modules/services/networking/nixops-dns.nix b/nixos/modules/services/networking/nixops-dns.nix
new file mode 100644
index 000000000000..2bb1263b7fa2
--- /dev/null
+++ b/nixos/modules/services/networking/nixops-dns.nix
@@ -0,0 +1,79 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  pkg = pkgs.nixops-dns;
+  cfg = config.services.nixops-dns;
+in
+
+{
+  options = {
+    services.nixops-dns = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable the nixops-dns resolution
+          of NixOps virtual machines via dnsmasq and fake domain name.
+        '';
+      };
+
+      user = mkOption {
+        type = types.str;
+        description = ''
+          The user the nixops-dns daemon should run as.
+          This should be the user, which is also used for nixops and
+          have the .nixops directory in its home.
+        '';
+      };
+
+      domain = mkOption {
+        type = types.str;
+        description = ''
+          Fake domain name to resolve to NixOps virtual machines.
+
+          For example "ops" will resolve "vm.ops".
+        '';
+        example = "ops";
+        default = "ops";
+      };
+
+      dnsmasq = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Enable dnsmasq forwarding to nixops-dns. This allows to use
+          nixops-dns for `services.nixops-dns.domain` resolution
+          while forwarding the rest of the queries to original resolvers.
+        '';
+      };
+
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.nixops-dns = {
+      description = "nixops-dns: DNS server for resolving NixOps machines";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        Type = "simple";
+        User = cfg.user;
+        ExecStart="${pkg}/bin/nixops-dns --domain=.${cfg.domain}";
+      };
+    };
+
+    services.dnsmasq = mkIf cfg.dnsmasq {
+      enable = true;
+      resolveLocalQueries = true;
+      servers = [
+        "/${cfg.domain}/127.0.0.1#5300"
+      ];
+      extraConfig = ''
+        bind-interfaces
+        listen-address=127.0.0.1
+      '';
+    };
+
+  };
+}
diff --git a/nixos/modules/services/networking/softether.nix b/nixos/modules/services/networking/softether.nix
index 9087b75c29c1..65df93a00da9 100644
--- a/nixos/modules/services/networking/softether.nix
+++ b/nixos/modules/services/networking/softether.nix
@@ -5,6 +5,8 @@ with lib;
 let
   cfg = config.services.softether;
 
+  package = cfg.package.override { dataDir = cfg.dataDir; };
+
 in
 {
 
@@ -49,7 +51,7 @@ in
 
       dataDir = mkOption {
         type = types.string;
-        default = "${cfg.package.dataDir}";
+        default = "/var/lib/softether";
         description = ''
           Data directory for SoftEther VPN.
         '';
@@ -64,11 +66,8 @@ in
   config = mkIf cfg.enable (
 
     mkMerge [{
-      environment.systemPackages = [
-          (pkgs.lib.overrideDerivation cfg.package (attrs: {
-            dataDir = cfg.dataDir;
-          }))
-        ];
+      environment.systemPackages = [ package ];
+
       systemd.services."softether-init" = {
         description = "SoftEther VPN services initial task";
         wantedBy = [ "network.target" ];
@@ -80,11 +79,11 @@ in
             for d in vpnserver vpnbridge vpnclient vpncmd; do
                 if ! test -e ${cfg.dataDir}/$d; then
                     ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
-                    install -m0600 ${cfg.package}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
+                    install -m0600 ${package}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
                 fi
             done
             rm -rf ${cfg.dataDir}/vpncmd/vpncmd
-            ln -s ${cfg.package}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
+            ln -s ${package}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
         '';
       };
     }
@@ -97,12 +96,12 @@ in
         wantedBy = [ "network.target" ];
         serviceConfig = {
           Type = "forking";
-          ExecStart = "${cfg.package}/bin/vpnserver start";
-          ExecStop = "${cfg.package}/bin/vpnserver stop";
+          ExecStart = "${package}/bin/vpnserver start";
+          ExecStop = "${package}/bin/vpnserver stop";
         };
         preStart = ''
             rm -rf ${cfg.dataDir}/vpnserver/vpnserver
-            ln -s ${cfg.package}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
+            ln -s ${package}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
         '';
         postStop = ''
             rm -rf ${cfg.dataDir}/vpnserver/vpnserver
@@ -118,12 +117,12 @@ in
         wantedBy = [ "network.target" ];
         serviceConfig = {
           Type = "forking";
-          ExecStart = "${cfg.package}/bin/vpnbridge start";
-          ExecStop = "${cfg.package}/bin/vpnbridge stop";
+          ExecStart = "${package}/bin/vpnbridge start";
+          ExecStop = "${package}/bin/vpnbridge stop";
         };
         preStart = ''
             rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
-            ln -s ${cfg.package}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
+            ln -s ${package}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
         '';
         postStop = ''
             rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
@@ -139,12 +138,12 @@ in
         wantedBy = [ "network.target" ];
         serviceConfig = {
           Type = "forking";
-          ExecStart = "${cfg.package}/bin/vpnclient start";
-          ExecStop = "${cfg.package}/bin/vpnclient stop";
+          ExecStart = "${package}/bin/vpnclient start";
+          ExecStop = "${package}/bin/vpnclient stop";
         };
         preStart = ''
             rm -rf ${cfg.dataDir}/vpnclient/vpnclient
-            ln -s ${cfg.package}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
+            ln -s ${package}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
         '';
         postStart = ''
             sleep 1
diff --git a/nixos/modules/services/networking/tox-bootstrapd.nix b/nixos/modules/services/networking/tox-bootstrapd.nix
index c1f945773e23..cb0e6b158651 100644
--- a/nixos/modules/services/networking/tox-bootstrapd.nix
+++ b/nixos/modules/services/networking/tox-bootstrapd.nix
@@ -69,7 +69,7 @@ in
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig =
-        { ExecStart = "${pkg}/bin/tox-bootstrapd ${cfgFile}";
+        { ExecStart = "${pkg}/bin/tox-bootstrapd --config=${cfgFile}";
           Type = "forking";
           inherit PIDFile;
           User = "tox-bootstrapd";
diff --git a/nixos/modules/services/security/hologram-agent.nix b/nixos/modules/services/security/hologram-agent.nix
index 6c53a2df6306..39ed506f7617 100644
--- a/nixos/modules/services/security/hologram-agent.nix
+++ b/nixos/modules/services/security/hologram-agent.nix
@@ -35,10 +35,9 @@ in {
   config = mkIf cfg.enable {
     boot.kernelModules = [ "dummy" ];
 
-    networking.interfaces.dummy0 = {
-      ipAddress = "169.254.169.254";
-      prefixLength = 32;
-    };
+    networking.interfaces.dummy0.ipv4.addresses = [
+      { address = "169.254.169.254"; prefixLength = 32; }
+    ];
 
     systemd.services.hologram-agent = {
       description = "Provide EC2 instance credentials to machines outside of EC2";
diff --git a/nixos/modules/services/ttys/agetty.nix b/nixos/modules/services/ttys/agetty.nix
index 3429397d2cc2..b50de496e975 100644
--- a/nixos/modules/services/ttys/agetty.nix
+++ b/nixos/modules/services/ttys/agetty.nix
@@ -64,8 +64,8 @@ in
 
   config = {
     # Note: this is set here rather than up there so that changing
-    # nixosLabel would not rebuild manual pages
-    services.mingetty.greetingLine = mkDefault ''<<< Welcome to NixOS ${config.system.nixosLabel} (\m) - \l >>>'';
+    # nixos.label would not rebuild manual pages
+    services.mingetty.greetingLine = mkDefault ''<<< Welcome to NixOS ${config.system.nixos.label} (\m) - \l >>>'';
 
     systemd.services."getty@" =
       { serviceConfig.ExecStart = [
diff --git a/nixos/modules/services/web-servers/varnish/default.nix b/nixos/modules/services/web-servers/varnish/default.nix
index c3bc065d4651..d63fb954ef96 100644
--- a/nixos/modules/services/web-servers/varnish/default.nix
+++ b/nixos/modules/services/web-servers/varnish/default.nix
@@ -1,9 +1,13 @@
 { config, lib, pkgs, ...}:
+
+with lib;
+
 let
   cfg = config.services.varnish;
 
+  commandLine = "-f ${pkgs.writeText "default.vcl" cfg.config}" +
+      optionalString (cfg.extraModules != []) " -p vmod_path='${makeSearchPathOutput "lib" "lib/varnish/vmods" ([pkgs.varnish] ++ cfg.extraModules)}' -r vmod_path";
 in
-with lib;
 {
   options = {
     services.varnish = {
@@ -69,8 +73,7 @@ with lib;
       serviceConfig = {
         Type = "simple";
         PermissionsStartOnly = true;
-        ExecStart = "${pkgs.varnish}/sbin/varnishd -a ${cfg.http_address} -f ${pkgs.writeText "default.vcl" cfg.config} -n ${cfg.stateDir} -F ${cfg.extraCommandLine}"
-          + optionalString (cfg.extraModules != []) " -p vmod_path='${makeSearchPathOutput "lib" "lib/varnish/vmods" ([pkgs.varnish] ++ cfg.extraModules)}' -r vmod_path";
+        ExecStart = "${pkgs.varnish}/sbin/varnishd -a ${cfg.http_address} -n ${cfg.stateDir} -F ${cfg.extraCommandLine} ${commandLine}";
         Restart = "always";
         RestartSec = "5s";
         User = "varnish";
@@ -83,6 +86,14 @@ with lib;
 
     environment.systemPackages = [ pkgs.varnish ];
 
+    # check .vcl syntax at compile time (e.g. before nixops deployment)
+    system.extraDependencies = [
+      (pkgs.stdenv.mkDerivation {
+        name = "check-varnish-syntax";
+        buildCommand = "${pkgs.varnish}/sbin/varnishd -C ${commandLine} 2> $out";
+      })
+    ];
+
     users.extraUsers.varnish = {
       group = "varnish";
       uid = config.ids.uids.varnish;
diff --git a/nixos/modules/services/x11/xautolock.nix b/nixos/modules/services/x11/xautolock.nix
index 28fc92024bcb..a614559970e9 100644
--- a/nixos/modules/services/x11/xautolock.nix
+++ b/nixos/modules/services/x11/xautolock.nix
@@ -26,9 +26,9 @@ in
         };
 
         locker = mkOption {
-          default = "xlock"; # default according to `man xautolock`
-          example = "i3lock -i /path/to/img";
-          type = types.string;
+          default = "${pkgs.xlockmore}/bin/xlock"; # default according to `man xautolock`
+          example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img";
+          type = types.str;
 
           description = ''
             The script to use when automatically locking the computer.
@@ -37,8 +37,8 @@ in
 
         nowlocker = mkOption {
           default = null;
-          example = "i3lock -i /path/to/img";
-          type = types.nullOr types.string;
+          example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img";
+          type = types.nullOr types.str;
 
           description = ''
             The script to use when manually locking the computer with <command>xautolock -locknow</command>.
@@ -56,10 +56,8 @@ in
 
         notifier = mkOption {
           default = null;
-          example = literalExample ''
-            "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\""
-          '';
-          type = types.nullOr types.string;
+          example = "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\"";
+          type = types.nullOr types.str;
 
           description = ''
             Notification script to be used to warn about the pending autolock.
@@ -68,8 +66,8 @@ in
 
         killer = mkOption {
           default = null; # default according to `man xautolock` is none
-          example = "systemctl suspend";
-          type = types.nullOr types.string;
+          example = "${pkgs.systemd}/bin/systemctl suspend";
+          type = types.nullOr types.str;
 
           description = ''
             The script to use when nothing has happend for as long as <option>killtime</option>
@@ -131,6 +129,12 @@ in
           assertion = cfg.killer != null -> cfg.killtime >= 10;
           message = "killtime has to be at least 10 minutes according to `man xautolock`";
         }
-      ];
+      ] ++ (lib.flip map [ "locker" "notifier" "nowlocker" "killer" ]
+        (option:
+        {
+          assertion = cfg."${option}" != null -> builtins.substring 0 1 cfg."${option}" == "/";
+          message = "Please specify a canonical path for `services.xserver.xautolock.${option}`";
+        })
+      );
     };
   }