From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 558A696E67 for ; Tue, 16 Apr 2024 15:20:18 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id BAD221BB29 for ; Tue, 16 Apr 2024 15:19:23 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 16 Apr 2024 15:19:19 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id B29974524B for ; Tue, 16 Apr 2024 15:19:15 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Tue, 16 Apr 2024 15:19:05 +0200 Message-Id: <20240416131909.2867605-13-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240416131909.2867605-1-d.csapak@proxmox.com> References: <20240416131909.2867605-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.014 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH qemu-server 3/3] api: create: implement extracting disks when needed for import-from X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Apr 2024 13:20:18 -0000 when 'import-from' contains a disk image that needs extraction (currently only from an 'ova' archive), do that in 'create_disks' and overwrite the '$source' volid. Collect the names into a 'delete_sources' list, that we use later to clean it up again (either when we're finished with importing or in an error case). Signed-off-by: Dominik Csapak --- PVE/API2/Qemu.pm | 26 ++++++++++++++++++++------ PVE/QemuServer.pm | 5 ++++- PVE/QemuServer/Helpers.pm | 9 +++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index f3ce83d6..afdb507f 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -161,8 +161,8 @@ my $check_storage_access = sub { my $src_vmid; if (PVE::Storage::parse_volume_id($src_image, 1)) { # PVE-managed volume (my $vtype, undef, $src_vmid) = PVE::Storage::parse_volname($storecfg, $src_image); - raise_param_exc({ $ds => "$src_image has wrong type '$vtype' - not an image" }) - if $vtype ne 'images'; + raise_param_exc({ $ds => "$src_image has wrong type '$vtype' - needs to be 'images' or 'import'" }) + if $vtype ne 'images' && $vtype ne 'import'; } if ($src_vmid) { # might be actively used by VM and will be copied via clone_disk() @@ -335,6 +335,7 @@ my sub create_disks : prototype($$$$$$$$$$) { my $res = {}; my $live_import_mapping = {}; + my $delete_sources = []; my $code = sub { my ($ds, $disk) = @_; @@ -391,6 +392,13 @@ my sub create_disks : prototype($$$$$$$$$$) { $needs_creation = $live_import; + if (PVE::Storage::copy_needs_extraction($source)) { # needs extraction beforehand + print "extracting $source\n"; + $source = PVE::Storage::extract_disk_from_import_file($source, $vmid); + print "finished extracting to $source\n"; + push @$delete_sources, $source; + } + if (PVE::Storage::parse_volume_id($source, 1)) { # PVE-managed volume if ($live_import && $ds ne 'efidisk0') { my $path = PVE::Storage::path($storecfg, $source) @@ -514,13 +522,14 @@ my sub create_disks : prototype($$$$$$$$$$) { eval { PVE::Storage::vdisk_free($storecfg, $volid); }; warn $@ if $@; } + PVE::QemuServer::Helpers::cleanup_extracted_images($delete_sources); die $err; } # don't return empty import mappings $live_import_mapping = undef if !%$live_import_mapping; - return ($vollist, $res, $live_import_mapping); + return ($vollist, $res, $live_import_mapping, $delete_sources); }; my $check_cpu_model_access = sub { @@ -1079,6 +1088,7 @@ __PACKAGE__->register_method({ my $createfn = sub { my $live_import_mapping = {}; + my $delete_sources = []; # ensure no old replication state are exists PVE::ReplicationState::delete_guest_states($vmid); @@ -1096,7 +1106,7 @@ __PACKAGE__->register_method({ my $vollist = []; eval { - ($vollist, my $created_opts, $live_import_mapping) = create_disks( + ($vollist, my $created_opts, $live_import_mapping, $delete_sources) = create_disks( $rpcenv, $authuser, $conf, @@ -1148,6 +1158,7 @@ __PACKAGE__->register_method({ eval { PVE::Storage::vdisk_free($storecfg, $volid); }; warn $@ if $@; } + PVE::QemuServer::Helpers::cleanup_extracted_images($delete_sources); die "$emsg $err"; } @@ -1164,7 +1175,7 @@ __PACKAGE__->register_method({ warn $@ if $@; return; } else { - return $live_import_mapping; + return ($live_import_mapping, $delete_sources); } }; @@ -1191,7 +1202,7 @@ __PACKAGE__->register_method({ $code = sub { # If a live import was requested the create function returns # the mapping for the startup. - my $live_import_mapping = eval { $createfn->() }; + my ($live_import_mapping, $delete_sources) = eval { $createfn->() }; if (my $err = $@) { eval { my $conffile = PVE::QemuConfig->config_file($vmid); @@ -1213,7 +1224,10 @@ __PACKAGE__->register_method({ $vmid, $conf, $import_options, + $delete_sources, ); + } else { + PVE::QemuServer::Helpers::cleanup_extracted_images($delete_sources); } }; } diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index abe175a4..01133f39 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -7292,7 +7292,7 @@ sub pbs_live_restore { # therefore already handled in the `$create_disks()` call happening in the # `create` api call sub live_import_from_files { - my ($mapping, $vmid, $conf, $restore_options) = @_; + my ($mapping, $vmid, $conf, $restore_options, $delete_sources) = @_; my $live_restore_backing = {}; for my $dev (keys %$mapping) { @@ -7353,6 +7353,8 @@ sub live_import_from_files { mon_cmd($vmid, 'blockdev-del', 'node-name' => "drive-$ds-restore"); } + PVE::QemuServer::Helpers::cleanup_extracted_images($delete_sources); + close($qmeventd_fd); }; @@ -7361,6 +7363,7 @@ sub live_import_from_files { if ($err) { warn "An error occurred during live-restore: $err\n"; _do_vm_stop($storecfg, $vmid, 1, 1, 10, 0, 1); + PVE::QemuServer::Helpers::cleanup_extracted_images($delete_sources); die "live-restore failed\n"; } diff --git a/PVE/QemuServer/Helpers.pm b/PVE/QemuServer/Helpers.pm index 0afb6317..40b90a6e 100644 --- a/PVE/QemuServer/Helpers.pm +++ b/PVE/QemuServer/Helpers.pm @@ -225,4 +225,13 @@ sub windows_version { return $winversion; } +sub cleanup_extracted_images { + my ($delete_sources) = @_; + + for my $source (@$delete_sources) { + eval { PVE::Storage::cleanup_extracted_image($source) }; + warn $@ if $@; + } +} + 1; -- 2.39.2