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