import json import uncloud.secrets as secrets from django.core.management.base import BaseCommand from django.contrib.auth import get_user_model from uncloud_vm.models import VMSnapshotProduct, VMProduct, VMHost from datetime import datetime class Command(BaseCommand): help = 'Select VM Host for VMs' def add_arguments(self, parser): parser.add_argument('--this-hostname', required=True) parser.add_argument('--this-cluster', required=True) parser.add_argument('--create-vm-snapshots', action='store_true') parser.add_argument('--schedule-vms', action='store_true') parser.add_argument('--start-vms', action='store_true') def handle(self, *args, **options): for cmd in [ 'create_vm_snapshots', 'schedule_vms', 'start_vms' ]: if options[cmd]: f = getattr(self, cmd) f(args, options) def schedule_vms(self, *args, **options): for pending_vm in VMProduct.objects.filter(status='PENDING'): cores_needed = pending_vm.cores ram_needed = pending_vm.ram_in_gb # Database filtering possible_vmhosts = VMHost.objects.filter(physical_cores__gte=cores_needed) # Logical filtering possible_vmhosts = [ vmhost for vmhost in possible_vmhosts if vmhost.available_cores >=cores_needed and vmhost.available_ram_in_gb >= ram_needed ] if not possible_vmhosts: log.error("No suitable Host found - cannot schedule VM {}".format(pending_vm)) continue vmhost = possible_vmhosts[0] pending_vm.vmhost = vmhost pending_vm.status = 'SCHEDULED' pending_vm.save() print("Scheduled VM {} on VMHOST {}".format(pending_vm, pending_vm.vmhost)) print(self) def start_vms(self, *args, **options): vmhost = VMHost.objects.get(hostname=options['this_hostname']) if not vmhost: raise Exception("No vmhost {} exists".format(options['vmhostname'])) # not active? done here if not vmhost.status = 'ACTIVE': return vms_to_start = VMProduct.objects.filter(vmhost=vmhost, status='SCHEDULED') for vm in vms_to_start: """ run qemu: check if VM is not already active / qemu running prepare / create the Qemu arguments """ print("Starting VM {}".format(VM)) def check_vms(self, *args, **options): """ Check if all VMs that are supposed to run are running """ def modify_vms(self, *args, **options): """ Check all VMs that are requested to be modified and restart them """ def create_vm_snapshots(self, *args, **options): this_cluster = VMCluster(option['this_cluster']) for snapshot in VMSnapshotProduct.objects.filter(status='PENDING', cluster=this_cluster): if not snapshot.extra_data: snapshot.extra_data = {} # TODO: implement locking here if 'creating_hostname' in snapshot.extra_data: pass snapshot.extra_data['creating_hostname'] = options['this_hostname'] snapshot.extra_data['creating_start'] = str(datetime.now()) snapshot.save() # something on the line of: # for disk im vm.disks: # rbd snap create pool/image-name@snapshot name # snapshot.extra_data['snapshots'] # register the snapshot names in extra_data (?) print(snapshot) def check_health(self, *args, **options): pending_vms = VMProduct.objects.filter(status='PENDING') vmhosts = VMHost.objects.filter(status='active') # 1. Check that all active hosts reported back N seconds ago # 2. Check that no VM is running on a dead host # 3. Migrate VMs if necessary # 4. Check that no VMs have been pending for longer than Y seconds # If VM snapshots exist without a VM -> notify user (?) print("Nothing is good, you should implement me")