sqry_daemon/lifecycle/units/mod.rs
1//! Service unit generators — Task 9 §F.
2//!
3//! Each submodule emits a platform-native service descriptor as a `String`.
4//! The generators are pure functions: `&DaemonConfig` + `&InstallOptions` →
5//! `String`. No OS API calls are made; tests run on any host regardless of
6//! target OS.
7//!
8//! # Platform gating
9//!
10//! | Module | `cfg` gate | Subcommand |
11//! |-------------|------------------------------|--------------------------|
12//! | `systemd` | `target_os = "linux"` | `install-systemd-user/system` |
13//! | `launchd` | `target_os = "macos"` | `install-launchd` |
14//! | `windows` | `target_os = "windows"` | `install-windows` |
15//!
16//! # Design reference
17//!
18//! `docs/reviews/sqryd-daemon/2026-04-19/task-9-design_iter3_request.md`
19//! §F.1–§F.4 + §F.5 (testing).
20
21/// systemd user + system unit generators (Task 9 U6, Linux only).
22///
23/// Exports [`systemd::generate_user_unit`] and [`systemd::generate_system_unit`].
24/// [`systemd::resolve_system_unit_user`] validates the `%i` account name before
25/// `generate_system_unit` is called.
26#[cfg(target_os = "linux")]
27pub mod systemd;
28
29/// launchd user-agent plist generator (Task 9 U7, macOS only).
30///
31/// Exports [`launchd::generate_plist`], [`launchd::default_install_path`],
32/// and the constants [`launchd::PLIST_LABEL`] / [`launchd::INSTALL_PATH`].
33#[cfg(target_os = "macos")]
34pub mod launchd;
35
36#[cfg(target_os = "windows")]
37pub mod windows;
38
39// ---------------------------------------------------------------------------
40// Shared types.
41// ---------------------------------------------------------------------------
42
43/// Options forwarded to every service-unit generator.
44///
45/// Passed alongside `&DaemonConfig` to each `generate_*` function so that
46/// per-install overrides (e.g. a specific service account on the system
47/// systemd unit, or a custom label on the launchd plist) can be supplied
48/// without touching the config file.
49#[derive(Debug, Clone, Default)]
50pub struct InstallOptions {
51 /// Optional user account name.
52 ///
53 /// - **systemd system unit** (U6): the `%i` template value, validated via
54 /// `users::get_user_by_name` on Linux. Falls back to `$USER` env if
55 /// `None`. The generator exits `EX_CONFIG` (78) if the account is
56 /// unresolvable.
57 /// - **Windows** (U8): the account passed to `sc.exe obj=` and the Task
58 /// Scheduler `UserId`. Defaults to `"LocalSystem"` for the service and
59 /// the current user for the Task Scheduler job if `None`.
60 /// - Ignored by the systemd user unit and launchd generators (they always
61 /// run as the invoking user).
62 pub user: Option<String>,
63
64 /// Override the path to the `sqryd` binary embedded in the generated unit.
65 ///
66 /// When `None`, generators call [`std::env::current_exe()`] to resolve the
67 /// running binary. Set this to a fixed path in tests for portable,
68 /// deterministic snapshot assertions.
69 pub exe_path: Option<std::path::PathBuf>,
70
71 /// Override the user home directory used by the launchd plist generator.
72 ///
73 /// When `None`, the launchd generator calls [`dirs::home_dir()`] (falling
74 /// back to the `$HOME` environment variable) to resolve the invoking user's
75 /// home directory. Set this to a fixed path in tests to inject arbitrary
76 /// home-directory values — including paths that contain XML-significant
77 /// characters — for portable, deterministic assertions independent of the
78 /// real home directory.
79 ///
80 /// Ignored by all non-launchd generators.
81 pub home_dir: Option<std::path::PathBuf>,
82}