Skip to main content

sysd_manager_comcontroler/sysdbus/
to_proxy.rs

1#![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
62///1 Ensure that the  proxy is up and running
63///2 Tertemine mode
64///2 Connect to the proxy and return a proxy object
65fn ensure_proxy_up() {
66    //TODO ensure_proxy_up
67}
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        // .path(path)?
76        .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        //.path(path)?
92        .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}