]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - flakes/mediagoblin/flake.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / flakes / mediagoblin / flake.nix
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