diff --git a/Dockerfile b/Dockerfile index 4f57585..d6b95ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,6 +41,7 @@ RUN python3 -m venv venv && \ chown -R www-data:www-data /srv/webvirtcloud RUN . venv/bin/activate && \ + python3 manage.py makemigrations && \ python3 manage.py migrate && \ python3 manage.py collectstatic --noinput && \ chown -R www-data:www-data /srv/webvirtcloud diff --git a/admin/__init__.py b/admin/__init__.py index b7f8a6a..052dc42 100644 --- a/admin/__init__.py +++ b/admin/__init__.py @@ -1 +1 @@ -defautl_app_config = 'admin.apps.AdminConfig' +default_app_config = 'admin.apps.AdminConfig' diff --git a/appsettings/migrations/0006_auto_20220630_0717.py b/appsettings/migrations/0006_auto_20220630_0717.py index b9d9871..9ffc860 100644 --- a/appsettings/migrations/0006_auto_20220630_0717.py +++ b/appsettings/migrations/0006_auto_20220630_0717.py @@ -24,5 +24,5 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(add_default_settings, del_default_settings), + migrations.RunPython(add_default_settings, del_default_settings), ] diff --git a/appsettings/migrations/0007_auto_20220905_0918.py b/appsettings/migrations/0007_auto_20220905_0918.py new file mode 100644 index 0000000..229e1cb --- /dev/null +++ b/appsettings/migrations/0007_auto_20220905_0918.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.13 on 2022-06-30 07:17 + +from django.db import migrations +from django.utils.translation import gettext_lazy as _ + +def update_default_settings(apps, schema_editor): + setting = apps.get_model("appsettings", "AppSettings") + db_alias = schema_editor.connection.alias + setting.objects.using(db_alias).filter(key="INSTANCE_MACHINE_DEFAULT_TYPE").update(choices="q35,x86_64,virt"), + setting.objects.using(db_alias).filter(key="INSTANCE_ARCH_DEFAULT_TYPE").update(choices="x86_64,i686,aarch64"), + + +class Migration(migrations.Migration): + + dependencies = [ + ('appsettings', '0006_auto_20220630_0717'), + ] + + operations = [ + migrations.RunPython(update_default_settings, None) + ] diff --git a/appsettings/migrations/0008_auto_20220905_1459.py b/appsettings/migrations/0008_auto_20220905_1459.py new file mode 100644 index 0000000..2390d5d --- /dev/null +++ b/appsettings/migrations/0008_auto_20220905_1459.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.13 on 2022-06-30 07:17 + +from django.db import migrations +from django.utils.translation import gettext_lazy as _ + +def add_default_settings(apps, schema_editor): + setting = apps.get_model("appsettings", "AppSettings") + db_alias = schema_editor.connection.alias + setting.objects.using(db_alias).bulk_create([ + setting(32, _("VM CD-ROM Device"), "INSTANCE_CDROM_ADD", "sata", "None,ide,sata,scsi,virtio", _("Add or not cdrom device while instance creating")), + setting(33, _("VM Video Type"), "INSTANCE_VIDEO_DEFAULT_TYPE", "vga", "None,virtio,vga,cirrus,vmvga,bochs,ramfb", _("Change instance default video type")), + setting(34, _("VM Input Device"), "INSTANCE_INPUT_DEFAULT_DEVICE", "default", "None,default,virtio,usb", _("Add or not input device with specify its type")), + ]) + + +def del_default_settings(apps, schema_editor): + setting = apps.get_model("appsettings", "AppSettings") + db_alias = schema_editor.connection.alias + setting.objects.using(db_alias).filter(key="INSTANCE_CDROM_ADD").delete() + setting.objects.using(db_alias).filter(key="INSTANCE_VIDEO_DEFAULT_TYPE").delete() + setting.objects.using(db_alias).filter(key="INSTANCE_INPUT_DEFAULT_DEVICE").delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('appsettings', '0007_auto_20220905_0918'), + ] + + operations = [ + migrations.RunPython(add_default_settings, del_default_settings), + ] diff --git a/instances/api/viewsets.py b/instances/api/viewsets.py index 4960f07..1fb06bb 100644 --- a/instances/api/viewsets.py +++ b/instances/api/viewsets.py @@ -199,24 +199,24 @@ class CreateInstanceViewSet(viewsets.ViewSet): firmware["secure"] = "yes" ret = conn.create_instance( - serializer.validated_data['name'], - serializer.validated_data['memory'], - serializer.validated_data['vcpu'], - serializer.validated_data['vcpu_mode'], - util.randomUUID(), - arch, - machine, - firmware, - volume_list, - serializer.validated_data['networks'], - serializer.validated_data['nwfilter'], - serializer.validated_data['graphics'], - serializer.validated_data['virtio'], - serializer.validated_data['listener_addr'], - serializer.validated_data['video'], - serializer.validated_data['console_pass'], - serializer.validated_data['mac'], - serializer.validated_data['qemu_ga'], + name=serializer.validated_data['name'], + memory=serializer.validated_data['memory'], + vcpu=serializer.validated_data['vcpu'], + vcpu_mode=serializer.validated_data['vcpu_mode'], + uuid=util.randomUUID(), + arch=arch, + machine=machine, + firmware=firmware, + volumes=volume_list, + networks=serializer.validated_data['networks'], + nwfilter=serializer.validated_data['nwfilter'], + graphics=serializer.validated_data['graphics'], + virtio=serializer.validated_data['virtio'], + listener_addr=serializer.validated_data['listener_addr'], + video=serializer.validated_data['video'], + console_pass=serializer.validated_data['console_pass'], + mac=serializer.validated_data['mac'], + qemu_ga=serializer.validated_data['qemu_ga'], ) msg = f"Instance {serializer.validated_data['name']} is created" return Response({'status': msg }) diff --git a/instances/models.py b/instances/models.py index fa18483..222f886 100644 --- a/instances/models.py +++ b/instances/models.py @@ -3,7 +3,6 @@ from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from libvirt import VIR_DOMAIN_XML_SECURE -from vrtManager.create import wvmCreate from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES from computes.models import Compute @@ -228,7 +227,7 @@ class MigrateInstance(models.Model): class CreateInstance(models.Model): compute = models.ForeignKey(Compute, related_name='host', on_delete=models.DO_NOTHING) name = models.CharField(max_length=64, error_messages={'required': _('No Virtual Machine name has been entered')}) - firmware = models.CharField(max_length=50) + firmware = models.CharField(max_length=64) vcpu = models.IntegerField(error_messages={'required': _('No VCPU has been entered')}) vcpu_mode = models.CharField(max_length=20, blank=True) disk = models.IntegerField(blank=True) @@ -238,15 +237,17 @@ class CreateInstance(models.Model): storage = models.CharField(max_length=256, blank=True) template = models.CharField(max_length=256, blank=True) images = models.CharField(max_length=256, blank=True) - cache_mode = models.CharField(max_length=12, error_messages={'required': _('Please select HDD cache mode')}) + cache_mode = models.CharField(max_length=16, error_messages={'required': _('Please select HDD cache mode')}) hdd_size = models.IntegerField(blank=True) meta_prealloc = models.BooleanField(default=False, blank=True) virtio = models.BooleanField(default=True) qemu_ga = models.BooleanField(default=False) mac = models.CharField(max_length=17, blank=True) console_pass = models.CharField(max_length=64, blank=True) - graphics = models.CharField(max_length=12, error_messages={'required': _('Please select a graphics type')}) - video = models.CharField(max_length=12, error_messages={'required': _('Please select a video driver')}) + add_cdrom = models.CharField(max_length=16) + add_input = models.CharField(max_length=16) + graphics = models.CharField(max_length=16, error_messages={'required': _('Please select a graphics type')}) + video = models.CharField(max_length=16, error_messages={'required': _('Please select a video driver')}) listener_addr = models.CharField(max_length=20, choices=QEMU_CONSOLE_LISTENER_ADDRESSES) class Meta: diff --git a/instances/templates/create_instance_w2.html b/instances/templates/create_instance_w2.html index f71328a..d26b2a6 100644 --- a/instances/templates/create_instance_w2.html +++ b/instances/templates/create_instance_w2.html @@ -227,7 +227,7 @@ {% endif %} {% for video in videos %} - + {% endfor %} @@ -248,6 +248,32 @@ +
+ +
+ +
+
+
+ +
+ +
+
@@ -478,6 +504,32 @@
+
+ +
+ +
+
+
+ +
+ +
+
@@ -694,6 +746,32 @@
+
+ +
+ +
+
+
+ +
+ +
+
diff --git a/instances/views.py b/instances/views.py index 1c97523..fc04ee4 100644 --- a/instances/views.py +++ b/instances/views.py @@ -1376,6 +1376,7 @@ def create_instance(request, compute_id, arch, machine): default_cpu_mode = app_settings.INSTANCE_CPU_DEFAULT_MODE instances = conn.get_instances() videos = conn.get_video_models(arch, machine) + default_video = app_settings.INSTANCE_VIDEO_DEFAULT_TYPE cache_modes = sorted(conn.get_cache_modes().items()) default_cache = app_settings.INSTANCE_VOLUME_DEFAULT_CACHE default_io = app_settings.INSTANCE_VOLUME_DEFAULT_IO @@ -1394,6 +1395,9 @@ def create_instance(request, compute_id, arch, machine): nwfilters = conn.get_nwfilters() storages = sorted(conn.get_storages(only_actives=True)) default_graphics = app_settings.QEMU_CONSOLE_DEFAULT_TYPE + default_cdrom = app_settings.INSTANCE_CDROM_ADD + input_device_buses = ['default', 'virtio', 'usb'] + default_input_device_bus = app_settings.INSTANCE_INPUT_DEFAULT_DEVICE dom_caps = conn.get_dom_capabilities(arch, machine) caps = conn.get_capabilities(arch) @@ -1552,6 +1556,8 @@ def create_instance(request, compute_id, arch, machine): console_pass=data["console_pass"], mac=data["mac"], qemu_ga=data["qemu_ga"], + add_cdrom=data["add_cdrom"], + add_input=data["add_input"], ) create_instance = Instance(compute_id=compute_id, name=data["name"], uuid=uuid) create_instance.save() diff --git a/vrtManager/create.py b/vrtManager/create.py index 0044fe0..63a8f7a 100644 --- a/vrtManager/create.py +++ b/vrtManager/create.py @@ -165,6 +165,8 @@ class wvmCreate(wvmConnect): console_pass="random", mac=None, qemu_ga=True, + add_cdrom="sata", + add_input="default" ): """ Create VM function @@ -233,10 +235,20 @@ class wvmCreate(wvmConnect): fd_disk_letters = list(string.ascii_lowercase) hd_disk_letters = list(string.ascii_lowercase) sd_disk_letters = list(string.ascii_lowercase) - add_cd = True + def get_letter(bus_type): + if bus_type == "ide": + return hd_disk_letters.pop(0) + elif bus_type in ["sata", "scsi"]: + return sd_disk_letters.pop(0) + elif bus_type == "fdc": + return fd_disk_letters.pop(0) + elif bus_type == "virtio": + return vd_disk_letters.pop(0) + else: + return sd_disk_letters.pop(0) + for volume in volumes: - disk_opts = "" if volume["cache_mode"] is not None and volume["cache_mode"] != "default": disk_opts += f"cache='{volume['cache_mode']}' " @@ -251,7 +263,7 @@ class wvmCreate(wvmConnect): stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if volume["device"] == "cdrom": - add_cd = False + add_cdrom = "None" if stg_type == "rbd": ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) @@ -274,34 +286,24 @@ class wvmCreate(wvmConnect): xml += f""" """ xml += f""" """ - if volume.get("bus") == "virtio": - xml += """""" % (vd_disk_letters.pop(0), volume.get("bus")) - elif volume.get("bus") == "ide": - xml += """""" % (hd_disk_letters.pop(0), volume.get("bus")) - elif volume.get("bus") == "fdc": - xml += """""" % (fd_disk_letters.pop(0), volume.get("bus")) - elif volume.get("bus") in ["sata", "scsi"]: - xml += """""" % (sd_disk_letters.pop(0), volume.get("bus")) + if volume.get("bus") in dom_caps["disk_bus"]: + dev_prefix = util.vol_dev_type(volume.get("bus")) + xml += """""" % (dev_prefix, get_letter(volume.get("bus")), volume.get("bus")) else: - xml += """""" % sd_disk_letters.pop(0) + xml += """""" % get_letter("sata") xml += """""" if volume.get("bus") == "scsi": xml += f"""""" - if add_cd: + if add_cdrom != "None": xml += """ """ - if "ide" in dom_caps["disk_bus"]: - xml += """""" % (hd_disk_letters.pop(0), "ide") - elif "sata" in dom_caps["disk_bus"]: - xml += """""" % (sd_disk_letters.pop(0), "sata") - elif "scsi" in dom_caps["disk_bus"]: - xml += """""" % (sd_disk_letters.pop(0), "scsi") - else: - xml += """""" % (vd_disk_letters.pop(0), "virtio") + if add_cdrom in dom_caps["disk_bus"]: + dev_prefix = util.vol_dev_type(add_cdrom) + xml += """""" % (dev_prefix, get_letter(add_cdrom), add_cdrom) xml += """""" if mac: @@ -322,14 +324,16 @@ class wvmCreate(wvmConnect): elif console_pass != "": console_pass = "passwd='" + console_pass + "'" - if "usb" in dom_caps["disk_bus"]: - xml += f"""""" - xml += f"""""" - xml += f"""""" - else: - xml += """""" - xml += """""" - xml += """""" + if add_input != "None": + xml += """""" + if add_input in dom_caps["disk_bus"]: + xml += f"""""" + xml += f"""""" + xml += f"""""" + else: + xml += """""" + xml += """""" + xml += """""" xml += f""" diff --git a/vrtManager/util.py b/vrtManager/util.py index d618896..ab47f32 100644 --- a/vrtManager/util.py +++ b/vrtManager/util.py @@ -182,3 +182,15 @@ UEFI_ARCH_PATTERNS = { r".*arm/QEMU_EFI.*", # fedora, gerd's firmware repo ], } + + +def vol_dev_type(vol_bus): + if vol_bus == "ide": + return "hd" + elif vol_bus == "fdc": + return "fd" + elif vol_bus == "virtio": + return "vd" + elif vol_bus in ["scsi", "sata"]: + return "sd" +