Skip to main content

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}