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/continuous-integration/gitlab-runner.nix540
-rw-r--r--nixos/modules/services/mail/postfix.nix1
-rw-r--r--nixos/modules/services/mail/roundcube.nix2
-rw-r--r--nixos/modules/services/mail/spamassassin.nix1
-rw-r--r--nixos/modules/services/misc/autofs.nix1
-rw-r--r--nixos/modules/services/misc/disnix.nix5
-rw-r--r--nixos/modules/services/misc/gitlab.nix2
-rw-r--r--nixos/modules/services/misc/pykms.nix1
-rw-r--r--nixos/modules/services/misc/sssd.nix5
-rw-r--r--nixos/modules/services/networking/gogoclient.nix1
-rw-r--r--nixos/modules/services/networking/hostapd.nix2
-rw-r--r--nixos/modules/services/networking/openfire.nix1
-rw-r--r--nixos/modules/services/networking/ssh/lshd.nix6
-rw-r--r--nixos/modules/services/networking/tcpcrypt.nix1
-rw-r--r--nixos/modules/services/networking/thelounge.nix1
-rw-r--r--nixos/modules/services/networking/wicd.nix1
-rw-r--r--nixos/modules/services/printing/cupsd.nix16
-rw-r--r--nixos/modules/services/web-apps/mediawiki.nix23
-rw-r--r--nixos/modules/services/web-apps/nextcloud.nix4
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/default.nix2
-rw-r--r--nixos/modules/services/web-servers/jboss/default.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/pantheon.xml2
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix3
-rw-r--r--nixos/modules/services/x11/hardware/digimend.nix7
24 files changed, 499 insertions, 130 deletions
diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix
index bd4cf6a37bad..84f04a276412 100644
--- a/nixos/modules/services/continuous-integration/gitlab-runner.nix
+++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix
@@ -1,160 +1,494 @@
 { config, lib, pkgs, ... }:
-
 with lib;
-
 let
   cfg = config.services.gitlab-runner;
-  configFile =
-    if (cfg.configFile == null) then
-      (pkgs.runCommand "config.toml" {
-        buildInputs = [ pkgs.remarshal ];
-        preferLocalBuild = true;
-      } ''
-        remarshal -if json -of toml \
-          < ${pkgs.writeText "config.json" (builtins.toJSON cfg.configOptions)} \
-          > $out
-      '')
-    else
-      cfg.configFile;
   hasDocker = config.virtualisation.docker.enable;
