mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
Networks, Interfaces, Storages, Storage, Volume, MigrateInstance and CreateInstance were unmanaged models with no table, there only so that ModelSerializers and the new VM ModelForm could take their fields. They made content types and migrations, and their DO_NOTHING foreign keys added reverse accessors that meant nothing (Compute.host, Compute.target_host, Instance.source_host). The serializers are plain Serializers and NewVMForm a Form, field for field as the models gave them (types, lengths, required, defaults, the minimum of 1 for vCPUs, memory and disk size; the form's labels are still derived from the field names). Compared field by field before and after, the API schema changes only where the models were wrong: - no int64 bounds on the listing fields; - the interface fields lose the titles that named the wrong column (type was "Status", state "Device", mac "Forward"); - a pool's volumes is a list of objects (it was described as an integer) and a volume's allocation an integer (it was untyped). One migration per app deletes the models; none touches a table.
125 lines
4.7 KiB
Python
125 lines
4.7 KiB
Python
from computes.models import Compute
|
|
from django.conf import settings
|
|
from instances.models import Flavor, Instance
|
|
from instances.utils import nic_macs
|
|
from rest_framework import serializers
|
|
|
|
|
|
class InstanceSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Instance
|
|
fields = ["id", "compute", "name", "uuid", "is_template", "created", "drbd"]
|
|
|
|
|
|
class InstanceDetailsSerializer(serializers.ModelSerializer):
|
|
def get_fields(self):
|
|
fields = super().get_fields()
|
|
# the host's ISO images are a superuser's, as on the VM page
|
|
request = self.context.get("request")
|
|
if not (request and request.user.is_superuser):
|
|
del fields["media_iso"]
|
|
return fields
|
|
|
|
class Meta:
|
|
model = Instance
|
|
fields = [
|
|
"id",
|
|
"compute",
|
|
"status",
|
|
"uuid",
|
|
"name",
|
|
"title",
|
|
"description",
|
|
"is_template",
|
|
"created",
|
|
"drbd",
|
|
"arch",
|
|
"machine",
|
|
"vcpu",
|
|
"memory",
|
|
"firmware",
|
|
"nvram",
|
|
"bootmenu",
|
|
"boot_order",
|
|
"disks",
|
|
"media",
|
|
"media_iso",
|
|
"snapshots",
|
|
"networks",
|
|
"console_type",
|
|
"console_port",
|
|
"console_keymap",
|
|
"console_listener_address",
|
|
"video_model",
|
|
"guest_agent_ready",
|
|
"autostart",
|
|
]
|
|
|
|
|
|
class FlavorSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Flavor
|
|
fields = ["id", "label", "memory", "vcpu", "disk"]
|
|
# as the web form (instances.forms.FlavorForm): MiB, vCPUs and GiB, each at least 1
|
|
extra_kwargs = {"memory": {"min_value": 1}, "vcpu": {"min_value": 1}, "disk": {"min_value": 1}}
|
|
|
|
|
|
class DestroyOptionsSerializer(serializers.Serializer):
|
|
"""What a VM's delete takes besides the VM: from the web form's checkboxes
|
|
or an API body, JSON or form-encoded ("false" is false)."""
|
|
|
|
delete_disk = serializers.BooleanField(default=False)
|
|
delete_nvram = serializers.BooleanField(default=False)
|
|
|
|
|
|
class DestroySerializer(DestroyOptionsSerializer):
|
|
"""The API's delete: a job, which a new submission key per request names."""
|
|
|
|
submission_key = serializers.CharField(write_only=True)
|
|
|
|
|
|
class CreateInstanceSerializer(serializers.Serializer):
|
|
"""The API's VM create: the new VM form's fields, as a job."""
|
|
|
|
name = serializers.CharField(max_length=64)
|
|
# BIOS, UEFI or UEFI Secure Boot, as the host offers; left out: the machine's default
|
|
firmware = serializers.CharField(required=False)
|
|
tpm = serializers.BooleanField(required=False)
|
|
vcpu = serializers.IntegerField(min_value=1)
|
|
vcpu_mode = serializers.CharField(max_length=64)
|
|
memory = serializers.IntegerField(min_value=1)
|
|
networks = serializers.CharField(max_length=256)
|
|
mac = serializers.CharField(allow_blank=True, max_length=255, required=False)
|
|
nwfilter = serializers.CharField(allow_blank=True, max_length=256, required=False)
|
|
storage = serializers.CharField(initial="default")
|
|
hdd_size = serializers.IntegerField(min_value=1, required=False)
|
|
cache_mode = serializers.CharField(initial="none")
|
|
meta_prealloc = serializers.BooleanField(required=False)
|
|
virtio = serializers.BooleanField(initial=True)
|
|
qemu_ga = serializers.BooleanField(initial=True)
|
|
cloud_init = serializers.BooleanField(required=False)
|
|
video = serializers.CharField(initial="vga")
|
|
listener_addr = serializers.ChoiceField(choices=settings.QEMU_CONSOLE_LISTENER_ADDRESSES)
|
|
submission_key = serializers.CharField(write_only=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 MigrateSerializer(serializers.Serializer):
|
|
instance = serializers.PrimaryKeyRelatedField(queryset=Instance.objects.all())
|
|
target_compute = serializers.PrimaryKeyRelatedField(queryset=Compute.objects.all())
|
|
live = serializers.BooleanField(default=True)
|
|
offline = serializers.BooleanField(default=False)
|
|
# left out, also from a form-encoded request: auto converge on
|
|
autoconverge = serializers.BooleanField(default=True)
|
|
compress = serializers.BooleanField(default=False)
|
|
unsafe = serializers.BooleanField(default=False)
|
|
# {target: pool of the destination} of the disks copied there; delete_source deletes their source files
|
|
disk_pools = serializers.DictField(child=serializers.CharField(allow_blank=True), default=dict)
|
|
delete_source = serializers.BooleanField(default=False)
|
|
submission_key = serializers.CharField(write_only=True)
|