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 = lib.mdDoc ''
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 = lib.mdDoc "Location of Jirafeau storage directory.";
37 };
38
39 enable = mkEnableOption (lib.mdDoc "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 lib.mdDoc ''
53 Jirefeau configuration. Refer to <${documentationLink}> for supported
54 values.
55 '';
56 };
57
58 hostName = mkOption {
59 type = types.str;
60 default = "localhost";
61 description = lib.mdDoc "URL of instance. Must have trailing slash.";
62 };
63
64 maxUploadSizeMegabytes = mkOption {
65 type = types.int;
66 default = 0;
67 description = lib.mdDoc "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 lib.mdDoc ''
77 Timeout for reading client request bodies and headers. Refer to
78 <${nginxCoreDocumentation}#client_body_timeout> and
79 <${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 = literalExpression ''
88 {
89 serverAliases = [ "wiki.''${config.networking.domain}" ];
90 }
91 '';
92 description = lib.mdDoc "Extra configuration for the nginx virtual host of Jirafeau.";
93 };
94
95 package = mkOption {
96 type = types.package;
97 default = pkgs.jirafeau;
98 defaultText = literalExpression "pkgs.jirafeau";
99 description = lib.mdDoc "Jirafeau package to use";
100 };
101
102 poolConfig = mkOption {
103 type = with types; attrsOf (oneOf [ str int bool ]);
104 default = {
105 "pm" = "dynamic";
106 "pm.max_children" = 32;
107 "pm.start_servers" = 2;
108 "pm.min_spare_servers" = 2;
109 "pm.max_spare_servers" = 4;
110 "pm.max_requests" = 500;
111 };
112 description = lib.mdDoc ''
113 Options for Jirafeau PHP pool. See documentation on `php-fpm.conf` for
114 details on configuration directives.
115 '';
116 };
117 };
118
119
120 config = mkIf cfg.enable {
121 services = {
122 nginx = {
123 enable = true;
124 virtualHosts."${cfg.hostName}" = mkMerge [
125 cfg.nginxConfig
126 {
127 extraConfig = let
128 clientMaxBodySize =
129 if cfg.maxUploadSizeMegabytes == 0 then "0" else "${cfg.maxUploadSizeMegabytes}m";
130 in
131 ''
132 index index.php;
133 client_max_body_size ${clientMaxBodySize};
134 client_body_timeout ${cfg.maxUploadTimeout};
135 client_header_timeout ${cfg.maxUploadTimeout};
136 '';
137 locations = {
138 "~ \\.php$".extraConfig = ''
139 include ${config.services.nginx.package}/conf/fastcgi_params;
140 fastcgi_split_path_info ^(.+\.php)(/.+)$;
141 fastcgi_index index.php;
142 fastcgi_pass unix:${config.services.phpfpm.pools.jirafeau.socket};
143 fastcgi_param PATH_INFO $fastcgi_path_info;
144 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
145 '';
146 };
147 root = mkForce "${cfg.package}";
148 }
149 ];
150 };
151
152 phpfpm.pools.jirafeau = {
153 inherit group user;
154 phpEnv."JIRAFEAU_CONFIG" = "${localConfig}";
155 settings = {
156 "listen.mode" = "0660";
157 "listen.owner" = user;
158 "listen.group" = group;
159 } // cfg.poolConfig;
160 };
161 };
162
163 systemd.tmpfiles.rules = [
164 "d ${cfg.dataDir} 0750 ${user} ${group} - -"
165 "d ${cfg.dataDir}/files/ 0750 ${user} ${group} - -"
166 "d ${cfg.dataDir}/links/ 0750 ${user} ${group} - -"
167 "d ${cfg.dataDir}/async/ 0750 ${user} ${group} - -"
168 ];
169 };
170
171 # uses attributes of the linked package
172 meta.buildDocsInSandbox = false;
173}