+  hashedServices = with builtins; (mapAttrs' (name: service: nameValuePair
+    "${name}_${config.networking.hostName}_${
+        substring 0 12
+        (hashString "md5" (unsafeDiscardStringContext (toJSON service)))}"
+      service)
+    cfg.services);
+  configPath = "$HOME/.gitlab-runner/config.toml";
+  configureScript = pkgs.writeShellScriptBin "gitlab-runner-configure" (
+    if (cfg.configFile != null) then ''
+      mkdir -p $(dirname ${configPath})
+      cp ${cfg.configFile} ${configPath}
+      # make config file readable by service
+      chown -R --reference=$HOME $(dirname ${configPath})
+    '' else ''
+      export CONFIG_FILE=${configPath}
+
+      mkdir -p $(dirname ${configPath})
+
+      # remove no longer existing services
+      gitlab-runner verify --delete
+
+      # current and desired state
+      NEEDED_SERVICES=$(echo ${concatStringsSep " " (attrNames hashedServices)} | tr " " "\n")
+      REGISTERED_SERVICES=$(gitlab-runner list 2>&1 | grep 'Executor' | awk '{ print $1 }')
+
+      # difference between current and desired state
+      NEW_SERVICES=$(grep -vxF -f <(echo "$REGISTERED_SERVICES") <(echo "$NEEDED_SERVICES") || true)
+      OLD_SERVICES=$(grep -vxF -f <(echo "$NEEDED_SERVICES") <(echo "$REGISTERED_SERVICES") || true)
+
+      # register new services
+      ${concatStringsSep "\n" (mapAttrsToList (name: service: ''
+        if echo "$NEW_SERVICES" | grep -xq ${name}; then
+          bash -c ${escapeShellArg (concatStringsSep " \\\n " ([
+            "set -a && source ${service.registrationConfigFile} &&"
+            "gitlab-runner register"
+            "--non-interactive"
+            "--name ${name}"
+            "--executor ${service.executor}"
+            "--limit ${toString service.limit}"
+            "--request-concurrency ${toString service.requestConcurrency}"
+            "--maximum-timeout ${toString service.maximumTimeout}"
+          ] ++ service.registrationFlags
+            ++ optional (service.buildsDir != null)
+            "--builds-dir ${service.buildsDir}"
+            ++ optional (service.preCloneScript != null)
+            "--pre-clone-script ${service.preCloneScript}"
+            ++ optional (service.preBuildScript != null)
+            "--pre-build-script ${service.preBuildScript}"
+            ++ optional (service.postBuildScript != null)
+            "--post-build-script ${service.postBuildScript}"
+            ++ optional (service.tagList != [ ])
+            "--tag-list ${concatStringsSep "," service.tagList}"
+            ++ optional service.runUntagged
+            "--run-untagged"
+            ++ optional service.protected
+            "--access-level ref_protected"
+            ++ optional service.debugTraceDisabled
+            "--debug-trace-disabled"
+            ++ map (e: "--env ${escapeShellArg e}") (mapAttrsToList (name: value: "${name}=${value}") service.environmentVariables)
+            ++ optionals (service.executor == "docker") (
+              assert (
+                assertMsg (service.dockerImage != null)
+                  "dockerImage option is required for docker executor (${name})");
+              [ "--docker-image ${service.dockerImage}" ]
+              ++ optional service.dockerDisableCache
+              "--docker-disable-cache"
+              ++ optional service.dockerPrivileged
+              "--docker-privileged"
+              ++ map (v: "--docker-volumes ${escapeShellArg v}") service.dockerVolumes
+              ++ map (v: "--docker-extra-hosts ${escapeShellArg v}") service.dockerExtraHosts
+              ++ map (v: "--docker-allowed-images ${escapeShellArg v}") service.dockerAllowedImages
+              ++ map (v: "--docker-allowed-services ${escapeShellArg v}") service.dockerAllowedServices
+            )
+          ))} && sleep 1
+        fi
+      '') hashedServices)}
+
+      # unregister old services
+      for NAME in $(echo "$OLD_SERVICES")
+      do
+        [ ! -z "$NAME" ] && gitlab-runner unregister \
+          --name "$NAME" && sleep 1
+      done
+
+      # update global options
+      remarshal --if toml --of json ${configPath} \
+        | jq -cM '.check_interval = ${toString cfg.checkInterval} |
+                  .concurrent = ${toString cfg.concurrent}' \
+        | remarshal --if json --of toml \
+        | sponge ${configPath}
+
+      # make config file readable by service
+      chown -R --reference=$HOME $(dirname ${configPath})
+    '');
+  startScript = pkgs.writeShellScriptBin "gitlab-runner-start" ''
+    export CONFIG_FILE=${configPath}
+    exec gitlab-runner run --working-directory $HOME
+  '';
 in
 {
   options.services.gitlab-runner = {
     enable = mkEnableOption "Gitlab Runner";
-
     configFile = mkOption {
+      type = types.nullOr types.path;
       default = null;
       description = ''
         Configuration file for gitlab-runner.
-        Use this option in favor of configOptions to avoid placing CI tokens in the nix store.
 
-        <option>configFile</option> takes precedence over <option>configOptions</option>.
+        <option>configFile</option> takes precedence over <option>services</option>.
+        <option>checkInterval</option> and <option>concurrent</option> will be ignored too.
 
-        Warning: Not using <option>configFile</option> will potentially result in secrets
-        leaking into the WORLD-READABLE nix store.
+        This option is deprecated, please use <option>services</option> instead.
+        You can use <option>registrationConfigFile</option> and
+        <option>registrationFlags</option>
+        for settings not covered by this module.
       '';
-      type = types.nullOr types.path;
     };
-
-    configOptions = mkOption {
+    checkInterval = mkOption {
+      type = types.int;
+      default = 0;
+      example = literalExample "with lib; (length (attrNames config.services.gitlab-runner.services)) * 3";
       description = ''
-        Configuration for gitlab-runner
-        <option>configFile</option> will take precedence over this option.
-
-        Warning: all Configuration, especially CI token, will be stored in a
-        WORLD-READABLE file in the Nix Store.
-
-        If you want to protect your CI token use <option>configFile</option> instead.
+        Defines the interval length, in seconds, between new jobs check.
+        The default value is 3;
+        if set to 0 or lower, the default value will be used.
+        See <link xlink:href="https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-check_interval-works">runner documentation</link> for more information.
+      '';
+    };
+    concurrent = mkOption {
+      type = types.int;
+      default = 1;
+      example = literalExample "config.nix.maxJobs";
+      description = ''
+        Limits how many jobs globally can be run concurrently.
+        The most upper limit of jobs using all defined runners.
+        0 does not mean unlimited.
       '';
-      type = types.attrs;
-      example = {
-        concurrent = 2;
-        runners = [{
-          name = "docker-nix-1.11";
-          url = "https://CI/";
-          token = "TOKEN";
-          executor = "docker";
-          builds_dir = "";
-          docker = {
-            host = "";
-            image = "nixos/nix:1.11";
-            privileged = true;
-            disable_cache = true;
-            cache_dir = "";
-          };
-        }];
-      };
     };
-
     gracefulTermination = mkOption {
-      default = false;
       type = types.bool;
+      default = false;
       description = ''
-        Finish all remaining jobs before stopping, restarting or reconfiguring.
-        If not set gitlab-runner will stop immediatly without waiting for jobs to finish,
-        which will lead to failed builds.
+        Finish all remaining jobs before stopping.
+        If not set gitlab-runner will stop immediatly without waiting
+        for jobs to finish, which will lead to failed builds.
       '';
     };
-
     gracefulTimeout = mkOption {
-      default = "infinity";
       type = types.str;
+      default = "infinity";
       example = "5min 20s";
-      description = ''Time to wait until a graceful shutdown is turned into a forceful one.'';
-    };
-
-    workDir = mkOption {
-      default = "/var/lib/gitlab-runner";
-      type = types.path;
-      description = "The working directory used";
+      description = ''
+        Time to wait until a graceful shutdown is turned into a forceful one.
+      '';
     };
-
     package = mkOption {
-      description = "Gitlab Runner package to use";
+      type = types.package;
       default = pkgs.gitlab-runner;
       defaultText = "pkgs.gitlab-runner";
-      type = types.package;
       example = literalExample "pkgs.gitlab-runner_1_11";
+      description = "Gitlab Runner package to use.";
     };
-
-    packages = mkOption {
-      default = [ pkgs.bash pkgs.docker-machine ];
-      defaultText = "[ pkgs.bash pkgs.docker-machine ]";
+    extraPackages = mkOption {
       type = types.listOf types.package;
+      default = [ ];
       description = ''
-        Packages to add to PATH for the gitlab-runner process.
+        Extra packages to add to PATH for the gitlab-runner process.
       '';
     };
+    services = mkOption {
+      description = "GitLab Runner services.";
+      default = { };
+      example = literalExample ''
+        {
+          # runner for building in docker via host's nix-daemon
+          # nix store will be readable in runner, might be insecure
+          nix = {
+            # File should contain at least these two variables:
+            # `CI_SERVER_URL`
+            # `REGISTRATION_TOKEN`
+            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
+            dockerImage = "alpine";
+            dockerVolumes = [
+              "/nix/store:/nix/store:ro"
+              "/nix/var/nix/db:/nix/var/nix/db:ro"
+              "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro"
+            ];
+            dockerDisableCache = true;
+            preBuildScript = pkgs.writeScript "setup-container" '''
+              mkdir -p -m 0755 /nix/var/log/nix/drvs
+              mkdir -p -m 0755 /nix/var/nix/gcroots
+              mkdir -p -m 0755 /nix/var/nix/profiles
+              mkdir -p -m 0755 /nix/var/nix/temproots
+              mkdir -p -m 0755 /nix/var/nix/userpool
+              mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
+              mkdir -p -m 1777 /nix/var/nix/profiles/per-user
+              mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
+              mkdir -p -m 0700 "$HOME/.nix-defexpr"
 
-  };
+              . ''${pkgs.nix}/etc/profile.d/nix.sh
 
+              ''${pkgs.nix}/bin/nix-env -i ''${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])}
+
+              ''${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
+              ''${pkgs.nix}/bin/nix-channel --update nixpkgs
+            ''';
+            environmentVariables = {
+              ENV = "/etc/profile";
+              USER = "root";
+              NIX_REMOTE = "daemon";
+              PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin";
+              NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
+            };
+            tagList = [ "nix" ];
+          };
+          # runner for building docker images
+          docker-images = {
+            # File should contain at least these two variables:
+            # `CI_SERVER_URL`
+            # `REGISTRATION_TOKEN`
+            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
+            dockerImage = "docker:stable";
+            dockerVolumes = [
+              "/var/run/docker.sock:/var/run/docker.sock"
+            ];
+            tagList = [ "docker-images" ];
+          };
+          # runner for executing stuff on host system (very insecure!)
+          # make sure to add required packages (including git!)
+          # to `environment.systemPackages`
+          shell = {
+            # File should contain at least these two variables:
+            # `CI_SERVER_URL`
+            # `REGISTRATION_TOKEN`
+            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
+            executor = "shell";
+            tagList = [ "shell" ];
+          };
+          # runner for everything else
+          default = {
+            # File should contain at least these two variables:
+            # `CI_SERVER_URL`
+            # `REGISTRATION_TOKEN`
+            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
+            dockerImage = "debian:stable";
+          };
+        }
+      '';
+      type = types.attrsOf (types.submodule {
+        options = {
+          registrationConfigFile = mkOption {
+            type = types.path;
+            description = ''
+              Absolute path to a file with environment variables
+              used for gitlab-runner registration.
+              A list of all supported environment variables can be found in
+              <literal>gitlab-runner register --help</literal>.
+
+              Ones that you probably want to set is
+
+              <literal>CI_SERVER_URL=&lt;CI server URL&gt;</literal>
+
+              <literal>REGISTRATION_TOKEN=&lt;registration secret&gt;</literal>
+            '';
+          };
+          registrationFlags = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            example = [ "--docker-helper-image my/gitlab-runner-helper" ];
+            description = ''
+              Extra command-line flags passed to
+              <literal>gitlab-runner register</literal>.
+              Execute <literal>gitlab-runner register --help</literal>
+              for a list of supported flags.
+            '';
+          };
+          environmentVariables = mkOption {
+            type = types.attrsOf types.str;
+            default = { };
+            example = { NAME = "value"; };
+            description = ''
+              Custom environment variables injected to build environment.
+              For secrets you can use <option>registrationConfigFile</option>
+              with <literal>RUNNER_ENV</literal> variable set.
+            '';
+          };
+          executor = mkOption {
+            type = types.str;
+            default = "docker";
+            description = ''
+              Select executor, eg. shell, docker, etc.
+              See <link xlink:href="https://docs.gitlab.com/runner/executors/README.html">runner documentation</link> for more information.
+            '';
+          };
+          buildsDir = mkOption {
+            type = types.nullOr types.path;
+            default = null;
+            example = "/var/lib/gitlab-runner/builds";
+            description = ''
+              Absolute path to a directory where builds will be stored
+              in context of selected executor (Locally, Docker, SSH).
+            '';
+          };
+          dockerImage = mkOption {
+            type = types.nullOr types.str;
+            default = null;
+            description = ''
+              Docker image to be used.
+            '';
+          };
+          dockerVolumes = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            example = [ "/var/run/docker.sock:/var/run/docker.sock" ];
+            description = ''
+              Bind-mount a volume and create it
+              if it doesn't exist prior to mounting.
+            '';
+          };
+          dockerDisableCache = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              Disable all container caching.
+            '';
+          };
+          dockerPrivileged = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              Give extended privileges to container.
+            '';
+          };
+          dockerExtraHosts = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            example = [ "other-host:127.0.0.1" ];
+            description = ''
+              Add a custom host-to-IP mapping.
+            '';
+          };
+          dockerAllowedImages = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            example = [ "ruby:*" "python:*" "php:*" "my.registry.tld:5000/*:*" ];
+            description = ''
+              Whitelist allowed images.
+            '';
+          };
+          dockerAllowedServices = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            example = [ "postgres:9" "redis:*" "mysql:*" ];
+            description = ''
+              Whitelist allowed services.
+            '';
+          };
+          preCloneScript = mkOption {
+            type = types.nullOr types.path;
+            default = null;
+            description = ''
+              Runner-specific command script executed before code is pulled.
+            '';
+          };
+          preBuildScript = mkOption {
+            type = types.nullOr types.path;
+            default = null;
+            description = ''
+              Runner-specific command script executed after code is pulled,
+              just before build executes.
+            '';
+          };
+          postBuildScript = mkOption {
+            type = types.nullOr types.path;
+            default = null;
+            description = ''
+              Runner-specific command script executed after code is pulled
+              and just after build executes.
+            '';
+          };
+          tagList = mkOption {
+            type = types.listOf types.str;
+            default = [ ];
+            description = ''
+              Tag list.
+            '';
+          };
+          runUntagged = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              Register to run untagged builds; defaults to
+              <literal>true</literal> when <option>tagList</option> is empty.
+            '';
+          };
+          limit = mkOption {
+            type = types.int;
+            default = 0;
+            description = ''
+              Limit how many jobs can be handled concurrently by this service.
+              0 (default) simply means don't limit.
+            '';
+          };
+          requestConcurrency = mkOption {
+            type = types.int;
+            default = 0;
+            description = ''
+              Limit number of concurrent requests for new jobs from GitLab.
+            '';
+          };
+          maximumTimeout = mkOption {
+            type = types.int;
+            default = 0;
+            description = ''
+              What is the maximum timeout (in seconds) that will be set for
+              job when using this Runner. 0 (default) simply means don't limit.
+            '';
+          };
+          protected = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              When set to true Runner will only run on pipelines
+              triggered on protected branches.
+            '';
+          };
+          debugTraceDisabled = mkOption {
+            type = types.bool;
+            default = false;
+            description = ''
+              When set to true Runner will disable the possibility of
+              using the <literal>CI_DEBUG_TRACE</literal> feature.
+            '';
+          };
+        };
+      });
+    };
+  };
   config = mkIf cfg.enable {
+    warnings = optional (cfg.configFile != null) "services.gitlab-runner.`configFile` is deprecated, please use services.gitlab-runner.`services`.";
+    environment.systemPackages = [ cfg.package ];
     systemd.services.gitlab-runner = {
-      path = cfg.packages;
-      environment = config.networking.proxy.envVars // {
-        # Gitlab runner will not start if the HOME variable is not set
-        HOME = cfg.workDir;
-      };
       description = "Gitlab Runner";
+      documentation = [ "https://docs.gitlab.com/runner/" ];
       after = [ "network.target" ]
         ++ optional hasDocker "docker.service";
       requires = optional hasDocker "docker.service";
       wantedBy = [ "multi-user.target" ];
+      environment = config.networking.proxy.envVars // {
+        HOME = "/var/lib/gitlab-runner";
+      };
+      path = with pkgs; [
+        bash
+        gawk
+        jq
+        moreutils
+        remarshal
+        utillinux
+        cfg.package.bin
+      ] ++ cfg.extraPackages;
       reloadIfChanged = true;
