sn_node_manager/cmd/
daemon.rs1use crate::{
10 add_services::{add_daemon, config::AddDaemonServiceOptions},
11 config::{self, is_running_as_root},
12 helpers::{download_and_extract_release, get_bin_version},
13 print_banner, ServiceManager, VerbosityLevel,
14};
15use color_eyre::{eyre::eyre, Result};
16use sn_releases::{ReleaseType, SafeReleaseRepoActions};
17use sn_service_management::{
18 control::{ServiceControl, ServiceController},
19 DaemonService, NodeRegistry,
20};
21use std::{net::Ipv4Addr, path::PathBuf};
22
23pub async fn add(
24 address: Ipv4Addr,
25 env_variables: Option<Vec<(String, String)>>,
26 port: u16,
27 src_path: Option<PathBuf>,
28 url: Option<String>,
29 version: Option<String>,
30 verbosity: VerbosityLevel,
31) -> Result<()> {
32 if !is_running_as_root() {
33 error!("The daemon add command must run as the root user");
34 return Err(eyre!("The add command must run as the root user"));
35 }
36
37 if verbosity != VerbosityLevel::Minimal {
38 print_banner("Add Daemon Service");
39 }
40
41 let service_user = "safe";
42 let service_manager = ServiceController {};
43 debug!("Trying to create service user '{service_user}' for the daemon");
44 service_manager.create_service_user(service_user)?;
45
46 let mut node_registry = NodeRegistry::load(&config::get_node_registry_path()?)?;
47 let release_repo = <dyn SafeReleaseRepoActions>::default_config();
48
49 let (daemon_src_bin_path, version) = if let Some(path) = src_path {
50 let version = get_bin_version(&path)?;
51 (path, version)
52 } else {
53 download_and_extract_release(
54 ReleaseType::SafenodeManagerDaemon,
55 url.clone(),
56 version,
57 &*release_repo,
58 verbosity,
59 None,
60 )
61 .await?
62 };
63
64 info!("Adding daemon service");
65
66 add_daemon(
71 AddDaemonServiceOptions {
72 address,
73 env_variables,
74 daemon_install_bin_path: config::get_daemon_install_path(),
75 daemon_src_bin_path,
76 port,
77 user: "root".to_string(),
78 version,
79 },
80 &mut node_registry,
81 &ServiceController {},
82 )?;
83 Ok(())
84}
85
86pub async fn start(verbosity: VerbosityLevel) -> Result<()> {
87 if !is_running_as_root() {
88 error!("The daemon start command must run as the root user");
89 return Err(eyre!("The start command must run as the root user"));
90 }
91
92 let mut node_registry = NodeRegistry::load(&config::get_node_registry_path()?)?;
93 if let Some(daemon) = &mut node_registry.daemon {
94 if verbosity != VerbosityLevel::Minimal {
95 print_banner("Start Daemon Service");
96 }
97 info!("Starting daemon service");
98
99 let service = DaemonService::new(daemon, Box::new(ServiceController {}));
100 let mut service_manager =
101 ServiceManager::new(service, Box::new(ServiceController {}), verbosity);
102 service_manager.start().await?;
103
104 println!(
105 "Endpoint: {}",
106 service_manager
107 .service
108 .service_data
109 .endpoint
110 .map_or("-".to_string(), |e| e.to_string())
111 );
112
113 node_registry.save()?;
114 return Ok(());
115 }
116
117 error!("The daemon service has not been added yet");
118 Err(eyre!("The daemon service has not been added yet"))
119}
120
121pub async fn stop(verbosity: VerbosityLevel) -> Result<()> {
122 if !is_running_as_root() {
123 error!("The daemon stop command must run as the root user");
124 return Err(eyre!("The stop command must run as the root user"));
125 }
126
127 let mut node_registry = NodeRegistry::load(&config::get_node_registry_path()?)?;
128 if let Some(daemon) = &mut node_registry.daemon {
129 if verbosity != VerbosityLevel::Minimal {
130 print_banner("Stop Daemon Service");
131 }
132 info!("Stopping daemon service");
133
134 let service = DaemonService::new(daemon, Box::new(ServiceController {}));
135 let mut service_manager =
136 ServiceManager::new(service, Box::new(ServiceController {}), verbosity);
137 service_manager.stop().await?;
138
139 node_registry.save()?;
140
141 return Ok(());
142 }
143
144 error!("The daemon service has not been added yet");
145 Err(eyre!("The daemon service has not been added yet"))
146}