1use crate::config::Config;
8use crate::distro::{get_package_manager, PackageManager};
9use crate::rollback::RollbackManager;
10use crate::utils::run_command;
11use log::info;
12use std::error::Error;
13
14pub fn setup_monitoring(config: &Config, rollback: &RollbackManager) -> Result<(), Box<dyn Error>> {
28 if config.monitoring {
29 info!("Setting up monitoring...");
30
31 let snapshot = rollback.create_snapshot()?;
32
33 install_monitoring_tools(config)?;
34 configure_prometheus()?;
35 setup_grafana()?;
36 setup_node_exporter()?;
37
38 rollback.commit_snapshot(snapshot)?;
39
40 info!("Monitoring setup completed");
41 } else {
42 info!("Monitoring setup skipped as per user preference");
43 }
44 Ok(())
45}
46
47pub fn install_monitoring_tools(config: &Config) -> Result<(), Box<dyn Error>> {
57 let package_manager = get_package_manager()?;
58
59 match package_manager {
61 PackageManager::Apt => {
62 run_command("apt", &["update"])?;
63 run_command("apt", &["install", "-y", "prometheus"])?;
64 }
65 PackageManager::Yum | PackageManager::Dnf => {
66 install_prometheus_from_source()?;
68 }
69 }
70
71 match package_manager {
73 PackageManager::Apt => {
74 run_command(
75 "apt",
76 &[
77 "install",
78 "-y",
79 "apt-transport-https",
80 "software-properties-common",
81 "wget",
82 ],
83 )?;
84 run_command(
85 "wget",
86 &[
87 "-q",
88 "-O",
89 "/usr/share/keyrings/grafana.key",
90 "https://packages.grafana.com/gpg.key",
91 ],
92 )?;
93 run_command("echo", &["deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main", ">", "/etc/apt/sources.list.d/grafana.list"])?;
94 run_command("apt", &["update"])?;
95 run_command("apt", &["install", "-y", "grafana"])?;
96 }
97 PackageManager::Yum | PackageManager::Dnf => {
98 run_command(
99 "wget",
100 &[
101 "-q",
102 "-O",
103 "/etc/yum.repos.d/grafana.repo",
104 "https://packages.grafana.com/oss/rpm/grafana.repo",
105 ],
106 )?;
107 match package_manager {
108 PackageManager::Yum => run_command("yum", &["install", "-y", "grafana"])?,
109 PackageManager::Dnf => run_command("dnf", &["install", "-y", "grafana"])?,
110 _ => unreachable!(),
111 }
112 }
113 }
114
115 Ok(())
116}
117
118pub fn configure_prometheus() -> Result<(), Box<dyn Error>> {
127 let prometheus_config = r#"
128global:
129 scrape_interval: 15s
130
131scrape_configs:
132 - job_name: 'node'
133 static_configs:
134 - targets: ['localhost:9100']
135"#;
136 std::fs::write("/etc/prometheus/prometheus.yml", prometheus_config)?;
137
138 run_command("systemctl", &["restart", "prometheus"])?;
139 run_command("systemctl", &["enable", "prometheus"])?;
140
141 Ok(())
142}
143
144pub fn setup_grafana() -> Result<(), Box<dyn Error>> {
154 run_command("systemctl", &["start", "grafana-server"])?;
155 run_command("systemctl", &["enable", "grafana-server"])?;
156
157 Ok(())
161}
162
163pub fn setup_node_exporter() -> Result<(), Box<dyn Error>> {
172 let package_manager = get_package_manager()?;
173
174 match package_manager {
175 PackageManager::Apt => {
176 run_command("apt", &["install", "-y", "prometheus-node-exporter"])?;
177 }
178 PackageManager::Yum | PackageManager::Dnf => {
179 install_node_exporter_from_source()?;
181 }
182 }
183
184 run_command("systemctl", &["start", "node_exporter"])?;
185 run_command("systemctl", &["enable", "node_exporter"])?;
186
187 Ok(())
188}
189
190pub fn install_prometheus_from_source() -> Result<(), Box<dyn Error>> {
199 run_command("wget", &["https://github.com/prometheus/prometheus/releases/download/v2.30.3/prometheus-2.30.3.linux-amd64.tar.gz"])?;
200 run_command("tar", &["xvfz", "prometheus-2.30.3.linux-amd64.tar.gz"])?;
201 run_command("mv", &["prometheus-2.30.3.linux-amd64", "prometheus"])?;
202
203 run_command(
205 "useradd",
206 &["--no-create-home", "--shell", "/bin/false", "prometheus"],
207 )?;
208
209 run_command("mkdir", &["/etc/prometheus", "/var/lib/prometheus"])?;
211 run_command(
212 "chown",
213 &[
214 "prometheus:prometheus",
215 "/etc/prometheus",
216 "/var/lib/prometheus",
217 ],
218 )?;
219
220 run_command(
222 "mv",
223 &[
224 "prometheus/prometheus",
225 "prometheus/promtool",
226 "/usr/local/bin/",
227 ],
228 )?;
229 run_command(
230 "chown",
231 &[
232 "prometheus:prometheus",
233 "/usr/local/bin/prometheus",
234 "/usr/local/bin/promtool",
235 ],
236 )?;
237
238 run_command(
240 "mv",
241 &[
242 "prometheus/consoles",
243 "prometheus/console_libraries",
244 "/etc/prometheus/",
245 ],
246 )?;
247 run_command(
248 "mv",
249 &[
250 "prometheus/prometheus.yml",
251 "/etc/prometheus/prometheus.yml",
252 ],
253 )?;
254 run_command("chown", &["-R", "prometheus:prometheus", "/etc/prometheus"])?;
255
256 let service_file = r#"[Unit]
258Description=Prometheus
259Wants=network-online.target
260After=network-online.target
261
262[Service]
263User=prometheus
264Group=prometheus
265Type=simple
266ExecStart=/usr/local/bin/prometheus \
267 --config.file /etc/prometheus/prometheus.yml \
268 --storage.tsdb.path /var/lib/prometheus/ \
269 --web.console.templates=/etc/prometheus/consoles \
270 --web.console.libraries=/etc/prometheus/console_libraries
271
272[Install]
273WantedBy=multi-user.target
274"#;
275 std::fs::write("/etc/systemd/system/prometheus.service", service_file)?;
276
277 run_command("systemctl", &["daemon-reload"])?;
278
279 Ok(())
280}
281
282pub fn install_node_exporter_from_source() -> Result<(), Box<dyn Error>> {
291 run_command("wget", &["https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz"])?;
292 run_command("tar", &["xvfz", "node_exporter-1.2.2.linux-amd64.tar.gz"])?;
293
294 run_command(
296 "useradd",
297 &["--no-create-home", "--shell", "/bin/false", "node_exporter"],
298 )?;
299
300 run_command(
302 "mv",
303 &[
304 "node_exporter-1.2.2.linux-amd64/node_exporter",
305 "/usr/local/bin/",
306 ],
307 )?;
308 run_command(
309 "chown",
310 &[
311 "node_exporter:node_exporter",
312 "/usr/local/bin/node_exporter",
313 ],
314 )?;
315
316 let service_file = r#"[Unit]
318Description=Node Exporter
319Wants=network-online.target
320After=network-online.target
321
322[Service]
323User=node_exporter
324Group=node_exporter
325Type=simple
326ExecStart=/usr/local/bin/node_exporter
327
328[Install]
329WantedBy=multi-user.target
330"#;
331 std::fs::write("/etc/systemd/system/node_exporter.service", service_file)?;
332
333 run_command("systemctl", &["daemon-reload"])?;
334
335 Ok(())
336}