-      restartTriggers = [
-         config.environment.etc."gitlab-runner/config.toml".source
-      ];
       serviceConfig = {
+        # Set `DynamicUser` under `systemd.services.gitlab-runner.serviceConfig`
+        # to `lib.mkForce false` in your configuration to run this service as root.
+        # You can also set `User` and `Group` options to run this service as desired user.
+        # Make sure to restart service or changes won't apply.
+        DynamicUser = true;
         StateDirectory = "gitlab-runner";
-        ExecReload= "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-        ExecStart = ''${cfg.package.bin}/bin/gitlab-runner run \
-          --working-directory ${cfg.workDir} \
-          --config /etc/gitlab-runner/config.toml \
-          --service gitlab-runner \
-          --user gitlab-runner \
-        '';
-
-      } //  optionalAttrs (cfg.gracefulTermination) {
+        SupplementaryGroups = optional hasDocker "docker";
+        ExecStartPre = "!${configureScript}/bin/gitlab-runner-configure";
+        ExecStart = "${startScript}/bin/gitlab-runner-start";
+        ExecReload = "!${configureScript}/bin/gitlab-runner-configure";
+      } // optionalAttrs (cfg.gracefulTermination) {
         TimeoutStopSec = "${cfg.gracefulTimeout}";
         KillSignal = "SIGQUIT";
         KillMode = "process";
       };
     };
