Skip to main content

horto_os_ui_shared/
paths.rs

1//! Host filesystem layout (`HostPaths`) for setup and day-2 ops.
2
3use std::path::{Path, PathBuf};
4
5/// Default host layout used on a Horto box (`/srv/...`).
6///
7/// Tests and dry-run hosts override these with a temporary tree.
8///
9/// # Examples
10///
11/// ```
12/// use horto_os_ui_shared::HostPaths;
13/// use std::path::PathBuf;
14///
15/// let paths = HostPaths {
16///     active_setup: PathBuf::from("/tmp/active"),
17///     backup: PathBuf::from("/tmp/backup"),
18///     docker: PathBuf::from("/tmp/docker"),
19///     etc: PathBuf::from("/tmp/etc"),
20///     lease_file: PathBuf::from("/tmp/leases"),
21/// };
22/// assert!(paths.resume_file().ends_with("horto_setup_state.json"));
23/// ```
24#[derive(Debug, Clone)]
25pub struct HostPaths {
26    /// `/srv/active_setup` (env files, staging, resume).
27    pub active_setup: PathBuf,
28    /// `/srv/backup`.
29    pub backup: PathBuf,
30    /// `/srv/docker`.
31    pub docker: PathBuf,
32    /// `/etc` (or a tempfile stand-in in tests).
33    pub etc: PathBuf,
34    /// dnsmasq leases file.
35    pub lease_file: PathBuf,
36}
37
38impl Default for HostPaths {
39    fn default() -> Self {
40        Self {
41            active_setup: PathBuf::from("/srv/active_setup"),
42            backup: PathBuf::from("/srv/backup"),
43            docker: PathBuf::from("/srv/docker"),
44            etc: PathBuf::from("/etc"),
45            lease_file: PathBuf::from("/var/lib/misc/dnsmasq.leases"),
46        }
47    }
48}
49
50impl HostPaths {
51    /// Resume JSON path under `active_setup`.
52    #[must_use]
53    pub fn resume_file(&self) -> PathBuf {
54        self.active_setup.join("horto_setup_state.json")
55    }
56
57    /// IoT-LAN env file (`iot-lan_conf.env`).
58    #[must_use]
59    pub fn full_env_file(&self) -> PathBuf {
60        self.active_setup.join("iot-lan_conf.env")
61    }
62
63    /// Alias for [`Self::full_env_file`] (tip name).
64    #[must_use]
65    pub fn iot_lan_env_file(&self) -> PathBuf {
66        self.full_env_file()
67    }
68
69    /// Minimal setup env file.
70    #[must_use]
71    pub fn minimal_env_file(&self) -> PathBuf {
72        self.active_setup.join("minimal_setup_vars.env")
73    }
74
75    /// OS configuration env under active setup.
76    #[must_use]
77    pub fn os_configuration_file(&self) -> PathBuf {
78        self.active_setup.join("os-configuration.env")
79    }
80
81    /// Status-API service links (host/ports). Overrides embedded defaults when present.
82    #[must_use]
83    pub fn service_links_file(&self) -> PathBuf {
84        self.active_setup.join("service_links.env")
85    }
86
87    /// Staged `/etc` tree before apply (`s4` → `s5`).
88    #[must_use]
89    pub fn staging_etc(&self) -> PathBuf {
90        self.active_setup.join("etc")
91    }
92
93    /// Protected initial `/etc` backup destination (`s3`).
94    #[must_use]
95    pub fn initial_backup_etc(&self) -> PathBuf {
96        self.backup.join("etc/initial_setup")
97    }
98
99    /// Docker assets directory (leases export, stack files).
100    #[must_use]
101    pub fn docker_assets(&self) -> PathBuf {
102        self.docker.join("assets")
103    }
104
105    /// Exported leases JSON path.
106    #[must_use]
107    pub fn leases_json(&self) -> PathBuf {
108        self.docker_assets().join("leases.json")
109    }
110
111    /// Exported leases HTML path.
112    #[must_use]
113    pub fn leases_html(&self) -> PathBuf {
114        self.docker_assets().join("leases.html")
115    }
116}
117
118/// Default `/srv/active_setup`.
119pub const ACTIVE_SETUP: &str = "/srv/active_setup";
120/// Default `/srv/backup`.
121pub const BACKUP: &str = "/srv/backup";
122/// Default `/srv/docker`.
123pub const DOCKER: &str = "/srv/docker";
124/// Default `/etc`.
125pub const ETC: &str = "/etc";
126/// Default resume file path on a Horto box.
127pub const RESUME_FILE: &str = "/srv/active_setup/horto_setup_state.json";
128
129/// Display helper for plan / log lines.
130#[must_use]
131pub fn path_str(p: &Path) -> String {
132    p.display().to_string()
133}