]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
api: create disks: avoid adding secondary cloud-init drives
[qemu-server.git] / PVE / API2 / Qemu.pm
index 06780918de5a764bcc1508aec1c7a9e614471522..3ec31c26898644114c7727d9030a6545626dd849 100644 (file)
@@ -328,6 +328,15 @@ my $create_disks = sub {
        } elsif (defined($volname) && $volname eq 'cloudinit') {
            $storeid = $storeid // $default_storage;
            die "no storage ID specified (and no default storage)\n" if !$storeid;
+
+           if (
+               my $ci_key = PVE::QemuConfig->has_cloudinit($conf, $ds)
+               || PVE::QemuConfig->has_cloudinit($conf->{pending} || {}, $ds)
+               || PVE::QemuConfig->has_cloudinit($res, $ds)
+           ) {
+               die "$ds - cloud-init drive is already attached at '$ci_key'\n";
+           }
+
            my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
            my $name = "vm-$vmid-cloudinit";
 
@@ -424,6 +433,16 @@ my $create_disks = sub {
                my ($vtype) = PVE::Storage::parse_volname($storecfg, $volid);
                die "cannot use volume $volid - content type needs to be 'images' or 'iso'"
                    if $vtype ne 'images' && $vtype ne 'iso';
+
+               if (PVE::QemuServer::Drive::drive_is_cloudinit($disk)) {
+                   if (
+                       my $ci_key = PVE::QemuConfig->has_cloudinit($conf, $ds)
+                       || PVE::QemuConfig->has_cloudinit($conf->{pending} || {}, $ds)
+                       || PVE::QemuConfig->has_cloudinit($res, $ds)
+                   ) {
+                       die "$ds - cloud-init drive is already attached at '$ci_key'\n";
+                   }
+               }
            }
 
            PVE::Storage::activate_volumes($storecfg, [ $volid ]) if $storeid;
@@ -2443,8 +2462,9 @@ __PACKAGE__->register_method({
 
        if ($conf->{vga}) {
            my $vga = PVE::QemuServer::parse_vga($conf->{vga});
-           $status->{spice} = 1
-               if $vga->{type} =~ /^virtio/ || PVE::QemuServer::vga_conf_has_spice($conf->{vga});
+           my $spice = defined($vga->{type}) && $vga->{type} =~ /^virtio/;
+           $spice ||= PVE::QemuServer::vga_conf_has_spice($conf->{vga});
+           $status->{spice} = 1 if $spice;
        }
        $status->{agent} = 1 if PVE::QemuServer::get_qga_key($conf, 'enabled');
 
@@ -2976,10 +2996,17 @@ __PACKAGE__->register_method({
        # early check for storage permission, for better user feedback
        if ($todisk) {
            $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']);
+           my $conf = PVE::QemuConfig->load_config($vmid);
+
+           # cannot save the state of a non-virtualized PCIe device, so resume cannot really work
+           for my $key (keys %$conf) {
+               next if $key !~ /^hostpci\d+/;
+               die "cannot suspend VM to disk due to passed-through PCI device(s), which lack the"
+                   ." possibility to save/restore their internal state\n";
+           }
 
            if (!$statestorage) {
                # get statestorage from config if none is given
-               my $conf = PVE::QemuConfig->load_config($vmid);
                my $storecfg = PVE::Storage::config();
                $statestorage = PVE::QemuServer::find_vmstate_storage($conf, $storecfg);
            }
@@ -3879,6 +3906,13 @@ __PACKAGE__->register_method({
 
                    $drive->{file} = $new_volid;
 
+                   my $boot_order = PVE::QemuServer::device_bootorder($source_conf);
+                   if (defined(delete $boot_order->{$disk})) {
+                       print "removing disk '$disk' from boot order config\n";
+                       my $boot_devs = [ sort { $boot_order->{$a} <=> $boot_order->{$b} } keys %$boot_order ];
+                       $source_conf->{boot} = PVE::QemuServer::print_bootorder($boot_devs);
+                   }
+
                    delete $source_conf->{$disk};
                    print "removing disk '${disk}' from VM '${vmid}' config\n";
                    PVE::QemuConfig->write_config($vmid, $source_conf);