-
-    # Make the gitlab-runner command availabe so users can query the runner
-    environment.systemPackages = [ cfg.package ];
-
-    # Make sure the config can be reloaded on change
-    environment.etc."gitlab-runner/config.toml".source = configFile;
-
-    users.users.gitlab-runner = {
-      group = "gitlab-runner";
-      extraGroups = optional hasDocker "docker";
-      uid = config.ids.uids.gitlab-runner;
-      home = cfg.workDir;
-      createHome = true;
-    };
-
-    users.groups.gitlab-runner.gid = config.ids.gids.gitlab-runner;
+    # Enable docker if `docker` executor is used in any service
+    virtualisation.docker.enable = mkIf (
+      any (s: s.executor == "docker") (attrValues cfg.services)
+    ) (mkDefault true);
   };
+  imports = [
+    (mkRenamedOptionModule [ "services" "gitlab-runner" "packages" ] [ "services" "gitlab-runner" "extraPackages" ] )
+    (mkRemovedOptionModule [ "services" "gitlab-runner" "configOptions" ] "Use services.gitlab-runner.services option instead" )
+    (mkRemovedOptionModule [ "services" "gitlab-runner" "workDir" ] "You should move contents of workDir (if any) to /var/lib/gitlab-runner" )
+  ];
 }
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index 19e11b31d9ca..608f64a68fb0 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -269,6 +269,7 @@ in
       };
 
       enableSmtp = mkOption {
+        type = types.bool;
         default = true;
         description = "Whether to enable smtp in master.cf.";
       };
diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix
index 21e92cfee016..ed1439745ac9 100644
--- a/nixos/modules/services/mail/roundcube.nix
+++ b/nixos/modules/services/mail/roundcube.nix
@@ -7,7 +7,7 @@ let
   fpm = config.services.phpfpm.pools.roundcube;
   localDB = cfg.database.host == "localhost";
   user = cfg.database.username;
-  phpWithPspell = pkgs.php.withExtensions (e: [ e.pspell ] ++ pkgs.php.enabledExtensions);
+  phpWithPspell = pkgs.php.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled);
 in
 {
   options.services.roundcube = {
diff --git a/nixos/modules/services/mail/spamassassin.nix b/nixos/modules/services/mail/spamassassin.nix
index f6c0b9c794c9..4e642542ec66 100644
--- a/nixos/modules/services/mail/spamassassin.nix
+++ b/nixos/modules/services/mail/spamassassin.nix
@@ -15,6 +15,7 @@ in
       enable = mkEnableOption "the SpamAssassin daemon";
 
       debug = mkOption {
+        type = types.bool;
         default = false;
         description = "Whether to run the SpamAssassin daemon in debug mode";
       };
diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix
index 84f49f964b12..5e7c1e668288 100644
--- a/nixos/modules/services/misc/autofs.nix
+++ b/nixos/modules/services/misc/autofs.nix
@@ -57,6 +57,7 @@ in
       };
 
       debug = mkOption {
+        type = types.bool;
         default = false;
         description = ''
           Pass -d and -7 to automount and write log to the system journal.
diff --git a/nixos/modules/services/misc/disnix.nix b/nixos/modules/services/misc/disnix.nix
index 0776ac679088..69386cdbb381 100644
--- a/nixos/modules/services/misc/disnix.nix
+++ b/nixos/modules/services/misc/disnix.nix
@@ -25,10 +25,7 @@ in
         description = "Whether to support multi-user mode by enabling the Disnix D-Bus service";
       };
 
-      useWebServiceInterface = mkOption {
-        default = false;
-        description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
-      };
+      useWebServiceInterface = mkEnableOption "the DisnixWebService interface running on Apache Tomcat";
 
       package = mkOption {
         type = types.path;
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index aa9589853797..730166b04d20 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -180,7 +180,7 @@ let
         ${optionalString (cfg.smtp.passwordFile != null) ''password: "@smtpPassword@",''}
         domain: "${cfg.smtp.domain}",
         ${optionalString (cfg.smtp.authentication != null) "authentication: :${cfg.smtp.authentication},"}
-        enable_starttls_auto: ${toString cfg.smtp.enableStartTLSAuto},
+        enable_starttls_auto: ${boolToString cfg.smtp.enableStartTLSAuto},
         ca_file: "/etc/ssl/certs/ca-certificates.crt",
         openssl_verify_mode: '${cfg.smtp.opensslVerifyMode}'
       }
diff --git a/nixos/modules/services/misc/pykms.nix b/nixos/modules/services/misc/pykms.nix
index 25aa27ae7673..d6aeae48ccb6 100644
--- a/nixos/modules/services/misc/pykms.nix
+++ b/nixos/modules/services/misc/pykms.nix
@@ -82,6 +82,7 @@ in {
         ]);
         ProtectHome = "tmpfs";
         WorkingDirectory = libDir;
