| 
									
										
										
										
											2020-04-08 09:49:56 +02:00
										 |  |  | { config, lib, pkgs, utils, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  |   inherit (lib) mkDefault mkEnableOption mkIf mkOption types literalExample; | 
					
						
							|  |  |  |   cfg = config.services.engelsystem; | 
					
						
							|  |  |  | in { | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  |     services.engelsystem = { | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         example = true; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2020-10-27 21:11:22 +01:00
										 |  |  |           Whether to enable engelsystem, an online tool for coordinating volunteers | 
					
						
							| 
									
										
										
										
											2020-04-08 09:49:56 +02:00
										 |  |  |           and shifts on large events. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |         type = lib.types.bool; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       domain = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         example = "engelsystem.example.com"; | 
					
						
							|  |  |  |         description = "Domain to serve on."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       package = mkOption { | 
					
						
							|  |  |  |         type = types.package; | 
					
						
							|  |  |  |         example = literalExample "pkgs.engelsystem"; | 
					
						
							|  |  |  |         description = "Engelsystem package used for the service."; | 
					
						
							|  |  |  |         default = pkgs.engelsystem; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       createDatabase = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = true; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Whether to create a local database automatically. | 
					
						
							|  |  |  |           This will override every database setting in <option>services.engelsystem.config</option>. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.engelsystem.config = mkOption { | 
					
						
							|  |  |  |       type = types.attrs; | 
					
						
							|  |  |  |       default = { | 
					
						
							|  |  |  |         database = { | 
					
						
							|  |  |  |           host = "localhost"; | 
					
						
							|  |  |  |           database = "engelsystem"; | 
					
						
							|  |  |  |           username = "engelsystem"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       example = { | 
					
						
							|  |  |  |         maintenance = false; | 
					
						
							|  |  |  |         database = { | 
					
						
							|  |  |  |           host = "database.example.com"; | 
					
						
							|  |  |  |           database = "engelsystem"; | 
					
						
							|  |  |  |           username = "engelsystem"; | 
					
						
							|  |  |  |           password._secret = "/var/keys/engelsystem/database"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         email = { | 
					
						
							|  |  |  |           driver = "smtp"; | 
					
						
							|  |  |  |           host = "smtp.example.com"; | 
					
						
							|  |  |  |           port = 587; | 
					
						
							|  |  |  |           from.address = "engelsystem@example.com"; | 
					
						
							|  |  |  |           from.name = "example engelsystem"; | 
					
						
							|  |  |  |           encryption = "tls"; | 
					
						
							|  |  |  |           username = "engelsystem@example.com"; | 
					
						
							|  |  |  |           password._secret = "/var/keys/engelsystem/mail"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         autoarrive = true; | 
					
						
							|  |  |  |         min_password_length = 6; | 
					
						
							|  |  |  |         default_locale = "de_DE"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       description = ''
 | 
					
						
							|  |  |  |         Options to be added to config.php, as a nix attribute set. Options containing secret data | 
					
						
							|  |  |  |         should be set to an attribute set containing the attribute _secret - a string pointing to a | 
					
						
							|  |  |  |         file containing the value the option should be set to. See the example to get a better | 
					
						
							|  |  |  |         picture of this: in the resulting config.php file, the email.password key will be set to | 
					
						
							|  |  |  |         the contents of the /var/keys/engelsystem/mail file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         See https://engelsystem.de/doc/admin/configuration/ for available options. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Note that the admin user login credentials cannot be set here - they always default to | 
					
						
							|  |  |  |         admin:asdfasdf. Log in and change them immediately. | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf cfg.enable { | 
					
						
							|  |  |  |     # create database | 
					
						
							|  |  |  |     services.mysql = mkIf cfg.createDatabase { | 
					
						
							|  |  |  |       enable = true; | 
					
						
							|  |  |  |       package = mkDefault pkgs.mysql; | 
					
						
							|  |  |  |       ensureUsers = [{ | 
					
						
							|  |  |  |         name = "engelsystem"; | 
					
						
							|  |  |  |         ensurePermissions = { "engelsystem.*" = "ALL PRIVILEGES"; }; | 
					
						
							|  |  |  |       }]; | 
					
						
							|  |  |  |       ensureDatabases = [ "engelsystem" ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     environment.etc."engelsystem/config.php".source = | 
					
						
							|  |  |  |       pkgs.writeText "config.php" ''
 | 
					
						
							|  |  |  |         <?php | 
					
						
							|  |  |  |         return json_decode(file_get_contents("/var/lib/engelsystem/config.json"), true); | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.phpfpm.pools.engelsystem = { | 
					
						
							|  |  |  |       user = "engelsystem"; | 
					
						
							|  |  |  |       settings = { | 
					
						
							|  |  |  |         "listen.owner" = config.services.nginx.user; | 
					
						
							|  |  |  |         "pm" = "dynamic"; | 
					
						
							|  |  |  |         "pm.max_children" = 32; | 
					
						
							|  |  |  |         "pm.max_requests" = 500; | 
					
						
							|  |  |  |         "pm.start_servers" = 2; | 
					
						
							|  |  |  |         "pm.min_spare_servers" = 2; | 
					
						
							|  |  |  |         "pm.max_spare_servers" = 5; | 
					
						
							|  |  |  |         "php_admin_value[error_log]" = "stderr"; | 
					
						
							|  |  |  |         "php_admin_flag[log_errors]" = true; | 
					
						
							|  |  |  |         "catch_workers_output" = true; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.nginx = { | 
					
						
							|  |  |  |       enable = true; | 
					
						
							|  |  |  |       virtualHosts."${cfg.domain}".locations = { | 
					
						
							|  |  |  |         "/" = { | 
					
						
							|  |  |  |           root = "${cfg.package}/share/engelsystem/public"; | 
					
						
							|  |  |  |           extraConfig = ''
 | 
					
						
							|  |  |  |             index index.php; | 
					
						
							|  |  |  |             try_files $uri $uri/ /index.php?$args; | 
					
						
							|  |  |  |             autoindex off; | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         "~ \\.php$" = { | 
					
						
							|  |  |  |           root = "${cfg.package}/share/engelsystem/public"; | 
					
						
							|  |  |  |           extraConfig = ''
 | 
					
						
							|  |  |  |             fastcgi_pass unix:${config.services.phpfpm.pools.engelsystem.socket}; | 
					
						
							|  |  |  |             fastcgi_index index.php; | 
					
						
							|  |  |  |             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | 
					
						
							|  |  |  |             include ${config.services.nginx.package}/conf/fastcgi_params; | 
					
						
							|  |  |  |             include ${config.services.nginx.package}/conf/fastcgi.conf; | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     systemd.services."engelsystem-init" = { | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  |       serviceConfig = { Type = "oneshot"; }; | 
					
						
							|  |  |  |       script = | 
					
						
							|  |  |  |         let | 
					
						
							|  |  |  |           genConfigScript = pkgs.writeScript "engelsystem-gen-config.sh" | 
					
						
							|  |  |  |             (utils.genJqSecretsReplacementSnippet cfg.config "config.json"); | 
					
						
							|  |  |  |         in ''
 | 
					
						
							|  |  |  |           umask 077 | 
					
						
							|  |  |  |           mkdir -p /var/lib/engelsystem/storage/app | 
					
						
							|  |  |  |           mkdir -p /var/lib/engelsystem/storage/cache/views | 
					
						
							|  |  |  |           cd /var/lib/engelsystem | 
					
						
							|  |  |  |           ${genConfigScript} | 
					
						
							|  |  |  |           chmod 400 config.json | 
					
						
							|  |  |  |           chown -R engelsystem . | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     systemd.services."engelsystem-migrate" = { | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  |       serviceConfig = { | 
					
						
							|  |  |  |         Type = "oneshot"; | 
					
						
							|  |  |  |         User = "engelsystem"; | 
					
						
							|  |  |  |         Group = "engelsystem"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       script = ''
 | 
					
						
							|  |  |  |         ${cfg.package}/bin/migrate | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |       after = [ "engelsystem-init.service" "mysql.service" ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     systemd.services."phpfpm-engelsystem".after = | 
					
						
							|  |  |  |       [ "engelsystem-migrate.service" ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     users.users.engelsystem = { | 
					
						
							|  |  |  |       isSystemUser = true; | 
					
						
							|  |  |  |       createHome = true; | 
					
						
							|  |  |  |       home = "/var/lib/engelsystem/storage"; | 
					
						
							|  |  |  |       group = "engelsystem"; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     users.groups.engelsystem = { }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |