2015-11-03 16:42:16 +01:00
package PVE::Report ;
use strict ;
use warnings ;
use PVE::pvecfg ;
use PVE::Tools ;
2016-10-28 10:56:40 +02:00
$ ENV { 'PATH' } = '/sbin:/bin:/usr/sbin:/usr/bin' ;
2017-06-09 12:06:12 +02:00
my $ cmd_timeout = 10 ; # generous timeout
2018-03-02 09:38:57 +01:00
# NOTE: always add new sections to the report_order array!
my $ report_def = {
general = > {
title = > 'general system info' ,
cmds = > [
'hostname' ,
'pveversion --verbose' ,
'cat /etc/hosts' ,
'top -b -n 1 | head -n 15' ,
'pvesubscription get' ,
'lscpu' ,
2019-03-08 10:20:56 +01:00
'pvesh get /cluster/resources --type node --output-format=yaml' ,
2018-03-02 09:38:57 +01:00
] ,
} ,
storage = > [
'cat /etc/pve/storage.cfg' ,
'pvesm status' ,
'cat /etc/fstab' ,
2018-03-02 09:38:58 +01:00
'findmnt --ascii' ,
2018-03-02 09:38:57 +01:00
'df --human' ,
] ,
'virtual guests' = > [
'qm list' ,
sub { dir2text ( '/etc/pve/qemu-server/' , '\d.*conf' ) } ,
2018-03-02 09:38:59 +01:00
'pct list' ,
2018-03-02 09:38:57 +01:00
sub { dir2text ( '/etc/pve/lxc/' , '\d.*conf' ) } ,
] ,
network = > [
'ip -details -statistics address' ,
2019-03-13 14:59:35 +01:00
'ip -details -4 route show' ,
'ip -details -6 route show' ,
2018-03-02 09:38:57 +01:00
'cat /etc/network/interfaces' ,
] ,
firewall = > [
sub { dir2text ( '/etc/pve/firewall/' , '.*fw' ) } ,
2019-03-13 13:15:02 +01:00
'cat /etc/pve/local/host.fw' ,
2018-03-02 09:38:57 +01:00
'iptables-save' ,
] ,
cluster = > [
'pvecm nodes' ,
'pvecm status' ,
'cat /etc/pve/corosync.conf 2>/dev/null'
] ,
bios = > [
'dmidecode -t bios' ,
] ,
2018-03-02 09:39:00 +01:00
pci = > [
'lspci -nnk' ,
] ,
2018-03-02 09:38:57 +01:00
disks = > [
'lsblk --ascii' ,
] ,
volumes = > [
2019-03-28 14:02:20 +01:00
'pvs' ,
2018-03-02 09:38:57 +01:00
'lvs' ,
'vgs' ,
] ,
2015-11-03 16:42:16 +01:00
} ;
2018-03-02 09:38:57 +01:00
my @ report_order = ( 'general' , 'storage' , 'virtual guests' , 'network' ,
2018-03-02 09:39:00 +01:00
'firewall' , 'cluster' , 'bios' , 'pci' , 'disks' , 'volumes' ) ;
2015-11-03 16:42:16 +01:00
2018-03-02 09:38:57 +01:00
push @ { $ report_def - > { volumes } } , 'zpool status' , 'zfs list' if cmd_exists ( 'zfs' ) ;
2015-11-03 16:42:16 +01:00
2018-03-02 09:38:57 +01:00
push @ { $ report_def - > { disk } } , 'multipath -ll' , 'multipath -v3' if cmd_exists ( 'multipath' ) ;
2015-11-03 16:42:16 +01:00
2018-03-02 09:38:57 +01:00
my $ report = '' ;
2015-11-03 16:42:16 +01:00
# output the content of all the files of a directory
sub dir2text {
my ( $ target_dir , $ regexp ) = @ _ ;
PVE::Tools:: dir_glob_foreach ( $ target_dir , $ regexp , sub {
my ( $ file ) = @ _ ;
2017-06-09 12:06:12 +02:00
$ report . = "\n# cat $target_dir$file\n" ;
2015-11-03 16:42:16 +01:00
$ report . = PVE::Tools:: file_get_contents ( $ target_dir . $ file ) . "\n" ;
} ) ;
}
2018-03-02 09:38:57 +01:00
# command -v is the posix equivalent of 'which'
sub cmd_exists { system ( "command -v '$_[0]' > /dev/null 2>&1" ) == 0 }
2015-11-03 16:42:16 +01:00
sub generate {
2017-06-09 12:06:12 +02:00
my $ record_output = sub {
$ report . = shift . "\n" ;
} ;
my $ run_cmd_params = {
outfunc = > $ record_output ,
errfunc = > $ record_output ,
timeout = > $ cmd_timeout ,
noerr = > 1 , # avoid checking programs exit code
} ;
2018-03-02 09:38:57 +01:00
foreach my $ section ( @ report_order ) {
my $ s = $ report_def - > { $ section } ;
my $ title = "info about $section" ;
my $ commands = $ s ;
if ( ref ( $ s ) eq 'HASH' ) {
$ commands = $ s - > { cmds } ;
$ title = $ s - > { title } if defined ( $ s - > { title } ) ;
} elsif ( ref ( $ s ) ne 'ARRAY' ) {
die "unknown report definition in section '$section'!" ;
}
2015-11-03 16:42:16 +01:00
$ report . = "\n==== $title ====\n" ;
2018-03-02 09:38:57 +01:00
foreach my $ command ( @$ commands ) {
2017-06-09 12:06:12 +02:00
eval {
if ( ref $ command eq 'CODE' ) {
PVE::Tools:: run_with_timeout ( $ cmd_timeout , $ command ) ;
} else {
$ report . = "\n# $command\n" ;
PVE::Tools:: run_command ( $ command , %$ run_cmd_params ) ;
}
} ;
$ report . = "\nERROR: $@\n" if $@ ;
2015-11-03 16:42:16 +01:00
}
}
2017-06-09 12:06:12 +02:00
return $ report ;
2015-11-03 16:42:16 +01:00
}
2018-03-02 09:38:57 +01:00
1 ;