+        SyslogIdentifier = "pykms";
         Restart = "on-failure";
         MemoryLimit = cfg.memoryLimit;
       };
diff --git a/nixos/modules/services/misc/sssd.nix b/nixos/modules/services/misc/sssd.nix
index 36008d257410..77f6ccfe64f0 100644
--- a/nixos/modules/services/misc/sssd.nix
+++ b/nixos/modules/services/misc/sssd.nix
@@ -75,6 +75,11 @@ in {
       };
 
       system.nssModules = optional cfg.enable pkgs.sssd;
+      system.nssDatabases = {
+        passwd = [ "sss" ];
+        shadow = [ "sss" ];
+        services = [ "sss" ];
+      };
       services.dbus.packages = [ pkgs.sssd ];
     })
 
diff --git a/nixos/modules/services/networking/gogoclient.nix b/nixos/modules/services/networking/gogoclient.nix
index c9b03bca7112..99455b183144 100644
--- a/nixos/modules/services/networking/gogoclient.nix
+++ b/nixos/modules/services/networking/gogoclient.nix
@@ -19,6 +19,7 @@ in
         '';
       };
       autorun = mkOption {
+        type = types.bool;
         default = true;
         description = ''
           Whether to automatically start the tunnel.
diff --git a/nixos/modules/services/networking/hostapd.nix b/nixos/modules/services/networking/hostapd.nix
index 12c0626a9414..6418ae699431 100644
--- a/nixos/modules/services/networking/hostapd.nix
+++ b/nixos/modules/services/networking/hostapd.nix
@@ -72,6 +72,7 @@ in
       };
 
       noScan = mkOption {
+        type = types.bool;
         default = false;
         description = ''
           Do not scan for overlapping BSSs in HT40+/- mode.
@@ -127,6 +128,7 @@ in
       };
 
       wpa = mkOption {
+        type = types.bool;
         default = true;
         description = ''
           Enable WPA (IEEE 802.11i/D3.0) to authenticate with the access point.
diff --git a/nixos/modules/services/networking/openfire.nix b/nixos/modules/services/networking/openfire.nix
index c74f3611f79e..fe0499d52323 100644
--- a/nixos/modules/services/networking/openfire.nix
+++ b/nixos/modules/services/networking/openfire.nix
@@ -12,6 +12,7 @@ with lib;
       enable = mkEnableOption "OpenFire XMPP server";
 
       usePostgreSQL = mkOption {
+        type = types.bool;
         default = true;
         description = "
           Whether you use PostgreSQL service for your storage back-end.
diff --git a/nixos/modules/services/networking/ssh/lshd.nix b/nixos/modules/services/networking/ssh/lshd.nix
index 892e59778c34..41d0584080e4 100644
--- a/nixos/modules/services/networking/ssh/lshd.nix
+++ b/nixos/modules/services/networking/ssh/lshd.nix
@@ -54,21 +54,25 @@ in
       };
 
       syslog = mkOption {
+        type = types.bool;
         default = true;
         description = ''Whether to enable syslog output.'';
       };
 
       passwordAuthentication = mkOption {
+        type = types.bool;
         default = true;
         description = ''Whether to enable password authentication.'';
       };
 
       publicKeyAuthentication = mkOption {
+        type = types.bool;
         default = true;
         description = ''Whether to enable public key authentication.'';
       };
 
       rootLogin = mkOption {
+        type = types.bool;
         default = false;
         description = ''Whether to enable remote root login.'';
       };
@@ -90,11 +94,13 @@ in
       };
 
       tcpForwarding = mkOption {
+        type = types.bool;
         default = true;
         description = ''Whether to enable TCP/IP forwarding.'';
       };
 
       x11Forwarding = mkOption {
+        type = types.bool;
         default = true;
         description = ''Whether to enable X11 forwarding.'';
       };
