diff --git a/plugin/src/modules_service.rs b/plugin/src/modules_service.rs index 05e33ad..a08b119 100644 --- a/plugin/src/modules_service.rs +++ b/plugin/src/modules_service.rs @@ -101,9 +101,10 @@ pub mod qobject { #[qproperty(bool, dock_applet_mpris, cxx_name = "dockAppletMpris")] #[qproperty(bool, dock_applet_notifications, cxx_name = "dockAppletNotifications")] #[qproperty(bool, dock_applet_power, cxx_name = "dockAppletPower")] - // Unified systemd bar module (covers local + nspawn containers, and later remotes). + // Unified systemd bar module (covers local + nspawn containers + remotes). #[qproperty(bool, systemd_enable, cxx_name = "systemdEnable")] #[qproperty(i32, systemd_interval, cxx_name = "systemdInterval")] + #[qproperty(QList_QString, systemd_machines, cxx_name = "systemdMachines")] type ModulesService = super::ModulesServiceRust; } @@ -443,6 +444,34 @@ mod data { } } + // Systemd-bar group: enable + poll interval + remote SSH targets. Each + // `machines` entry is a string like "host" or "user@host"; the local + // machine is deduped by hostname even if listed. + #[derive(Deserialize, Debug)] + #[serde(rename_all = "camelCase")] + pub struct Systemd { + #[serde(default = "t")] + pub enable: bool, + #[serde(default = "Systemd::d_interval")] + pub interval: i32, + #[serde(default)] + pub machines: Vec, + } + impl Systemd { + fn d_interval() -> i32 { + 15_000 + } + } + impl Default for Systemd { + fn default() -> Self { + Self { + enable: true, + interval: Self::d_interval(), + machines: Vec::new(), + } + } + } + #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct StatsDaemon { @@ -518,7 +547,7 @@ mod data { #[serde(default)] pub dock: Dock, #[serde(default)] - pub systemd: WithInterval, + pub systemd: Systemd, #[serde(default)] pub stats_daemon: StatsDaemon, } @@ -595,6 +624,7 @@ pub struct ModulesServiceRust { dock_applet_power: bool, systemd_enable: bool, systemd_interval: i32, + systemd_machines: QList, } impl Default for ModulesServiceRust { @@ -678,6 +708,13 @@ impl ModulesServiceRust { dock_applet_power: d.dock.applets.power, systemd_enable: d.systemd.enable, systemd_interval: d.systemd.interval, + systemd_machines: { + let mut list = QList::::default(); + for s in &d.systemd.machines { + list.append(QString::from(s.as_str())); + } + list + }, } } } @@ -691,6 +728,10 @@ pub(crate) fn config_path(file: &str) -> PathBuf { base.join("nova-shell").join(file) } +pub(crate) fn load_systemd_machines() -> Vec { + load_modules_data().systemd.machines +} + fn load_modules_data() -> ModulesData { let path = config_path("modules.json"); let raw = match std::fs::read_to_string(&path) { diff --git a/plugin/src/systemd_service.rs b/plugin/src/systemd_service.rs index f58288d..fcee982 100644 --- a/plugin/src/systemd_service.rs +++ b/plugin/src/systemd_service.rs @@ -6,6 +6,7 @@ // to require QuickControls2.prl files that nixpkgs strips. Switch to // QList when a release ships with both fixes. +use crate::modules_service; use core::pin::Pin; use cxx_qt_lib::QString; use serde::Serialize; @@ -270,6 +271,28 @@ impl qobject::SystemdService { }); } + // Configured remote machines (placeholders; transport lands in step 4). + // Dedup local: drop entries matching the local hostname or `localhost`, + // with or without a `user@` prefix. + let host = read_hostname(); + let cfg_machines = modules_service::load_systemd_machines(); + for target in cfg_machines { + let host_part = target.rsplit_once('@').map_or(target.as_str(), |(_, h)| h); + if host_part == host || host_part == "localhost" { + continue; + } + all_machines.push(MachineJson { + name: target.clone(), + is_local: false, + marker: String::new(), + system_state: "pending".into(), + running_count: 0, + total_count: 0, + failed_units: Vec::new(), + running_units: Vec::new(), + }); + } + let machines_json = serde_json::to_string(&all_machines).unwrap_or_else(|_| "[]".into()); self.as_mut().set_failed_count(local_failed_count); diff --git a/shell/applets/SystemdMachineSection.qml b/shell/applets/SystemdMachineSection.qml index 3c7e244..b5329f2 100644 --- a/shell/applets/SystemdMachineSection.qml +++ b/shell/applets/SystemdMachineSection.qml @@ -91,6 +91,8 @@ Column { return NS.ThemeService.base0B; if (st === "degraded") return NS.ThemeService.base0A; + if (st === "pending") + return NS.ThemeService.base04; return NS.ThemeService.base08; } opacity: 0.85