Fix: Mount-Unit nutzt pro Scope das richtige WantedBy und network-online.target
mount_service_unit() schrieb bislang unabhaengig vom Installations-Scope immer "WantedBy=multi-user.target" - fuer eine User-Scope-Installation (systemctl --user) ist dieses Ziel falsch/wirkungslos, da es dort keine Entsprechung hat; die Unit haette nie zuverlaessig automatisch gestartet werden koennen. Nimmt jetzt den Scope entgegen und setzt fuer System "multi-user.target", fuer User "default.target". Ebenso wartete die Unit unabhaengig vom Scope auf network-online.target - auch das ist ein Ziel des System-Managers ohne sinnvolle Entsprechung unter systemctl --user. Die Ordnungsabhaengigkeit (After=/Wants=) wird jetzt nur noch im System-Kontext gesetzt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+40
-3
@@ -32,9 +32,21 @@ fn binary_path() -> String {
|
||||
.unwrap_or_else(|| "/usr/bin/smart-mount".to_string())
|
||||
}
|
||||
|
||||
fn mount_service_unit() -> String {
|
||||
fn mount_service_unit(scope: Scope) -> String {
|
||||
let wanted_by = match scope {
|
||||
Scope::System => "multi-user.target",
|
||||
Scope::User => "default.target",
|
||||
};
|
||||
// `network-online.target` ist ein Ziel des System-Managers - unter `systemctl --user` gibt
|
||||
// es dafür keine sinnvolle Entsprechung (die Unit existiert dort nicht bzw. wird nie
|
||||
// erreicht), die Ordnungsabhängigkeit wäre also für User-Scope-Units wirkungslos statt
|
||||
// schlicht harmlos. Nur im System-Kontext gesetzt.
|
||||
let network_wait = match scope {
|
||||
Scope::System => "After=network-online.target\nWants=network-online.target\n",
|
||||
Scope::User => "",
|
||||
};
|
||||
format!(
|
||||
"[Unit]\nDescription=smart-mount: mount configured drive pairs at boot\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nExecStart={} mount --all\n\n[Install]\nWantedBy=multi-user.target\n",
|
||||
"[Unit]\nDescription=smart-mount: mount configured drive pairs at boot\n{network_wait}\n[Service]\nType=oneshot\nExecStart={} mount --all\n\n[Install]\nWantedBy={wanted_by}\n",
|
||||
binary_path()
|
||||
)
|
||||
}
|
||||
@@ -93,7 +105,7 @@ pub fn install(scope: Scope, watch_interval_secs: u64) -> Result<()> {
|
||||
let dir = unit_dir(scope)?;
|
||||
std::fs::create_dir_all(&dir).map_err(|e| Error::io(&dir, e))?;
|
||||
|
||||
std::fs::write(dir.join(MOUNT_SERVICE), mount_service_unit())
|
||||
std::fs::write(dir.join(MOUNT_SERVICE), mount_service_unit(scope))
|
||||
.map_err(|e| Error::io(&dir, e))?;
|
||||
std::fs::write(dir.join(WATCH_SERVICE), watch_service_unit())
|
||||
.map_err(|e| Error::io(&dir, e))?;
|
||||
@@ -337,6 +349,31 @@ fn cron_schedule_for_interval(interval_secs: u64) -> String {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn mount_service_unit_system_scope_uses_multi_user_target() {
|
||||
let unit = mount_service_unit(Scope::System);
|
||||
assert!(unit.contains("WantedBy=multi-user.target"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mount_service_unit_user_scope_uses_default_target() {
|
||||
let unit = mount_service_unit(Scope::User);
|
||||
assert!(unit.contains("WantedBy=default.target"));
|
||||
assert!(!unit.contains("WantedBy=multi-user.target"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mount_service_unit_system_scope_waits_for_network_online() {
|
||||
let unit = mount_service_unit(Scope::System);
|
||||
assert!(unit.contains("network-online.target"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mount_service_unit_user_scope_does_not_reference_network_online_target() {
|
||||
let unit = mount_service_unit(Scope::User);
|
||||
assert!(!unit.contains("network-online.target"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn managed_cron_block_for_user_crontab_has_no_user_field() {
|
||||
let block = managed_cron_block(120, None);
|
||||
|
||||
Reference in New Issue
Block a user