diff --git a/nixos/modules/services/networking/tcpcrypt.nix b/nixos/modules/services/networking/tcpcrypt.nix
index 18f2e135124b..5a91054e1668 100644
--- a/nixos/modules/services/networking/tcpcrypt.nix
+++ b/nixos/modules/services/networking/tcpcrypt.nix
@@ -15,6 +15,7 @@ in
   options = {
 
     networking.tcpcrypt.enable = mkOption {
+      type = types.bool;
       default = false;
       description = ''
         Whether to enable opportunistic TCP encryption. If the other end
diff --git a/nixos/modules/services/networking/thelounge.nix b/nixos/modules/services/networking/thelounge.nix
index 875d8f661697..a1b06703484b 100644
--- a/nixos/modules/services/networking/thelounge.nix
+++ b/nixos/modules/services/networking/thelounge.nix
@@ -62,7 +62,6 @@ in {
     systemd.services.thelounge = {
       description = "The Lounge web IRC client";
       wantedBy = [ "multi-user.target" ];
-      environment = { THELOUNGE_HOME = dataDir; };
       preStart = "ln -sf ${pkgs.writeText "config.js" configJsData} ${dataDir}/config.js";
       serviceConfig = {
         User = "thelounge";
diff --git a/nixos/modules/services/networking/wicd.nix b/nixos/modules/services/networking/wicd.nix
index 03c6bd28aaba..aa10a50f876a 100644
--- a/nixos/modules/services/networking/wicd.nix
+++ b/nixos/modules/services/networking/wicd.nix
@@ -9,6 +9,7 @@ with lib;
   options = {
 
     networking.wicd.enable = mkOption {
+      type = types.bool;
       default = false;
       description = ''
         Whether to start <command>wicd</command>. Wired and
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index 59306d625e6b..e67badfcd29e 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -153,6 +153,16 @@ in
         '';
       };
 
+      allowFrom = mkOption {
+        type = types.listOf types.str;
+        default = [ "localhost" ];
+        example = [ "all" ];
+        apply = concatMapStringsSep "\n" (x: "Allow ${x}");
+        description = ''
+          From which hosts to allow unconditional access.
+        '';
+      };
+
       bindirCmds = mkOption {
         type = types.lines;
         internal = true;
@@ -403,19 +413,19 @@ in
 
         <Location />
           Order allow,deny
-          Allow localhost
+          ${cfg.allowFrom}
         </Location>
 
         <Location /admin>
           Order allow,deny
-          Allow localhost
+          ${cfg.allowFrom}
         </Location>
 
         <Location /admin/conf>
           AuthType Basic
           Require user @SYSTEM
           Order allow,deny
-          Allow localhost
+          ${cfg.allowFrom}
         </Location>
 
         <Policy default>
diff --git a/nixos/modules/services/web-apps/mediawiki.nix b/nixos/modules/services/web-apps/mediawiki.nix
index e9ed53857d81..0a5b6047bb58 100644
--- a/nixos/modules/services/web-apps/mediawiki.nix
+++ b/nixos/modules/services/web-apps/mediawiki.nix
@@ -29,7 +29,7 @@ let
       '') cfg.skins)}
 
       ${concatStringsSep "\n" (mapAttrsToList (k: v: ''
-        ln -s ${v} $out/share/mediawiki/extensions/${k}
+        ln -s ${if v != null then v else "$src/share/mediawiki/extensions/${k}"} $out/share/mediawiki/extensions/${k}
       '') cfg.extensions)}
     '';
   };
@@ -204,17 +204,28 @@ in
         default = {};
         type = types.attrsOf types.path;
         description = ''
-          List of paths whose content is copied to the 'skins'
-          subdirectory of the MediaWiki installation.
+          Attribute set of paths whose content is copied to the <filename>skins</filename>
+          subdirectory of the MediaWiki installation in addition to the default skins.
         '';
       };
 
       extensions = mkOption {
         default = {};
-        type = types.attrsOf types.path;
+        type = types.attrsOf (types.nullOr types.path);
         description = ''
-          List of paths whose content is copied to the 'extensions'
-          subdirectory of the MediaWiki installation.
+          Attribute set of paths whose content is copied to the <filename>extensions</filename>
+          subdirectory of the MediaWiki installation and enabled in configuration.
+
+          Use <literal>null</literal> instead of path to enable extensions that are part of MediaWiki.
+        '';
+        example = literalExample ''
+          {
+            Matomo = pkgs.fetchzip {
+              url = "https://github.com/DaSchTour/matomo-mediawiki-extension/archive/v4.0.1.tar.gz";
+              sha256 = "0g5rd3zp0avwlmqagc59cg9bbkn3r7wx7p6yr80s644mj6dlvs1b";
+            };
+            ParserFunctions = null;
+          }
         '';
       };
 
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index 5f6f2bc7a16d..f826096bf608 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -11,8 +11,8 @@ let
       base = pkgs.php74;
     in
       base.buildEnv {
-        extensions = e: with e;
-          base.enabledExtensions ++ [
+        extensions = { enabled, all }: with all;
+          enabled ++ [
             apcu redis memcached imagick
           ];
         extraConfig = phpOptionsStr;
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index 653c17068346..8abee7130d7c 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -338,7 +338,7 @@ let
     }
     ''
       cat ${php}/etc/php.ini > $out
-      cat ${php}/lib/custom-php.ini > $out
+      cat ${php.phpIni} > $out
       echo "$options" >> $out
     '';
 
diff --git a/nixos/modules/services/web-servers/jboss/default.nix b/nixos/modules/services/web-servers/jboss/default.nix
index 3a125982831b..ca5b8635fc00 100644
--- a/nixos/modules/services/web-servers/jboss/default.nix
+++ b/nixos/modules/services/web-servers/jboss/default.nix
@@ -60,6 +60,7 @@ in
       };
 
       useJK = mkOption {
+        type = types.bool;
         default = false;
         description = "Whether to use to connector to the Apache HTTP server";
       };
diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.xml b/nixos/modules/services/x11/desktop-managers/pantheon.xml
index 9541f2cfd4ee..7905ceebd9aa 100644
--- a/nixos/modules/services/x11/desktop-managers/pantheon.xml
+++ b/nixos/modules/services/x11/desktop-managers/pantheon.xml
@@ -1,7 +1,7 @@
 <chapter xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xml:id="chap-pantheon">
- <title>Pantheon Destkop</title>
+ <title>Pantheon Desktop</title>
  <para>
   Pantheon is the desktop environment created for the elementary OS distribution. It is written from scratch in Vala, utilizing GNOME technologies with GTK 3 and Granite.
  </para>
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index d7bef68e5bcb..622ea62f3a91 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -93,16 +93,17 @@ in
       };
 
       wayland = mkOption {
+        type = types.bool;
         default = true;
         description = ''
           Allow GDM to run on Wayland instead of Xserver.
           Note to enable Wayland with Nvidia you need to
           enable the <option>nvidiaWayland</option>.
         '';
-        type = types.bool;
       };
 
       nvidiaWayland = mkOption {
+        type = types.bool;
         default = false;
         description = ''
           Whether to allow wayland to be used with the proprietary
diff --git a/nixos/modules/services/x11/hardware/digimend.nix b/nixos/modules/services/x11/hardware/digimend.nix
index a9f5640905aa..b1b1682f00b2 100644
--- a/nixos/modules/services/x11/hardware/digimend.nix
+++ b/nixos/modules/services/x11/hardware/digimend.nix
@@ -16,12 +16,7 @@ in
 
     services.xserver.digimend = {
 
-      enable = mkOption {
-        default = false;
-        description = ''
-          Whether to enable the digimend drivers for Huion/XP-Pen/etc. tablets.
-        '';
-      };
+      enable = mkEnableOption "the digimend drivers for Huion/XP-Pen/etc. tablets";
 
     };