]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
VM.Snapshot.Rollback privilege added
[qemu-server.git] / PVE / API2 / Qemu.pm
index 40e68ddd702aeafb7a17363c95d5b1a1bc5468cb..869eb8c109aeb87883e43b0cbc2483b5adf53a2a 100644 (file)
@@ -52,6 +52,7 @@ my $resolve_cdrom_alias = sub {
     }
 };
 
+my $NEW_DISK_RE = qr!^(([^/:\s]+):)?(\d+(\.\d+)?)$!;
 my $check_storage_access = sub {
    my ($rpcenv, $authuser, $storecfg, $vmid, $settings, $default_storage) = @_;
 
@@ -66,10 +67,13 @@ my $check_storage_access = sub {
            # nothing to check
        } elsif ($isCDROM && ($volid eq 'cdrom')) {
            $rpcenv->check($authuser, "/", ['Sys.Console']);
-       } elsif (!$isCDROM && ($volid =~ m/^(([^:\s]+):)?(\d+(\.\d+)?)$/)) {
+       } elsif (!$isCDROM && ($volid =~ $NEW_DISK_RE)) {
            my ($storeid, $size) = ($2 || $default_storage, $3);
            die "no storage ID specified (and no default storage)\n" if !$storeid;
            $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
+           my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
+           raise_param_exc({ storage => "storage '$storeid' does not support vm images"})
+               if !$scfg->{content}->{images};
        } else {
            PVE::Storage::check_volume_access($rpcenv, $authuser, $storecfg, $vmid, $volid);
        }
@@ -115,7 +119,6 @@ my $check_storage_access_clone = sub {
 
 # Note: $pool is only needed when creating a VM, because pool permissions
 # are automatically inherited if VM already exists inside a pool.
-my $NEW_DISK_RE = qr!^(([^/:\s]+):)?(\d+(\.\d+)?)$!;
 my $create_disks = sub {
     my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $default_storage) = @_;
 
@@ -137,35 +140,17 @@ my $create_disks = sub {
            my $defformat = PVE::Storage::storage_default_format($storecfg, $storeid);
            my $fmt = $disk->{format} || $defformat;
 
+           $size = PVE::Tools::convert_size($size, 'gb' => 'kb'); # vdisk_alloc uses kb
+
            my $volid;
            if ($ds eq 'efidisk0') {
-               # handle efidisk
-               my $ovmfvars = '/usr/share/kvm/OVMF_VARS-pure-efi.fd';
-               die "uefi vars image not found\n" if ! -f $ovmfvars;
-               $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
-                                                     $fmt, undef, 128);
-               $disk->{file} = $volid;
-               $disk->{size} = 128*1024;
-               my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid);
-               my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
-               my $qemufmt = PVE::QemuServer::qemu_img_format($scfg, $volname);
-               my $path = PVE::Storage::path($storecfg, $volid);
-               my $efidiskcmd = ['/usr/bin/qemu-img', 'convert', '-n', '-f', 'raw', '-O', $qemufmt];
-               push @$efidiskcmd, $ovmfvars;
-               push @$efidiskcmd, $path;
-
-               PVE::Storage::activate_volumes($storecfg, [$volid]);
-
-               eval { PVE::Tools::run_command($efidiskcmd); };
-               my $err = $@;
-               die "Copying of EFI Vars image failed: $err" if $err;
+               ($volid, $size) = PVE::QemuServer::create_efidisk($storecfg, $storeid, $vmid, $fmt);
            } else {
-               $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
-                                                     $fmt, undef, $size*1024*1024);
-               $disk->{file} = $volid;
-               $disk->{size} = $size*1024*1024*1024;
+               $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, $size);
            }
            push @$vollist, $volid;
+           $disk->{file} = $volid;
+           $disk->{size} = PVE::Tools::convert_size($size, 'kb' => 'b');
            delete $disk->{format}; # no longer needed
            $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
        } else {
@@ -905,7 +890,7 @@ my $update_vm_api  = sub {
     my $background_delay = extract_param($param, 'background_delay');
 
     my @paramarr = (); # used for log message
-    foreach my $key (keys %$param) {
+    foreach my $key (sort keys %$param) {
        push @paramarr, "-$key", $param->{$key};
     }
 
@@ -2529,7 +2514,10 @@ __PACKAGE__->register_method({
                my $jobs = {};
 
                eval {
-                   local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { die "interrupted by signal\n"; };
+                   local $SIG{INT} =
+                       local $SIG{TERM} =
+                       local $SIG{QUIT} =
+                       local $SIG{HUP} = sub { die "interrupted by signal\n"; };
 
                    PVE::Storage::activate_volumes($storecfg, $vollist, $snapname);
 
@@ -2709,7 +2697,10 @@ __PACKAGE__->register_method({
                my $newvollist = [];
 
                eval {
-                   local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { die "interrupted by signal\n"; };
+                   local $SIG{INT} =
+                       local $SIG{TERM} =
+                       local $SIG{QUIT} =
+                       local $SIG{HUP} = sub { die "interrupted by signal\n"; };
 
                    warn "moving disk with snapshots, snapshots will not be moved!\n"
                        if $snapshotted;
@@ -3351,7 +3342,7 @@ __PACKAGE__->register_method({
     proxyto => 'node',
     description => "Get snapshot configuration",
     permissions => {
-       check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
+       check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any => 1],
     },
     parameters => {
        additionalProperties => 0,
@@ -3390,7 +3381,7 @@ __PACKAGE__->register_method({
     proxyto => 'node',
     description => "Rollback VM state to specified snapshot.",
     permissions => {
-       check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
+       check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any => 1],
     },
     parameters => {
        additionalProperties => 0,