from django.db import models 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 from vrtManager.instance import wvmInstance class Flavor(models.Model): label = models.CharField(_('label'), max_length=12, unique=True) memory = models.IntegerField(_('memory')) vcpu = models.IntegerField(_('vcpu')) disk = models.IntegerField(_('disk')) def __str__(self): return self.label class InstanceManager(models.Manager): def get_queryset(self): return super().get_queryset().select_related('compute') class Instance(models.Model): compute = models.ForeignKey(Compute, on_delete=models.CASCADE) name = models.CharField(_('name'), max_length=120, db_index=True) uuid = models.CharField(_('uuid'), max_length=36, db_index=True) is_template = models.BooleanField(_('is template'), default=False) created = models.DateTimeField(_('created'), auto_now_add=True) drbd = models.CharField(_('drbd'), max_length=24, default="None") objects = InstanceManager() def __str__(self): return f'{self.compute}/{self.name}' @cached_property def proxy(self): return wvmInstance( self.compute.hostname, self.compute.login, self.compute.password, self.compute.type, self.name, ) @cached_property def media(self): return self.proxy.get_media_devices() @cached_property def media_iso(self): return sorted(self.proxy.get_iso_media()) @cached_property def disks(self): return self.proxy.get_disk_devices() @cached_property def status(self): return self.proxy.get_status() @cached_property def autostart(self): return self.proxy.get_autostart() @cached_property def bootmenu(self): return self.proxy.get_bootmenu() @cached_property def boot_order(self): return self.proxy.get_bootorder() @cached_property def arch(self): return self.proxy.get_arch() @cached_property def machine(self): return self.proxy.get_machine_type() @cached_property def firmware(self): return self.proxy.get_loader() @cached_property def nvram(self): return self.proxy.get_nvram() @cached_property def vcpu(self): return self.proxy.get_vcpu() @cached_property def vcpu_range(self): return self.proxy.get_max_cpus() @cached_property def cur_vcpu(self): return self.proxy.get_cur_vcpu() @cached_property def vcpus(self): return self.proxy.get_vcpus() @cached_property def get_uuid(self): return self.proxy.get_uuid() @cached_property def memory(self): return self.proxy.get_memory() @cached_property def cur_memory(self): return self.proxy.get_cur_memory() @cached_property def title(self): return self.proxy.get_title() @cached_property def description(self): return self.proxy.get_description() @cached_property def networks(self): return self.proxy.get_net_devices() @cached_property def qos(self): return self.proxy.get_all_qos() @cached_property def telnet_port(self): return self.proxy.get_telnet_port() @cached_property def console_type(self): return self.proxy.get_console_type() @cached_property def console_port(self): return self.proxy.get_console_port() @cached_property def console_keymap(self): return self.proxy.get_console_keymap() @cached_property def console_listener_address(self): return self.proxy.get_console_listener_addr() @cached_property def guest_agent(self): return False if self.proxy.get_guest_agent() is None else True @cached_property def guest_agent_ready(self): return self.proxy.is_agent_ready() @cached_property def video_model(self): return self.proxy.get_video_model() @cached_property def video_models(self): return self.proxy.get_video_models(self.arch, self.machine) @cached_property def snapshots(self): return sorted(self.proxy.get_snapshot(), reverse=True, key=lambda k: k['date']) @cached_property def inst_xml(self): return self.proxy._XMLDesc(VIR_DOMAIN_XML_SECURE) @cached_property def has_managed_save_image(self): return self.proxy.get_managed_save_image() @cached_property def console_passwd(self): return self.proxy.get_console_passwd() @cached_property def cache_modes(self): return sorted(self.proxy.get_cache_modes().items()) @cached_property def io_modes(self): return sorted(self.proxy.get_io_modes().items()) @cached_property def discard_modes(self): return sorted(self.proxy.get_discard_modes().items()) @cached_property def detect_zeroes_modes(self): return sorted(self.proxy.get_detect_zeroes_modes().items()) @cached_property def formats(self): return self.proxy.get_image_formats() class MigrateInstance(models.Model): instance = models.ForeignKey(Instance, related_name='source_host', on_delete=models.DO_NOTHING) target_compute = models.ForeignKey(Compute, related_name='target_host', on_delete=models.DO_NOTHING) live = models.BooleanField(_('Live')) xml_del = models.BooleanField(_('Undefine XML'), default=True) offline = models.BooleanField(_('Offline')) autoconverge = models.BooleanField(_('Auto Converge'), default=True) compress = models.BooleanField(_('Compress'), default=False) postcopy = models.BooleanField(_('Post Copy'), default=False) unsafe = models.BooleanField(_('Unsafe'), default=False) class Meta: managed = False 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) 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) memory = models.IntegerField(error_messages={'required': _('No RAM size has been entered')}) networks = models.CharField(max_length=256, error_messages={'required': _('No Network pool has been choosen')}) nwfilter = models.CharField(max_length=256, blank=True) 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')}) 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')}) listener_addr = models.CharField(max_length=20, choices=QEMU_CONSOLE_LISTENER_ADDRESSES) class Meta: managed = False class PermissionSet(models.Model): """ Dummy model for holding set of permissions we need to be automatically added by Django """ class Meta: default_permissions = () permissions = [ ('clone_instances', 'Can clone instances'), ('passwordless_console', _('Can access console without password')), ('view_instances', 'Can view instances'), ('snapshot_instances', 'Can snapshot instances'), ] managed = False