Commit

Author:

Hash:

Timestamp:

+139 -116 +/-21 browse

Kevin Schoon [me@kevinschoon.com]

d907cd91a24b933e29696c1d6fc46f3242f7bbe8

Sun, 14 Jun 2026 07:40:23 +0000 (1 month ago)

clean up various systemd integrations and default paths
clean up various systemd integrations and default paths

Changes the default paths Ayllu will use when XDG_* variables
are not set to also use those provided by systemd.
1diff --git a/PKGBUILD b/PKGBUILD
2index 105adb8..11ebe40 100644
3--- a/PKGBUILD
4+++ b/PKGBUILD
5 @@ -62,11 +62,11 @@ package() {
6 done
7
8 for script in $(find ./systemd/system -type f); do
9- install -Dm644 "${srcdir}/${script}" "${pkgdir}/etc/systemd/system/$(basename $script)"
10+ install -Dm644 "${srcdir}/${script}" "${pkgdir}/usr/lib/systemd/system/$(basename $script)"
11 done
12
13 for script in $(find ./systemd/user -type f); do
14- install -Dm644 "${srcdir}/${script}" "${pkgdir}/etc/systemd/user/$(basename $script)"
15+ install -Dm644 "${srcdir}/${script}" "${pkgdir}/usr/lib/systemd/user/$(basename $script)"
16 done
17
18 install -Dm644 ${srcdir}/LICENSE "${pkgdir}/usr/share/licenses/ayllu"
19 diff --git a/ayllu-build/src/workspace.rs b/ayllu-build/src/workspace.rs
20index 896dd8f..1671dd0 100644
21--- a/ayllu-build/src/workspace.rs
22+++ b/ayllu-build/src/workspace.rs
23 @@ -410,6 +410,7 @@ mod test {
24 let config = Config {
25 build: Build {
26 work_dir: test_dir.path().to_path_buf(),
27+ runtime_dir: test_dir.path().join("runtime"),
28 images: HashMap::from_iter([(
29 "test".to_string(),
30 Image {
31 diff --git a/ayllu-shell/src/config.rs b/ayllu-shell/src/config.rs
32index 84e6d53..84d644d 100644
33--- a/ayllu-shell/src/config.rs
34+++ b/ayllu-shell/src/config.rs
35 @@ -48,7 +48,7 @@ impl Config {
36 }
37
38 fn default_build_socket() -> PathBuf {
39- ayllu_config::runtime_dir().join("ayllu-build.socket")
40+ ayllu_config::runtime_dir().join("ayllu/build.socket")
41 }
42 }
43
44 diff --git a/contrib/systemd/system/ayllu-build-gc.service b/contrib/systemd/system/ayllu-build-gc.service
45index 838b3e0..c253641 100644
46--- a/contrib/systemd/system/ayllu-build-gc.service
47+++ b/contrib/systemd/system/ayllu-build-gc.service
48 @@ -1,11 +1,19 @@
49 [Unit]
50 Description=Ayllu Build Garbage Collector
51- Wants=multi-user.target
52 After=multi-user.target
53
54 [Service]
55 Type=oneshot
56+ ProtectSystem=strict
57+ ProtectHome=true
58+ RuntimeDirectoryPreserve=yes
59+ StateDirectory=ayllu
60+ RuntimeDirectory=ayllu
61+ ConfigurationDirectory=ayllu
62 User=ayllu
63 Group=ayllu
64 Restart=no
65 ExecStart=/usr/bin/ayllu-build gc --workspace
66+
67+ [Install]
68+ WantedBy=multi-user.target
69 diff --git a/contrib/systemd/system/ayllu-build-gc.timer b/contrib/systemd/system/ayllu-build-gc.timer
70index b7b9929..b09c906 100644
71--- a/contrib/systemd/system/ayllu-build-gc.timer
72+++ b/contrib/systemd/system/ayllu-build-gc.timer
73 @@ -1,8 +1,10 @@
74 [Unit]
75 Description=Hourly Garbage Collection for Ayllu Build
76+ Documentation=man:ayllu-build-gc(1)
77
78 [Timer]
79- OnActiveSec=3600
80+ OnBootSec=5m
81+ OnUnitActiveSec=1h
82
83 [Install]
84 WantedBy=timers.target
85 diff --git a/contrib/systemd/system/ayllu-build.service b/contrib/systemd/system/ayllu-build.service
86deleted file mode 100644
87index e20654b..0000000
88--- a/contrib/systemd/system/ayllu-build.service
89+++ /dev/null
90 @@ -1,11 +0,0 @@
91- [Unit]
92- Description=Ayllu Build Invocation
93- Requires=ayllu-build.socket
94- After=network.target
95-
96- [Service]
97- User=ayllu
98- Group=ayllu
99- Type=simple
100- StandardInput=socket
101- ExecStart=/usr/bin/ayllu-build
102 diff --git a/contrib/systemd/system/ayllu-build.socket b/contrib/systemd/system/ayllu-build.socket
103index 7acd067..bd4075f 100644
104--- a/contrib/systemd/system/ayllu-build.socket
105+++ b/contrib/systemd/system/ayllu-build.socket
106 @@ -1,6 +1,8 @@
107 [Unit]
108- Description=Ayllu Hyper Performant Code Forge
109+ Description=Ayllu Build Socket
110+ Documentation=man:ayllu-build(1)
111
112 [Socket]
113+ Accept=yes
114 SocketUser=ayllu
115- ListenSequentialPacket=/var/run/ayllu/ayllu-build.socket
116+ ListenStream=%t/ayllu/build.socket
117 diff --git a/contrib/systemd/system/ayllu-build@.service b/contrib/systemd/system/ayllu-build@.service
118new file mode 100644
119index 0000000..ca8de51
120--- /dev/null
121+++ b/contrib/systemd/system/ayllu-build@.service
122 @@ -0,0 +1,19 @@
123+ [Unit]
124+ Description=Ayllu Build Invocation
125+ Requires=ayllu-build.socket
126+ After=network.target
127+
128+ [Service]
129+ User=ayllu
130+ Group=ayllu
131+ Type=simple
132+ ProtectSystem=strict
133+ ProtectHome=true
134+ RuntimeDirectoryPreserve=yes
135+ StateDirectory=ayllu
136+ RuntimeDirectory=ayllu
137+ ConfigurationDirectory=ayllu
138+ StandardInput=socket
139+ StandardOutput=journal
140+ StandardError=journal
141+ ExecStart=/usr/bin/ayllu-build evaluate --stdin
142 diff --git a/contrib/systemd/system/ayllu-mail.service b/contrib/systemd/system/ayllu-mail.service
143deleted file mode 100644
144index 510c08a..0000000
145--- a/contrib/systemd/system/ayllu-mail.service
146+++ /dev/null
147 @@ -1,11 +0,0 @@
148- [Unit]
149- Description=Ayllu Hyper Performant Code Forge (Mail Server Plugin)
150- After=network.target
151-
152- [Service]
153- ExecStart=/usr/bin/ayllu-mail serve
154- User=ayllu
155- Group=ayllu
156-
157- [Install]
158- WantedBy=multi-user.target
159 diff --git a/contrib/systemd/system/ayllu-mail.socket b/contrib/systemd/system/ayllu-mail.socket
160deleted file mode 100644
161index 9111e41..0000000
162--- a/contrib/systemd/system/ayllu-mail.socket
163+++ /dev/null
164 @@ -1,6 +0,0 @@
165- [Unit]
166- Description=Ayllu Hyper Performant Code Forge (Mail Server Plugin)
167-
168- [Socket]
169- SocketUser=ayllu
170- ListenSequentialPacket=/var/run/ayllu/mail.socket
171 diff --git a/contrib/systemd/system/ayllu-migrate.service b/contrib/systemd/system/ayllu-migrate.service
172new file mode 100644
173index 0000000..c9e6dd1
174--- /dev/null
175+++ b/contrib/systemd/system/ayllu-migrate.service
176 @@ -0,0 +1,14 @@
177+ [Unit]
178+ Description=Ayllu Migration
179+ Documentation=man:ayllu-migrate(1)
180+
181+ [Service]
182+ ExecStart=/usr/bin/ayllu-migrate
183+ ConfigurationDirectory=ayllu
184+ StateDirectory=ayllu
185+ Type=oneshot
186+ User=ayllu
187+ Group=ayllu
188+
189+ [Install]
190+ WantedBy=default.target
191 diff --git a/contrib/systemd/system/ayllu-web.service b/contrib/systemd/system/ayllu-web.service
192index ecb4546..98e7aad 100644
193--- a/contrib/systemd/system/ayllu-web.service
194+++ b/contrib/systemd/system/ayllu-web.service
195 @@ -1,9 +1,16 @@
196 [Unit]
197- Description=Ayllu Hyper Performant Code Forge
198+ Description=Ayllu Web Interface
199+ Documentation=man:ayllu-web(1)
200 After=network.target
201
202 [Service]
203 ExecStart=/usr/bin/ayllu-web serve
204+ ProtectSystem=strict
205+ ProtectHome=true
206+ RuntimeDirectoryPreserve=yes
207+ StateDirectory=ayllu
208+ RuntimeDirectory=ayllu
209+ ConfigurationDirectory=ayllu
210 User=ayllu
211 Group=ayllu
212
213 diff --git a/contrib/systemd/user/ayllu-build-gc.service b/contrib/systemd/user/ayllu-build-gc.service
214index 695af63..f5ed796 100644
215--- a/contrib/systemd/user/ayllu-build-gc.service
216+++ b/contrib/systemd/user/ayllu-build-gc.service
217 @@ -1,9 +1,11 @@
218 [Unit]
219 Description=Ayllu Build Garbage Collector
220- Wants=multi-user.target
221 After=multi-user.target
222
223 [Service]
224 Type=oneshot
225 Restart=no
226 ExecStart=/usr/bin/ayllu-build gc --workspace
227+
228+ [Install]
229+ WantedBy=multi-user.target
230 diff --git a/contrib/systemd/user/ayllu-build-gc.timer b/contrib/systemd/user/ayllu-build-gc.timer
231index b7b9929..b09c906 100644
232--- a/contrib/systemd/user/ayllu-build-gc.timer
233+++ b/contrib/systemd/user/ayllu-build-gc.timer
234 @@ -1,8 +1,10 @@
235 [Unit]
236 Description=Hourly Garbage Collection for Ayllu Build
237+ Documentation=man:ayllu-build-gc(1)
238
239 [Timer]
240- OnActiveSec=3600
241+ OnBootSec=5m
242+ OnUnitActiveSec=1h
243
244 [Install]
245 WantedBy=timers.target
246 diff --git a/contrib/systemd/user/ayllu-build.socket b/contrib/systemd/user/ayllu-build.socket
247index 29f30e3..bd4075f 100644
248--- a/contrib/systemd/user/ayllu-build.socket
249+++ b/contrib/systemd/user/ayllu-build.socket
250 @@ -1,5 +1,8 @@
251 [Unit]
252 Description=Ayllu Build Socket
253+ Documentation=man:ayllu-build(1)
254
255 [Socket]
256- ListenSequentialPacket=%t/ayllu-build.socket
257+ Accept=yes
258+ SocketUser=ayllu
259+ ListenStream=%t/ayllu/build.socket
260 diff --git a/contrib/systemd/user/ayllu-build@.service b/contrib/systemd/user/ayllu-build@.service
261new file mode 100644
262index 0000000..522e4b9
263--- /dev/null
264+++ b/contrib/systemd/user/ayllu-build@.service
265 @@ -0,0 +1,11 @@
266+ [Unit]
267+ Description=Ayllu Build Invocation
268+ Requires=ayllu-build.socket
269+ After=network.target
270+
271+ [Service]
272+ Type=simple
273+ StandardInput=socket
274+ StandardOutput=journal
275+ StandardError=journal
276+ ExecStart=/usr/bin/ayllu-build evaluate --stdin
277 diff --git a/contrib/systemd/user/ayllu-job-template@.service b/contrib/systemd/user/ayllu-job-template@.service
278deleted file mode 100644
279index 3effa52..0000000
280--- a/contrib/systemd/user/ayllu-job-template@.service
281+++ /dev/null
282 @@ -1,38 +0,0 @@
283- # A oneshot systemd unit template for running ayllu jobs after updating a repository.
284- # You can use it as a post-receive hook in your repo's hooks/ directory.
285- # Do not forget to set the hook file as executable!
286- #
287- # How to use:
288- # - Add to systemd's configuration paths, e.g. $HOME/.config/systemd/user/ or /etc/systemd/user/
289- # - Run `systemctl --user daemon-reload`
290- # - To execute the job, run:
291- # systemctl --user start ayllu-job-template@`systemd-escape "$(pwd)"`.service
292- # if your current directory is the repository directory. Otherwise replace
293- # `$(pwd)` with a variable `${VAR}` which holds the path to the repository:
294- # export VAR=/home/user/repos/user/repo/; \
295- # systemctl --user start ayllu-job-template@`systemd-escape "${VAR}"`.service
296- #
297- # Copyright 2024 Emmanouil Pitsidianakis <manos@pitsidianak.is>
298- # SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
299-
300- [Unit]
301- Description=Ayllu job post-receive hook for %I
302- StartLimitIntervalSec=60
303- StartLimitBurst=5
304-
305- [Service]
306- WantedBy=default.target
307- Type=oneshot
308- RemainAfterExit=no
309- TimeoutStartSec=5
310- ExecStart=/usr/bin/ayllu jobs run "%I"
311- KillSignal=SIGTERM
312- Restart=on-failure
313- RestartSec=12
314- RestartSteps=60
315- RestartMaxDelaySec=3600
316- OOMPolicy=kill
317- RuntimeMaxSec=3600
318-
319- [Install]
320- WantedBy=default.target
321 diff --git a/contrib/systemd/user/ayllu-migrate.service b/contrib/systemd/user/ayllu-migrate.service
322new file mode 100644
323index 0000000..c9e6dd1
324--- /dev/null
325+++ b/contrib/systemd/user/ayllu-migrate.service
326 @@ -0,0 +1,14 @@
327+ [Unit]
328+ Description=Ayllu Migration
329+ Documentation=man:ayllu-migrate(1)
330+
331+ [Service]
332+ ExecStart=/usr/bin/ayllu-migrate
333+ ConfigurationDirectory=ayllu
334+ StateDirectory=ayllu
335+ Type=oneshot
336+ User=ayllu
337+ Group=ayllu
338+
339+ [Install]
340+ WantedBy=default.target
341 diff --git a/contrib/systemd/user/ayllu-web.service b/contrib/systemd/user/ayllu-web.service
342index 379aaed..30f3b5b 100644
343--- a/contrib/systemd/user/ayllu-web.service
344+++ b/contrib/systemd/user/ayllu-web.service
345 @@ -1,8 +1,10 @@
346 [Unit]
347- Description=Ayllu Hyper Performant Code Forge
348+ Description=Ayllu Web Interface
349+ Documentation=man:ayllu-web(1)
350+ After=network.target
351
352 [Service]
353 ExecStart=/usr/bin/ayllu-web serve
354
355 [Install]
356- WantedBy=default.target
357+ WantedBy=multi-user.target
358 diff --git a/crates/config/src/reader.rs b/crates/config/src/reader.rs
359index b272f16..c36845a 100644
360--- a/crates/config/src/reader.rs
361+++ b/crates/config/src/reader.rs
362 @@ -20,27 +20,30 @@ pub trait Configurable {
363
364 /// attempt to read the configuration from the host
365 pub fn try_read() -> Option<(PathBuf, String)> {
366- let home_config = match env::var("XDG_CONFIG_HOME") {
367- Ok(path) => PathBuf::from_iter([path.as_str(), "ayllu", "config.toml"]),
368- Err(_) => PathBuf::from_iter([
369- env::var("HOME").unwrap_or(String::from("/")).as_str(),
370- ".config",
371- "ayllu",
372- "config.toml",
373- ]),
374- };
375- for path in [
376- &home_config,
377- Path::new("./config.toml"),
378- Path::new("/etc/ayllu/config.toml"),
379- ] {
380- eprintln!("reading configuration from {}", path.display());
381- let ret = std::fs::read_to_string(path);
382- match ret {
383- Ok(r) => return Some((path.to_path_buf(), r)),
384- Err(_) => continue,
385+ let config_path = [
386+ env::var("AYLLU_CONFIG_PATH").ok().map(PathBuf::from),
387+ env::var("XDG_CONFIG_HOME")
388+ .ok()
389+ .map(|path| PathBuf::from(path).join("ayllu/config.toml")),
390+ env::var("CONFIGURATION_DIRECTORY")
391+ .ok()
392+ .map(|path| PathBuf::from(path).join("config.toml")),
393+ Some(PathBuf::from("./config.toml")),
394+ Some(PathBuf::from("/etc/ayllu/config.toml")),
395+ ]
396+ .into_iter()
397+ .find(|path| path.as_ref().is_some_and(|path| path.exists()))
398+ .flatten();
399+
400+ if let Some(path) = config_path.as_ref() {
401+ eprintln!("reading configuration from {path:?}");
402+ match std::fs::read_to_string(path) {
403+ Ok(content) => return Some((path.to_path_buf(), content)),
404+ Err(err) => {
405+ eprintln!("Read failed: {err:?}, won't continue looking");
406+ }
407 };
408- }
409+ };
410 None
411 }
412
413 @@ -84,23 +87,22 @@ where
414 }
415 }
416
417- /// return the XDG_DATA_DIR
418+ /// return the data directory for persistent files.
419+ /// See systemd.exec(5)
420 pub fn data_dir() -> PathBuf {
421- match env::var("XDG_DATA_DIR") {
422- Ok(value) => PathBuf::from_iter([value.as_str(), "ayllu"]),
423- Err(_) => PathBuf::from_iter([
424- env::var("HOME").unwrap_or(String::from("/")).as_str(),
425- ".local",
426- "share",
427- "ayllu",
428- ]),
429- }
430+ env::var("XDG_DATA_DIR")
431+ .ok()
432+ .map(|path| PathBuf::from(path).join("ayllu"))
433+ .or_else(|| env::var("STATE_DIRECTORY").ok().map(PathBuf::from))
434+ .unwrap_or(PathBuf::from("/var/lib/ayllu"))
435 }
436
437- // return the XDG_RUNTIME_DIR
438+ /// Return the runtime directory for temporary work files
439+ /// See systemd.exec(5)
440 pub fn runtime_dir() -> PathBuf {
441- match env::var("XDG_RUNTIME_DIR") {
442- Ok(value) => PathBuf::from(value),
443- Err(_) => PathBuf::from("/tmp"),
444- }
445+ env::var("XDG_RUNTIME_DIR")
446+ .ok()
447+ .map(|path| PathBuf::from(path).join("ayllu"))
448+ .or_else(|| env::var("RUNTIME_DIRECTORY").ok().map(PathBuf::from))
449+ .unwrap_or(PathBuf::from("/run/ayllu"))
450 }
451 diff --git a/scripts/build_deb.sh b/scripts/build_deb.sh
452index 4234059..2e20d41 100755
453--- a/scripts/build_deb.sh
454+++ b/scripts/build_deb.sh
455 @@ -50,11 +50,11 @@ for script in $(find ./dist/completion -type f -name '_*'); do
456 done
457
458 for script in $(find ./contrib/systemd/system -type f); do
459- install -Dm644 "${script}" "${BUILD_DIR}/etc/systemd/system/$(basename $script)"
460+ install -Dm644 "${script}" "${BUILD_DIR}/usr/lib/systemd/system/$(basename $script)"
461 done
462
463 for script in $(find ./contrib/systemd/user -type f); do
464- install -Dm644 "${script}" "${BUILD_DIR}/etc/systemd/user/$(basename $script)"
465+ install -Dm644 "${script}" "${BUILD_DIR}/usr/lib/systemd/user/$(basename $script)"
466 done
467
468 install -Dm644 "LICENSE" "${BUILD_DIR}/usr/share/licenses/ayllu"