diff options
Diffstat (limited to 'nixos/modules/services')
30 files changed, 793 insertions, 625 deletions
diff --git a/nixos/modules/services/continuous-integration/buildbot/master.nix b/nixos/modules/services/continuous-integration/buildbot/master.nix index 0f07e6133bb..9c615fbe885 100644 --- a/nixos/modules/services/continuous-integration/buildbot/master.nix +++ b/nixos/modules/services/continuous-integration/buildbot/master.nix @@ -199,10 +199,10 @@ in { package = mkOption { type = types.package; - default = pkgs.pythonPackages.buildbot-full; - defaultText = "pkgs.pythonPackages.buildbot-full"; + default = pkgs.python3Packages.buildbot-full; + defaultText = "pkgs.python3Packages.buildbot-full"; description = "Package to use for buildbot."; - example = literalExample "pkgs.python3Packages.buildbot-full"; + example = literalExample "pkgs.python3Packages.buildbot"; }; packages = mkOption { diff --git a/nixos/modules/services/continuous-integration/buildbot/worker.nix b/nixos/modules/services/continuous-integration/buildbot/worker.nix index 4130ec918a7..49e04ca3622 100644 --- a/nixos/modules/services/continuous-integration/buildbot/worker.nix +++ b/nixos/modules/services/continuous-integration/buildbot/worker.nix @@ -118,10 +118,10 @@ in { package = mkOption { type = types.package; - default = pkgs.pythonPackages.buildbot-worker; - defaultText = "pkgs.pythonPackages.buildbot-worker"; + default = pkgs.python3Packages.buildbot-worker; + defaultText = "pkgs.python3Packages.buildbot-worker"; description = "Package to use for buildbot worker."; - example = literalExample "pkgs.python3Packages.buildbot-worker"; + example = literalExample "pkgs.python2Packages.buildbot-worker"; }; packages = mkOption { diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix index 467feb09b3a..89291d4438f 100644 --- a/nixos/modules/services/databases/mysql.nix +++ b/nixos/modules/services/databases/mysql.nix @@ -103,6 +103,24 @@ in }; initialDatabases = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.str; + description = '' + The name of the database to create. + ''; + }; + schema = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The initial schema of the database; if null (the default), + an empty database is created. + ''; + }; + }; + }); default = []; description = '' List of database names and their initial schemas that should be used to create databases on the first startup @@ -115,11 +133,13 @@ in }; initialScript = mkOption { + type = types.nullOr types.lines; default = null; description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database"; }; ensureDatabases = mkOption { + type = types.listOf types.str; default = []; description = '' Ensures that the specified databases exist. @@ -134,6 +154,38 @@ in }; ensureUsers = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.str; + description = '' + Name of the user to ensure. + ''; + }; + ensurePermissions = mkOption { + type = types.attrsOf types.str; + default = {}; + description = '' + Permissions to ensure for the user, specified as attribute set. + The attribute names specify the database and tables to grant the permissions for, + separated by a dot. You may use wildcards here. + The attribute values specfiy the permissions to grant. + You may specify one or multiple comma-separated SQL privileges here. + + For more information on how to specify the target + and on which privileges exist, see the + <link xlink:href="https://mariadb.com/kb/en/library/grant/">GRANT syntax</link>. + The attributes are used as <code>GRANT ''${attrName} ON ''${attrValue}</code>. + ''; + example = literalExample '' + { + "database.*" = "ALL PRIVILEGES"; + "*.*" = "SELECT, LOCK TABLES"; + } + ''; + }; + }; + }); default = []; description = '' Ensures that the specified users exist and have at least the ensured permissions. @@ -143,20 +195,22 @@ in option is changed. This means that users created and permissions assigned once through this option or otherwise have to be removed manually. ''; - example = literalExample ''[ - { - name = "nextcloud"; - ensurePermissions = { - "nextcloud.*" = "ALL PRIVILEGES"; - }; - } - { - name = "backup"; - ensurePermissions = { - "*.*" = "SELECT, LOCK TABLES"; - }; - } - ]''; + example = literalExample '' + [ + { + name = "nextcloud"; + ensurePermissions = { + "nextcloud.*" = "ALL PRIVILEGES"; + }; + } + { + name = "backup"; + ensurePermissions = { + "*.*" = "SELECT, LOCK TABLES"; + }; + } + ] + ''; }; # FIXME: remove this option; it's a really bad idea. diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix index 21c6a0b8db4..c101e7375af 100644 --- a/nixos/modules/services/databases/openldap.nix +++ b/nixos/modules/services/databases/openldap.nix @@ -8,7 +8,20 @@ let openldap = pkgs.openldap; dataFile = pkgs.writeText "ldap-contents.ldif" cfg.declarativeContents; - configFile = pkgs.writeText "slapd.conf" cfg.extraConfig; + configFile = pkgs.writeText "slapd.conf" ((optionalString cfg.defaultSchemas '' + include ${pkgs.openldap.out}/etc/schema/core.schema + include ${pkgs.openldap.out}/etc/schema/cosine.schema + include ${pkgs.openldap.out}/etc/schema/inetorgperson.schema + include ${pkgs.openldap.out}/etc/schema/nis.schema + '') + '' + ${cfg.extraConfig} + database ${cfg.database} + suffix ${cfg.suffix} + rootdn ${cfg.rootdn} + rootpw ${cfg.rootpw} + directory ${cfg.dataDir} + ${cfg.extraDatabaseConfig} + ''); configOpts = if cfg.configDir == null then "-f ${configFile}" else "-F ${cfg.configDir}"; in @@ -54,6 +67,52 @@ in description = "The database directory."; }; + defaultSchemas = mkOption { + type = types.bool; + default = true; + description = '' + Include the default schemas core, cosine, inetorgperson and nis. + This setting will be ignored if configDir is set. + ''; + }; + + database = mkOption { + type = types.str; + default = "mdb"; + description = '' + Database type to use for the LDAP. + This setting will be ignored if configDir is set. + ''; + }; + + suffix = mkOption { + type = types.str; + example = "dc=example,dc=org"; + description = '' + Specify the DN suffix of queries that will be passed to this backend + database. + This setting will be ignored if configDir is set. + ''; + }; + + rootdn = mkOption { + type = types.str; + example = "cn=admin,dc=example,dc=org"; + description = '' + Specify the distinguished name that is not subject to access control + or administrative limit restrictions for operations on this database. + This setting will be ignored if configDir is set. + ''; + }; + + rootpw = mkOption { + type = types.str; + description = '' + Password for the root user. + This setting will be ignored if configDir is set. + ''; + }; + logLevel = mkOption { type = types.str; default = "0"; @@ -118,6 +177,39 @@ in # ... ''; }; + + extraDatabaseConfig = mkOption { + type = types.lines; + default = ""; + description = '' + slapd.conf configuration after the database option. + This setting will be ignored if configDir is set. + ''; + example = '' + # Indices to maintain for this directory + # unique id so equality match only + index uid eq + # allows general searching on commonname, givenname and email + index cn,gn,mail eq,sub + # allows multiple variants on surname searching + index sn eq,sub + # sub above includes subintial,subany,subfinal + # optimise department searches + index ou eq + # if searches will include objectClass uncomment following + # index objectClass eq + # shows use of default index parameter + index default eq,sub + # indices missing - uses default eq,sub + index telephonenumber + + # other database parameters + # read more in slapd.conf reference section + cachesize 10000 + checkpoint 128 15 + ''; + }; + }; }; diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index aeab445a998..87b236dd5fd 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -238,6 +238,7 @@ in User = "postgres"; Group = "postgres"; PermissionsStartOnly = true; + RuntimeDirectory = "postgresql"; Type = if lib.versionAtLeast cfg.package.version "9.6" then "notify" else "simple"; diff --git a/nixos/modules/services/desktops/gsignond.nix b/nixos/modules/services/desktops/gsignond.nix index cf26e05d5c1..5ab9add9f32 100644 --- a/nixos/modules/services/desktops/gsignond.nix +++ b/nixos/modules/services/desktops/gsignond.nix @@ -9,6 +9,8 @@ let in { + meta.maintainers = pkgs.pantheon.maintainers; + ###### interface options = { diff --git a/nixos/modules/services/desktops/pantheon/contractor.nix b/nixos/modules/services/desktops/pantheon/contractor.nix index bd538db7241..2638a21df73 100644 --- a/nixos/modules/services/desktops/pantheon/contractor.nix +++ b/nixos/modules/services/desktops/pantheon/contractor.nix @@ -6,6 +6,8 @@ with lib; { + meta.maintainers = pkgs.pantheon.maintainers; + ###### interface options = { diff --git a/nixos/modules/services/desktops/pantheon/files.nix b/nixos/modules/services/desktops/pantheon/files.nix index 2edbe5b3a6d..577aad6c298 100644 --- a/nixos/modules/services/desktops/pantheon/files.nix +++ b/nixos/modules/services/desktops/pantheon/files.nix @@ -6,6 +6,8 @@ with lib; { + meta.maintainers = pkgs.pantheon.maintainers; + ###### interface options = { diff --git a/nixos/modules/services/mail/davmail.nix b/nixos/modules/services/mail/davmail.nix index a0cb81f84da..5b5cc294e5c 100644 --- a/nixos/modules/services/mail/davmail.nix +++ b/nixos/modules/services/mail/davmail.nix @@ -58,18 +58,26 @@ in config = mkIf cfg.enable { - services.davmail.config.davmail = mapAttrs (name: mkDefault) { - server = true; - disableUpdateCheck = true; - logFilePath = "/var/log/davmail/davmail.log"; - logFileSize = "1MB"; - mode = "auto"; - url = cfg.url; - caldavPort = 1080; - imapPort = 1143; - ldapPort = 1389; - popPort = 1110; - smtpPort = 1025; + services.davmail.config = { + davmail = mapAttrs (name: mkDefault) { + server = true; + disableUpdateCheck = true; + logFilePath = "/var/log/davmail/davmail.log"; + logFileSize = "1MB"; + mode = "auto"; + url = cfg.url; + caldavPort = 1080; + imapPort = 1143; + ldapPort = 1389; + popPort = 1110; + smtpPort = 1025; + }; + log4j = { + logger.davmail = mkDefault "WARN"; + logger.httpclient.wire = mkDefault "WARN"; + logger.org.apache.commons.httpclient = mkDefault "WARN"; + rootLogger = mkDefault "WARN"; + }; }; systemd.services.davmail = { diff --git a/nixos/modules/services/mail/mailcatcher.nix b/nixos/modules/services/mail/mailcatcher.nix new file mode 100644 index 00000000000..2c6aadadce9 --- /dev/null +++ b/nixos/modules/services/mail/mailcatcher.nix @@ -0,0 +1,60 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.mailcatcher; + + inherit (lib) mkEnableOption mkIf mkOption types; +in +{ + # interface + + options = { + + services.mailcatcher = { + enable = mkEnableOption "Enable MailCatcher."; + + http.ip = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "The ip address of the http server."; + }; + + http.port = mkOption { + type = types.port; + default = 1080; + description = "The port address of the http server."; + }; + + smtp.ip = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "The ip address of the smtp server."; + }; + + smtp.port = mkOption { + type = types.port; + default = 1025; + description = "The port address of the smtp server."; + }; + }; + + }; + + # implementation + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.mailcatcher ]; + + systemd.services.mailcatcher = { + description = "MailCatcher Service"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + DynamicUser = true; + Restart = "always"; + ExecStart = "${pkgs.mailcatcher}/bin/mailcatcher --foreground --no-quit --http-ip ${cfg.http.ip} --http-port ${toString cfg.http.port} --smtp-ip ${cfg.smtp.ip} --smtp-port ${toString cfg.smtp.port}"; + }; + }; + }; +} diff --git a/nixos/modules/services/misc/docker-registry.nix b/nixos/modules/services/misc/docker-registry.nix index f3d90e532c8..c87607d2666 100644 --- a/nixos/modules/services/misc/docker-registry.nix +++ b/nixos/modules/services/misc/docker-registry.nix @@ -14,9 +14,10 @@ let log.fields.service = "registry"; storage = { cache.blobdescriptor = blobCache; - filesystem.rootdirectory = cfg.storagePath; delete.enabled = cfg.enableDelete; - }; + } // (if cfg.storagePath != null + then { filesystem.rootdirectory = cfg.storagePath; } + else {}); http = { addr = "${cfg.listenAddress}:${builtins.toString cfg.port}"; headers.X-Content-Type-Options = ["nosniff"]; @@ -61,9 +62,12 @@ in { }; storagePath = mkOption { - type = types.path; + type = types.nullOr types.path; default = "/var/lib/docker-registry"; - description = "Docker registry storage path."; + description = '' + Docker registry storage path for the filesystem storage backend. Set to + null to configure another backend via extraConfig. + ''; }; enableDelete = mkOption { @@ -140,9 +144,12 @@ in { startAt = optional cfg.enableGarbageCollect cfg.garbageCollectDates; }; - users.users.docker-registry = { - createHome = true; - home = cfg.storagePath; - }; + users.users.docker-registry = + if cfg.storagePath != null + then { + createHome = true; + home = cfg.storagePath; + } + else {}; }; } diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index baa1c855c11..71277b48ecd 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -160,6 +160,22 @@ let ''; }; + gitlab-rails = pkgs.stdenv.mkDerivation rec { + name = "gitlab-rails"; + buildInputs = [ pkgs.makeWrapper ]; + dontBuild = true; + unpackPhase = ":"; + installPhase = '' + mkdir -p $out/bin + makeWrapper ${cfg.packages.gitlab.rubyEnv}/bin/rails $out/bin/gitlab-rails \ + ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \ + --set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip pkgs.git pkgs.gnutar config.services.postgresql.package pkgs.coreutils pkgs.procps ]}:$PATH' \ + --run 'cd ${cfg.packages.gitlab}/share/gitlab' + ''; + }; + + extraGitlabRb = pkgs.writeText "extra-gitlab.rb" cfg.extraGitlabRb; + smtpSettings = pkgs.writeText "gitlab-smtp-settings.rb" '' if Rails.env.production? Rails.application.config.action_mailer.delivery_method = :smtp @@ -266,6 +282,26 @@ in { description = "Extra configuration in config/database.yml."; }; + extraGitlabRb = mkOption { + type = types.str; + default = ""; + example = '' + if Rails.env.production? + Rails.application.config.action_mailer.delivery_method = :sendmail + ActionMailer::Base.delivery_method = :sendmail + ActionMailer::Base.sendmail_settings = { + location: "/run/wrappers/bin/sendmail", + arguments: "-i -t" + } + end + ''; + description = '' + Extra configuration to be placed in config/extra-gitlab.rb. This can + be used to add configuration not otherwise exposed through this module's + options. + ''; + }; + host = mkOption { type = types.str; default = config.networking.hostName; @@ -439,7 +475,7 @@ in { config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.git gitlab-rake cfg.packages.gitlab-shell ]; + environment.systemPackages = [ pkgs.git gitlab-rake gitlab-rails cfg.packages.gitlab-shell ]; # Redis is required for the sidekiq queue runner. services.redis.enable = mkDefault true; @@ -512,6 +548,7 @@ in { wantedBy = [ "multi-user.target" ]; path = with pkgs; [ openssh + procps # See https://gitlab.com/gitlab-org/gitaly/issues/1562 gitAndTools.git cfg.packages.gitaly.rubyEnv cfg.packages.gitaly.rubyEnv.wrappedRuby @@ -586,6 +623,7 @@ in { [ -L /run/gitlab/uploads ] || ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads cp ${cfg.packages.gitlab}/share/gitlab/VERSION ${cfg.statePath}/VERSION cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config + ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb ${optionalString cfg.smtp.enable '' ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb ''} diff --git a/nixos/modules/services/misc/plex.nix b/nixos/modules/services/misc/plex.nix index b06c1c4bbc6..fce9b29011f 100644 --- a/nixos/modules/services/misc/plex.nix +++ b/nixos/modules/services/misc/plex.nix @@ -146,7 +146,7 @@ in PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6"; PLEX_MEDIA_SERVER_TMPDIR="/tmp"; PLEX_MEDIA_SERVER_USE_SYSLOG="true"; - LD_LIBRARY_PATH="/run/opengl-driver/lib:${cfg.package}/usr/lib/plexmediaserver"; + LD_LIBRARY_PATH="/run/opengl-driver/lib:${cfg.package}/usr/lib/plexmediaserver/lib"; LC_ALL="en_US.UTF-8"; LANG="en_US.UTF-8"; }; diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index aba64e4f60f..4ea891262e5 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -261,10 +261,14 @@ let fi ''; + canonicalizePortList = + ports: lib.unique (builtins.sort builtins.lessThan ports); + commonOptions = { allowedTCPPorts = mkOption { - type = types.listOf types.int; + type = types.listOf types.port; default = [ ]; + apply = canonicalizePortList; example = [ 22 80 ]; description = '' @@ -274,7 +278,7 @@ let }; allowedTCPPortRanges = mkOption { - type = types.listOf (types.attrsOf types.int); + type = types.listOf (types.attrsOf types.port); default = [ ]; example = [ { from = 8999; to = 9003; } ]; description = @@ -285,8 +289,9 @@ let }; allowedUDPPorts = mkOption { - type = types.listOf types.int; + type = types.listOf types.port; default = [ ]; + apply = canonicalizePortList; example = [ 53 ]; description = '' @@ -295,7 +300,7 @@ let }; allowedUDPPortRanges = mkOption { - type = types.listOf (types.attrsOf types.int); + type = types.listOf (types.attrsOf types.port); default = [ ]; example = [ { from = 60000; to = 61000; } ]; description = diff --git a/nixos/modules/services/networking/quicktun.nix b/nixos/modules/services/networking/quicktun.nix new file mode 100644 index 00000000000..5bcf923f909 --- /dev/null +++ b/nixos/modules/services/networking/quicktun.nix @@ -0,0 +1,118 @@ +{ config, pkgs, lib, ... }: + +let + + cfg = config.services.quicktun; + +in + +with lib; + +{ + options = { + + services.quicktun = mkOption { + default = { }; + description = "QuickTun tunnels"; + type = types.attrsOf (types.submodule { + options = { + tunMode = mkOption { + type = types.int; + default = 0; + example = 1; + description = ""; + }; + + remoteAddress = mkOption { + type = types.str; + example = "tunnel.example.com"; + description = ""; + }; + + localAddress = mkOption { + type = types.str; + example = "0.0.0.0"; + description = ""; + }; + + localPort = mkOption { + type = types.int; + default = 2998; + description = ""; + }; + + remotePort = mkOption { + type = types.int; + default = 2998; + description = ""; + }; + + remoteFloat = mkOption { + type = types.int; + default = 0; + description = ""; + }; + + protocol = mkOption { + type = types.str; + default = "nacltai"; + description = ""; + }; + + privateKey = mkOption { + type = types.str; + description = ""; + }; + + publicKey = mkOption { + type = types.str; + description = ""; + }; + + timeWindow = mkOption { + type = types.int; + default = 5; + description = ""; + }; + + upScript = mkOption { + type = types.lines; + default = ""; + description = ""; + }; + }; + }); + }; + + }; + + config = mkIf (cfg != []) { + systemd.services = fold (a: b: a // b) {} ( + mapAttrsToList (name: qtcfg: { + "quicktun-${name}" = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + environment = { + "INTERFACE" = name; + "TUN_MODE" = toString qtcfg.tunMode; + "REMOTE_ADDRESS" = qtcfg.remoteAddress; + "LOCAL_ADDRESS" = qtcfg.localAddress; + "LOCAL_PORT" = toString qtcfg.localPort; + "REMOTE_PORT" = toString qtcfg.remotePort; + "REMOTE_FLOAT" = toString qtcfg.remoteFloat; + "PRIVATE_KEY" = qtcfg.privateKey; + "PUBLIC_KEY" = qtcfg.publicKey; + "TIME_WINDOW" = toString qtcfg.timeWindow; + "TUN_UP_SCRIPT" = pkgs.writeScript "quicktun-${name}-up.sh" qtcfg.upScript; + "SUID" = "nobody"; + }; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.quicktun}/bin/quicktun.${qtcfg.protocol}"; + }; + }; + }) cfg + ); + }; + +} diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 6f6977b38a1..3bc31832946 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -64,8 +64,8 @@ in sendmail. See <option>security.wrappers</option> If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root - will is allowed to have its own crontab file. The /var/cron/cron.deny file - is created automatically for you. So every user can use a crontab. + is allowed to have its own crontab file. The /var/cron/cron.deny file + is created automatically for you, so every user can use a crontab. Many nixos modules set systemCronJobs, so if you decide to disable vixie cron and enable another cron daemon, you may want it to get its system crontab diff --git a/nixos/modules/services/search/elasticsearch-curator.nix b/nixos/modules/services/search/elasticsearch-curator.nix index 8cb1275284a..9620c3e0b6d 100644 --- a/nixos/modules/services/search/elasticsearch-curator.nix +++ b/nixos/modules/services/search/elasticsearch-curator.nix @@ -86,7 +86,7 @@ in { startAt = cfg.interval; serviceConfig = { ExecStart = - "${pkgs.python3Packages.elasticsearch-curator}/bin/curator" + + "${pkgs.elasticsearch-curator}/bin/curator" + " --config ${curatorConfig} ${curatorAction}"; }; }; diff --git a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix index 50775c5262f..644aad82df2 100644 --- a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix +++ b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix @@ -3,112 +3,18 @@ poolName = "icingaweb2"; phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock"; - formatBool = b: if b then "1" else "0"; - - configIni = let - config = cfg.generalConfig; - in '' - [global] - show_stacktraces = "${formatBool config.showStacktraces}" - show_application_state_messages = "${formatBool config.showApplicationStateMessages}" - module_path = "${pkgs.icingaweb2}/modules${optionalString (builtins.length config.modulePath > 0) ":${concatStringsSep ":" config.modulePath}"}" - config_backend = "${config.configBackend}" - ${optionalString (config.configBackend == "db") ''config_resource = "${config.configResource}"''} - - [logging] - log = "${config.log}" - ${optionalString (config.log != "none") ''level = "${config.logLevel}"''} - ${optionalString (config.log == "php" || config.log == "syslog") ''application = "${config.logApplication}"''} - ${optionalString (config.log == "syslog") ''facility = "${config.logFacility}"''} - ${optionalString (config.log == "file") ''file = "${config.logFile}"''} - - [themes] - default = "${config.themeDefault}" - disabled = "${formatBool config.themeDisabled}" - - [authentication] - ${optionalString (config.authDefaultDomain != null) ''default_domain = "${config.authDefaultDomain}"''} - ''; - - resourcesIni = concatStringsSep "\n" (mapAttrsToList (name: config: '' - [${name}] - type = "${config.type}" - ${optionalString (config.type == "db") '' - db = "${config.db}" - host = "${config.host}" - ${optionalString (config.port != null) ''port = "${toString config.port}"''} - username = "${config.username}" - password = "${config.password}" - dbname = "${config.dbname}" - ${optionalString (config.charset != null) ''charset = "${config.charset}"''} - use_ssl = "${formatBool config.useSSL}" - ${optionalString (config.sslCert != null) ''ssl_cert = "${config.sslCert}"''} - ${optionalString (config.sslKey != null) ''ssl_cert = "${config.sslKey}"''} - ${optionalString (config.sslCA != null) ''ssl_cert = "${config.sslCA}"''} - ${optionalString (config.sslCApath != null) ''ssl_cert = "${config.sslCApath}"''} - ${optionalString (config.sslCipher != null) ''ssl_cert = "${config.sslCipher}"''} - ''} - ${optionalString (config.type == "ldap") '' - hostname = "${config.host}" - ${optionalString (config.port != null) ''port = "${toString config.port}"''} - root_dn = "${config.rootDN}" - bind_dn = "${config.username}" - bind_pw = "${config.password}" - encryption = "${config.ldapEncryption}" - timeout = "${toString config.ldapTimeout}" - ''} - ${optionalString (config.type == "ssh") '' - user = "${config.username}" - private_key = "${config.sshPrivateKey}" - ''} - - '') cfg.resources); - - authenticationIni = concatStringsSep "\n" (mapAttrsToList (name: config: '' - [${name}] - backend = "${config.backend}" - ${optionalString (config.domain != null) ''domain = "${config.domain}"''} - ${optionalString (config.backend == "external" && config.externalStripRegex != null) ''strip_username_regexp = "${config.externalStripRegex}"''} - ${optionalString (config.backend != "external") ''resource = "${config.resource}"''} - ${optionalString (config.backend == "ldap" || config.backend == "msldap") '' - ${optionalString (config.ldapUserClass != null) ''user_class = "${config.ldapUserClass}"''} - ${optionalString (config.ldapUserNameAttr != null) ''user_name_attribute = "${config.ldapUserNameAttr}"''} - ${optionalString (config.ldapFilter != null) ''filter = "${config.ldapFilter}"''} - ''} - '') cfg.authentications); - - groupsIni = concatStringsSep "\n" (mapAttrsToList (name: config: '' - [${name}] - backend = "${config.backend}" - resource = "${config.resource}" - ${optionalString (config.backend != "db") '' - ${optionalString (config.ldapUserClass != null) ''user_class = "${config.ldapUserClass}"''} - ${optionalString (config.ldapUserNameAttr != null) ''user_name_attribute = "${config.ldapUserNameAttr}"''} - ${optionalString (config.ldapGroupClass != null) ''group_class = "${config.ldapGroupClass}"''} - ${optionalString (config.ldapGroupNameAttr != null) ''group_name_attribute = "${config.ldapGroupNameAttr}"''} - ${optionalString (config.ldapGroupFilter != null) ''group_filter = "${config.ldapGroupFilter}"''} - ''} - ${optionalString (config.backend == "msldap" && config.ldapNestedSearch) ''nested_group_search = "1"''} - '') cfg.groupBackends); - - rolesIni = let - optionalList = var: attribute: optionalString (builtins.length var > 0) ''${attribute} = "${concatStringsSep "," var}"''; - in concatStringsSep "\n" (mapAttrsToList (name: config: '' - [${name}] - ${optionalList config.users "users"} - ${optionalList config.groups "groups"} - ${optionalList config.permissions "permissions"} - ${optionalList config.permissions "permissions"} - ${concatStringsSep "\n" (mapAttrsToList (key: value: optionalList value key) config.extraAssignments)} - '') cfg.roles); - + defaultConfig = { + global = { + module_path = "${pkgs.icingaweb2}/modules${optionalString (builtins.length config.modulePath > 0) ":${concatStringsSep ":" config.modulePath}"}"; + }; + }; in { options.services.icingaweb2 = with types; { enable = mkEnableOption "the icingaweb2 web interface"; pool = mkOption { type = str; - default = "${poolName}"; + default = poolName; description = '' Name of existing PHP-FPM pool that is used to run Icingaweb2. If not specified, a pool will automatically created with default values. @@ -143,7 +49,7 @@ in { default = {}; example = literalExample '' { - "snow" = pkgs.icingaweb2Modules.theme-snow; + "snow" = icingaweb2Modules.theme-snow; } ''; description = '' @@ -153,419 +59,130 @@ in { ''; }; - generalConfig = { - mutable = mkOption { - type = bool; - default = false; - description = '' - Make config.ini mutable (e.g. via the web interface). - Not that you need to update module_path manually. - ''; - }; - - showStacktraces = mkOption { - type = bool; - default = true; - description = "Enable stack traces in the Web UI"; - }; - - showApplicationStateMessages = mkOption { - type = bool; - default = true; - description = "Enable application state messages in the Web UI"; - }; - - modulePath = mkOption { - type = listOf str; - default = []; - description = "List of additional module search paths"; - }; - - configBackend = mkOption { - type = enum [ "ini" "db" "none" ]; - default = "db"; - description = "Where to store user preferences"; - }; - - configResource = mkOption { - type = nullOr str; - default = null; - description = "Database resource where user preferences are stored (if they are stored in a database)"; - }; - - log = mkOption { - type = enum [ "syslog" "php" "file" "none" ]; - default = "syslog"; - description = "Logging target"; - }; - - logLevel = mkOption { - type = enum [ "ERROR" "WARNING" "INFO" "DEBUG" ]; - default = "ERROR"; - description = "Maximum logging level to emit"; - }; - - logApplication = mkOption { - type = str; - default = "icingaweb2"; - description = "Application name to log under (syslog and php log)"; - }; - - logFacility = mkOption { - type = enum [ "user" "local0" "local1" "local2" "local3" "local4" "local5" "local6" "local7" ]; - default = "user"; - description = "Syslog facility to log to"; - }; - - logFile = mkOption { - type = str; - default = "/var/log/icingaweb2/icingaweb2.log"; - description = "File to log to"; - }; - - themeDefault = mkOption { - type = str; - default = "Icinga"; - description = "Name of the default theme"; - }; - - themeDisabled = mkOption { - type = bool; - default = false; - description = "Disallow users to change the theme"; - }; - - authDefaultDomain = mkOption { - type = nullOr str; - default = null; - description = "Domain for users logging in without a qualified domain"; + generalConfig = mkOption { + type = nullOr attrs; + default = null; + example = { + general = { + showStacktraces = 1; + config_resource = "icingaweb_db"; + }; + logging = { + log = "syslog"; + level = "CRITICAL"; + }; }; - }; + description = '' + config.ini contents. + Will automatically be converted to a .ini file. + If you don't set global.module_path, the module will take care of it. - mutableResources = mkOption { - type = bool; - default = false; - description = "Make resources.ini mutable (e.g. via the web interface)"; + If the value is null, no config.ini is created and you can + modify it manually (e.g. via the web interface). + Note that you need to update module_path manually. + ''; }; resources = mkOption { - default = {}; - description = "Icingaweb 2 resources to define"; - type = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - visible = false; - default = name; - type = str; - description = "Name of this resource"; - }; - - type = mkOption { - type = enum [ "db" "ldap" "ssh" ]; - default = "db"; - description = "Type of this resouce"; - }; - - db = mkOption { - type = enum [ "mysql" "pgsql" ]; - default = "mysql"; - description = "Type of this database resource"; - }; - - host = mkOption { - type = str; - description = "Host to connect to"; - }; - - port = mkOption { - type = nullOr port; - default = null; - description = "Port to connect on"; - }; - - username = mkOption { - type = str; - description = "Database or SSH user or LDAP bind DN to connect with"; - }; - - password = mkOption { - type = str; - description = "Password for the database user or LDAP bind DN"; - }; - - dbname = mkOption { - type = str; - description = "Name of the database to connect to"; - }; - - charset = mkOption { - type = nullOr str; - default = null; - example = "utf8"; - description = "Database character set to connect with"; - }; - - useSSL = mkOption { - type = nullOr bool; - default = false; - description = "Whether to connect to the database using SSL"; - }; - - sslCert = mkOption { - type = nullOr str; - default = null; - description = "The file path to the SSL certificate. Only available for the mysql database."; - }; - - sslKey = mkOption { - type = nullOr str; - default = null; - description = "The file path to the SSL key. Only available for the mysql database."; - }; - - sslCA = mkOption { - type = nullOr str; - default = null; - description = "The file path to the SSL certificate authority. Only available for the mysql database."; - }; - - sslCApath = mkOption { - type = nullOr str; - default = null; - description = "The file path to the directory that contains the trusted SSL CA certificates in PEM format. Only available for the mysql database."; - }; - - sslCipher = mkOption { - type = nullOr str; - default = null; - description = "A list of one or more permissible ciphers to use for SSL encryption, in a format understood by OpenSSL. Only available for the mysql database."; - }; - - rootDN = mkOption { - type = str; - description = "Root object of the LDAP tree"; - }; - - ldapEncryption = mkOption { - type = enum [ "none" "starttls" "ldaps" ]; - default = "none"; - description = "LDAP encryption to use"; - }; - - ldapTimeout = mkOption { - type = ints.positive; - default = 5; - description = "Connection timeout for every LDAP connection"; - }; - - sshPrivateKey = mkOption { - type = str; - description = "The path to the private key of the user"; - }; + type = nullOr attrs; + default = null; + example = { + icingaweb_db = { + type = "db"; + db = "mysql"; + host = "localhost"; + username = "icingaweb2"; + password = "icingaweb2"; + dbname = "icingaweb2"; }; - })); - }; + }; + description = '' + resources.ini contents. + Will automatically be converted to a .ini file. - mutableAuthConfig = mkOption { - type = bool; - default = true; - description = "Make authentication.ini mutable (e.g. via the web interface)"; + If the value is null, no resources.ini is created and you can + modify it manually (e.g. via the web interface). + Note that if you set passwords here, they will go into the nix store. + ''; }; authentications = mkOption { - default = {}; - description = "Icingaweb 2 authentications to define"; - type = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - visible = false; - default = name; - type = str; - description = "Name of this authentication"; - }; - - backend = mkOption { - type = enum [ "external" "ldap" "msldap" "db" ]; - default = "db"; - description = "The type of this authentication backend"; - }; - - domain = mkOption { - type = nullOr str; - default = null; - description = "Domain for domain-aware authentication"; - }; - - externalStripRegex = mkOption { - type = nullOr str; - default = null; - description = "Regular expression to strip off specific user name parts"; - }; - - resource = mkOption { - type = str; - description = "Name of the database/LDAP resource"; - }; - - ldapUserClass = mkOption { - type = nullOr str; - default = null; - description = "LDAP user class"; - }; - - ldapUserNameAttr = mkOption { - type = nullOr str; - default = null; - description = "LDAP attribute which contains the username"; - }; - - ldapFilter = mkOption { - type = nullOr str; - default = null; - description = "LDAP search filter"; - }; + type = nullOr attrs; + default = null; + example = { + icingaweb = { + backend = "db"; + resource = "icingaweb_db"; }; - })); - }; + }; + description = '' + authentication.ini contents. + Will automatically be converted to a .ini file. - mutableGroupsConfig = mkOption { - type = bool; - default = true; - description = "Make groups.ini mutable (e.g. via the web interface)"; + If the value is null, no authentication.ini is created and you can + modify it manually (e.g. via the web interface). + ''; }; groupBackends = mkOption { - default = {}; - description = "Icingaweb 2 group backends to define"; - type = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - visible = false; - default = name; - type = str; - description = "Name of this group backend"; - }; - - backend = mkOption { - type = enum [ "ldap" "msldap" "db" ]; - default = "db"; - description = "The type of this group backend"; - }; - - resource = mkOption { - type = str; - description = "Name of the database/LDAP resource"; - }; - - ldapUserClass = mkOption { - type = nullOr str; - default = null; - description = "LDAP user class"; - }; - - ldapUserNameAttr = mkOption { - type = nullOr str; - default = null; - description = "LDAP attribute which contains the username"; - }; - - ldapGroupClass = mkOption { - type = nullOr str; - default = null; - description = "LDAP group class"; - }; - - ldapGroupNameAttr = mkOption { - type = nullOr str; - default = null; - description = "LDAP attribute which contains the groupname"; - }; - - ldapGroupFilter = mkOption { - type = nullOr str; - default = null; - description = "LDAP group search filter"; - }; - - ldapNestedSearch = mkOption { - type = bool; - default = false; - description = "Enable nested group search in Active Directory based on the user"; - }; + type = nullOr attrs; + default = null; + example = { + icingaweb = { + backend = "db"; + resource = "icingaweb_db"; }; - })); - }; + }; + description = '' + groups.ini contents. + Will automatically be converted to a .ini file. - mutableRolesConfig = mkOption { - type = bool; - default = true; - description = "Make roles.ini mutable (e.g. via the web interface)"; + If the value is null, no groups.ini is created and you can + modify it manually (e.g. via the web interface). + ''; }; roles = mkOption { - default = {}; - description = "Icingaweb 2 roles to define"; - type = attrsOf (submodule ({ name, ... }: { - options = { - name = mkOption { - visible = false; - default = name; - type = str; - description = "Name of this role"; - }; - - users = mkOption { - type = listOf str; - default = []; - description = "List of users that are assigned to the role"; - }; - - groups = mkOption { - type = listOf str; - default = []; - description = "List of groups that are assigned to the role"; - }; - - permissions = mkOption { - type = listOf str; - default = []; - example = [ "application/share/navigation" "config/*" ]; - description = "The permissions to grant"; - }; - - extraAssignments = mkOption { - type = attrsOf (listOf str); - default = {}; - example = { "monitoring/blacklist/properties" = [ "sla" "customer"]; }; - description = "Additional assignments of this role"; - }; + type = nullOr attrs; + default = null; + example = { + Administrators = { + users = "admin"; + permissions = "*"; }; - })); + }; + description = '' + roles.ini contents. + Will automatically be converted to a .ini file. + + If the value is null, no roles.ini is created and you can + modify it manually (e.g. via the web interface). + ''; }; }; config = mkIf cfg.enable { services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") { - "${poolName}" = { - listen = phpfpmSocketName; - phpOptions = '' - extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so - date.timezone = "${cfg.timezone}" - ''; - extraConfig = '' - listen.owner = nginx - listen.group = nginx - listen.mode = 0600 - user = icingaweb2 - pm = dynamic - pm.max_children = 75 - pm.start_servers = 2 - pm.min_spare_servers = 2 - pm.max_spare_servers = 10 - ''; - }; + "${poolName}" = '' + listen = "${phpfpmSocketName}" + listen.owner = nginx + listen.group = nginx + listen.mode = 0600 + user = icingaweb2 + pm = dynamic + pm.max_children = 75 + pm.start_servers = 2 + pm.min_spare_servers = 2 + pm.max_spare_servers = 10 + ''; }; + services.phpfpm.phpOptions = mkIf (cfg.pool == "${poolName}") + '' + extension = ${pkgs.phpPackages.imagick}/lib/php/extensions/imagick.so + date.timezone = "${cfg.timezone}" + ''; + systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ]; services.nginx = { @@ -609,11 +226,11 @@ in { // doModule "test" // doModule "translation" # Configs - // optionalAttrs (!cfg.generalConfig.mutable) { "icingaweb2/config.ini".text = configIni; } - // optionalAttrs (!cfg.mutableResources) { "icingaweb2/resources.ini".text = resourcesIni; } - // optionalAttrs (!cfg.mutableAuthConfig) { "icingaweb2/authentication.ini".text = authenticationIni; } - // optionalAttrs (!cfg.mutableGroupsConfig) { "icingaweb2/groups.ini".text = groupsIni; } - // optionalAttrs (!cfg.mutableRolesConfig) { "icingaweb2/roles.ini".text = rolesIni; }; + // optionalAttrs (cfg.generalConfig != null) { "icingaweb2/config.ini".text = generators.toINI {} (defaultConfig // cfg.generalConfig); } + // optionalAttrs (cfg.resources != null) { "icingaweb2/resources.ini".text = generators.toINI {} cfg.resources; } + // optionalAttrs (cfg.authentications != null) { "icingaweb2/authentication.ini".text = generators.toINI {} cfg.authentications; } + // optionalAttrs (cfg.groupBackends != null) { "icingaweb2/groups.ini".text = generators.toINI {} cfg.groupBackends; } + // optionalAttrs (cfg.roles != null) { "icingaweb2/roles.ini".text = generators.toINI {} cfg.roles; }; # User and group users.groups.icingaweb2 = {}; diff --git a/nixos/modules/services/web-apps/matomo-doc.xml b/nixos/modules/services/web-apps/matomo-doc.xml index 20d2de9f418..021a89be3f6 100644 --- a/nixos/modules/services/web-apps/matomo-doc.xml +++ b/nixos/modules/services/web-apps/matomo-doc.xml @@ -12,15 +12,15 @@ An automatic setup is not suported by Matomo, so you need to configure Matomo itself in the browser-based Matomo setup. </para> - <section xml:id="module-services-matomo-database-setup"> <title>Database Setup</title> + <para> You also need to configure a MariaDB or MySQL database and -user for Matomo yourself, and enter those credentials in your browser. You can use passwordless database authentication via the UNIX_SOCKET authentication plugin with the following SQL commands: - <programlisting> +<programlisting> # For MariaDB INSTALL PLUGIN unix_socket SONAME 'auth_socket'; CREATE DATABASE matomo; @@ -46,30 +46,32 @@ database is not on the same host. </para> </section> - <section xml:id="module-services-matomo-archive-processing"> <title>Archive Processing</title> + <para> - This module comes with the systemd service <literal>matomo-archive-processing.service</literal> - and a timer that automatically triggers archive processing every hour. - This means that you can safely + This module comes with the systemd service + <literal>matomo-archive-processing.service</literal> and a timer that + automatically triggers archive processing every hour. This means that you + can safely <link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour"> - disable browser triggers for Matomo archiving - </link> at <literal>Administration > System > General Settings</literal>. + disable browser triggers for Matomo archiving </link> at + <literal>Administration > System > General Settings</literal>. </para> + <para> With automatic archive processing, you can now also enable to <link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs"> - delete old visitor logs - </link> at <literal>Administration > System > Privacy</literal>, - but make sure that you run <literal>systemctl start matomo-archive-processing.service</literal> - at least once without errors if you have already collected data before, - so that the reports get archived before the source data gets deleted. + delete old visitor logs </link> at <literal>Administration > System > + Privacy</literal>, but make sure that you run <literal>systemctl start + matomo-archive-processing.service</literal> at least once without errors if + you have already collected data before, so that the reports get archived + before the source data gets deleted. </para> </section> - <section xml:id="module-services-matomo-backups"> <title>Backup</title> + <para> You only need to take backups of your MySQL database and the <filename>/var/lib/matomo/config/config.ini.php</filename> file. Use a user @@ -78,9 +80,9 @@ <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/" />. </para> </section> - <section xml:id="module-services-matomo-issues"> <title>Issues</title> + <itemizedlist> <listitem> <para> @@ -97,7 +99,6 @@ </listitem> </itemizedlist> </section> - <section xml:id="module-services-matomo-other-web-servers"> <title>Using other Web Servers than nginx</title> diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 5ad241ace5c..d0e45e1c12a 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -32,7 +32,7 @@ let cd ${pkgs.nextcloud} exec /run/wrappers/bin/sudo -u nextcloud \ NEXTCLOUD_CONFIG_DIR="${cfg.home}/config" \ - ${config.services.phpfpm.phpPackage}/bin/php \ + ${phpPackage}/bin/php \ -c ${pkgs.writeText "php.ini" phpOptionsStr}\ occ $* ''; @@ -172,7 +172,7 @@ in { Database host. Note: for using Unix authentication with PostgreSQL, this should be - set to <literal>/tmp</literal>. + set to <literal>/run/postgresql</literal>. ''; }; dbport = mkOption { @@ -360,7 +360,7 @@ in { environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config"; serviceConfig.Type = "oneshot"; serviceConfig.User = "nextcloud"; - serviceConfig.ExecStart = "${pkgs.php}/bin/php -f ${pkgs.nextcloud}/cron.php"; + serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${pkgs.nextcloud}/cron.php"; }; }; diff --git a/nixos/modules/services/web-apps/nextcloud.xml b/nixos/modules/services/web-apps/nextcloud.xml index 9600d1be7c8..dfefa55c5d5 100644 --- a/nixos/modules/services/web-apps/nextcloud.xml +++ b/nixos/modules/services/web-apps/nextcloud.xml @@ -4,24 +4,26 @@ version="5.0" xml:id="module-services-nextcloud"> <title>Nextcloud</title> - <para> - <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an open-source, self-hostable cloud - platform. The server setup can be automated using - <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. A desktop client is packaged - at <literal>pkgs.nextcloud-client</literal>. + <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an open-source, + self-hostable cloud platform. The server setup can be automated using + <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. A + desktop client is packaged at <literal>pkgs.nextcloud-client</literal>. </para> - <section xml:id="module-services-nextcloud-basic-usage"> <title>Basic usage</title> + <para> Nextcloud is a PHP-based application which requires an HTTP server - (<literal><link linkend="opt-services.nextcloud.enable">services.nextcloud</link></literal> optionally supports - <literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>) and a database - (it's recommended to use <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>). + (<literal><link linkend="opt-services.nextcloud.enable">services.nextcloud</link></literal> + optionally supports + <literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>) + and a database (it's recommended to use + <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>). </para> + <para> - A very basic configuration may look like this: + A very basic configuration may look like this: <programlisting>{ pkgs, ... }: { services.nextcloud = { @@ -31,7 +33,7 @@ config = { <link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql"; <link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud"; - <link linkend="opt-services.nextcloud.config.dbhost">dbhost</link> = "/tmp"; # nextcloud will add /.s.PGSQL.5432 by itself + <link linkend="opt-services.nextcloud.config.dbhost">dbhost</link> = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself <link linkend="opt-services.nextcloud.config.dbname">dbname</link> = "nextcloud"; <link linkend="opt-services.nextcloud.config.adminpassFile">adminpassFile</link> = "/path/to/admin-pass-file"; <link linkend="opt-services.nextcloud.config.adminuser">adminuser</link> = "root"; @@ -55,45 +57,59 @@ <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; }</programlisting> </para> + <para> - The options <literal>hostName</literal> and <literal>nginx.enable</literal> are used internally to configure an - HTTP server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> and <literal>nginx</literal>. - The <literal>config</literal> attribute set is used for the <literal>config.php</literal> which is used - for the application's configuration. - <emphasis>Beware: this isn't entirely pure since the config is modified by the application's runtime!</emphasis> + The options <literal>hostName</literal> and <literal>nginx.enable</literal> + are used internally to configure an HTTP server using + <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> + and <literal>nginx</literal>. The <literal>config</literal> attribute set is + used for the <literal>config.php</literal> which is used for the + application's configuration. <emphasis>Beware: this isn't entirely pure + since the config is modified by the application's runtime!</emphasis> </para> + <para> - In case the application serves multiple hosts (those are checked with - <literal><link xlink:href="http://php.net/manual/en/reserved.variables.server.php">$_SERVER['HTTP_HOST']</link></literal>) - those can be added using - <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>. + In case the application serves multiple hosts (those are checked with + <literal><link xlink:href="http://php.net/manual/en/reserved.variables.server.php">$_SERVER['HTTP_HOST']</link></literal>) + those can be added using + <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>. </para> </section> - <section xml:id="module-services-nextcloud-pitfalls-during-upgrade"> <title>Pitfalls</title> + <para> - Unfortunately Nextcloud appears to be very stateful when it comes to managing its own configuration. The - config file lives in the home directory of the <literal>nextcloud</literal> user (by default - <literal>/var/lib/nextcloud/config/config.php</literal>) and is also used to track several - states of the application (e.g. whether installed or not). + Unfortunately Nextcloud appears to be very stateful when it comes to + managing its own configuration. The config file lives in the home directory + of the <literal>nextcloud</literal> user (by default + <literal>/var/lib/nextcloud/config/config.php</literal>) and is also used to + track several states of the application (e.g. whether installed or not). </para> + <para> - Right now changes to the <literal>services.nextcloud.config</literal> attribute set won't take effect - after the first install - (except <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>) since the actual configuration - file is generated by the NextCloud installer which also sets up critical parts such as the database - structure. + Right now changes to the <literal>services.nextcloud.config</literal> + attribute set won't take effect after the first install (except + <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>) + since the actual configuration file is generated by the NextCloud installer + which also sets up critical parts such as the database structure. </para> + <para> - <emphasis>Warning: don't delete <literal>config.php</literal>! This file tracks the application's state and a deletion can cause unwanted side-effects!</emphasis> + <emphasis>Warning: don't delete <literal>config.php</literal>! This file + tracks the application's state and a deletion can cause unwanted + side-effects!</emphasis> </para> + <para> - <emphasis>Warning: don't rerun <literal>nextcloud-occ maintenance:install</literal>! This command tries to install the application and can cause unwanted side-effects!</emphasis> + <emphasis>Warning: don't rerun <literal>nextcloud-occ + maintenance:install</literal>! This command tries to install the application + and can cause unwanted side-effects!</emphasis> </para> + <para> - The issues are known and reported in <link xlink:href="https://github.com/NixOS/nixpkgs/issues/49783">#49783</link>, for now it's unfortunately necessary to manually work around these issues. + The issues are known and reported in + <link xlink:href="https://github.com/NixOS/nixpkgs/issues/49783">#49783</link>, + for now it's unfortunately necessary to manually work around these issues. </para> </section> - </chapter> diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index 1eac5be2f8d..8f00f81b078 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -705,10 +705,7 @@ in path = [ httpd pkgs.coreutils pkgs.gnugrep ] - ++ # Needed for PHP's mail() function. !!! Probably the - # ssmtp module should export the path to sendmail in - # some way. - optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp + ++ optional enablePHP pkgs.system-sendmail # Needed for PHP's mail() function. ++ concatMap (svc: svc.extraServerPath) allSubservices; environment = diff --git a/nixos/modules/services/web-servers/meguca.nix b/nixos/modules/services/web-servers/meguca.nix index 11aebcb91d8..5a00070dc94 100644 --- a/nixos/modules/services/web-servers/meguca.nix +++ b/nixos/modules/services/web-servers/meguca.nix @@ -86,11 +86,19 @@ in with lib; { default = false; description = "Serve and listen only through HTTPS."; }; + + videoPaths = mkOption { + type = types.listOf types.path; + default = []; + example = [ "/home/okina/Videos/tehe_pero.webm" ]; + description = "Videos that will be symlinked into www/videos."; + }; }; config = mkIf cfg.enable { security.sudo.enable = cfg.enable; services.postgresql.enable = cfg.enable; + services.postgresql.package = pkgs.postgresql_11; services.meguca.passwordFile = mkDefault (pkgs.writeText "meguca-password-file" cfg.password); services.meguca.postgresArgsFile = mkDefault (pkgs.writeText "meguca-postgres-args" cfg.postgresArgs); services.meguca.postgresArgs = mkDefault "user=meguca password=${cfg.password} dbname=meguca sslmode=disable"; @@ -102,8 +110,16 @@ in with lib; { preStart = '' # Ensure folder exists or create it and links and permissions are correct - mkdir -p ${escapeShellArg cfg.dataDir} - ln -sf ${pkgs.meguca}/share/meguca/www ${escapeShellArg cfg.dataDir} + mkdir -p ${escapeShellArg cfg.dataDir}/www + rm -rf ${escapeShellArg cfg.dataDir}/www/videos + ln -sf ${pkgs.meguca}/share/meguca/www/* ${escapeShellArg cfg.dataDir}/www + unlink ${escapeShellArg cfg.dataDir}/www/videos + mkdir -p ${escapeShellArg cfg.dataDir}/www/videos + + for vid in ${escapeShellArg cfg.videoPaths}; do + ln -sf $vid ${escapeShellArg cfg.dataDir}/www/videos + done + chmod 750 ${escapeShellArg cfg.dataDir} chown -R meguca:meguca ${escapeShellArg cfg.dataDir} diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 1c9fbe048f8..3a154ab75ba 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -44,19 +44,7 @@ let } '')); - awkFormat = builtins.toFile "awkFormat-nginx.awk" '' - awk -f - {sub(/^[ \t]+/,"");idx=0} - /\{/{ctx++;idx=1} - /\}/{ctx--} - {id="";for(i=idx;i<ctx;i++)id=sprintf("%s%s", id, "\t");printf "%s%s\n", id, $0} - ''; - - configFile = pkgs.runCommand "nginx.conf" {} ('' - awk -f ${awkFormat} ${pre-configFile} | sed '/^\s*$/d' > $out - ''); - - pre-configFile = pkgs.writeText "pre-nginx.conf" '' + configFile = pkgs.writers.writeNginxConfig "nginx.conf" '' user ${cfg.user} ${cfg.group}; error_log ${cfg.logError}; daemon off; @@ -276,6 +264,7 @@ let ${optionalString (config.tryFiles != null) "try_files ${config.tryFiles};"} ${optionalString (config.root != null) "root ${config.root};"} ${optionalString (config.alias != null) "alias ${config.alias};"} + ${optionalString (config.return != null) "return ${config.return};"} ${config.extraConfig} ${optionalString (config.proxyPass != null && cfg.recommendedProxySettings) "include ${recommendedProxyConfig};"} } @@ -373,7 +362,7 @@ in preStart = mkOption { type = types.lines; default = '' - test -d ${cfg.stateDir}/logs || mkdir -m 750 -p ${cfg.stateDir}/logs + test -d ${cfg.stateDir}/logs || mkdir -m 750 -p ${cfg.stateDir}/logs test `stat -c %a ${cfg.stateDir}` = "750" || chmod 750 ${cfg.stateDir} test `stat -c %a ${cfg.stateDir}/logs` = "750" || chmod 750 ${cfg.stateDir}/logs chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir} diff --git a/nixos/modules/services/web-servers/nginx/location-options.nix b/nixos/modules/services/web-servers/nginx/location-options.nix index 9b44433d384..aeb9b1dd79e 100644 --- a/nixos/modules/services/web-servers/nginx/location-options.nix +++ b/nixos/modules/services/web-servers/nginx/location-options.nix @@ -64,6 +64,15 @@ with lib; ''; }; + return = mkOption { + type = types.nullOr types.str; + default = null; + example = "301 http://example.com$request_uri;"; + description = '' + Adds a return directive, for e.g. redirections. + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; diff --git a/nixos/modules/services/web-servers/unit/default.nix b/nixos/modules/services/web-servers/unit/default.nix new file mode 100644 index 00000000000..a4a9d370d64 --- /dev/null +++ b/nixos/modules/services/web-servers/unit/default.nix @@ -0,0 +1,125 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.unit; + + configFile = pkgs.writeText "unit.json" cfg.config; + +in { + options = { + services.unit = { + enable = mkEnableOption "Unit App Server"; + package = mkOption { + type = types.package; + default = pkgs.unit; + defaultText = "pkgs.unit"; + description = "Unit package to use."; + }; + user = mkOption { + type = types.str; + default = "unit"; + description = "User account under which unit runs."; + }; + group = mkOption { + type = types.str; + default = "unit"; + description = "Group account under which unit runs."; + }; + stateDir = mkOption { + default = "/var/spool/unit"; + description = "Unit data directory."; + }; + logDir = mkOption { + default = "/var/log/unit"; + description = "Unit log directory."; + }; + config = mkOption { + type = types.str; + default = '' + { + "listeners": {}, + "applications": {} + } + ''; + example = literalExample '' + { + "listeners": { + "*:8300": { + "application": "example-php-72" + } + }, + "applications": { + "example-php-72": { + "type": "php 7.2", + "processes": 4, + "user": "nginx", + "group": "nginx", + "root": "/var/www", + "index": "index.php", + "options": { + "file": "/etc/php.d/default.ini", + "admin": { + "max_execution_time": "30", + "max_input_time": "30", + "display_errors": "off", + "display_startup_errors": "off", + "open_basedir": "/dev/urandom:/proc/cpuinfo:/proc/meminfo:/etc/ssl/certs:/var/www", + "disable_functions": "exec,passthru,shell_exec,system" + } + } + } + } + } + ''; + description = "Unit configuration in JSON format. More details here https://unit.nginx.org/configuration"; + }; + }; + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.logDir}' 0750 ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.unit = { + description = "Unit App Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ curl ]; + preStart = '' + test -f '/run/unit/control.unit.sock' || rm -f '/run/unit/control.unit.sock' + ''; + postStart = '' + curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config' + ''; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + AmbientCapabilities = "CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID"; + CapabilityBoundingSet = "CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID"; + ExecStart = '' + ${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \ + --log '${cfg.logDir}/unit.log' --state '${cfg.stateDir}' --no-daemon \ + --user ${cfg.user} --group ${cfg.group} + ''; + RuntimeDirectory = "unit"; + RuntimeDirectoryMode = "0750"; + }; + }; + + users.users = optionalAttrs (cfg.user == "unit") (singleton { + name = "unit"; + group = cfg.group; + }); + + users.groups = optionalAttrs (cfg.group == "unit") (singleton { + name = "unit"; + }); + }; +} diff --git a/nixos/modules/services/x11/colord.nix b/nixos/modules/services/x11/colord.nix index d9e81d75072..17568df091d 100644 --- a/nixos/modules/services/x11/colord.nix +++ b/nixos/modules/services/x11/colord.nix @@ -18,22 +18,23 @@ in { config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.colord ]; + services.dbus.packages = [ pkgs.colord ]; services.udev.packages = [ pkgs.colord ]; - environment.systemPackages = [ pkgs.colord ]; + systemd.packages = [ pkgs.colord ]; - systemd.services.colord = { - description = "Manage, Install and Generate Color Profiles"; - serviceConfig = { - Type = "dbus"; - BusName = "org.freedesktop.ColorManager"; - ExecStart = "${pkgs.colord}/libexec/colord"; - PrivateTmp = true; - }; + environment.etc."tmpfiles.d/colord.conf".source = "${pkgs.colord}/lib/tmpfiles.d/colord.conf"; + + users.users.colord = { + home = "/var/lib/colord"; + group = "colord"; }; + users.groups.colord = {}; + }; } diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 67faddb1ddb..d0278271409 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -14,6 +14,9 @@ let in { + + meta.maintainers = pkgs.pantheon.maintainers; + options = { services.xserver.desktopManager.pantheon = { diff --git a/nixos/modules/services/x11/window-managers/dwm.nix b/nixos/modules/services/x11/window-managers/dwm.nix index a74bfce097d..7777913ce1e 100644 --- a/nixos/modules/services/x11/window-managers/dwm.nix +++ b/nixos/modules/services/x11/window-managers/dwm.nix @@ -25,7 +25,7 @@ in { name = "dwm"; start = '' - ${pkgs.dwm}/bin/dwm & + dwm & waitPID=$! ''; }; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index c4d5b6a9cde..e767b0eda31 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -246,7 +246,7 @@ in default = [ "ati" "cirrus" "vesa" "vmware" "modesetting" ]; example = [ "ati_unfree" "amdgpu" "amdgpu-pro" - "nv" "nvidia" "nvidiaLegacy340" "nvidiaLegacy304" + "nv" "nvidia" "nvidiaLegacy390" "nvidiaLegacy340" "nvidiaLegacy304" ]; # TODO(@oxij): think how to easily add the rest, like those nvidia things relatedPackages = concatLists @@ -259,6 +259,11 @@ in The names of the video drivers the configuration supports. They will be tried in order until one that supports your card is found. + Don't combine those with "incompatible" OpenGL implementations, + e.g. free ones (mesa-based) with proprietary ones. + + For unfree "nvidia*", the supported GPU lists are on + https://www.nvidia.com/object/unix.html ''; }; |