at 23.11-pre 8.3 kB view raw
1{ config, lib, pkgs, ... }: with lib; let 2 cfg = config.services.icingaweb2; 3 fpm = config.services.phpfpm.pools.${poolName}; 4 poolName = "icingaweb2"; 5 6 defaultConfig = { 7 global = { 8 module_path = "${pkgs.icingaweb2}/modules"; 9 }; 10 }; 11in { 12 meta.maintainers = with maintainers; [ das_j ]; 13 14 options.services.icingaweb2 = with types; { 15 enable = mkEnableOption (lib.mdDoc "the icingaweb2 web interface"); 16 17 pool = mkOption { 18 type = str; 19 default = poolName; 20 description = lib.mdDoc '' 21 Name of existing PHP-FPM pool that is used to run Icingaweb2. 22 If not specified, a pool will automatically created with default values. 23 ''; 24 }; 25 26 libraryPaths = mkOption { 27 type = attrsOf package; 28 default = { }; 29 description = lib.mdDoc '' 30 Libraries to add to the Icingaweb2 library path. 31 The name of the attribute is the name of the library, the value 32 is the package to add. 33 ''; 34 }; 35 36 virtualHost = mkOption { 37 type = nullOr str; 38 default = "icingaweb2"; 39 description = lib.mdDoc '' 40 Name of the nginx virtualhost to use and setup. If null, no virtualhost is set up. 41 ''; 42 }; 43 44 timezone = mkOption { 45 type = str; 46 default = "UTC"; 47 example = "Europe/Berlin"; 48 description = lib.mdDoc "PHP-compliant timezone specification"; 49 }; 50 51 modules = { 52 doc.enable = mkEnableOption (lib.mdDoc "the icingaweb2 doc module"); 53 migrate.enable = mkEnableOption (lib.mdDoc "the icingaweb2 migrate module"); 54 setup.enable = mkEnableOption (lib.mdDoc "the icingaweb2 setup module"); 55 test.enable = mkEnableOption (lib.mdDoc "the icingaweb2 test module"); 56 translation.enable = mkEnableOption (lib.mdDoc "the icingaweb2 translation module"); 57 }; 58 59 modulePackages = mkOption { 60 type = attrsOf package; 61 default = {}; 62 example = literalExpression '' 63 { 64 "snow" = icingaweb2Modules.theme-snow; 65 } 66 ''; 67 description = lib.mdDoc '' 68 Name-package attrset of Icingaweb 2 modules packages to enable. 69 70 If you enable modules manually (e.g. via the web ui), they will not be touched. 71 ''; 72 }; 73 74 generalConfig = mkOption { 75 type = nullOr attrs; 76 default = null; 77 example = { 78 general = { 79 showStacktraces = 1; 80 config_resource = "icingaweb_db"; 81 }; 82 logging = { 83 log = "syslog"; 84 level = "CRITICAL"; 85 }; 86 }; 87 description = lib.mdDoc '' 88 config.ini contents. 89 Will automatically be converted to a .ini file. 90 If you don't set global.module_path, the module will take care of it. 91 92 If the value is null, no config.ini is created and you can 93 modify it manually (e.g. via the web interface). 94 Note that you need to update module_path manually. 95 ''; 96 }; 97 98 resources = mkOption { 99 type = nullOr attrs; 100 default = null; 101 example = { 102 icingaweb_db = { 103 type = "db"; 104 db = "mysql"; 105 host = "localhost"; 106 username = "icingaweb2"; 107 password = "icingaweb2"; 108 dbname = "icingaweb2"; 109 }; 110 }; 111 description = lib.mdDoc '' 112 resources.ini contents. 113 Will automatically be converted to a .ini file. 114 115 If the value is null, no resources.ini is created and you can 116 modify it manually (e.g. via the web interface). 117 Note that if you set passwords here, they will go into the nix store. 118 ''; 119 }; 120 121 authentications = mkOption { 122 type = nullOr attrs; 123 default = null; 124 example = { 125 icingaweb = { 126 backend = "db"; 127 resource = "icingaweb_db"; 128 }; 129 }; 130 description = lib.mdDoc '' 131 authentication.ini contents. 132 Will automatically be converted to a .ini file. 133 134 If the value is null, no authentication.ini is created and you can 135 modify it manually (e.g. via the web interface). 136 ''; 137 }; 138 139 groupBackends = mkOption { 140 type = nullOr attrs; 141 default = null; 142 example = { 143 icingaweb = { 144 backend = "db"; 145 resource = "icingaweb_db"; 146 }; 147 }; 148 description = lib.mdDoc '' 149 groups.ini contents. 150 Will automatically be converted to a .ini file. 151 152 If the value is null, no groups.ini is created and you can 153 modify it manually (e.g. via the web interface). 154 ''; 155 }; 156 157 roles = mkOption { 158 type = nullOr attrs; 159 default = null; 160 example = { 161 Administrators = { 162 users = "admin"; 163 permissions = "*"; 164 }; 165 }; 166 description = lib.mdDoc '' 167 roles.ini contents. 168 Will automatically be converted to a .ini file. 169 170 If the value is null, no roles.ini is created and you can 171 modify it manually (e.g. via the web interface). 172 ''; 173 }; 174 }; 175 176 config = mkIf cfg.enable { 177 services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") { 178 ${poolName} = { 179 user = "icingaweb2"; 180 phpEnv = { 181 ICINGAWEB_LIBDIR = toString (pkgs.linkFarm "icingaweb2-libdir" (mapAttrsToList (name: path: { inherit name path; }) cfg.libraryPaths)); 182 }; 183 phpPackage = pkgs.php.withExtensions ({ enabled, all }: [ all.imagick ] ++ enabled); 184 phpOptions = '' 185 date.timezone = "${cfg.timezone}" 186 ''; 187 settings = mapAttrs (name: mkDefault) { 188 "listen.owner" = "nginx"; 189 "listen.group" = "nginx"; 190 "listen.mode" = "0600"; 191 "pm" = "dynamic"; 192 "pm.max_children" = 75; 193 "pm.start_servers" = 2; 194 "pm.min_spare_servers" = 2; 195 "pm.max_spare_servers" = 10; 196 }; 197 }; 198 }; 199 200 services.icingaweb2.libraryPaths = { 201 ipl = pkgs.icingaweb2-ipl; 202 thirdparty = pkgs.icingaweb2-thirdparty; 203 }; 204 205 systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ]; 206 207 services.nginx = { 208 enable = true; 209 virtualHosts = mkIf (cfg.virtualHost != null) { 210 ${cfg.virtualHost} = { 211 root = "${pkgs.icingaweb2}/public"; 212 213 extraConfig = '' 214 index index.php; 215 try_files $1 $uri $uri/ /index.php$is_args$args; 216 ''; 217 218 locations."~ ..*/.*.php$".extraConfig = '' 219 return 403; 220 ''; 221 222 locations."~ ^/index.php(.*)$".extraConfig = '' 223 fastcgi_intercept_errors on; 224 fastcgi_index index.php; 225 include ${config.services.nginx.package}/conf/fastcgi.conf; 226 try_files $uri =404; 227 fastcgi_split_path_info ^(.+\.php)(/.+)$; 228 fastcgi_pass unix:${fpm.socket}; 229 fastcgi_param SCRIPT_FILENAME ${pkgs.icingaweb2}/public/index.php; 230 ''; 231 }; 232 }; 233 }; 234 235 # /etc/icingaweb2 236 environment.etc = let 237 doModule = name: optionalAttrs (cfg.modules.${name}.enable) { "icingaweb2/enabledModules/${name}".source = "${pkgs.icingaweb2}/modules/${name}"; }; 238 in {} 239 # Module packages 240 // (mapAttrs' (k: v: nameValuePair "icingaweb2/enabledModules/${k}" { source = v; }) cfg.modulePackages) 241 # Built-in modules 242 // doModule "doc" 243 // doModule "migrate" 244 // doModule "setup" 245 // doModule "test" 246 // doModule "translation" 247 # Configs 248 // optionalAttrs (cfg.generalConfig != null) { "icingaweb2/config.ini".text = generators.toINI {} (defaultConfig // cfg.generalConfig); } 249 // optionalAttrs (cfg.resources != null) { "icingaweb2/resources.ini".text = generators.toINI {} cfg.resources; } 250 // optionalAttrs (cfg.authentications != null) { "icingaweb2/authentication.ini".text = generators.toINI {} cfg.authentications; } 251 // optionalAttrs (cfg.groupBackends != null) { "icingaweb2/groups.ini".text = generators.toINI {} cfg.groupBackends; } 252 // optionalAttrs (cfg.roles != null) { "icingaweb2/roles.ini".text = generators.toINI {} cfg.roles; }; 253 254 # User and group 255 users.groups.icingaweb2 = {}; 256 users.users.icingaweb2 = { 257 description = "Icingaweb2 service user"; 258 group = "icingaweb2"; 259 isSystemUser = true; 260 }; 261 }; 262}