* [pbs-devel] [PATCH proxmox-backup 1/3] report: add api endpoint and function to generate report
2020-11-03 12:29 [pbs-devel] [PATCH proxmox-backup 0/3] add system report Hannes Laimer
@ 2020-11-03 12:29 ` Hannes Laimer
2020-11-03 12:29 ` [pbs-devel] [PATCH proxmox-backup 2/3] report: add webui button for system report Hannes Laimer
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Hannes Laimer @ 2020-11-03 12:29 UTC (permalink / raw)
To: pbs-devel
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
src/api2/node.rs | 2 ++
src/api2/node/report.rs | 35 +++++++++++++++++++
src/server.rs | 3 ++
src/server/report.rs | 77 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 src/api2/node/report.rs
create mode 100644 src/server/report.rs
diff --git a/src/api2/node.rs b/src/api2/node.rs
index 30800d05..a19bea7e 100644
--- a/src/api2/node.rs
+++ b/src/api2/node.rs
@@ -38,6 +38,7 @@ mod services;
mod status;
mod syslog;
mod time;
+mod report;
pub const SHELL_CMD_SCHEMA: Schema = StringSchema::new("The command to run.")
.format(&ApiStringFormat::Enum(&[
@@ -310,6 +311,7 @@ pub const SUBDIRS: SubdirMap = &[
("dns", &dns::ROUTER),
("journal", &journal::ROUTER),
("network", &network::ROUTER),
+ ("report", &report::ROUTER),
("rrd", &rrd::ROUTER),
("services", &services::ROUTER),
("status", &status::ROUTER),
diff --git a/src/api2/node/report.rs b/src/api2/node/report.rs
new file mode 100644
index 00000000..b58427d7
--- /dev/null
+++ b/src/api2/node/report.rs
@@ -0,0 +1,35 @@
+use anyhow::Error;
+use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
+use serde_json::{json, Value};
+
+use crate::api2::types::*;
+use crate::config::acl::PRIV_SYS_AUDIT;
+use crate::server::generate_report;
+
+#[api(
+ input: {
+ properties: {
+ node: {
+ schema: NODE_SCHEMA,
+ },
+ },
+ },
+ returns: {
+ type: String,
+ description: "Returns report of the node"
+ },
+ access: {
+ permission: &Permission::Privilege(&["system", "status"], PRIV_SYS_AUDIT, false),
+ },
+)]
+/// Generate a report
+fn get_report(
+ _param: Value,
+ _info: &ApiMethod,
+ _rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Value, Error> {
+ Ok(json!(generate_report()))
+}
+
+pub const ROUTER: Router = Router::new()
+ .get(&API_METHOD_GET_REPORT);
diff --git a/src/server.rs b/src/server.rs
index 05fd25d9..983a300d 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -84,3 +84,6 @@ pub use gc_job::*;
mod email_notifications;
pub use email_notifications::*;
+
+mod report;
+pub use report::*;
diff --git a/src/server/report.rs b/src/server/report.rs
new file mode 100644
index 00000000..8c109660
--- /dev/null
+++ b/src/server/report.rs
@@ -0,0 +1,77 @@
+use std::path::Path;
+use std::process::Command;
+
+use lazy_static::lazy_static;
+
+use crate::config::datastore;
+use crate::tools::subscription::read_subscription;
+
+lazy_static! {
+ static ref FILES: Vec<&'static str> = vec!["/etc/hosts", "/etc/network/interfaces"];
+
+ // (<command>, <arg [, arg]>)
+ static ref COMMANDS: Vec<(&'static str, Vec<&'static str>)> = vec![
+ ("/usr/bin/df", vec!["-h"]),
+ ("/usr/bin/lsblk", vec!["-ascii"])
+ ];
+
+ // (<description>, <function to call>)
+ static ref FUNCTION_CALLS: Vec<(&'static str, fn() -> String)> = vec![
+ ("Subscription status", || match read_subscription() {
+ Ok(Some(sub_info)) => sub_info.status.to_string(),
+ _ => String::from("No subscription found"),
+ }),
+ ("Datastores", || {
+ let config = match datastore::config() {
+ Ok((config, _digest)) => config,
+ _ => return String::from("could not read datastore config"),
+ };
+
+ let mut list = Vec::new();
+ for (store, _) in &config.sections {
+ list.push(store.as_str());
+ }
+ list.join(", ")
+ })
+ ];
+}
+
+pub fn generate_report() -> String {
+ use proxmox::tools::fs::file_read_optional_string;
+
+ let file_contents = FILES
+ .iter()
+ .map(|file_name| {
+ let content = match file_read_optional_string(Path::new(file_name)) {
+ Ok(Some(content)) => content,
+ Err(err) => err.to_string(),
+ _ => String::from("Could not be read!"),
+ };
+ format!("# {}\n{}", file_name, content)
+ })
+ .collect::<Vec<String>>()
+ .join("\n\n");
+
+ let command_outputs = COMMANDS
+ .iter()
+ .map(|(command, args)| {
+ let output = match Command::new(command).args(args).output() {
+ Ok(output) => String::from_utf8_lossy(&output.stdout).to_string(),
+ Err(err) => err.to_string(),
+ };
+ format!("# {} {}\n{}", command, args.join(" "), output)
+ })
+ .collect::<Vec<String>>()
+ .join("\n\n");
+
+ let function_outputs = FUNCTION_CALLS
+ .iter()
+ .map(|(desc, function)| format!("# {}\n{}", desc, function()))
+ .collect::<Vec<String>>()
+ .join("\n\n");
+
+ format!(
+ " FILES\n{}\n COMMANDS\n{}\n FUNCTIONS\n{}",
+ file_contents, command_outputs, function_outputs
+ )
+}
--
2.20.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 2/3] report: add webui button for system report
2020-11-03 12:29 [pbs-devel] [PATCH proxmox-backup 0/3] add system report Hannes Laimer
2020-11-03 12:29 ` [pbs-devel] [PATCH proxmox-backup 1/3] report: add api endpoint and function to generate report Hannes Laimer
@ 2020-11-03 12:29 ` Hannes Laimer
2020-11-03 12:29 ` [pbs-devel] [PATCH proxmox-backup 3/3] manager: add report cli command Hannes Laimer
2020-11-04 7:49 ` [pbs-devel] applied-series: [PATCH proxmox-backup 0/3] add system report Thomas Lamprecht
3 siblings, 0 replies; 5+ messages in thread
From: Hannes Laimer @ 2020-11-03 12:29 UTC (permalink / raw)
To: pbs-devel
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
www/Subscription.js | 75 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 1 deletion(-)
diff --git a/www/Subscription.js b/www/Subscription.js
index d2ad5af0..498600bf 100644
--- a/www/Subscription.js
+++ b/www/Subscription.js
@@ -28,6 +28,73 @@ Ext.define('PBS.Subscription', {
enableTextSelection: true,
},
+ showReport: function() {
+ var me = this;
+
+ var getReportFileName = function() {
+ var now = Ext.Date.format(new Date(), 'D-d-F-Y-G-i');
+ return `${me.nodename}-pbs-report-${now}.txt`;
+ };
+
+ var view = Ext.createWidget('component', {
+ itemId: 'system-report-view',
+ scrollable: true,
+ style: {
+ 'background-color': 'white',
+ 'white-space': 'pre',
+ 'font-family': 'monospace',
+ padding: '5px',
+ },
+ });
+
+ var reportWindow = Ext.create('Ext.window.Window', {
+ title: gettext('System Report'),
+ width: 1024,
+ height: 600,
+ layout: 'fit',
+ modal: true,
+ buttons: [
+ '->',
+ {
+ text: gettext('Download'),
+ handler: function() {
+ var fileContent = Ext.String.htmlDecode(reportWindow.getComponent('system-report-view').html);
+ var fileName = getReportFileName();
+
+ // Internet Explorer
+ if (window.navigator.msSaveOrOpenBlob) {
+ navigator.msSaveOrOpenBlob(new Blob([fileContent]), fileName);
+ } else {
+ var element = document.createElement('a');
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' +
+ encodeURIComponent(fileContent));
+ element.setAttribute('download', fileName);
+ element.style.display = 'none';
+ document.body.appendChild(element);
+ element.click();
+ document.body.removeChild(element);
+ }
+ },
+ },
+ ],
+ items: view,
+ });
+
+ Proxmox.Utils.API2Request({
+ url: '/api2/extjs/nodes/' + me.nodename + '/report',
+ method: 'GET',
+ waitMsgTarget: me,
+ failure: function(response) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ success: function(response) {
+ var report = Ext.htmlEncode(response.result.data);
+ reportWindow.show();
+ view.update(report);
+ },
+ });
+ },
+
initComponent: function() {
let me = this;
@@ -105,7 +172,13 @@ Ext.define('PBS.Subscription', {
selModel: false,
callback: reload,
},
- //'-',
+ '-',
+ {
+ text: gettext('System Report'),
+ handler: function() {
+ Proxmox.Utils.checked_command(function() { me.showReport(); });
+ },
+ },
],
rows: rows,
});
--
2.20.1
^ permalink raw reply [flat|nested] 5+ messages in thread