]> git.proxmox.com Git - pve-manager.git/commitdiff
pvereport: improve output and add timeouts to commands
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 9 Jun 2017 10:06:12 +0000 (12:06 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 21 Jun 2017 05:45:22 +0000 (07:45 +0200)
Each command may not run longer than 10 seconds. This avoids
situations where no output gets generated because of a infinitely
hanging command (e.g. check for dead NFS storage)
Also ensure that commands are separated with a new line from each
other to improve readability.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
PVE/Report.pm

index 6717d28603a3d242193479fcccf9f5f6733fcf46..eaf7c82f0910966066bbadc032a9c347a978947f 100644 (file)
@@ -7,6 +7,8 @@ use PVE::Tools;
 
 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
 
+my $cmd_timeout = 10; # generous timeout
+
 my $report;
 
 my @general = ('hostname', 'pveversion --verbose', 'cat /etc/hosts', 'top -b -n 1  | head -n 15',
@@ -92,36 +94,41 @@ sub dir2text {
 
     PVE::Tools::dir_glob_foreach($target_dir, $regexp, sub {
        my ($file) = @_;
-       $report .=  "# cat $target_dir$file\n";
+       $report .=  "\n# cat $target_dir$file\n";
        $report .= PVE::Tools::file_get_contents($target_dir.$file)."\n";
     });
 }
 
-# execute commands and display their output as if they've been done on a interactive shell
-# so the local sysadmin can reproduce what we're doing
-sub do_execute {
-    my ($command) = @_;
-    $report .= "# $command \n";
-    open (COMMAND, "$command 2>&1 |");
-    while (<COMMAND>) {
-       $report .= $_;
-    }
-}
-
 sub generate {
+
+    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
+    };
+
     foreach my $subreport (@global_report) {
        my $title = $subreport->{'title'};
        my @commands = @{$subreport->{'commands'}};
 
        $report .= "\n==== $title ====\n";
        foreach my $command (@commands) {
-           if (ref $command eq 'CODE') {
-               &$command;
-           } else {
-               do_execute($command);
-               next;
-           }
+           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 $@;
        }
     }
-return $report;
+
+    return $report;
 }