From 03ac93ea53b449b56e1ecbdbe65866c6459665e7 Mon Sep 17 00:00:00 2001 From: catborise Date: Sun, 4 Oct 2026 18:33:28 +0300 Subject: [PATCH] fix(instances): CD-ROM bus, USB controller and MACs of a new VM Creating each option on a RHEL qemu-kvm host showed: - CD-ROM: the create page offered every disk bus, but the empty CD-ROM of a new VM works only on ide, sata and scsi. fdc and virtio failed ("Invalid bus type", "does not support ejectable media"), usb failed with a device named 'Nonea' because vol_dev_type() had no prefix for usb, and after that libvirt refuses an empty usb disk. Only ide, sata and scsi are offered now, and another value is refused before any storage is allocated. vol_dev_type() names usb disks sdX, which also fixes data volumes on the usb bus. - USB controller: any input device added a bare , which libvirt turns into piix3-uhci (USB 1.1) on q35 instead of its default qemu-xhci. The bare controller is gone; libvirt adds the machine's default for USB inputs. - MACs: with more networks than MAC addresses, create_instance indexed past the list and the request failed with a 500. NICs without a given MAC now get one from libvirt. MAC addresses are validated (format, not more than networks) by the page and the API before anything is created; they went into the XML unchecked. Unit tests cover the refused values, the MAC rule and the usb prefix. Live tests create a VM with every offered CD-ROM bus and start it, check the USB controller with a USB input device and create a VM with two networks and one MAC. --- instances/api/serializers.py | 8 +++ instances/templates/create_instance_w2.html | 6 +- instances/test_create_instance.py | 75 ++++++++++++++++----- instances/test_live_create.py | 24 +++++++ instances/utils.py | 14 ++++ instances/views.py | 15 ++++- vrtManager/create.py | 11 +-- vrtManager/test_util.py | 1 + vrtManager/util.py | 2 +- 9 files changed, 130 insertions(+), 26 deletions(-) diff --git a/instances/api/serializers.py b/instances/api/serializers.py index 999cfa03..5c2847c8 100644 --- a/instances/api/serializers.py +++ b/instances/api/serializers.py @@ -1,4 +1,5 @@ from instances.models import CreateInstance, Flavor, Instance, MigrateInstance +from instances.utils import nic_macs from rest_framework import serializers @@ -58,6 +59,13 @@ class CreateInstanceSerializer(serializers.ModelSerializer): virtio = serializers.BooleanField(initial=True) qemu_ga = serializers.BooleanField(initial=True) + def validate(self, attrs): + try: + nic_macs(attrs.get("mac"), attrs.get("networks", "")) + except ValueError as err: + raise serializers.ValidationError({"mac": str(err)}) + return attrs + class Meta: model = CreateInstance fields = [ diff --git a/instances/templates/create_instance_w2.html b/instances/templates/create_instance_w2.html index e70260c3..648f8341 100644 --- a/instances/templates/create_instance_w2.html +++ b/instances/templates/create_instance_w2.html @@ -251,7 +251,7 @@
- {% for bus in disk_buses %} + {% for bus in cdrom_buses %} @@ -744,7 +744,7 @@
""" xml += f"""""" diff --git a/vrtManager/test_util.py b/vrtManager/test_util.py index fb174231..b1279563 100644 --- a/vrtManager/test_util.py +++ b/vrtManager/test_util.py @@ -123,6 +123,7 @@ class TestVrtManagerUtil(unittest.TestCase): self.assertEqual(vol_dev_type("ide"), "hd") self.assertEqual(vol_dev_type("fdc"), "fd") self.assertEqual(vol_dev_type("virtio"), "vd") + self.assertEqual(vol_dev_type("usb"), "sd") self.assertEqual(vol_dev_type("scsi"), "sd") self.assertEqual(vol_dev_type("sata"), "sd") self.assertIsNone(vol_dev_type("unknown_bus")) diff --git a/vrtManager/util.py b/vrtManager/util.py index 26ca01f9..de32a1d3 100644 --- a/vrtManager/util.py +++ b/vrtManager/util.py @@ -208,6 +208,6 @@ def vol_dev_type(vol_bus): return "fd" elif vol_bus == "virtio": return "vd" - elif vol_bus in ["scsi", "sata"]: + elif vol_bus in ["scsi", "sata", "usb"]: return "sd"