ant_service_management/
lib.rs1pub mod auditor;
10pub mod control;
11pub mod daemon;
12pub mod error;
13pub mod faucet;
14pub mod node;
15pub mod rpc;
16
17#[macro_use]
18extern crate tracing;
19
20pub mod antctl_proto {
21 tonic::include_proto!("antctl_proto");
22}
23
24use async_trait::async_trait;
25use auditor::AuditorServiceData;
26use semver::Version;
27use serde::{Deserialize, Serialize};
28use service_manager::ServiceInstallCtx;
29use std::{
30 io::{Read, Write},
31 path::{Path, PathBuf},
32};
33
34pub use daemon::{DaemonService, DaemonServiceData};
35pub use error::{Error, Result};
36pub use faucet::{FaucetService, FaucetServiceData};
37pub use node::{NodeService, NodeServiceData};
38
39#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
40pub enum ServiceStatus {
41 Added,
43 Running,
45 Stopped,
47 Removed,
49}
50
51#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
52pub enum NatDetectionStatus {
53 Public,
54 UPnP,
55 Private,
56}
57
58#[derive(Clone, Debug, PartialEq)]
59pub enum UpgradeResult {
60 Forced(String, String),
61 NotRequired,
62 Upgraded(String, String),
63 UpgradedButNotStarted(String, String, String),
64 Error(String),
65}
66
67#[derive(Clone, Debug, Eq, PartialEq)]
68pub struct UpgradeOptions {
69 pub auto_restart: bool,
70 pub env_variables: Option<Vec<(String, String)>>,
71 pub force: bool,
72 pub start_service: bool,
73 pub target_bin_path: PathBuf,
74 pub target_version: Version,
75}
76
77#[async_trait]
78pub trait ServiceStateActions {
79 fn bin_path(&self) -> PathBuf;
80 fn build_upgrade_install_context(&self, options: UpgradeOptions) -> Result<ServiceInstallCtx>;
81 fn data_dir_path(&self) -> PathBuf;
82 fn is_user_mode(&self) -> bool;
83 fn log_dir_path(&self) -> PathBuf;
84 fn name(&self) -> String;
85 fn pid(&self) -> Option<u32>;
86 fn on_remove(&mut self);
87 async fn on_start(&mut self, pid: Option<u32>, full_refresh: bool) -> Result<()>;
88 async fn on_stop(&mut self) -> Result<()>;
89 fn set_version(&mut self, version: &str);
90 fn status(&self) -> ServiceStatus;
91 fn version(&self) -> String;
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize)]
95pub struct StatusSummary {
96 pub nodes: Vec<NodeServiceData>,
97 pub daemon: Option<DaemonServiceData>,
98 pub faucet: Option<FaucetServiceData>,
99}
100
101#[derive(Clone, Debug, Serialize, Deserialize)]
102pub struct NodeRegistry {
103 pub auditor: Option<AuditorServiceData>,
104 pub daemon: Option<DaemonServiceData>,
105 pub environment_variables: Option<Vec<(String, String)>>,
106 pub faucet: Option<FaucetServiceData>,
107 pub nat_status: Option<NatDetectionStatus>,
108 pub nodes: Vec<NodeServiceData>,
109 pub save_path: PathBuf,
110}
111
112impl NodeRegistry {
113 pub fn save(&self) -> Result<()> {
114 debug!(
115 "Saving node registry to {}",
116 self.save_path.to_string_lossy()
117 );
118 let path = Path::new(&self.save_path);
119 if let Some(parent) = path.parent() {
120 std::fs::create_dir_all(parent).inspect_err(|err| {
121 error!("Error creating node registry parent {parent:?}: {err:?}")
122 })?;
123 }
124
125 let json = serde_json::to_string(self)?;
126 let mut file = std::fs::File::create(self.save_path.clone())
127 .inspect_err(|err| error!("Error creating node registry file: {err:?}"))?;
128 file.write_all(json.as_bytes())
129 .inspect_err(|err| error!("Error writing to node registry: {err:?}"))?;
130
131 Ok(())
132 }
133
134 pub fn load(path: &Path) -> Result<Self> {
135 if !path.exists() {
136 debug!("Loading default node registry as {path:?} does not exist");
137 return Ok(NodeRegistry {
138 auditor: None,
139 daemon: None,
140 environment_variables: None,
141 faucet: None,
142 nat_status: None,
143 nodes: vec![],
144 save_path: path.to_path_buf(),
145 });
146 }
147 debug!("Loading node registry from {}", path.to_string_lossy());
148
149 let mut file = std::fs::File::open(path)
150 .inspect_err(|err| error!("Error opening node registry: {err:?}"))?;
151
152 let mut contents = String::new();
153 file.read_to_string(&mut contents)
154 .inspect_err(|err| error!("Error reading node registry: {err:?}"))?;
155
156 if contents.is_empty() {
159 return Ok(NodeRegistry {
160 auditor: None,
161 daemon: None,
162 environment_variables: None,
163 faucet: None,
164 nat_status: None,
165 nodes: vec![],
166 save_path: path.to_path_buf(),
167 });
168 }
169
170 Self::from_json(&contents)
171 }
172
173 pub fn from_json(json: &str) -> Result<Self> {
174 let registry = serde_json::from_str(json)
175 .inspect_err(|err| error!("Error deserializing node registry: {err:?}"))?;
176 Ok(registry)
177 }
178
179 pub fn to_status_summary(&self) -> StatusSummary {
180 StatusSummary {
181 nodes: self.nodes.clone(),
182 daemon: self.daemon.clone(),
183 faucet: self.faucet.clone(),
184 }
185 }
186}
187
188pub fn get_local_node_registry_path() -> Result<PathBuf> {
189 let path = dirs_next::data_dir()
190 .ok_or_else(|| {
191 error!("Failed to get data_dir");
192 Error::UserDataDirectoryNotObtainable
193 })?
194 .join("autonomi")
195 .join("local_node_registry.json");
196 if let Some(parent) = path.parent() {
197 std::fs::create_dir_all(parent)
198 .inspect_err(|err| error!("Error creating node registry parent {parent:?}: {err:?}"))?;
199 }
200 Ok(path)
201}