[pve-devel] [PATCH v2 storage 1/2] add extract vzdump config methods

Fabian Grünbichler f.gruenbichler at proxmox.com
Fri Jun 3 11:08:07 CEST 2016


extract_vzdump_config_tar is an adapted combination
of tar_archive_search_conf() and the first part of
recover_config(), both from PVE::LXC::Create.

a compressed vma backup file needs special error
handling because vma exits as soon as it found the config
file, which the used decompressors treat as error.
---
 PVE/Storage.pm | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/PVE/Storage.pm b/PVE/Storage.pm
index b8cd03e..1192ce3 100755
--- a/PVE/Storage.pm
+++ b/PVE/Storage.pm
@@ -1221,6 +1221,125 @@ sub foreach_volid {
     }
 }
 
+sub extract_vzdump_config_tar {
+    my ($archive, $conf_re) = @_;
+
+    die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
+
+    my $pid = open(my $fh, '-|', 'tar', 'tf', $archive) ||
+       die "unable to open file '$archive'\n";
+
+    my $file;
+    while (defined($file = <$fh>)) {
+	if ($file =~ m!$conf_re!) {
+	    $file = $1; # untaint
+	    last;
+	}
+    }
+
+    kill 15, $pid;
+    waitpid $pid, 0;
+    close $fh;
+
+    die "ERROR: archive contains no configuration file\n" if !$file;
+    chomp $file;
+
+    my $raw = '';
+    my $out = sub {
+	my $output = shift;
+	$raw .= "$output\n";
+    };
+
+    PVE::Tools::run_command(['tar', '-xpOf', $archive, $file, '--occurrence'], outfunc => $out);
+
+    return wantarray ? ($raw, $file) : $raw;
+}
+
+sub extract_vzdump_config_vma {
+    my ($archive, $comp) = @_;
+
+    my $cmd;
+    my $raw = '';
+    my $out = sub {
+	my $output = shift;
+	$raw .= "$output\n";
+    };
+
+
+    if ($comp) {
+	my $uncomp;
+	if ($comp eq 'gz') {
+	    $uncomp = ["zcat", $archive];
+	} elsif ($comp eq 'lzo') {
+	    $uncomp = ["lzop", "-d", "-c", $archive];
+	} else {
+	    die "unknown compression method '$comp'\n";
+	}
+	$cmd = [$uncomp, ["vma", "config", "-"]];
+
+	# in some cases, lzop/zcat exits with 1 when its stdout pipe is
+	# closed early by vma, detect this and ignore the exit code later
+	my $broken_pipe;
+	my $errstring;
+	my $err = sub {
+	    my $output = shift;
+	    if ($output =~ m/lzop: Broken pipe: <stdout>/ || $output =~ m/gzip: stdout: Broken pipe/) {
+		$broken_pipe = 1;
+	    } elsif (!defined ($errstring) && $output !~ m/^\s*$/) {
+		$errstring = "Failed to extract config from VMA archive: $output\n";
+	    }
+	};
+
+	# in other cases, the pipeline will exit with exit code 141
+	# because of the broken pipe, handle / ignore this as well
+	my $rc;
+	eval {
+	    $rc = PVE::Tools::run_command($cmd, outfunc => $out, errfunc => $err, noerr => 1);
+	};
+	my $rerr = $@;
+
+	# use exit code if no stderr output and not just broken pipe
+	if (!$errstring && !$broken_pipe && $rc > 0 && $rc != 141) {
+	    die "$rerr\n" if $rerr;
+	    die "config extraction failed with exit code $rc\n";
+	}
+	die "$errstring\n" if $errstring;
+    } else {
+	# simple case without compression and weird piping behaviour
+	PVE::Tools::run_command(["vma", "config", $archive], outfunc => $out);
+    }
+
+    return wantarray ? ($raw, undef) : $raw;
+}
+
+sub extract_vzdump_config {
+    my ($cfg, $volid) = @_;
+
+    my $archive = abs_filesystem_path($cfg, $volid);
+
+    if ($volid =~ /\/vzdump-(lxc|openvz)-\d+-(\d{4})_(\d{2})_(\d{2})-(\d{2})_(\d{2})_(\d{2})\.(tgz|(tar(\.(gz|lzo))?))$/) {
+	return extract_vzdump_config_tar($archive,'^(\./etc/vzdump/(pct|vps)\.conf)$');
+    } elsif ($volid =~ /\/vzdump-qemu-\d+-(\d{4})_(\d{2})_(\d{2})-(\d{2})_(\d{2})_(\d{2})\.(tgz|((tar|vma)(\.(gz|lzo))?))$/) {
+	my $format;
+	my $comp;
+	if ($7 eq 'tgz') {
+	    $format = 'tar';
+	    $comp = 'gz';
+	} else {
+	    $format = $9;
+	    $comp = $11 if defined($11);
+	}
+
+	if ($format eq 'tar') {
+	    return extract_vzdump_config_tar($archive, qr!\(\./qemu-server\.conf\)!);
+	} else {
+	    return extract_vzdump_config_vma($archive, $comp);
+	}
+    } else {
+	die "cannot determine backup guest type for backup archive '$volid'\n";
+    }
+}
+
 # bash completion helper
 
 sub complete_storage {
-- 
2.1.4




More information about the pve-devel mailing list