]> git.proxmox.com Git - proxmox-backup.git/blob - src/server/report.rs
use new fsync parameter to replace_file and atomic_open_or_create
[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 ]
16 }
17
18 fn commands() -> Vec<(&'static str, Vec<&'static str>)> {
19 vec![
20 // ("<command>", vec![<arg [, arg]>])
21 ("proxmox-backup-manager", vec!["versions", "--verbose"]),
22 ("df", vec!["-h"]),
23 ("lsblk", vec!["--ascii"]),
24 ("zpool", vec!["status"]),
25 ("zfs", vec!["list"]),
26 ("proxmox-backup-manager", vec!["subscription", "get"]),
27 ]
28 }
29
30 // (description, function())
31 type FunctionMapping = (&'static str, fn() -> String);
32
33 fn function_calls() -> Vec<FunctionMapping> {
34 vec![
35 ("Datastores", || {
36 let config = match pbs_config::datastore::config() {
37 Ok((config, _digest)) => config,
38 _ => return String::from("could not read datastore config"),
39 };
40
41 let mut list = Vec::new();
42 for store in config.sections.keys() {
43 list.push(store.as_str());
44 }
45 list.join(", ")
46 })
47 ]
48 }
49
50 pub fn generate_report() -> String {
51 use proxmox::tools::fs::file_read_optional_string;
52
53 let file_contents = files()
54 .iter()
55 .map(|file_name| {
56 let content = match file_read_optional_string(Path::new(file_name)) {
57 Ok(Some(content)) => content,
58 Ok(None) => String::from("# file does not exist"),
59 Err(err) => err.to_string(),
60 };
61 format!("$ cat '{}'\n{}", file_name, content)
62 })
63 .collect::<Vec<String>>()
64 .join("\n\n");
65
66 let command_outputs = commands()
67 .iter()
68 .map(|(command, args)| {
69 let output = Command::new(command)
70 .env("PROXMOX_OUTPUT_NO_BORDER", "1")
71 .args(args)
72 .output();
73 let output = match output {
74 Ok(output) => String::from_utf8_lossy(&output.stdout).to_string(),
75 Err(err) => err.to_string(),
76 };
77 format!("$ `{} {}`\n{}", command, args.join(" "), output)
78 })
79 .collect::<Vec<String>>()
80 .join("\n\n");
81
82 let function_outputs = function_calls()
83 .iter()
84 .map(|(desc, function)| format!("$ {}\n{}", desc, function()))
85 .collect::<Vec<String>>()
86 .join("\n\n");
87
88 format!(
89 "= FILES =\n\n{}\n= COMMANDS =\n\n{}\n= FUNCTIONS =\n\n{}\n",
90 file_contents, command_outputs, function_outputs
91 )
92 }