Specifying a drive parameter causes the restore operation to skip it
and keep the current drive instead.

TODO add some limits to what can be changed?

Signed-off-by: Fabian Ebner <f.eb...@proxmox.com>
---
 PVE/API2/Qemu.pm  | 14 +++++++++++---
 PVE/QemuServer.pm | 44 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 976d1bd6..08b1a635 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -823,9 +823,6 @@ __PACKAGE__->register_method({
        }
 
        if ($archive) {
-           my $keystr = join(' ', keys %$param);
-           raise_param_exc({ archive => "option conflicts with other options 
($keystr)"}) if $keystr;
-
            if ($archive eq '-') {
                die "pipe requires cli environment\n" if $rpcenv->{type} ne 
'cli';
                $archive = { type => 'pipe' };
@@ -873,6 +870,16 @@ __PACKAGE__->register_method({
 
            die "$emsg vm is running\n" if 
PVE::QemuServer::check_running($vmid);
 
+           for my $opt (sort keys $param->%*) {
+               next if !PVE::QemuServer::Drive::is_valid_drivename($opt);
+               my $drive = PVE::QemuServer::Drive::parse_drive($opt, 
$conf->{$opt});
+               my $newdrive = PVE::QemuServer::Drive::parse_drive($opt, 
$param->{$opt});
+               die "$opt - adding new drive during restore is not 
implemented\n" if !$drive;
+               die "$opt - unable to parse\n" if !$newdrive;
+               die "$opt - need to pass same volid to keep existing drive 
rather than restoring\n"
+                   if $drive->{file} ne $newdrive->{file};
+           }
+
            my $realcmd = sub {
                my $restore_options = {
                    storage => $storage,
@@ -880,6 +887,7 @@ __PACKAGE__->register_method({
                    unique => $unique,
                    bwlimit => $bwlimit,
                    live => $live_restore,
+                   override_conf => $param,
                };
                if ($archive->{type} eq 'file' || $archive->{type} eq 'pipe') {
                    die "live-restore is only compatible with backup images 
from a Proxmox Backup Server\n"
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 741a5e89..95ca0444 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6295,6 +6295,7 @@ my $parse_backup_hints = sub {
     while (defined(my $line = <$fh>)) {
        if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
            my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
+
            die "archive does not contain data for drive '$virtdev'\n"
                if !$devinfo->{$devname};
 
@@ -6309,6 +6310,8 @@ my $parse_backup_hints = sub {
            $devinfo->{$devname}->{format} = $format;
            $devinfo->{$devname}->{storeid} = $storeid;
 
+           next if $options->{override_conf}->{$virtdev}; # not being restored
+
            my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
            $check_storage->($storeid, $scfg); # permission and content type 
check
 
@@ -6476,6 +6479,17 @@ my $restore_destroy_volumes = sub {
     }
 };
 
+my $restore_merge_config = sub {
+    my ($filename, $backup_conf_raw, $override_conf) = @_;
+
+    my $backup_conf = parse_vm_config($filename, $backup_conf_raw);
+    for my $key (keys $override_conf->%*) {
+       $backup_conf->{$key} = $override_conf->{$key};
+    }
+
+    return $backup_conf;
+};
+
 sub scan_volids {
     my ($cfg, $vmid) = @_;
 
@@ -6785,8 +6799,10 @@ sub restore_proxmox_backup_archive {
        $new_conf_raw .= "\nlock: create";
     }
 
-    PVE::Tools::file_set_contents($conffile, $new_conf_raw);
+    my $new_conf = $restore_merge_config->($conffile, $new_conf_raw, 
$options->{override_conf});
+    PVE::QemuConfig->write_config($vmid, $new_conf);
 
+    # TODO still needed with write_config?
     PVE::Cluster::cfs_update(); # make sure we read new file
 
     eval { rescan($vmid, 1); };
@@ -6808,6 +6824,12 @@ sub restore_proxmox_backup_archive {
        # these special drives are already restored before start
        delete $devinfo->{'drive-efidisk0'};
        delete $devinfo->{'drive-tpmstate0-backup'};
+
+       for my $key (keys $options->{override_conf}->%*) {
+           next if !is_valid_drivename($key);
+           delete $devinfo->{"drive-$key"};
+       }
+
        pbs_live_restore($vmid, $conf, $storecfg, $devinfo, $repo, $keyfile, 
$pbs_backup_name);
 
        PVE::QemuConfig->remove_lock($vmid, "create");
@@ -7000,8 +7022,15 @@ sub restore_vma_archive {
        my $map = $restore_allocate_devices->($cfg, $virtdev_hash, $vmid);
 
        # print restore information to $fifofh
-       foreach my $virtdev (sort keys %$virtdev_hash) {
-           my $d = $virtdev_hash->{$virtdev};
+       for my $devname (sort keys $devinfo->%*) {
+           my $d = $devinfo->{$devname};
+
+           if (!$virtdev_hash->{$d->{virtdev}}) { # skipped
+               print $fifofh "format=raw:0:$d->{devname}=/dev/null\n";
+               print "not restoring '$d->{devname}'\n";
+               next;
+           }
+
            next if $d->{is_cloudinit}; # no need to restore cloudinit
 
            my $storeid = $d->{storeid};
@@ -7091,8 +7120,10 @@ sub restore_vma_archive {
        die $err;
     }
 
-    PVE::Tools::file_set_contents($conffile, $new_conf_raw);
+    my $new_conf = $restore_merge_config->($conffile, $new_conf_raw, 
$opts->{override_conf});
+    PVE::QemuConfig->write_config($vmid, $new_conf);
 
+    # TODO still needed with write_config?
     PVE::Cluster::cfs_update(); # make sure we read new file
 
     eval { rescan($vmid, 1); };
@@ -7104,6 +7135,11 @@ sub restore_vma_archive {
 sub restore_tar_archive {
     my ($archive, $vmid, $user, $opts) = @_;
 
+    if (scalar(keys $opts->{override_conf}->%*) > 0) {
+       my $keystring = join(' ', keys $opts->{override_conf}->%*);
+       die "cannot pass along options ($keystring) when restoring from tar 
archive\n";
+    }
+
     if ($archive ne '-') {
        my $firstfile = tar_archive_read_firstfile($archive);
        die "ERROR: file '$archive' does not look like a QemuServer vzdump 
backup\n"
-- 
2.30.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to