]> git.proxmox.com Git - pve-manager.git/blame - PVE/Report.pm
d/control: recommend proxmox-offline-mirror-helper
[pve-manager.git] / PVE / Report.pm
CommitLineData
2f7faeed
EK
1package PVE::Report;
2
3use strict;
4use warnings;
180a86d3 5
2f7faeed
EK
6use PVE::Tools;
7
3a0b2c40
TL
8# output the content of all the files of a directory
9my sub dir2text {
10 my ($target_dir, $regexp) = @_;
11
6b72e9dd 12 print STDERR "dir2text '${target_dir}${regexp}'...";
3a0b2c40
TL
13 my $text = '';
14 PVE::Tools::dir_glob_foreach($target_dir, $regexp, sub {
15 my ($file) = @_;
16 $text .= "\n# cat $target_dir$file\n";
17 $text .= PVE::Tools::file_get_contents($target_dir.$file)."\n";
18 });
19 return $text;
20}
21
22# command -v is the posix equivalent of 'which'
23my sub cmd_exists { system("command -v '$_[0]' > /dev/null 2>&1") == 0 }
ee3a8989 24
01c8f6fe 25my $init_report_cmds = sub {
01c8f6fe
TL
26 my $report_def = {
27 general => {
28 title => 'general system info',
f784b925 29 order => 10,
01c8f6fe
TL
30 cmds => [
31 'hostname',
32 'pveversion --verbose',
33 'cat /etc/hosts',
01c8f6fe 34 'pvesubscription get',
ea717e8f
SI
35 'cat /etc/apt/sources.list',
36 sub { dir2text('/etc/apt/sources.list.d/', '.*list') },
8672c64e 37 sub { dir2text('/etc/apt/sources.list.d/', '.*sources') },
01c8f6fe
TL
38 'lscpu',
39 'pvesh get /cluster/resources --type node --output-format=yaml',
40 ],
41 },
8b94e6bb
TL
42 'system-load' => {
43 title => 'overall system load info',
44 order => 20,
45 cmds => [
cdb63825 46 'top -b -c -w512 -n 1 -o TIME | head -n 30',
8b94e6bb
TL
47 'head /proc/pressure/*',
48 ],
49 },
f784b925
TL
50 storage => {
51 order => 30,
52 cmds => [
53 'cat /etc/pve/storage.cfg',
54 'pvesm status',
55 'cat /etc/fstab',
56 'findmnt --ascii',
80e456f6 57 'df --human -T',
f784b925
TL
58 ],
59 },
60 'virtual guests' => {
61 order => 40,
62 cmds => [
63 'qm list',
64 sub { dir2text('/etc/pve/qemu-server/', '\d.*conf') },
65 'pct list',
66 sub { dir2text('/etc/pve/lxc/', '\d.*conf') },
67 ],
68 },
69 network => {
70 order => 40,
71 cmds => [
72 'ip -details -statistics address',
73 'ip -details -4 route show',
74 'ip -details -6 route show',
75 'cat /etc/network/interfaces',
76 ],
77 },
78 firewall => {
79 order => 50,
80 cmds => [
81 sub { dir2text('/etc/pve/firewall/', '.*fw') },
82 'cat /etc/pve/local/host.fw',
83 'iptables-save',
84 ],
85 },
86 cluster => {
87 order => 60,
88 cmds => [
89 'pvecm nodes',
90 'pvecm status',
91 'cat /etc/pve/corosync.conf 2>/dev/null',
92 'ha-manager status',
93 ],
94 },
8b94e6bb 95 hardware => {
f784b925
TL
96 order => 70,
97 cmds => [
98 'dmidecode -t bios',
f784b925
TL
99 'lspci -nnk',
100 ],
101 },
8b94e6bb 102 'block devices' => {
f784b925
TL
103 order => 80,
104 cmds => [
c4c3ed73 105 'lsblk --ascii -M -o +HOTPLUG,ROTA,PHY-SEC,FSTYPE,MODEL,TRAN',
f784b925
TL
106 'ls -l /dev/disk/by-*/',
107 'iscsiadm -m node',
108 'iscsiadm -m session',
109 ],
110 },
111 volumes => {
112 order => 90,
113 cmds => [
114 'pvs',
115 'lvs',
116 'vgs',
117 ],
118 },
01c8f6fe 119 };
1cf7db21 120
fb925d65 121 if (cmd_exists('zfs')) {
f784b925 122 push @{$report_def->{volumes}->{cmds}},
fb925d65
TL
123 'zpool status',
124 'zpool list -v',
125 'zfs list',
126 ;
127 }
1cf7db21 128
01c8f6fe 129 if (-e '/etc/ceph/ceph.conf') {
f784b925 130 push @{$report_def->{volumes}->{cmds}},
c83c3d45
TL
131 'pveceph status',
132 'ceph osd status',
133 'ceph df',
134 'ceph osd df tree',
ea4d55c9 135 'ceph device ls',
c83c3d45
TL
136 'cat /etc/ceph/ceph.conf',
137 'ceph config dump',
138 'pveceph pool ls',
139 'ceph versions',
140 ;
01c8f6fe 141 }
2f7faeed 142
1226cd97 143 if (cmd_exists('multipath')) {
f784b925 144 push @{$report_def->{disks}->{cmds}},
1226cd97
ML
145 'cat /etc/multipath.conf',
146 'cat /etc/multipath/wwids',
fb925d65
TL
147 'multipath -ll',
148 ;
1226cd97 149 }
2f7faeed 150
01c8f6fe
TL
151 return $report_def;
152};
2f7faeed 153
2f7faeed 154sub generate {
f784b925 155 my $def = $init_report_cmds->();
01c8f6fe 156
3a0b2c40 157 my $report = '';
ee3a8989
TL
158 my $record_output = sub {
159 $report .= shift . "\n";
160 };
161
73cdcc98
TL
162 local $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
163 my $cmd_timeout = 10; # generous timeout
164
ee3a8989
TL
165 my $run_cmd_params = {
166 outfunc => $record_output,
167 errfunc => $record_output,
168 timeout => $cmd_timeout,
169 noerr => 1, # avoid checking programs exit code
170 };
171
f784b925 172 my $sorter = sub { ($def->{$_[0]}->{order} // 1<<30) <=> ($def->{$_[1]}->{order} // 1<<30) };
2c4ef55e 173
f784b925
TL
174 for my $section ( sort { $sorter->($a, $b) } keys %$def) {
175 my $s = $def->{$section};
176 my $title = $s->{title} // "info about $section";
2f7faeed
EK
177
178 $report .= "\n==== $title ====\n";
f784b925 179 for my $command (@{$s->{cmds}}) {
ee3a8989
TL
180 eval {
181 if (ref $command eq 'CODE') {
3a0b2c40 182 $report .= PVE::Tools::run_with_timeout($cmd_timeout, $command);
ee3a8989 183 } else {
01c8f6fe 184 print STDERR "Process ".$command."...";
ee3a8989
TL
185 $report .= "\n# $command\n";
186 PVE::Tools::run_command($command, %$run_cmd_params);
187 }
2bdf85f8 188 print STDERR "OK";
ee3a8989 189 };
2bdf85f8 190 print STDERR "\n";
ee3a8989 191 $report .= "\nERROR: $@\n" if $@;
2f7faeed
EK
192 }
193 }
ee3a8989
TL
194
195 return $report;
2f7faeed 196}
2c4ef55e
TL
197
1981;