ant_service_management/
daemon.rs

1// Copyright (C) 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::{
10    control::ServiceControl,
11    error::{Error, Result},
12    ServiceStateActions, ServiceStatus, UpgradeOptions,
13};
14use async_trait::async_trait;
15use serde::{Deserialize, Serialize};
16use service_manager::ServiceInstallCtx;
17use std::{ffi::OsString, net::SocketAddr, path::PathBuf};
18
19#[derive(Clone, Debug, Serialize, Deserialize)]
20pub struct DaemonServiceData {
21    pub daemon_path: PathBuf,
22    pub endpoint: Option<SocketAddr>,
23    pub pid: Option<u32>,
24    pub service_name: String,
25    pub status: ServiceStatus,
26    pub version: String,
27}
28
29pub struct DaemonService<'a> {
30    pub service_data: &'a mut DaemonServiceData,
31    pub service_control: Box<dyn ServiceControl + Send>,
32}
33
34impl<'a> DaemonService<'a> {
35    pub fn new(
36        service_data: &'a mut DaemonServiceData,
37        service_control: Box<dyn ServiceControl + Send>,
38    ) -> DaemonService<'a> {
39        DaemonService {
40            service_data,
41            service_control,
42        }
43    }
44}
45
46#[async_trait]
47impl ServiceStateActions for DaemonService<'_> {
48    fn bin_path(&self) -> PathBuf {
49        self.service_data.daemon_path.clone()
50    }
51
52    fn build_upgrade_install_context(&self, _options: UpgradeOptions) -> Result<ServiceInstallCtx> {
53        let (address, port) = self
54            .service_data
55            .endpoint
56            .ok_or_else(|| {
57                error!("Daemon endpoint not set in the service_data");
58                Error::DaemonEndpointNotSet
59            })
60            .map(|e| (e.ip().to_string(), e.port().to_string()))?;
61        let install_ctx = ServiceInstallCtx {
62            args: vec![
63                OsString::from("--port"),
64                OsString::from(port),
65                OsString::from("--address"),
66                OsString::from(address),
67            ],
68            autostart: true,
69            contents: None,
70            environment: None,
71            label: self.service_data.service_name.parse()?,
72            program: self.service_data.daemon_path.clone(),
73            username: None,
74            working_directory: None,
75            disable_restart_on_failure: false,
76        };
77        Ok(install_ctx)
78    }
79
80    fn data_dir_path(&self) -> PathBuf {
81        PathBuf::new()
82    }
83
84    fn is_user_mode(&self) -> bool {
85        // The daemon service should never run in user mode.
86        false
87    }
88
89    fn log_dir_path(&self) -> PathBuf {
90        PathBuf::new()
91    }
92
93    fn name(&self) -> String {
94        self.service_data.service_name.clone()
95    }
96
97    fn pid(&self) -> Option<u32> {
98        self.service_data.pid
99    }
100
101    fn on_remove(&mut self) {
102        self.service_data.status = ServiceStatus::Removed;
103    }
104
105    async fn on_start(&mut self, pid: Option<u32>, _full_refresh: bool) -> Result<()> {
106        self.service_data.pid = pid;
107        self.service_data.status = ServiceStatus::Running;
108        Ok(())
109    }
110
111    async fn on_stop(&mut self) -> Result<()> {
112        self.service_data.pid = None;
113        self.service_data.status = ServiceStatus::Stopped;
114        Ok(())
115    }
116
117    fn set_version(&mut self, version: &str) {
118        self.service_data.version = version.to_string();
119    }
120
121    fn status(&self) -> ServiceStatus {
122        self.service_data.status.clone()
123    }
124
125    fn version(&self) -> String {
126        self.service_data.version.clone()
127    }
128}