sysd_manager_comcontroler/sysdbus/
to_proxy.rs1#![allow(dead_code)]
2
3use base::{
4 consts::{MAX_HEART_BEAT_ELAPSE, MIN_HEART_BEAT_ELAPSE},
5 enums::UnitDBusLevel,
6 proxy::{DisEnAbleUnitFiles, DisEnAbleUnitFilesResponse},
7};
8use futures_util::stream::StreamExt;
9use tokio::time::{self, Duration};
10use tracing::{debug, error, info, warn};
11use zbus::proxy;
12use zvariant::OwnedObjectPath;
13
14use crate::{
15 errors::SystemdErrors,
16 sysdbus::{get_blocking_connection, get_connection, run_context},
17};
18
19#[proxy(
20 interface = "io.github.plrigaux.SysDManager",
21 default_service = "io.github.plrigaux.SysDManager",
22 default_path = "/io/github/plrigaux/SysDManager"
23)]
24pub trait SysDManagerComLink {
25 fn start_unit(&self, unit_name: &str, mode: &str) -> zbus::fdo::Result<OwnedObjectPath>;
26 fn stop_unit(&self, unit_name: &str, mode: &str) -> zbus::fdo::Result<OwnedObjectPath>;
27 fn restart_unit(&self, unit_name: &str, mode: &str) -> zbus::fdo::Result<OwnedObjectPath>;
28 fn clean_unit(&self, unit_name: &str, what: &[&str]) -> zbus::Result<()>;
29 fn freeze_unit(&self, unit_name: &str) -> zbus::fdo::Result<()>;
30 fn thaw_unit(&self, unit_name: &str) -> zbus::fdo::Result<()>;
31 fn reload(&self) -> zbus::fdo::Result<()>;
32
33 fn create_drop_in(
34 &mut self,
35 runtime: bool,
36 unit_name: &str,
37 file_name: &str,
38 content: &str,
39 ) -> zbus::fdo::Result<()>;
40 fn save_file(&mut self, file_name: &str, content: &str) -> zbus::fdo::Result<u64>;
41
42 fn revert_unit_files(&self, file_names: &[&str]) -> zbus::fdo::Result<Vec<DisEnAbleUnitFiles>>;
43
44 fn enable_unit_files_with_flags(
45 &mut self,
46 files: &[&str],
47 flags: u64,
48 ) -> zbus::fdo::Result<DisEnAbleUnitFilesResponse>;
49
50 fn disable_unit_files_with_flags(
51 &mut self,
52 files: &[&str],
53 flags: u64,
54 ) -> zbus::fdo::Result<DisEnAbleUnitFilesResponse>;
55
56 #[zbus(signal)]
57 fn hello(msg: String) -> zbus::fdo::Result<()>;
58
59 fn heart_beat(&self) -> zbus::fdo::Result<u64>;
60}
61
62fn ensure_proxy_up() {
66 }
68
69fn get_proxy<'a>() -> Result<SysDManagerComLinkProxyBlocking<'a>, SystemdErrors> {
70 let destination = run_context().destination_address();
71 let connection = get_blocking_connection(UnitDBusLevel::System)?;
72
73 info!("BusName Destination {}", destination);
74 let proxy = SysDManagerComLinkProxyBlocking::builder(&connection)
75 .destination(destination)?
77 .build()?;
78
79 Ok(proxy)
80}
81
82pub(super) async fn get_proxy_async<'a>() -> Result<SysDManagerComLinkProxy<'a>, SystemdErrors> {
83 let destination = super::RUN_CONTEXT
84 .get()
85 .expect("Supposed to be init")
86 .destination_address();
87 let connection = get_connection(UnitDBusLevel::System).await?;
88
89 info!("BusName Destination {}", destination);
90 let proxy = SysDManagerComLinkProxy::builder(&connection)
91 .destination(destination)?
93 .build()
94 .await?;
95
96 Ok(proxy)
97}
98
99pub fn start_unit(unit_name: &str, mode: &str) -> Result<String, SystemdErrors> {
100 let proxy = get_proxy()?;
101
102 let s = proxy.start_unit(unit_name, mode)?;
103 Ok(s.to_string())
104}
105
106pub fn stop_unit(unit_name: &str, mode: &str) -> Result<String, SystemdErrors> {
107 let proxy = get_proxy()?;
108
109 let s = proxy.stop_unit(unit_name, mode)?;
110 Ok(s.to_string())
111}
112
113pub fn restart_unit(unit_name: &str, mode: &str) -> Result<String, SystemdErrors> {
114 let proxy = get_proxy()?;
115
116 let s = proxy.restart_unit(unit_name, mode)?;
117 Ok(s.to_string())
118}
119
120pub fn clean_unit(unit_name: &str, what: &[&str]) -> Result<(), SystemdErrors> {
121 let proxy = get_proxy()?;
122
123 proxy.clean_unit(unit_name, what)?;
124 Ok(())
125}
126
127pub fn freeze_unit(unit_name: &str) -> Result<(), SystemdErrors> {
128 let proxy = get_proxy()?;
129 proxy.freeze_unit(unit_name)?;
130 Ok(())
131}
132
133pub fn thaw_unit(unit_name: &str) -> Result<(), SystemdErrors> {
134 let proxy: SysDManagerComLinkProxyBlocking<'_> = get_proxy()?;
135 proxy.thaw_unit(unit_name)?;
136 Ok(())
137}
138
139pub async fn reload() -> Result<(), SystemdErrors> {
140 let proxy = get_proxy_async().await?;
141 proxy.reload().await?;
142 Ok(())
143}
144
145fn extract_job_id(job: &str) -> Option<u32> {
146 job.rsplit_once('/')
147 .and_then(|(_, id)| id.parse::<u32>().ok())
148}
149
150pub async fn lazy_start_proxy_async() -> Result<(), SystemdErrors> {
151 crate::sysdbus::init_proxy_async2().await?;
152
153 Ok(())
154}
155
156pub(crate) async fn wait_hello(mut hello_stream: HelloStream) -> Result<(), SystemdErrors> {
157 if let Some(msg) = hello_stream.next().await {
158 let args = msg.args()?;
159 info!("Hello Proxy Args {:?}", args);
160 }
161 Ok(())
162}
163
164pub fn lazy_start_proxy_block() -> Result<(), SystemdErrors> {
165 crate::runtime().block_on(async move {
166 warn!("lazy 1");
167 lazy_start_proxy_async().await;
168 warn!("lazy 2");
169 });
170 Ok(())
171}
172
173pub(super) async fn send_heart_beat() -> Result<(), SystemdErrors> {
174 let proxy = get_proxy_async().await?;
175 loop {
176 match proxy.heart_beat().await {
177 Ok(delay) => {
178 debug!("Heath Beat delay {delay} millis");
179 let delay = delay.clamp(MIN_HEART_BEAT_ELAPSE, MAX_HEART_BEAT_ELAPSE);
180 time::sleep(Duration::from_millis(delay)).await;
181 }
182 Err(err) => {
183 error!("Heart Beat {err:?}");
184 return Err(err.into());
185 }
186 }
187 }
188}
189
190#[macro_export]
191macro_rules! proxy_call_blocking {
192 ($func:ident, $($param:expr),+) => {
193 match $crate::to_proxy::$func($($param),+) {
194 Ok(ok) => Ok(ok),
195 Err(SystemdErrors::ZFdoServiceUnknowm(msg)) => {
196 warn!("Blocking ServiceUnkown: {:?} Func: {}", msg, stringify!($func));
197 $crate::to_proxy::lazy_start_proxy_block();
198 $crate::to_proxy::$func($($param),+)
199 },
200 Err(err) => Err(err)
201 }
202 }
203}
204
205#[macro_export]
206macro_rules! proxy_call_async {
207 ($func:ident) => {
208 proxy_call_async!($func,)
209 };
210
211 ($func:ident, $($param:expr),*) => {
212 match $crate::to_proxy::$func($($param),*).await {
213 Ok(ok) => Ok(ok),
214 Err(SystemdErrors::ZFdoServiceUnknowm(msg)) => {
215 warn!("Async ServiceUnkown: {:?} Function: {}", msg, stringify!($func));
216 $crate::to_proxy::lazy_start_proxy_async().await;
217 $crate::to_proxy::$func($($param),*).await
218 },
219 Err(err) => Err(err)
220 }
221 }
222}
223
224pub(crate) async fn create_drop_in(
225 runtime: bool,
226 unit_name: &str,
227 file_path: &str,
228 content: &str,
229) -> Result<(), SystemdErrors> {
230 let mut proxy = get_proxy_async().await?;
231 proxy
232 .create_drop_in(runtime, unit_name, file_path, content)
233 .await
234 .map_err(|e| e.into())
235}
236
237pub async fn save_file(file_path: &str, content: &str) -> Result<u64, SystemdErrors> {
238 let mut proxy = get_proxy_async().await?;
239 proxy
240 .save_file(file_path, content)
241 .await
242 .map_err(|e| e.into())
243}
244
245pub async fn revert_unit_files(
246 unit_names: &[&str],
247) -> Result<Vec<DisEnAbleUnitFiles>, SystemdErrors> {
248 let proxy = get_proxy_async().await?;
249 proxy
250 .revert_unit_files(unit_names)
251 .await
252 .map_err(|e| e.into())
253}
254
255pub fn enable_unit_files_with_flags(
256 unit_files: &[&str],
257 flags: u64,
258) -> Result<DisEnAbleUnitFilesResponse, SystemdErrors> {
259 let mut proxy: SysDManagerComLinkProxyBlocking<'_> = get_proxy()?;
260 proxy
261 .enable_unit_files_with_flags(unit_files, flags)
262 .map_err(|err| err.into())
263}
264
265pub fn disable_unit_files_with_flags(
266 unit_files: &[&str],
267 flags: u64,
268) -> Result<DisEnAbleUnitFilesResponse, SystemdErrors> {
269 let mut proxy: SysDManagerComLinkProxyBlocking<'_> = get_proxy()?;
270 proxy
271 .disable_unit_files_with_flags(unit_files, flags)
272 .map_err(|err| err.into())
273}