Extend volume import functionality to support 'iso', 'snippets',
'vztmpl', and 'import' types, in addition to the existing support for
'images' and 'rootdir'. This is a prerequisite for the ability to move
ISOs, snippets and container templates between nodes.
Existing behavior for importing VM disks and container volumes remains
unchanged.

Signed-off-by: Filip Schauer <f.scha...@proxmox.com>
---
 src/PVE/Storage/Plugin.pm | 72 ++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm
index 0b0b5a8..c010d9c 100644
--- a/src/PVE/Storage/Plugin.pm
+++ b/src/PVE/Storage/Plugin.pm
@@ -1684,6 +1684,8 @@ sub volume_export_formats {
            or return;
        my ($size, $format) = file_size_info($file);
 
+       return ('raw+size') if !defined($format);
+
        if ($with_snapshots) {
            return ($format.'+size') if ($format eq 'qcow2' || $format eq 
'vmdk');
            return ();
@@ -1712,14 +1714,18 @@ sub volume_import {
 
     # XXX: Should we bother with conversion routines at this level? This won't
     # happen without manual CLI usage, so for now we just error out...
-    die "cannot import format $format into a file of format $file_format\n"
-       if $data_format ne $file_format && !($data_format eq 'tar' && 
$file_format eq 'subvol');
+    if (($vtype eq 'images' || $vtype eq 'rootdir') && $data_format ne 
$file_format &&
+       !($data_format eq 'tar' && $file_format eq 'subvol')
+    ) {
+       die "cannot import format $format into a file of format $file_format\n";
+    }
 
     # Check for an existing file first since interrupting alloc_image doesn't
     # free it.
     my $file = $class->path($scfg, $volname, $storeid);
     if (-e $file) {
-       die "file '$file' already exists\n" if !$allow_rename;
+       die "file '$file' already exists\n"
+           if !$allow_rename || ($vtype ne 'images' && $vtype ne 'rootdir');
        warn "file '$file' already exists - importing with a different name\n";
        $name = undef;
     }
@@ -1727,29 +1733,44 @@ sub volume_import {
     my ($size) = read_common_header($fh);
     $size = int($size/1024);
 
-    eval {
-       my $allocname = $class->alloc_image($storeid, $scfg, $vmid, 
$file_format, $name, $size);
-       my $oldname = $volname;
-       $volname = $allocname;
-       if (defined($name) && $allocname ne $oldname) {
-           die "internal error: unexpected allocated name: '$allocname' != 
'$oldname'\n";
+    if ($vtype eq 'images' || $vtype eq 'rootdir') {
+       eval {
+           my $allocname = $class->alloc_image($storeid, $scfg, $vmid, 
$file_format, $name, $size);
+           my $oldname = $volname;
+           $volname = $allocname;
+           if (defined($name) && $allocname ne $oldname) {
+               die "internal error: unexpected allocated name: '$allocname' != 
'$oldname'\n";
+           }
+           my $file = $class->path($scfg, $volname, $storeid)
+               or die "internal error: failed to get path to newly allocated 
volume $volname\n";
+           if ($data_format eq 'raw' || $data_format eq 'qcow2' || 
$data_format eq 'vmdk') {
+               run_command(['dd', "of=$file", 'conv=sparse', 'bs=64k'],
+                   input => '<&'.fileno($fh));
+           } elsif ($data_format eq 'tar') {
+               run_command(['tar', @COMMON_TAR_FLAGS, '-C', $file, '-xf', '-'],
+                   input => '<&'.fileno($fh));
+           } else {
+               die "volume import format '$format' not available for $class";
+           }
+       };
+       if (my $err = $@) {
+           eval { $class->free_image($storeid, $scfg, $volname, 0, 
$file_format) };
+           warn $@ if $@;
+           die $err;
        }
-       my $file = $class->path($scfg, $volname, $storeid)
-           or die "internal error: failed to get path to newly allocated 
volume $volname\n";
-       if ($data_format eq 'raw' || $data_format eq 'qcow2' || $data_format eq 
'vmdk') {
-           run_command(['dd', "of=$file", 'conv=sparse', 'bs=64k'],
-                       input => '<&'.fileno($fh));
-       } elsif ($data_format eq 'tar') {
-           run_command(['tar', @COMMON_TAR_FLAGS, '-C', $file, '-xf', '-'],
-                       input => '<&'.fileno($fh));
-       } else {
-           die "volume import format '$format' not available for $class";
+    } elsif (grep { $vtype eq $_ } qw(import iso snippets vztmpl)) {
+       eval {
+           run_command(['dd', "of=$file", 'bs=64k'], input => 
'<&'.fileno($fh));
+       };
+       if (my $err = $@) {
+           if (-e $file) {
+               eval { unlink($file) };
+               warn $@ if $@;
+           }
+           die $err;
        }
-    };
-    if (my $err = $@) {
-       eval { $class->free_image($storeid, $scfg, $volname, 0, $file_format) };
-       warn $@ if $@;
-       die $err;
+    } else {
+       die "importing volume of type '$vtype' not implemented\n";
     }
 
     return "$storeid:$volname";
@@ -1759,6 +1780,9 @@ sub volume_import_formats {
     my ($class, $scfg, $storeid, $volname, $snapshot, $base_snapshot, 
$with_snapshots) = @_;
     if ($scfg->{path} && !defined($base_snapshot)) {
        my $format = ($class->parse_volname($volname))[6];
+
+       return ('raw+size') if !defined($format);
+
        if ($with_snapshots) {
            return ($format.'+size') if ($format eq 'qcow2' || $format eq 
'vmdk');
            return ();
-- 
2.39.5



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

Reply via email to