]> git.proxmox.com Git - proxmox-backup.git/blob - src/server/report.rs
split the namespace out of BackupGroup/Dir api types
[proxmox-backup.git] / src / server / report.rs
1 use std::path::Path;
2 use std::process::Command;
3
4 fn files() -> Vec<&'static str> {
5 vec![
6 "/etc/hostname",
7 "/etc/hosts",
8 "/etc/network/interfaces",
9 "/etc/proxmox-backup/datastore.cfg",
10 "/etc/proxmox-backup/user.cfg",
11 "/etc/proxmox-backup/acl.cfg",
12 "/etc/proxmox-backup/remote.cfg",
13 "/etc/proxmox-backup/sync.cfg",
14 "/etc/proxmox-backup/verification.cfg",
15 "/etc/proxmox-backup/tape.cfg",
16 "/etc/proxmox-backup/media-pool.cfg",
17 "/etc/proxmox-backup/traffic-control.cfg",
18 ]
19 }
20
21 fn commands() -> Vec<(&'static str, Vec<&'static str>)> {
22 vec![
23 // ("<command>", vec![<arg [, arg]>])
24 ("proxmox-backup-manager", vec!["versions", "--verbose"]),
25 ("proxmox-backup-manager", vec!["subscription", "get"]),
26 ("df", vec!["-h"]),
27 ("lsblk", vec!["--ascii"]),
28 ("ls", vec!["-l", "/dev/disk/by-id", "/dev/disk/by-path"]),
29 ("zpool", vec!["status"]),
30 ("zfs", vec!["list"]),
31 ]
32 }
33
34 // (description, function())
35 type FunctionMapping = (&'static str, fn() -> String);
36
37 fn function_calls() -> Vec<FunctionMapping> {
38 vec![("Datastores", || {
39 let config = match pbs_config::datastore::config() {
40 Ok((config, _digest)) => config,
41 _ => return String::from("could not read datastore config"),
42 };
43
44 let mut list = Vec::new();
45 for store in config.sections.keys() {
46 list.push(store.as_str());
47 }
48 list.join(", ")
49 })]
50 }
51
52 pub fn generate_report() -> String {
53 use proxmox_sys::fs::file_read_optional_string;
54
55 let file_contents = files()
56 .iter()
57 .map(|file_name| {
58 let content = match file_read_optional_string(Path::new(file_name)) {
59 Ok(Some(content)) => content,
60 Ok(None) => String::from("# file does not exist"),
61 Err(err) => err.to_string(),
62 };
63 format!("$ cat '{}'\n{}", file_name, content)
64 })
65 .collect::<Vec<String>>()
66 .join("\n\n");
67
68 let command_outputs = commands()
69 .iter()
70 .map(|(command, args)| {
71 let output = Command::new(command)
72 .env("PROXMOX_OUTPUT_NO_BORDER", "1")
73 .args(args)
74 .output();
75 let output = match output {
76 Ok(output) => String::from_utf8_lossy(&output.stdout).to_string(),
77 Err(err) => err.to_string(),
78 };
79 format!("$ `{} {}`\n{}", command, args.join(" "), output)
80 })
81 .collect::<Vec<String>>()
82 .join("\n\n");
83
84 let function_outputs = function_calls()
85 .iter()
86 .map(|(desc, function)| format!("$ {}\n{}", desc, function()))
87 .collect::<Vec<String>>()
88 .join("\n\n");
89
90 format!(
91 "= FILES =\n\n{}\n= COMMANDS =\n\n{}\n= FUNCTIONS =\n\n{}\n",
92 file_contents, command_outputs, function_outputs
93 )
94 }