1{ config, lib, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.services.jirafeau;
6
7 group = config.services.nginx.group;
8 user = config.services.nginx.user;
9
10 withTrailingSlash = str: if hasSuffix "/" str then str else "${str}/";
11
12 localConfig = pkgs.writeText "config.local.php" ''
13 <?php
14 $cfg['admin_password'] = '${cfg.adminPasswordSha256}';
15 $cfg['web_root'] = 'http://${withTrailingSlash cfg.hostName}';
16 $cfg['var_root'] = '${withTrailingSlash cfg.dataDir}';
17 $cfg['maximal_upload_size'] = ${builtins.toString cfg.maxUploadSizeMegabytes};
18 $cfg['installation_done'] = true;
19
20 ${cfg.extraConfig}
21 '';
22in
23{
24 options.services.jirafeau = {
25 adminPasswordSha256 = mkOption {
26 type = types.str;
27 default = "";
28 description = ''
29 SHA-256 of the desired administration password. Leave blank/unset for no password.
30 '';
31 };
32
33 dataDir = mkOption {
34 type = types.path;
35 default = "/var/lib/jirafeau/data/";
36 description = "Location of Jirafeau storage directory.";
37 };
38
39 enable = mkEnableOption "Jirafeau file upload application.";
40
41 extraConfig = mkOption {
42 type = types.lines;
43 default = "";
44 example = ''
45 $cfg['style'] = 'courgette';
46 $cfg['organisation'] = 'ACME';
47 '';
48 description = let
49 documentationLink =
50 "https://gitlab.com/mojo42/Jirafeau/-/blob/${cfg.package.version}/lib/config.original.php";
51 in
52 ''
53 Jirefeau configuration. Refer to <link xlink:href="${documentationLink}"/> for supported
54 values.
55 '';
56 };
57
58 hostName = mkOption {
59 type = types.str;
60 default = "localhost";
61 description = "URL of instance. Must have trailing slash.";
62 };
63
64 maxUploadSizeMegabytes = mkOption {
65 type = types.int;
66 default = 0;
67 description = "Maximum upload size of accepted files.";
68 };
69
70 maxUploadTimeout = mkOption {
71 type = types.str;
72 default = "30m";
73 description = let
74 nginxCoreDocumentation = "http://nginx.org/en/docs/http/ngx_http_core_module.html";
75 in
76 ''
77 Timeout for reading client request bodies and headers. Refer to
78 <link xlink:href="${nginxCoreDocumentation}#client_body_timeout"/> and
79 <link xlink:href="${nginxCoreDocumentation}#client_header_timeout"/> for accepted values.
80 '';
81 };
82
83 nginxConfig = mkOption {
84 type = types.submodule
85 (import ../web-servers/nginx/vhost-options.nix { inherit config lib; });
86 default = {};
87 example = {
88 serverAliases = [ "wiki.\${config.networking.domain}" ];
89 };
90 description = "Extra configuration for the nginx virtual host of Jirafeau.";
91 };
92
93 package = mkOption {
94 type = types.package;
95 default = pkgs.jirafeau;
96 defaultText = "pkgs.jirafeau";
97 description = "Jirafeau package to use";
98 example = "pkgs.jirafeau";
99 };
100
101 poolConfig = mkOption {
102 type = with types; attrsOf (oneOf [ str int bool ]);
103 default = {
104 "pm" = "dynamic";
105 "pm.max_children" = 32;
106 "pm.start_servers" = 2;
107 "pm.min_spare_servers" = 2;
108 "pm.max_spare_servers" = 4;
109 "pm.max_requests" = 500;
110 };
111 description = ''
112 Options for Jirafeau PHP pool. See documentation on <literal>php-fpm.conf</literal> for
113 details on configuration directives.
114 '';
115 };
116 };
117
118
119 config = mkIf cfg.enable {
120 services = {
121 nginx = {
122 enable = true;
123 virtualHosts."${cfg.hostName}" = mkMerge [
124 cfg.nginxConfig
125 {
126 extraConfig = let
127 clientMaxBodySize =
128 if cfg.maxUploadSizeMegabytes == 0 then "0" else "${cfg.maxUploadSizeMegabytes}m";
129 in
130 ''
131 index index.php;
132 client_max_body_size ${clientMaxBodySize};
133 client_body_timeout ${cfg.maxUploadTimeout};
134 client_header_timeout ${cfg.maxUploadTimeout};
135 '';
136 locations = {
137 "~ \\.php$".extraConfig = ''
138 include ${pkgs.nginx}/conf/fastcgi_params;
139 fastcgi_split_path_info ^(.+\.php)(/.+)$;
140 fastcgi_index index.php;
141 fastcgi_pass unix:${config.services.phpfpm.pools.jirafeau.socket};
142 fastcgi_param PATH_INFO $fastcgi_path_info;
143 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
144 '';
145 };
146 root = mkForce "${cfg.package}";
147 }
148 ];
149 };
150
151 phpfpm.pools.jirafeau = {
152 inherit group user;
153 phpEnv."JIRAFEAU_CONFIG" = "${localConfig}";
154 settings = {
155 "listen.mode" = "0660";
156 "listen.owner" = user;
157 "listen.group" = group;
158 } // cfg.poolConfig;
159 };
160 };
161
162 systemd.tmpfiles.rules = [
163 "d ${cfg.dataDir} 0750 ${user} ${group} - -"
164 "d ${cfg.dataDir}/files/ 0750 ${user} ${group} - -"
165 "d ${cfg.dataDir}/links/ 0750 ${user} ${group} - -"
166 "d ${cfg.dataDir}/async/ 0750 ${user} ${group} - -"
167 ];
168 };
169}