[pve-devel] [PATCH storage] add extract vzdump config methods
Fabian Grünbichler
f.gruenbichler at proxmox.com
Tue May 24 12:41:05 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.
---
PVE/Storage.pm | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/PVE/Storage.pm b/PVE/Storage.pm
index b8cd03e..bd96a29 100755
--- a/PVE/Storage.pm
+++ b/PVE/Storage.pm
@@ -1221,6 +1221,115 @@ 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";
+ };
+
+ # lzop/zcat will exit 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";
+ }
+ };
+
+ 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", "-"]];
+ } else {
+ $cmd = ["vma", "config", $archive];
+ }
+
+ eval {
+ PVE::Tools::run_command($cmd, outfunc => $out, errfunc => $err);
+ };
+
+ # use exit code if no stderr output and not just broken pipe
+ $errstring = "$@\n" if !$errstring && $@ && !$broken_pipe;
+ die $errstring if $errstring;
+ 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, '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