diff --git a/appsettings/migrations/0022_cpu_mode_choices.py b/appsettings/migrations/0022_cpu_mode_choices.py
new file mode 100644
index 00000000..d1e3d980
--- /dev/null
+++ b/appsettings/migrations/0022_cpu_mode_choices.py
@@ -0,0 +1,25 @@
+from django.db import migrations
+
+CHOICES = "host-model,host-passthrough,maximum"
+
+
+def fix_cpu_mode(apps, schema_editor):
+ """The CPU modes a new VM can have: no-model and custom matched no choice
+ of the new VM dialog, which then showed another one. Not undone on the way
+ back, as nothing needs the old choices."""
+ AppSettings = apps.get_model("appsettings", "AppSettings")
+ for setting in AppSettings.objects.using(schema_editor.connection.alias).filter(key="INSTANCE_CPU_DEFAULT_MODE"):
+ setting.choices = CHOICES
+ if setting.value not in CHOICES.split(","):
+ setting.value = "host-model"
+ setting.save()
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("appsettings", "0021_setting_descriptions"),
+ ]
+
+ operations = [
+ migrations.RunPython(fix_cpu_mode, migrations.RunPython.noop),
+ ]
diff --git a/appsettings/tests/test_migrations.py b/appsettings/tests/test_migrations.py
index 98cf4f5a..30f0829f 100644
--- a/appsettings/tests/test_migrations.py
+++ b/appsettings/tests/test_migrations.py
@@ -99,3 +99,17 @@ class DescriptionsTestCase(TestCase):
with self.subTest(key=key):
self.assertLessEqual(len(text), limit)
self.assertEqual(AppSettings.objects.get(key=key).description, text)
+
+
+cpu_mode = importlib.import_module("appsettings.migrations.0022_cpu_mode_choices")
+
+
+class CpuModeChoicesTestCase(TestCase):
+ def test_the_default_cpu_mode_is_one_the_new_vm_dialog_offers(self):
+ for old, new in (("no-model", "host-model"), ("custom", "host-model"), ("host-passthrough", "host-passthrough")):
+ with self.subTest(old=old):
+ AppSettings.objects.filter(key="INSTANCE_CPU_DEFAULT_MODE").update(
+ value=old, choices="no-model,host-model,host-passthrough,custom")
+ cpu_mode.fix_cpu_mode(apps, SimpleNamespace(connection=connection))
+ setting = AppSettings.objects.get(key="INSTANCE_CPU_DEFAULT_MODE")
+ self.assertEqual((setting.value, setting.choices), (new, "host-model,host-passthrough,maximum"))
diff --git a/instances/forms.py b/instances/forms.py
index ba9247e3..010a26e3 100644
--- a/instances/forms.py
+++ b/instances/forms.py
@@ -67,7 +67,6 @@ class NewVMForm(forms.ModelForm):
# name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=64)
# firmware = forms.CharField(max_length=50, required=False)
# vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')})
- # vcpu_mode = forms.CharField(max_length=20, required=False)
# disk = forms.IntegerField(required=False)
# memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')})
# networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')})
diff --git a/instances/jobs.py b/instances/jobs.py
index a6ac5090..7bb72489 100644
--- a/instances/jobs.py
+++ b/instances/jobs.py
@@ -13,7 +13,7 @@ from libvirt import (VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE, VIR_DOMAIN_JOB_NONE,
VIR_ERR_NO_DOMAIN, VIR_ERR_NO_STORAGE_VOL, libvirtError)
from vrtManager import util
from vrtManager.connection import wvmConnect
-from vrtManager.create import wvmCreate
+from vrtManager.create import cpu_choices, wvmCreate
from vrtManager.instance import check_snapshot_name, wvmInstance
from accounts.models import UserInstance, UserSSHKey
@@ -665,6 +665,8 @@ class CreateInstance(Kind):
raise util.OperationError(_("Image has already exist. Please check volumes or change instance name"))
if data["cache_mode"] not in conn.get_cache_modes():
raise util.OperationError(_("Invalid cache mode"))
+ if data["vcpu_mode"] not in cpu_choices(conn.get_dom_capabilities(data["arch"], data["machine"])):
+ raise util.OperationError(_("This host offers no CPU mode or model %(mode)s") % {"mode": data["vcpu_mode"]})
if data["add_cdrom"] != "None" and data["add_cdrom"] not in cdrom_buses:
raise util.OperationError(_("A CD-ROM cannot use the %(bus)s bus") % {"bus": data["add_cdrom"]})
if data["cloud_init"]:
diff --git a/instances/models.py b/instances/models.py
index 02c5083c..5f55aeda 100644
--- a/instances/models.py
+++ b/instances/models.py
@@ -352,7 +352,8 @@ class CreateInstance(models.Model):
vcpu = models.IntegerField(
error_messages={"required": _("No VCPU has been entered")}, validators=[MinValueValidator(1)]
)
- vcpu_mode = models.CharField(max_length=20, blank=True)
+ # a mode of libvirt's (host-model, host-passthrough, maximum) or a CPU model's name
+ vcpu_mode = models.CharField(max_length=64)
disk = models.IntegerField(blank=True)
memory = models.IntegerField(
error_messages={"required": _("No RAM size has been entered")}, validators=[MinValueValidator(1)]
diff --git a/instances/templates/create_instance_w2.html b/instances/templates/create_instance_w2.html
index 23f066b6..62ea9694 100644
--- a/instances/templates/create_instance_w2.html
+++ b/instances/templates/create_instance_w2.html
@@ -82,8 +82,8 @@
{% if dom_caps.cpu_modes %}
-