diff options
author | Frederik Rietdijk <fridh@fridh.nl> | 2019-07-13 09:45:40 +0200 |
---|---|---|
committer | Frederik Rietdijk <fridh@fridh.nl> | 2019-07-13 09:45:40 +0200 |
commit | 54065ae20d6c91cab54aa706d6e819baf673b80c (patch) | |
tree | 4b2efeafb2b34de1153ccfb5cf01387842c86143 /nixos/modules | |
parent | 22cb7f25f2f939a5e38f5e0c0920a743c37a9480 (diff) | |
parent | 7803ff314c707ee11a6d8d1c9ac4cde70737d22e (diff) | |
download | nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar.gz nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar.bz2 nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar.lz nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar.xz nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.tar.zst nixpkgs-54065ae20d6c91cab54aa706d6e819baf673b80c.zip |
Merge master into staging-next
Diffstat (limited to 'nixos/modules')
21 files changed, 1030 insertions, 472 deletions
diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix index 2defab51bc3..57cac56bd8a 100644 --- a/nixos/modules/hardware/opengl.nix +++ b/nixos/modules/hardware/opengl.nix @@ -118,6 +118,19 @@ in set. This can be used to add OpenCL drivers, VA-API/VDPAU drivers etc. ''; }; + + setLdLibraryPath = mkOption { + type = types.bool; + internal = true; + default = false; + description = '' + Whether the <literal>LD_LIBRARY_PATH</literal> environment variable + should be set to the locations of driver libraries. Drivers which + rely on overriding libraries should set this to true. Drivers which + support <literal>libglvnd</literal> and other dispatch libraries + instead of overriding libraries should not set this. + ''; + }; }; }; @@ -145,11 +158,8 @@ in ) ]; - environment.sessionVariables.LD_LIBRARY_PATH = - [ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib"; - - environment.variables.XDG_DATA_DIRS = - [ "/run/opengl-driver/share" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/share"; + environment.sessionVariables.LD_LIBRARY_PATH = mkIf cfg.setLdLibraryPath + ([ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib"); hardware.opengl.package = mkDefault (makePackage pkgs); hardware.opengl.package32 = mkDefault (makePackage pkgs.pkgsi686Linux); diff --git a/nixos/modules/hardware/video/amdgpu-pro.nix b/nixos/modules/hardware/video/amdgpu-pro.nix index ab9e0c92020..8e91e9d2baa 100644 --- a/nixos/modules/hardware/video/amdgpu-pro.nix +++ b/nixos/modules/hardware/video/amdgpu-pro.nix @@ -30,10 +30,11 @@ in nixpkgs.config.xorg.abiCompat = "1.19"; services.xserver.drivers = singleton - { name = "amdgpu"; modules = [ package ]; libPath = [ package ]; }; + { name = "amdgpu"; modules = [ package ]; }; hardware.opengl.package = package; hardware.opengl.package32 = package32; + hardware.opengl.setLdLibraryPath = true; boot.extraModulePackages = [ package ]; diff --git a/nixos/modules/hardware/video/ati.nix b/nixos/modules/hardware/video/ati.nix index 6102919f015..f867bba8063 100644 --- a/nixos/modules/hardware/video/ati.nix +++ b/nixos/modules/hardware/video/ati.nix @@ -21,10 +21,11 @@ in nixpkgs.config.xorg.abiCompat = "1.17"; services.xserver.drivers = singleton - { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; }; + { name = "fglrx"; modules = [ ati_x11 ]; }; hardware.opengl.package = ati_x11; hardware.opengl.package32 = pkgs.pkgsi686Linux.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; }; + hardware.opengl.setLdLibraryPath = true; environment.systemPackages = [ ati_x11 ]; diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index a5740929a31..da3c8ee5a9f 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -138,7 +138,6 @@ in services.xserver.drivers = singleton { name = "nvidia"; modules = [ nvidia_x11.bin ]; - libPath = [ nvidia_x11 ]; deviceSection = optionalString optimusCfg.enable '' BusID "${optimusCfg.nvidiaBusId}" diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 14ba5a573b1..1047df95cdf 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -516,7 +516,7 @@ tss = 176; #memcached = 177; # unused, removed 2018-01-03 #ntp = 179; # unused - #zabbix = 180; # unused + zabbix = 180; #redis = 181; # unused, removed 2018-01-03 #unifi = 183; # unused #uptimed = 184; # unused diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 1d1995eda25..db47e69bd4a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -516,6 +516,7 @@ ./services/monitoring/uptime.nix ./services/monitoring/vnstat.nix ./services/monitoring/zabbix-agent.nix + ./services/monitoring/zabbix-proxy.nix ./services/monitoring/zabbix-server.nix ./services/network-filesystems/beegfs.nix ./services/network-filesystems/cachefilesd.nix @@ -782,6 +783,7 @@ ./services/web-apps/virtlyst.nix ./services/web-apps/wordpress.nix ./services/web-apps/youtrack.nix + ./services/web-apps/zabbix.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/caddy.nix ./services/web-servers/fcgiwrap.nix diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 1b77a895d71..e127782e85f 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -171,6 +171,9 @@ with lib; The starting time can be configured via <literal>services.postgresqlBackup.startAt</literal>. '') + # zabbixServer + (mkRenamedOptionModule [ "services" "zabbixServer" "dbServer" ] [ "services" "zabbixServer" "database" "host" ]) + # Profile splitting (mkRenamedOptionModule [ "virtualisation" "growPartition" ] [ "boot" "growPartition" ]) @@ -214,6 +217,7 @@ with lib; (mkRemovedOptionModule [ "services" "winstone" ] "The corresponding package was removed from nixpkgs.") (mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd") (mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.") + (mkRemovedOptionModule [ "services" "zabbixServer" "dbPassword" ] "Use services.zabbixServer.database.passwordFile instead.") # ZSH (mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ]) diff --git a/nixos/modules/services/monitoring/zabbix-agent.nix b/nixos/modules/services/monitoring/zabbix-agent.nix index 0519e7c2ad6..b1645f86110 100644 --- a/nixos/modules/services/monitoring/zabbix-agent.nix +++ b/nixos/modules/services/monitoring/zabbix-agent.nix @@ -1,73 +1,118 @@ -# Zabbix agent daemon. { config, lib, pkgs, ... }: -with lib; - let - cfg = config.services.zabbixAgent; - zabbix = cfg.package; - - stateDir = "/run/zabbix"; - - logDir = "/var/log/zabbix"; - - pidFile = "${stateDir}/zabbix_agentd.pid"; + inherit (lib) mkDefault mkEnableOption mkIf mkOption; + inherit (lib) attrValues concatMapStringsSep literalExample optionalString types; - configFile = pkgs.writeText "zabbix_agentd.conf" - '' - Server = ${cfg.server} + user = "zabbix-agent"; + group = "zabbix-agent"; - LogFile = ${logDir}/zabbix_agentd - - PidFile = ${pidFile} - - StartAgents = 1 + moduleEnv = pkgs.symlinkJoin { + name = "zabbix-agent-module-env"; + paths = attrValues cfg.modules; + }; - ${config.services.zabbixAgent.extraConfig} - ''; + configFile = pkgs.writeText "zabbix_agent.conf" '' + LogType = console + Server = ${cfg.server} + ListenIP = ${cfg.listen.ip} + ListenPort = ${toString cfg.listen.port} + ${optionalString (cfg.modules != {}) "LoadModulePath = ${moduleEnv}/lib"} + ${concatMapStringsSep "\n" (name: "LoadModule = ${name}") (builtins.attrNames cfg.modules)} + ${cfg.extraConfig} + ''; in { - - ###### interface + # interface options = { services.zabbixAgent = { + enable = mkEnableOption "the Zabbix Agent"; - enable = mkOption { - default = false; + package = mkOption { + type = types.package; + default = pkgs.zabbix.agent; + defaultText = "pkgs.zabbix.agent"; + description = "The Zabbix package to use."; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ nettools ]; + defaultText = "[ nettools ]"; + example = "[ nettools mysql ]"; description = '' - Whether to run the Zabbix monitoring agent on this machine. - It will send monitoring data to a Zabbix server. + Packages to be added to the Zabbix <envar>PATH</envar>. + Typically used to add executables for scripts, but can be anything. ''; }; - package = mkOption { - type = types.attrs; # Note: pkgs.zabbixXY isn't a derivation, but an attrset of { server = ...; agent = ...; }. - default = pkgs.zabbix; - defaultText = "pkgs.zabbix"; - example = literalExample "pkgs.zabbix34"; - description = '' - The Zabbix package to use. + modules = mkOption { + type = types.attrsOf types.package; + description = "A set of modules to load."; + default = {}; + example = literalExample '' + { + "dummy.so" = pkgs.stdenv.mkDerivation { + name = "zabbix-dummy-module-''${cfg.package.version}"; + src = cfg.package.src; + buildInputs = [ cfg.package ]; + sourceRoot = "zabbix-''${cfg.package.version}/src/modules/dummy"; + installPhase = ''' + mkdir -p $out/lib + cp dummy.so $out/lib/ + '''; + }; + } ''; }; server = mkOption { - default = "127.0.0.1"; + type = types.str; description = '' The IP address or hostname of the Zabbix server to connect to. ''; }; + listen = { + ip = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + List of comma delimited IP addresses that the agent should listen on. + ''; + }; + + port = mkOption { + type = types.port; + default = 10050; + description = '' + Agent will listen on this port for connections from the server. + ''; + }; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for the Zabbix Agent. + ''; + }; + + # TODO: for bonus points migrate this to https://github.com/NixOS/rfcs/pull/42 extraConfig = mkOption { default = ""; type = types.lines; description = '' - Configuration that is injected verbatim into the configuration file. + Configuration that is injected verbatim into the configuration file. Refer to + <link xlink:href="https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_agentd"/> + for details on supported values. ''; }; @@ -75,38 +120,38 @@ in }; - - ###### implementation + # implementation config = mkIf cfg.enable { - users.users = mkIf (!config.services.zabbixServer.enable) (singleton - { name = "zabbix"; - uid = config.ids.uids.zabbix; - description = "Zabbix daemon user"; - }); + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.listen.port ]; + }; - systemd.services."zabbix-agent" = - { description = "Zabbix Agent"; + users.users.${user} = { + description = "Zabbix Agent daemon user"; + inherit group; + }; - wantedBy = [ "multi-user.target" ]; + users.groups.${group} = { }; - path = [ pkgs.nettools ]; + systemd.services."zabbix-agent" = { + description = "Zabbix Agent"; - preStart = - '' - mkdir -m 0755 -p ${stateDir} ${logDir} - chown zabbix ${stateDir} ${logDir} - ''; + wantedBy = [ "multi-user.target" ]; - serviceConfig.ExecStart = "@${zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}"; - serviceConfig.Type = "forking"; - serviceConfig.RemainAfterExit = true; - serviceConfig.Restart = "always"; - serviceConfig.RestartSec = 2; - }; + path = [ "/run/wrappers" ] ++ cfg.extraPackages; + + serviceConfig = { + ExecStart = "@${cfg.package}/sbin/zabbix_agentd zabbix_agentd -f --config ${configFile}"; + Restart = "always"; + RestartSec = 2; - environment.systemPackages = [ zabbix.agent ]; + User = user; + Group = group; + PrivateTmp = true; + }; + }; }; diff --git a/nixos/modules/services/monitoring/zabbix-proxy.nix b/nixos/modules/services/monitoring/zabbix-proxy.nix new file mode 100644 index 00000000000..c1a45fba4af --- /dev/null +++ b/nixos/modules/services/monitoring/zabbix-proxy.nix @@ -0,0 +1,290 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.zabbixProxy; + pgsql = config.services.postgresql; + mysql = config.services.mysql; + + inherit (lib) mkDefault mkEnableOption mkIf mkOption; + inherit (lib) attrValues concatMapStringsSep literalExample optional optionalAttrs optionalString types; + + user = "zabbix"; + group = "zabbix"; + runtimeDir = "/run/zabbix"; + stateDir = "/var/lib/zabbix"; + passwordFile = "${runtimeDir}/zabbix-dbpassword.conf"; + + moduleEnv = pkgs.symlinkJoin { + name = "zabbix-proxy-module-env"; + paths = attrValues cfg.modules; + }; + + configFile = pkgs.writeText "zabbix_proxy.conf" '' + LogType = console + ListenIP = ${cfg.listen.ip} + ListenPort = ${toString cfg.listen.port} + # TODO: set to cfg.database.socket if database type is pgsql? + DBHost = ${optionalString (cfg.database.createLocally != true) cfg.database.host} + ${optionalString (cfg.database.createLocally != true) "DBPort = ${cfg.database.port}"} + DBName = ${cfg.database.name} + DBUser = ${cfg.database.user} + ${optionalString (cfg.database.passwordFile != null) "Include ${passwordFile}"} + ${optionalString (mysqlLocal && cfg.database.socket != null) "DBSocket = ${cfg.database.socket}"} + SocketDir = ${runtimeDir} + FpingLocation = /run/wrappers/bin/fping + ${optionalString (cfg.modules != {}) "LoadModulePath = ${moduleEnv}/lib"} + ${concatMapStringsSep "\n" (name: "LoadModule = ${name}") (builtins.attrNames cfg.modules)} + ${cfg.extraConfig} + ''; + + mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql"; + pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql"; + +in + +{ + # interface + + options = { + + services.zabbixProxy = { + enable = mkEnableOption "the Zabbix Proxy"; + + package = mkOption { + type = types.package; + default = + if cfg.database.type == "mysql" then pkgs.zabbix.proxy-mysql + else if cfg.database.type == "pgsql" then pkgs.zabbix.proxy-pgsql + else pkgs.zabbix.proxy-sqlite; + defaultText = "pkgs.zabbix.proxy-pgsql"; + description = "The Zabbix package to use."; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ nettools nmap traceroute ]; + defaultText = "[ nettools nmap traceroute ]"; + description = '' + Packages to be added to the Zabbix <envar>PATH</envar>. + Typically used to add executables for scripts, but can be anything. + ''; + }; + + modules = mkOption { + type = types.attrsOf types.package; + description = "A set of modules to load."; + default = {}; + example = literalExample '' + { + "dummy.so" = pkgs.stdenv.mkDerivation { + name = "zabbix-dummy-module-''${cfg.package.version}"; + src = cfg.package.src; + buildInputs = [ cfg.package ]; + sourceRoot = "zabbix-''${cfg.package.version}/src/modules/dummy"; + installPhase = ''' + mkdir -p $out/lib + cp dummy.so $out/lib/ + '''; + }; + } + ''; + }; + + database = { + type = mkOption { + type = types.enum [ "mysql" "pgsql" "sqlite" ]; + example = "mysql"; + default = "pgsql"; + description = "Database engine to use."; + }; + + host = mkOption { + type = types.str; + default = "localhost"; + description = "Database host address."; + }; + + port = mkOption { + type = types.int; + default = if cfg.database.type == "mysql" then mysql.port else pgsql.port; + description = "Database host port."; + }; + + name = mkOption { + type = types.str; + default = "zabbix"; + description = "Database name."; + }; + + user = mkOption { + type = types.str; + default = "zabbix"; + description = "Database user."; + }; + + passwordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/zabbix-dbpassword"; + description = '' + A file containing the password corresponding to + <option>database.user</option>. + ''; + }; + + socket = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/postgresql"; + description = "Path to the unix socket file to use for authentication."; + }; + + createLocally = mkOption { + type = types.bool; + default = true; + description = "Whether to create a local database automatically."; + }; + }; + + listen = { + ip = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + List of comma delimited IP addresses that the trapper should listen on. + Trapper will listen on all network interfaces if this parameter is missing. + ''; + }; + + port = mkOption { + type = types.port; + default = 10051; + description = '' + Listen port for trapper. + ''; + }; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for the Zabbix Proxy. + ''; + }; + + # TODO: for bonus points migrate this to https://github.com/NixOS/rfcs/pull/42 + extraConfig = mkOption { + default = ""; + type = types.lines; + description = '' + Configuration that is injected verbatim into the configuration file. Refer to + <link xlink:href="https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_proxy"/> + for details on supported values. + ''; + }; + + }; + + }; + + # implementation + + config = mkIf cfg.enable { + + assertions = [ + { assertion = !config.services.zabbixServer.enable; + message = "Please choose one of services.zabbixServer or services.zabbixProxy."; + } + { assertion = cfg.database.createLocally -> cfg.database.user == user; + message = "services.zabbixProxy.database.user must be set to ${user} if services.zabbixProxy.database.createLocally is set true"; + } + { assertion = cfg.database.createLocally -> cfg.database.passwordFile == null; + message = "a password cannot be specified if services.zabbixProxy.database.createLocally is set to true"; + } + ]; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.listen.port ]; + }; + + services.mysql = optionalAttrs mysqlLocal { + enable = true; + package = mkDefault pkgs.mariadb; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }; + } + ]; + }; + + services.postgresql = optionalAttrs pgsqlLocal { + enable = true; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; }; + } + ]; + }; + + users.users.${user} = { + description = "Zabbix daemon user"; + uid = config.ids.uids.zabbix; + inherit group; + }; + + users.groups.${group} = { + gid = config.ids.gids.zabbix; + }; + + security.wrappers = { + fping.source = "${pkgs.fping}/bin/fping"; + }; + + systemd.services."zabbix-proxy" = { + description = "Zabbix Proxy"; + + wantedBy = [ "multi-user.target" ]; + after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; + + path = [ "/run/wrappers" ] ++ cfg.extraPackages; + preStart = optionalString pgsqlLocal '' + if ! test -e "${stateDir}/db-created"; then + cat ${cfg.package}/share/zabbix/database/postgresql/schema.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/postgresql/images.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/postgresql/data.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + touch "${stateDir}/db-created" + fi + '' + optionalString mysqlLocal '' + if ! test -e "${stateDir}/db-created"; then + cat ${cfg.package}/share/zabbix/database/mysql/schema.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/mysql/images.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/mysql/data.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + touch "${stateDir}/db-created" + fi + '' + optionalString (cfg.database.passwordFile != null) '' + # create a copy of the supplied password file in a format zabbix can consume + touch ${passwordFile} + chmod 0600 ${passwordFile} + echo -n "DBPassword = " > ${passwordFile} + cat ${cfg.database.passwordFile} >> ${passwordFile} + ''; + + serviceConfig = { + ExecStart = "@${cfg.package}/sbin/zabbix_proxy zabbix_proxy -f --config ${configFile}"; + Restart = "always"; + RestartSec = 2; + + User = user; + Group = group; + RuntimeDirectory = "zabbix"; + StateDirectory = "zabbix"; + PrivateTmp = true; + }; + }; + + }; + +} diff --git a/nixos/modules/services/monitoring/zabbix-server.nix b/nixos/modules/services/monitoring/zabbix-server.nix index fdeab6af441..11311b466c3 100644 --- a/nixos/modules/services/monitoring/zabbix-server.nix +++ b/nixos/modules/services/monitoring/zabbix-server.nix @@ -1,125 +1,292 @@ -# Zabbix server daemon. { config, lib, pkgs, ... }: -with lib; - let - cfg = config.services.zabbixServer; + pgsql = config.services.postgresql; + mysql = config.services.mysql; - stateDir = "/run/zabbix"; + inherit (lib) mkDefault mkEnableOption mkIf mkOption; + inherit (lib) attrValues concatMapStringsSep literalExample optional optionalAttrs optionalString types; - logDir = "/var/log/zabbix"; + user = "zabbix"; + group = "zabbix"; + runtimeDir = "/run/zabbix"; + stateDir = "/var/lib/zabbix"; + passwordFile = "${runtimeDir}/zabbix-dbpassword.conf"; - libDir = "/var/lib/zabbix"; + moduleEnv = pkgs.symlinkJoin { + name = "zabbix-server-module-env"; + paths = attrValues cfg.modules; + }; - pidFile = "${stateDir}/zabbix_server.pid"; + configFile = pkgs.writeText "zabbix_server.conf" '' + LogType = console + ListenIP = ${cfg.listen.ip} + ListenPort = ${toString cfg.listen.port} + # TODO: set to cfg.database.socket if database type is pgsql? + DBHost = ${optionalString (cfg.database.createLocally != true) cfg.database.host} + ${optionalString (cfg.database.createLocally != true) "DBPort = ${cfg.database.port}"} + DBName = ${cfg.database.name} + DBUser = ${cfg.database.user} + ${optionalString (cfg.database.passwordFile != null) "Include ${passwordFile}"} + ${optionalString (mysqlLocal && cfg.database.socket != null) "DBSocket = ${cfg.database.socket}"} + SocketDir = ${runtimeDir} + FpingLocation = /run/wrappers/bin/fping + ${optionalString (cfg.modules != {}) "LoadModulePath = ${moduleEnv}/lib"} + ${concatMapStringsSep "\n" (name: "LoadModule = ${name}") (builtins.attrNames cfg.modules)} + ${cfg.extraConfig} + ''; + + mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql"; + pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql"; - configFile = pkgs.writeText "zabbix_server.conf" - '' - LogFile = ${logDir}/zabbix_server +in - PidFile = ${pidFile} +{ + # interface - ${optionalString (cfg.dbServer != "localhost") '' - DBHost = ${cfg.dbServer} - ''} + options = { - DBName = zabbix + services.zabbixServer = { + enable = mkEnableOption "the Zabbix Server"; - DBUser = zabbix + package = mkOption { + type = types.package; + default = if cfg.database.type == "mysql" then pkgs.zabbix.server-mysql else pkgs.zabbix.server-pgsql; + defaultText = "pkgs.zabbix.server-pgsql"; + description = "The Zabbix package to use."; + }; - ${optionalString (cfg.dbPassword != "") '' - DBPassword = ${cfg.dbPassword} - ''} + extraPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ nettools nmap traceroute ]; + defaultText = "[ nettools nmap traceroute ]"; + description = '' + Packages to be added to the Zabbix <envar>PATH</envar>. + Typically used to add executables for scripts, but can be anything. + ''; + }; - ${config.services.zabbixServer.extraConfig} - ''; + modules = mkOption { + type = types.attrsOf types.package; + description = "A set of modules to load."; + default = {}; + example = literalExample '' + { + "dummy.so" = pkgs.stdenv.mkDerivation { + name = "zabbix-dummy-module-''${cfg.package.version}"; + src = cfg.package.src; + buildInputs = [ cfg.package ]; + sourceRoot = "zabbix-''${cfg.package.version}/src/modules/dummy"; + installPhase = ''' + mkdir -p $out/lib + cp dummy.so $out/lib/ + '''; + }; + } + ''; + }; - useLocalPostgres = cfg.dbServer == "localhost" || cfg.dbServer == ""; + database = { + type = mkOption { + type = types.enum [ "mysql" "pgsql" ]; + example = "mysql"; + default = "pgsql"; + description = "Database engine to use."; + }; + + host = mkOption { + type = types.str; + default = "localhost"; + description = "Database host address."; + }; + + port = mkOption { + type = types.int; + default = if cfg.database.type == "mysql" then mysql.port else pgsql.port; + description = "Database host port."; + }; + + name = mkOption { + type = types.str; + default = "zabbix"; + description = "Database name."; + }; + + user = mkOption { + type = types.str; + default = "zabbix"; + description = "Database user."; + }; + + passwordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/zabbix-dbpassword"; + description = '' + A file containing the password corresponding to + <option>database.user</option>. + ''; + }; + + socket = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/postgresql"; + description = "Path to the unix socket file to use for authentication."; + }; + + createLocally = mkOption { + type = types.bool; + default = true; + description = "Whether to create a local database automatically."; + }; + }; -in + listen = { + ip = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + List of comma delimited IP addresses that the trapper should listen on. + Trapper will listen on all network interfaces if this parameter is missing. + ''; + }; -{ + port = mkOption { + type = types.port; + default = 10051; + description = '' + Listen port for trapper. + ''; + }; + }; - ###### interface + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for the Zabbix Server. + ''; + }; - options = { + # TODO: for bonus points migrate this to https://github.com/NixOS/rfcs/pull/42 + extraConfig = mkOption { + default = ""; + type = types.lines; + description = '' + Configuration that is injected verbatim into the configuration file. Refer to + <link xlink:href="https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_server"/> + for details on supported values. + ''; + }; - services.zabbixServer.enable = mkOption { - default = false; - type = types.bool; - description = '' - Whether to run the Zabbix server on this machine. - ''; }; - services.zabbixServer.dbServer = mkOption { - default = "localhost"; - type = types.str; - description = '' - Hostname or IP address of the database server. - Use an empty string ("") to use peer authentication. - ''; - }; + }; - services.zabbixServer.dbPassword = mkOption { - default = ""; - type = types.str; - description = "Password used to connect to the database server."; - }; + # implementation - services.zabbixServer.extraConfig = mkOption { - default = ""; - type = types.lines; - description = '' - Configuration that is injected verbatim into the configuration file. - ''; + config = mkIf cfg.enable { + + assertions = [ + { assertion = cfg.database.createLocally -> cfg.database.user == user; + message = "services.zabbixServer.database.user must be set to ${user} if services.zabbixServer.database.createLocally is set true"; + } + { assertion = cfg.database.createLocally -> cfg.database.passwordFile == null; + message = "a password cannot be specified if services.zabbixServer.database.createLocally is set to true"; + } + ]; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [ cfg.listen.port ]; }; - }; + services.mysql = optionalAttrs mysqlLocal { + enable = true; + package = mkDefault pkgs.mariadb; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }; + } + ]; + }; - ###### implementation + services.postgresql = optionalAttrs pgsqlLocal { + enable = true; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { name = cfg.database.user; + ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; }; + } + ]; + }; - config = mkIf cfg.enable { + users.users.${user} = { + description = "Zabbix daemon user"; + uid = config.ids.uids.zabbix; + inherit group; + }; - services.postgresql.enable = useLocalPostgres; + users.groups.${group} = { + gid = config.ids.gids.zabbix; + }; - users.users = singleton - { name = "zabbix"; - uid = config.ids.uids.zabbix; - description = "Zabbix daemon user"; - }; + security.wrappers = { + fping.source = "${pkgs.fping}/bin/fping"; + }; - systemd.services."zabbix-server" = - { description = "Zabbix Server"; - - wantedBy = [ "multi-user.target" ]; - after = optional useLocalPostgres "postgresql.service"; - - preStart = - '' - mkdir -m 0755 -p ${stateDir} ${logDir} ${libDir} - chown zabbix ${stateDir} ${logDir} ${libDir} - - if ! test -e "${libDir}/db-created"; then - ${pkgs.su}/bin/su -s "$SHELL" ${config.services.postgresql.superUser} -c '${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole zabbix' || true - ${pkgs.su}/bin/su -s "$SHELL" ${config.services.postgresql.superUser} -c '${pkgs.postgresql}/bin/createdb --owner zabbix zabbix' || true - cat ${pkgs.zabbix.server}/share/zabbix/db/schema/postgresql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' - cat ${pkgs.zabbix.server}/share/zabbix/db/data/images_pgsql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' - cat ${pkgs.zabbix.server}/share/zabbix/db/data/data.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' - touch "${libDir}/db-created" - fi - ''; + systemd.services."zabbix-server" = { + description = "Zabbix Server"; + + wantedBy = [ "multi-user.target" ]; + after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; + + path = [ "/run/wrappers" ] ++ cfg.extraPackages; + preStart = '' + # pre 19.09 compatibility + if test -e "${runtimeDir}/db-created"; then + mv "${runtimeDir}/db-created" "${stateDir}/" + fi + '' + optionalString pgsqlLocal '' + if ! test -e "${stateDir}/db-created"; then + cat ${cfg.package}/share/zabbix/database/postgresql/schema.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/postgresql/images.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/postgresql/data.sql | ${pgsql.package}/bin/psql ${cfg.database.name} + touch "${stateDir}/db-created" + fi + '' + optionalString mysqlLocal '' + if ! test -e "${stateDir}/db-created"; then + cat ${cfg.package}/share/zabbix/database/mysql/schema.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/mysql/images.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + cat ${cfg.package}/share/zabbix/database/mysql/data.sql | ${mysql.package}/bin/mysql ${cfg.database.name} + touch "${stateDir}/db-created" + fi + '' + optionalString (cfg.database.passwordFile != null) '' + # create a copy of the supplied password file in a format zabbix can consume + touch ${passwordFile} + chmod 0600 ${passwordFile} + echo -n "DBPassword = " > ${passwordFile} + cat ${cfg.database.passwordFile} >> ${passwordFile} + ''; - path = [ pkgs.nettools ]; + serviceConfig = { + ExecStart = "@${cfg.package}/sbin/zabbix_server zabbix_server -f --config ${configFile}"; + Restart = "always"; + RestartSec = 2; - serviceConfig.ExecStart = "@${pkgs.zabbix.server}/sbin/zabbix_server zabbix_server --config ${configFile}"; - serviceConfig.Type = "forking"; - serviceConfig.Restart = "always"; - serviceConfig.RestartSec = 2; - serviceConfig.PIDFile = pidFile; + User = user; + Group = group; + RuntimeDirectory = "zabbix"; + StateDirectory = "zabbix"; + PrivateTmp = true; }; + }; + + systemd.services.httpd.after = + optional (config.services.zabbixWeb.enable && mysqlLocal) "mysql.service" ++ + optional (config.services.zabbixWeb.enable && pgsqlLocal) "postgresql.service"; }; diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix index c217ccaa405..7b278603455 100644 --- a/nixos/modules/services/networking/dhcpcd.nix +++ b/nixos/modules/services/networking/dhcpcd.nix @@ -162,7 +162,7 @@ in wantedBy = [ "multi-user.target" ] ++ optional (!hasDefaultGatewaySet) "network-online.target"; wants = [ "network.target" "systemd-udev-settle.service" ]; - before = [ "network.target" ]; + before = [ "network-online.target" ]; after = [ "systemd-udev-settle.service" ]; # Stopping dhcpcd during a reconfiguration is undesirable diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix index ca34ff9df4e..fc516c01230 100644 --- a/nixos/modules/services/networking/kresd.nix +++ b/nixos/modules/services/networking/kresd.nix @@ -80,8 +80,11 @@ in # Syntax depends on being IPv6 or IPv4. (iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53") cfg.interfaces; - socketConfig.ListenDatagram = listenStreams; - socketConfig.FreeBind = true; + socketConfig = { + ListenDatagram = listenStreams; + FreeBind = true; + FileDescriptorName = "dns"; + }; }; systemd.sockets.kresd-tls = mkIf (cfg.listenTLS != []) rec { diff --git a/nixos/modules/services/torrent/deluge.nix b/nixos/modules/services/torrent/deluge.nix index 01a5890a784..48ec4d692e2 100644 --- a/nixos/modules/services/torrent/deluge.nix +++ b/nixos/modules/services/torrent/deluge.nix @@ -118,36 +118,74 @@ in { more informations. ''; }; + + user = mkOption { + type = types.str; + default = "deluge"; + description = '' + User account under which deluge runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "deluge"; + description = '' + Group under which deluge runs. + ''; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = []; + description = '' + Extra packages available at runtime to enable Deluge's plugins. For example, + extraction utilities are required for the built-in "Extractor" plugin. + This always contains unzip, gnutar, xz, p7zip and bzip2. + ''; + }; }; deluge.web = { enable = mkEnableOption "Deluge Web daemon"; + port = mkOption { - type = types.port; + type = types.port; default = 8112; description = '' Deluge web UI port. ''; }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for deluge web daemon + ''; + }; }; }; }; config = mkIf cfg.enable { - systemd.tmpfiles.rules = [ "d '${configDir}' 0770 deluge deluge" ] + # Provide a default set of `extraPackages`. + services.deluge.extraPackages = with pkgs; [ unzip gnutar xz p7zip bzip2 ]; + + systemd.tmpfiles.rules = [ "d '${configDir}' 0770 ${cfg.user} ${cfg.group}" ] ++ optional (cfg.config ? "download_location") - "d '${cfg.config.download_location}' 0770 deluge deluge" + "d '${cfg.config.download_location}' 0770 ${cfg.user} ${cfg.group}" ++ optional (cfg.config ? "torrentfiles_location") - "d '${cfg.config.torrentfiles_location}' 0770 deluge deluge" + "d '${cfg.config.torrentfiles_location}' 0770 ${cfg.user} ${cfg.group}" ++ optional (cfg.config ? "move_completed_path") - "d '${cfg.config.move_completed_path}' 0770 deluge deluge"; + "d '${cfg.config.move_completed_path}' 0770 ${cfg.user} ${cfg.group}"; systemd.services.deluged = { after = [ "network.target" ]; description = "Deluge BitTorrent Daemon"; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.deluge ]; + path = [ pkgs.deluge ] ++ cfg.extraPackages; serviceConfig = { ExecStart = '' ${pkgs.deluge}/bin/deluged \ @@ -157,8 +195,8 @@ in { # To prevent "Quit & shutdown daemon" from working; we want systemd to # manage it! Restart = "on-success"; - User = "deluge"; - Group = "deluge"; + User = cfg.user; + Group = cfg.group; UMask = "0002"; LimitNOFILE = cfg.openFilesLimit; }; @@ -177,26 +215,37 @@ in { --config ${configDir} \ --port ${toString cfg.web.port} ''; - User = "deluge"; - Group = "deluge"; + User = cfg.user; + Group = cfg.group; }; }; - networking.firewall = mkIf (cfg.declarative && cfg.openFirewall && !(cfg.config.random_port or true)) { - allowedTCPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault)); - allowedUDPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault)); - }; + networking.firewall = mkMerge [ + (mkIf (cfg.declarative && cfg.openFirewall && !(cfg.config.random_port or true)) { + allowedTCPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault)); + allowedUDPPortRanges = singleton (listToRange (cfg.config.listen_ports or listenPortsDefault)); + }) + (mkIf (cfg.web.openFirewall) { + allowedTCPPorts = [ cfg.web.port ]; + }) + ]; environment.systemPackages = [ pkgs.deluge ]; - users.users.deluge = { - group = "deluge"; - uid = config.ids.uids.deluge; - home = cfg.dataDir; - createHome = true; - description = "Deluge Daemon user"; + users.users = mkIf (cfg.user == "deluge") { + deluge = { + group = cfg.group; + uid = config.ids.uids.deluge; + home = cfg.dataDir; + createHome = true; + description = "Deluge Daemon user"; + }; }; - users.groups.deluge.gid = config.ids.gids.deluge; + users.groups = mkIf (cfg.group == "deluge") { + deluge = { + gid = config.ids.gids.deluge; + }; + }; }; } diff --git a/nixos/modules/services/web-apps/zabbix.nix b/nixos/modules/services/web-apps/zabbix.nix new file mode 100644 index 00000000000..4b5334579a9 --- /dev/null +++ b/nixos/modules/services/web-apps/zabbix.nix @@ -0,0 +1,225 @@ +{ config, lib, pkgs, ... }: + +let + + inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption types; + inherit (lib) literalExample mapAttrs optionalString; + + cfg = config.services.zabbixWeb; + fpm = config.services.phpfpm.pools.zabbix; + + user = "zabbix"; + group = "zabbix"; + stateDir = "/var/lib/zabbix"; + + zabbixConfig = pkgs.writeText "zabbix.conf.php" '' + <?php + // Zabbix GUI configuration file. + global $DB; + $DB['TYPE'] = '${ { "mysql" = "MYSQL"; "pgsql" = "POSTGRESQL"; "oracle" = "ORACLE"; }.${cfg.database.type} }'; + $DB['SERVER'] = '${cfg.database.host}'; + $DB['PORT'] = '${toString cfg.database.port}'; + $DB['DATABASE'] = '${cfg.database.name}'; + $DB['USER'] = '${cfg.database.user}'; + $DB['PASSWORD'] = ${if cfg.database.passwordFile != null then "file_get_contents('${cfg.database.passwordFile}')" else "''"}; + // Schema name. Used for IBM DB2 and PostgreSQL. + $DB['SCHEMA'] = '''; + $ZBX_SERVER = '${cfg.server.address}'; + $ZBX_SERVER_PORT = '${toString cfg.server.port}'; + $ZBX_SERVER_NAME = '''; + $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG; + ''; + +in +{ + # interface + + options.services = { + zabbixWeb = { + enable = mkEnableOption "the Zabbix web interface"; + + package = mkOption { + type = types.package; + default = pkgs.zabbix.web; + defaultText = "zabbix.web"; + description = "Which Zabbix package to use."; + }; + + server = { + port = mkOption { + type = types.int; + description = "The port of the Zabbix server to connect to."; + default = 10051; + }; + + address = mkOption { + type = types.str; + description = "The IP address or hostname of the Zabbix server to connect to."; + default = "localhost"; + }; + }; + + database = { + type = mkOption { + type = types.enum [ "mysql" "pgsql" "oracle" ]; + example = "mysql"; + default = "pgsql"; + description = "Database engine to use."; + }; + + host = mkOption { + type = types.str; + default = ""; + description = "Database host address."; + }; + + port = mkOption { + type = types.int; + default = + if cfg.database.type == "mysql" then config.services.mysql.port + else if cfg.database.type == "pgsql" then config.services.postgresql.port + else 1521; + description = "Database host port."; + }; + + name = mkOption { + type = types.str; + default = "zabbix"; + description = "Database name."; + }; + + user = mkOption { + type = types.str; + default = "zabbix"; + description = "Database user."; + }; + + passwordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/zabbix-dbpassword"; + description = '' + A file containing the password corresponding to + <option>database.user</option>. + ''; + }; + + socket = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/postgresql"; + description = "Path to the unix socket file to use for authentication."; + }; + }; + + virtualHost = mkOption { + type = types.submodule ({ + options = import ../web-servers/apache-httpd/per-server-options.nix { + inherit lib; + forMainServer = false; + }; + }); + example = { + hostName = "zabbix.example.org"; + enableSSL = true; + adminAddr = "webmaster@example.org"; + sslServerCert = "/var/lib/acme/zabbix.example.org/full.pem"; + sslServerKey = "/var/lib/acme/zabbix.example.org/key.pem"; + }; + description = '' + Apache configuration can be done by adapting <literal>services.httpd.virtualHosts.<name></literal>. + See <xref linkend="opt-services.httpd.virtualHosts"/> for further information. + ''; + }; + + poolConfig = mkOption { + type = types.lines; + default = '' + pm = dynamic + pm.max_children = 32 + pm.start_servers = 2 + pm.min_spare_servers = 2 + pm.max_spare_servers = 4 + pm.max_requests = 500 + ''; + description = '' + Options for the Zabbix PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives. + ''; + }; + + }; + }; + + # implementation + + config = mkIf cfg.enable { + + systemd.tmpfiles.rules = [ + "d '${stateDir}' 0750 ${user} ${group} - -" + "d '${stateDir}/session' 0750 ${user} ${config.services.httpd.group} - -" + ]; + + services.phpfpm.pools.zabbix = { + phpOptions = '' + # https://www.zabbix.com/documentation/current/manual/installation/install + memory_limit = 128M + post_max_size = 16M + upload_max_filesize = 2M + max_execution_time = 300 + max_input_time = 300 + session.auto_start = 0 + mbstring.func_overload = 0 + always_populate_raw_post_data = -1 + # https://bbs.archlinux.org/viewtopic.php?pid=1745214#p1745214 + session.save_path = ${stateDir}/session + '' + optionalString (config.time.timeZone != null) '' + date.timezone = "${config.time.timeZone}" + '' + optionalString (cfg.database.type == "oracle") '' + extension=${pkgs.phpPackages.oci8}/lib/php/extensions/oci8.so + ''; + listen = "/run/phpfpm/zabbix.sock"; + extraConfig = '' + listen.owner = ${config.services.httpd.user}; + listen.group = ${config.services.httpd.group}; + user = ${user}; + group = ${config.services.httpd.group}; + env[ZABBIX_CONFIG] = ${zabbixConfig} + ${cfg.poolConfig} + ''; + }; + + services.httpd = { + enable = true; + adminAddr = mkDefault cfg.virtualHost.adminAddr; + extraModules = [ "proxy_fcgi" ]; + virtualHosts = [ (mkMerge [ + cfg.virtualHost { + documentRoot = mkForce "${cfg.package}/share/zabbix"; + extraConfig = '' + <Directory "${cfg.package}/share/zabbix"> + <FilesMatch "\.php$"> + <If "-f %{REQUEST_FILENAME}"> + SetHandler "proxy:unix:${fpm.listen}|fcgi://localhost/" + </If> + </FilesMatch> + AllowOverride all + Options -Indexes + DirectoryIndex index.php + </Directory> + ''; + } + ]) ]; + }; + + users.users.${user} = mapAttrs (name: mkDefault) { + description = "Zabbix daemon user"; + uid = config.ids.uids.zabbix; + inherit group; + }; + + users.groups.${group} = mapAttrs (name: mkDefault) { + gid = config.ids.gids.zabbix; + }; + + }; +} diff --git a/nixos/modules/services/web-servers/apache-httpd/foswiki.nix b/nixos/modules/services/web-servers/apache-httpd/foswiki.nix deleted file mode 100644 index 8c1ac8935a4..00000000000 --- a/nixos/modules/services/web-servers/apache-httpd/foswiki.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ config, pkgs, lib, serverInfo, ... }: -let - inherit (pkgs) foswiki; - inherit (serverInfo.serverConfig) user group; - inherit (config) vardir; -in -{ - options.vardir = lib.mkOption { - type = lib.types.path; - default = "/var/www/foswiki"; - description = "The directory where variable foswiki data will be stored and served from."; - }; - - # TODO: this will probably need to be better customizable - extraConfig = - let httpd-conf = pkgs.runCommand "foswiki-httpd.conf" - { preferLocalBuild = true; } - '' - substitute '${foswiki}/foswiki_httpd_conf.txt' "$out" \ - --replace /var/www/foswiki/ "${vardir}/" - ''; - in - '' - RewriteEngine on - RewriteRule /foswiki/(.*) ${vardir}/$1 - - <Directory "${vardir}"> - Require all granted - </Directory> - - Include ${httpd-conf} - <Directory "${vardir}/pub"> - Options FollowSymlinks - </Directory> - ''; - - /** This handles initial setup and updates. - It will probably need some tweaking, maybe per-site. */ - startupScript = pkgs.writeScript "foswiki_startup.sh" ( - let storeLink = "${vardir}/package"; in - '' - [ -e '${storeLink}' ] || needs_setup=1 - mkdir -p '${vardir}' - cd '${vardir}' - ln -sf -T '${foswiki}' '${storeLink}' - - if [ -n "$needs_setup" ]; then # do initial setup - mkdir -p bin lib - # setup most of data/ as copies only - cp -r '${foswiki}'/data '${vardir}/' - rm -r '${vardir}'/data/{System,mime.types} - ln -sr -t '${vardir}/data/' '${storeLink}'/data/{System,mime.types} - - ln -sr '${storeLink}/locale' . - - mkdir pub - ln -sr '${storeLink}/pub/System' pub/ - - mkdir templates - ln -sr '${storeLink}'/templates/* templates/ - - ln -sr '${storeLink}/tools' . - - mkdir -p '${vardir}'/working/{logs,tmp} - ln -sr '${storeLink}/working/README' working/ # used to check dir validity - - chown -R '${user}:${group}' . - chmod +w -R . - fi - - # bin/* and lib/* shall always be overwritten, in case files are added - ln -srf '${storeLink}'/bin/* '${vardir}/bin/' - ln -srf '${storeLink}'/lib/* '${vardir}/lib/' - '' - /* Symlinking bin/ one-by-one ensures that ${vardir}/lib/LocalSite.cfg - is used instead of ${foswiki}/... */ - ); -} diff --git a/nixos/modules/services/web-servers/apache-httpd/trac.nix b/nixos/modules/services/web-servers/apache-httpd/trac.nix deleted file mode 100644 index 28b411a64b6..00000000000 --- a/nixos/modules/services/web-servers/apache-httpd/trac.nix +++ /dev/null @@ -1,121 +0,0 @@ -{ config, lib, pkgs, serverInfo, ... }: - -with lib; - -let - - # Build a Subversion instance with Apache modules and Swig/Python bindings. - subversion = pkgs.subversion.override { - bdbSupport = true; - httpServer = true; - pythonBindings = true; - apacheHttpd = httpd; - }; - - httpd = serverInfo.serverConfig.package; - - versionPre24 = versionOlder httpd.version "2.4"; - -in - -{ - - options = { - - projectsLocation = mkOption { - description = "URL path in which Trac projects can be accessed"; - default = "/projects"; - }; - - projects = mkOption { - description = "List of projects that should be provided by Trac. If they are not defined yet empty projects are created."; - default = []; - example = - [ { identifier = "myproject"; - name = "My Project"; - databaseURL="postgres://root:password@/tracdb"; - subversionRepository="/data/subversion/myproject"; - } - ]; - }; - - user = mkOption { - default = "wwwrun"; - description = "User account under which Trac runs."; - }; - - group = mkOption { - default = "wwwrun"; - description = "Group under which Trac runs."; - }; - - ldapAuthentication = { - enable = mkOption { - default = false; - description = "Enable the ldap authentication in trac"; - }; - - url = mkOption { - default = "ldap://127.0.0.1/dc=example,dc=co,dc=ke?uid?sub?(objectClass=inetOrgPerson)"; - description = "URL of the LDAP authentication"; - }; - - name = mkOption { - default = "Trac server"; - description = "AuthName"; - }; - }; - - }; - - extraModules = singleton - { name = "python"; path = "${pkgs.mod_python}/modules/mod_python.so"; }; - - extraConfig = '' - <Location ${config.projectsLocation}> - SetHandler mod_python - PythonHandler trac.web.modpython_frontend - PythonOption TracEnvParentDir /var/trac/projects - PythonOption TracUriRoot ${config.projectsLocation} - PythonOption PYTHON_EGG_CACHE /var/trac/egg-cache - </Location> - ${if config.ldapAuthentication.enable then '' - <LocationMatch "^${config.projectsLocation}[^/]+/login$"> - AuthType Basic - AuthName "${config.ldapAuthentication.name}" - AuthBasicProvider "ldap" - AuthLDAPURL "${config.ldapAuthentication.url}" - ${if versionPre24 then "authzldapauthoritative Off" else ""} - require valid-user - </LocationMatch> - '' else ""} - ''; - - globalEnvVars = singleton - { name = "PYTHONPATH"; - value = - makeSearchPathOutput "lib" "lib/${pkgs.python.libPrefix}/site-packages" - [ pkgs.mod_python - pkgs.pythonPackages.trac - pkgs.pythonPackages.setuptools - pkgs.pythonPackages.genshi - pkgs.pythonPackages.psycopg2 - subversion - ]; - }; - - startupScript = pkgs.writeScript "activateTrac" '' - mkdir -p /var/trac - chown ${config.user}:${config.group} /var/trac - - ${concatMapStrings (project: - '' - if [ ! -d /var/trac/${project.identifier} ] - then - export PYTHONPATH=${pkgs.pythonPackages.psycopg2}/lib/${pkgs.python.libPrefix}/site-packages - ${pkgs.pythonPackages.trac}/bin/trac-admin /var/trac/${project.identifier} initenv "${project.name}" "${project.databaseURL}" svn "${project.subversionRepository}" - fi - '' ) (config.projects)} - ''; - -} diff --git a/nixos/modules/services/web-servers/apache-httpd/zabbix.nix b/nixos/modules/services/web-servers/apache-httpd/zabbix.nix deleted file mode 100644 index cab16593bcb..00000000000 --- a/nixos/modules/services/web-servers/apache-httpd/zabbix.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ config, lib, pkgs, serverInfo, ... }: - -with lib; - -let - - # The Zabbix PHP frontend needs to be able to write its - # configuration settings (the connection info to the database) to - # the "conf" subdirectory. So symlink $out/conf to some directory - # outside of the Nix store where we want to keep this stateful info. - # Note that different instances of the frontend will therefore end - # up with their own copies of the PHP sources. !!! Alternatively, - # we could generate zabbix.conf.php declaratively. - zabbixPHP = pkgs.runCommand "${pkgs.zabbix.server.name}-php" {} - '' - cp -rs ${pkgs.zabbix.server}/share/zabbix/php "$out" - chmod -R u+w $out - ln -s "${if config.configFile == null - then "${config.stateDir}/zabbix.conf.php" - else config.configFile}" "$out/conf/zabbix.conf.php" - ''; - -in - -{ - - enablePHP = true; - - phpOptions = - '' - post_max_size = 32M - max_execution_time = 300 - max_input_time = 300 - ''; - - extraConfig = '' - Alias ${config.urlPrefix}/ ${zabbixPHP}/ - - <Directory ${zabbixPHP}> - DirectoryIndex index.php - Order deny,allow - Allow from * - </Directory> - ''; - - startupScript = pkgs.writeScript "zabbix-startup-hook" '' - mkdir -p ${config.stateDir} - chown -R ${serverInfo.serverConfig.user} ${config.stateDir} - ''; - - # The frontend needs "ps" to find out whether zabbix_server is running. - extraServerPath = [ pkgs.procps ]; - - options = { - - urlPrefix = mkOption { - default = "/zabbix"; - description = " - The URL prefix under which the Zabbix service appears. - Use the empty string to have it appear in the server root. - "; - }; - - configFile = mkOption { - default = null; - type = types.nullOr types.path; - description = '' - The configuration file (zabbix.conf.php) which contains the database - connection settings. If not set, the configuration settings will created - by the web installer. - ''; - }; - - stateDir = mkOption { - default = "/var/lib/zabbix/frontend"; - description = " - Directory where the dynamically generated configuration data - of the PHP frontend will be stored. - "; - }; - - }; - -} diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index a1ed2fd1e97..82730c5e80c 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -662,10 +662,9 @@ in restartIfChanged = false; environment = - { - LD_LIBRARY_PATH = concatStringsSep ":" ([ "/run/opengl-driver/lib" ] - ++ concatLists (catAttrs "libPath" cfg.drivers)); - } // cfg.displayManager.job.environment; + optionalAttrs config.hardware.opengl.setLdLibraryPath + { LD_LIBRARY_PATH = pkgs.addOpenGLRunpath.driverLink; } + // cfg.displayManager.job.environment; preStart = '' diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index a36b3c180eb..a09c5dc4761 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -407,6 +407,29 @@ addEntry("NixOS - Default", $defaultConfig); $conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS; +# Find all the children of the current default configuration +# Do not search for grand children +my @links = sort (glob "$defaultConfig/fine-tune/*"); +foreach my $link (@links) { + + my $entryName = ""; + + my $cfgName = readFile("$link/configuration-name"); + + my $date = strftime("%F", localtime(lstat($link)->mtime)); + my $version = + -e "$link/nixos-version" + ? readFile("$link/nixos-version") + : basename((glob(dirname(Cwd::abs_path("$link/kernel")) . "/lib/modules/*"))[0]); + + if ($cfgName) { + $entryName = $cfgName; + } else { + $entryName = "($date - $version)"; + } + addEntry("NixOS - $entryName", $link); +} + my $grubBootPath = $grubBoot->path; # extraEntries could refer to @bootRoot@, which we have to substitute $conf =~ s/\@bootRoot\@/$grubBootPath/g; diff --git a/nixos/modules/tasks/auto-upgrade.nix b/nixos/modules/tasks/auto-upgrade.nix index 91f4ae79ee9..18753ae0c1a 100644 --- a/nixos/modules/tasks/auto-upgrade.nix +++ b/nixos/modules/tasks/auto-upgrade.nix @@ -53,6 +53,16 @@ let cfg = config.system.autoUpgrade; in ''; }; + allowReboot = mkOption { + default = false; + type = types.bool; + description = '' + Reboot the system into the new generation instead of a switch + if the new generation uses a different kernel, kernel modules + or initrd than the booted system. + ''; + }; + }; }; @@ -78,11 +88,23 @@ let cfg = config.system.autoUpgrade; in HOME = "/root"; } // config.networking.proxy.envVars; - path = [ pkgs.gnutar pkgs.xz.bin pkgs.gitMinimal config.nix.package.out ]; - - script = '' - ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch ${toString cfg.flags} - ''; + path = [ pkgs.coreutils pkgs.gnutar pkgs.xz.bin pkgs.gitMinimal config.nix.package.out ]; + + script = let + nixos-rebuild = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild"; + in + if cfg.allowReboot then '' + ${nixos-rebuild} boot ${toString cfg.flags} + booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" + built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})" + if [ "$booted" = "$built" ]; then + ${nixos-rebuild} switch ${toString cfg.flags} + else + /run/current-system/sw/bin/shutdown -r +1 + fi + '' else '' + ${nixos-rebuild} switch ${toString cfg.flags} + ''; startAt = cfg.dates; }; diff --git a/nixos/modules/virtualisation/parallels-guest.nix b/nixos/modules/virtualisation/parallels-guest.nix index 4e0f2cae299..828419fb4b9 100644 --- a/nixos/modules/virtualisation/parallels-guest.nix +++ b/nixos/modules/virtualisation/parallels-guest.nix @@ -47,7 +47,7 @@ in config = mkIf config.hardware.parallels.enable { services.xserver = { drivers = singleton - { name = "prlvideo"; modules = [ prl-tools ]; libPath = [ prl-tools ]; }; + { name = "prlvideo"; modules = [ prl-tools ]; }; screenSection = '' Option "NoMTRR" @@ -65,6 +65,7 @@ in hardware.opengl.package = prl-tools; hardware.opengl.package32 = pkgs.pkgsi686Linux.linuxPackages.prl-tools.override { libsOnly = true; kernel = null; }; + hardware.opengl.setLdLibraryPath = true; services.udev.packages = [ prl-tools ]; |