]>
Commit | Line | Data |
---|---|---|
1 | { | |
2 | description = "a free software media publishing platform that anyone can run."; | |
3 | inputs.myuids = { | |
4 | url = "path:../myuids"; | |
5 | }; | |
6 | inputs.flake-utils.url = "github:numtide/flake-utils"; | |
7 | inputs.nixpkgs = { | |
8 | url = "github:NixOS/nixpkgs/840c782d507d60aaa49aa9e3f6d0b0e780912742"; | |
9 | flake = false; | |
10 | }; | |
11 | inputs.mediagoblin = { | |
12 | url = "git+https://git.savannah.gnu.org/git/mediagoblin.git?submodules=1&ref=stable&rev=cd465ebfec837a75a44c4ebd727dffe2fff6d850"; | |
13 | flake = false; | |
14 | }; | |
15 | ||
16 | outputs = { self, myuids, nixpkgs, mediagoblin, flake-utils }: flake-utils.lib.eachSystem ["x86_64-linux"] (system: | |
17 | let | |
18 | pkgs = import nixpkgs { inherit system; overlays = []; }; | |
19 | version = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.mediagoblin.original.ref; | |
20 | inherit (pkgs) callPackage; | |
21 | in rec { | |
22 | packages.mediagoblin = callPackage ./. { src = mediagoblin // { inherit version; }; }; | |
23 | defaultPackage = packages.mediagoblin; | |
24 | legacyPackages.mediagoblin = packages.mediagoblin; | |
25 | checks = { | |
26 | build = defaultPackage; | |
27 | }; | |
28 | } | |
29 | ) // rec { | |
30 | overlays = { | |
31 | mediagoblin = final: prev: { | |
32 | mediagoblin = self.defaultPackage."${final.system}"; | |
33 | }; | |
34 | }; | |
35 | overlay = overlays.mediagoblin; | |
36 | nixosModule = { lib, pkgs, config, ... }: | |
37 | let | |
38 | name = "mediagoblin"; | |
39 | cfg = config.services.mediagoblin; | |
40 | ||
41 | uid = config.ids.uids.mediagoblin; | |
42 | gid = config.ids.gids.mediagoblin; | |
43 | ||
44 | paste_local = pkgs.writeText "paste_local.ini" '' | |
45 | [DEFAULT] | |
46 | debug = false | |
47 | ||
48 | [pipeline:main] | |
49 | pipeline = mediagoblin | |
50 | ||
51 | [app:mediagoblin] | |
52 | use = egg:mediagoblin#app | |
53 | config = ${cfg.configFile} ${cfg.package}/mediagoblin.ini | |
54 | /mgoblin_static = ${cfg.package}/mediagoblin/static | |
55 | ||
56 | [loggers] | |
57 | keys = root | |
58 | ||
59 | [handlers] | |
60 | keys = console | |
61 | ||
62 | [formatters] | |
63 | keys = generic | |
64 | ||
65 | [logger_root] | |
66 | level = INFO | |
67 | handlers = console | |
68 | ||
69 | [handler_console] | |
70 | class = StreamHandler | |
71 | args = (sys.stderr,) | |
72 | level = NOTSET | |
73 | formatter = generic | |
74 | ||
75 | [formatter_generic] | |
76 | format = %(levelname)-7.7s [%(name)s] %(message)s | |
77 | ||
78 | [filter:errors] | |
79 | use = egg:mediagoblin#errors | |
80 | debug = false | |
81 | ||
82 | [server:main] | |
83 | use = egg:waitress#main | |
84 | unix_socket = ${cfg.sockets.paster} | |
85 | unix_socket_perms = 777 | |
86 | url_scheme = https | |
87 | ''; | |
88 | in | |
89 | { | |
90 | options.services.mediagoblin = { | |
91 | enable = lib.mkEnableOption "Enable Mediagoblin’s service"; | |
92 | user = lib.mkOption { | |
93 | type = lib.types.str; | |
94 | default = name; | |
95 | description = "User account under which Mediagoblin runs"; | |
96 | }; | |
97 | group = lib.mkOption { | |
98 | type = lib.types.str; | |
99 | default = name; | |
100 | description = "Group under which Mediagoblin runs"; | |
101 | }; | |
102 | dataDir = lib.mkOption { | |
103 | type = lib.types.path; | |
104 | default = "/var/lib/${name}"; | |
105 | description = '' | |
106 | The directory where Mediagoblin stores its data. | |
107 | ''; | |
108 | }; | |
109 | socketsDir = lib.mkOption { | |
110 | type = lib.types.path; | |
111 | default = "/run/${name}"; | |
112 | description = '' | |
113 | The directory where Mediagoblin puts runtime files and sockets. | |
114 | ''; | |
115 | }; | |
116 | configFile = lib.mkOption { | |
117 | type = lib.types.path; | |
118 | description = '' | |
119 | The configuration file path for Mediagoblin. | |
120 | ''; | |
121 | }; | |
122 | package = lib.mkOption { | |
123 | type = lib.types.package; | |
124 | default = pkgs.mediagoblin; | |
125 | example = lib.literalExample '' | |
126 | pkgs.webapps.mediagoblin.withPlugins (p: [p.basicsearch]) | |
127 | ''; | |
128 | description = '' | |
129 | Mediagoblin package to use. | |
130 | ''; | |
131 | }; | |
132 | systemdStateDirectory = lib.mkOption { | |
133 | type = lib.types.str; | |
134 | # Use ReadWritePaths= instead if varDir is outside of /var/lib | |
135 | default = assert lib.strings.hasPrefix "/var/lib/" cfg.dataDir; | |
136 | lib.strings.removePrefix "/var/lib/" cfg.dataDir; | |
137 | description = '' | |
138 | Adjusted Mediagoblin data directory for systemd | |
139 | ''; | |
140 | readOnly = true; | |
141 | }; | |
142 | systemdRuntimeDirectory = lib.mkOption { | |
143 | type = lib.types.str; | |
144 | # Use ReadWritePaths= instead if socketsDir is outside of /run | |
145 | default = assert lib.strings.hasPrefix "/run/" cfg.socketsDir; | |
146 | lib.strings.removePrefix "/run/" cfg.socketsDir; | |
147 | description = '' | |
148 | Adjusted Mediagoblin sockets directory for systemd | |
149 | ''; | |
150 | readOnly = true; | |
151 | }; | |
152 | sockets = lib.mkOption { | |
153 | type = lib.types.attrsOf lib.types.path; | |
154 | default = { | |
155 | paster = "${cfg.socketsDir}/mediagoblin.sock"; | |
156 | }; | |
157 | readOnly = true; | |
158 | description = '' | |
159 | Mediagoblin sockets | |
160 | ''; | |
161 | }; | |
162 | pids = lib.mkOption { | |
163 | type = lib.types.attrsOf lib.types.path; | |
164 | default = { | |
165 | paster = "${cfg.socketsDir}/mediagoblin.pid"; | |
166 | celery = "${cfg.socketsDir}/mediagoblin-celeryd.pid"; | |
167 | }; | |
168 | readOnly = true; | |
169 | description = '' | |
170 | Mediagoblin pid files | |
171 | ''; | |
172 | }; | |
173 | }; | |
174 | ||
175 | config = lib.mkIf cfg.enable { | |
176 | nixpkgs.overlays = [ self.overlay ]; | |
177 | users.users = lib.optionalAttrs (cfg.user == name) { | |
178 | "${name}" = { | |
179 | inherit uid; | |
180 | group = cfg.group; | |
181 | description = "Mediagoblin user"; | |
182 | home = cfg.dataDir; | |
183 | useDefaultShell = true; | |
184 | }; | |
185 | }; | |
186 | users.groups = lib.optionalAttrs (cfg.group == name) { | |
187 | "${name}" = { | |
188 | inherit gid; | |
189 | }; | |
190 | }; | |
191 | ||
192 | systemd.slices.mediagoblin = { | |
193 | description = "Mediagoblin slice"; | |
194 | }; | |
195 | systemd.services.mediagoblin-web = { | |
196 | description = "Mediagoblin service"; | |
197 | wantedBy = [ "multi-user.target" ]; | |
198 | after = [ "network.target" ]; | |
199 | wants = [ "postgresql.service" "redis.service" ]; | |
200 | ||
201 | environment.SCRIPT_NAME = "/mediagoblin/"; | |
202 | ||
203 | script = '' | |
204 | exec ./bin/paster serve \ | |
205 | ${paste_local} \ | |
206 | --pid-file=${cfg.pids.paster} | |
207 | ''; | |
208 | preStop = '' | |
209 | exec ./bin/paster serve \ | |
210 | --pid-file=${cfg.pids.paster} \ | |
211 | ${paste_local} stop | |
212 | ''; | |
213 | preStart = '' | |
214 | if [ -d ${cfg.dataDir}/plugin_static/ ]; then | |
215 | rm ${cfg.dataDir}/plugin_static/coreplugin_basic_auth | |
216 | ln -sf ${cfg.package}/mediagoblin/plugins/basic_auth/static ${cfg.dataDir}/plugin_static/coreplugin_basic_auth | |
217 | fi | |
218 | ./bin/gmg -cf ${cfg.configFile} dbupdate | |
219 | ''; | |
220 | ||
221 | serviceConfig = { | |
222 | Slice = "mediagoblin.slice"; | |
223 | User = cfg.user; | |
224 | PrivateTmp = true; | |
225 | Restart = "always"; | |
226 | TimeoutSec = 15; | |
227 | Type = "simple"; | |
228 | WorkingDirectory = cfg.package; | |
229 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | |
230 | StateDirectory= cfg.systemdStateDirectory; | |
231 | PIDFile = cfg.pids.paster; | |
232 | }; | |
233 | ||
234 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
235 | }; | |
236 | ||
237 | systemd.services.mediagoblin-celeryd = { | |
238 | description = "Mediagoblin service"; | |
239 | wantedBy = [ "multi-user.target" ]; | |
240 | after = [ "network.target" "mediagoblin-web.service" ]; | |
241 | ||
242 | environment.MEDIAGOBLIN_CONFIG = cfg.configFile; | |
243 | environment.CELERY_CONFIG_MODULE = "mediagoblin.init.celery.from_celery"; | |
244 | ||
245 | script = '' | |
246 | exec ./bin/celery worker \ | |
247 | --logfile=${cfg.dataDir}/celery.log \ | |
248 | --loglevel=INFO | |
249 | ''; | |
250 | ||
251 | serviceConfig = { | |
252 | Slice = "mediagoblin.slice"; | |
253 | User = cfg.user; | |
254 | PrivateTmp = true; | |
255 | Restart = "always"; | |
256 | TimeoutSec = 60; | |
257 | Type = "simple"; | |
258 | WorkingDirectory = cfg.package; | |
259 | RuntimeDirectory = cfg.systemdRuntimeDirectory; | |
260 | StateDirectory= cfg.systemdStateDirectory; | |
261 | PIDFile = cfg.pids.celery; | |
262 | }; | |
263 | ||
264 | unitConfig.RequiresMountsFor = cfg.dataDir; | |
265 | }; | |
266 | }; | |
267 | }; | |
268 | }; | |
269 | } | |
270 | ||
271 |