def template_to_instance(template, hostname, owner): """ Instantiate a VM template with a given hostname and owner. """ cluster = template.cluster beparams = { "vcpus": template.vcpus, } memory = template.memory if has_balloonmem(cluster): minram = template.minmem beparams['minmem'] = minram beparams['maxmem'] = memory else: beparams['memory'] = memory vcpus = template.vcpus disk_size = template.disks[0]["size"] kwargs = { "os": template.os, "ip_check": template.ip_check, "name_check": template.name_check, "pnode": template.pnode, "beparams": beparams, } job_id = cluster.rapi.CreateInstance('create', hostname, template.disk_template, template.disks, template.nics, **kwargs) vm = VirtualMachine() vm.cluster = cluster vm.hostname = hostname vm.ram = memory if has_balloonmem(cluster): vm.minram = minram vm.virtual_cpus = vcpus vm.disk_size = disk_size vm.owner = owner vm.ignore_cache = True # Do a dance to get the VM and the job referencing each other. vm.save() job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) job.save() vm.last_job = job vm.save() # Grant admin permissions to the owner. owner.permissable.grant('admin', vm) return vm
def setUp(self): self.tearDown() models.client.GanetiRapiClient = RapiProxy cluster = Cluster(hostname='test.cluster', slug='test', username='******', password='******') cluster.id = 23 # XXX MySQL DB does not reset auto-increment IDs when an object is removed cluster.save() cluster.sync_nodes() template = VirtualMachineTemplate(template_name="Template1", cluster=cluster) template.disks = [{'size': 500}] template.nics = [{'mode': 'bridged', 'link': ''}] template.save() instance = VirtualMachine(hostname='new.vm.hostname', cluster=cluster) instance.info = INSTANCE instance.disks = [] instance.nics = [] instance.save() # Users self.create_users([ ('superuser', { 'is_superuser': True }), 'cluster_admin', 'create_vm', 'unauthorized', ]) self.cluster_admin.grant('admin', cluster) self.create_vm.grant('create_vm', cluster) self.create_template_data = dict( cluster=cluster.pk, template_name='foo_bar', memory=512, disk_template='plain', disk_count=0, nic_count=0, ) self.cluster = cluster self.template = template self.instance = instance self.c = Client()
def setUp(self): self.tearDown() models.client.GanetiRapiClient = RapiProxy cluster = Cluster(hostname='test.cluster', slug='test', username='******', password='******') cluster.id = 23 # XXX MySQL DB does not reset auto-increment # IDs when an object is removed cluster.save() cluster.sync_nodes() template = VirtualMachineTemplate(template_name="Template1", cluster=cluster) template.disks = [{'size': 500}] template.nics = [{'mode': 'bridged', 'link': ''}] template.save() instance = VirtualMachine(hostname='new.vm.hostname', cluster=cluster) instance.info = INSTANCE instance.disks = [] instance.nics = [] instance.save() # Users self.create_users([ ('superuser', {'is_superuser': True}), 'cluster_admin', 'create_vm', 'unauthorized', ]) self.cluster_admin.grant('admin', cluster) self.create_vm.grant('create_vm', cluster) self.create_template_data = dict( cluster=cluster.pk, template_name='foo_bar', memory=512, disk_template='plain', disk_count=0, nic_count=0, ) self.cluster = cluster self.template = template self.instance = instance self.c = Client()
def _update_vm(self, cluster, info, data, updated, callback): """ updates an individual VirtualMachine, this is the actual work function @param cluster - cluster this node is on @param info - info from ganeti @param data - data from database @param updated - counter object @param callback - callback fired when method is complete. """ name = info['name'] if name in data: id, mtime, status = data[name] if not mtime or mtime < info['mtime'] \ or status != info['status']: print ' Virtual Machine (updated) : %s' % name #print ' %s :: %s' % (mtime, datetime.fromtimestamp(info['mtime'])) # only update the whole object if it is new or modified. # # XXX status changes will not always be reflected in mtime # explicitly check status to see if it has changed. failing # to check this would result in state changes being lost parsed = VirtualMachine.parse_persistent_info(info) if 'delete' in parsed: VirtualMachine.objects.filter(pk=id).delete() else: VirtualMachine.objects.filter(pk=id) \ .update(serialized_info=cPickle.dumps(info), **parsed) updated += 1 else: # new vm vm = VirtualMachine(cluster=cluster, hostname=info['name']) vm.info = info vm.save() id = vm.id updated += 1 callback(id)
def template_to_instance(template, hostname, owner): """ Instantiate a VM template with a given hostname and owner. """ cluster = template.cluster beparams = {"vcpus": template.vcpus} memory = template.memory if has_balloonmem(cluster): minram = template.minmem beparams["minmem"] = minram beparams["maxmem"] = memory else: beparams["memory"] = memory vcpus = template.vcpus disk_size = template.disks[0]["size"] kwargs = { "os": template.os, "ip_check": template.ip_check, "name_check": template.name_check, "pnode": template.pnode, "beparams": beparams, } if template.snode: kwargs.update({"snode": template.snode}) # secondary node isn't set, check if drdb is set (this shouldn't happen if # form validation is correct) elif template.disk_template == "drdb": msg = "Disk template set to drdb, but no secondary node set" raise RuntimeError(msg) job_id = cluster.rapi.CreateInstance( "create", hostname, template.disk_template, template.disks, template.nics, **kwargs ) vm = VirtualMachine() vm.cluster = cluster vm.hostname = hostname vm.ram = memory if has_balloonmem(cluster): vm.minram = minram vm.virtual_cpus = vcpus vm.disk_size = disk_size vm.owner = owner vm.ignore_cache = True # Do a dance to get the VM and the job referencing each other. vm.save() job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) job.save() vm.last_job = job vm.save() # Grant admin permissions to the owner. owner.permissable.grant("admin", vm) return vm
def template_to_instance(template, hostname, owner): """ Instantiate a VM template with a given hostname and owner. """ cluster = template.cluster beparams = { "vcpus": template.vcpus, } hvparams = {} info = cluster.info hv = info['default_hypervisor'] kvm = hv == 'kvm' pvm = hv == 'xen-pvm' hvm = hv == 'xen-hvm' kvm_or_hvm = kvm or hvm kvm_or_pvm = kvm or pvm if kvm_or_hvm: hvparams.update(boot_order=template.boot_order) hvparams.update(cdrom_image_path=template.cdrom_image_path) hvparams.update(nic_type=template.nic_type) hvparams.update(disk_type=template.disk_type) if kvm_or_pvm: hvparams.update(kernel_path=template.kernel_path) hvparams.update(root_path=template.root_path) if kvm: hvparams.update(cdrom2_image_path=template.cdrom2_image_path) hvparams.update(serial_console=template.serial_console) memory = template.memory if has_balloonmem(cluster): minram = template.minmem beparams['minmem'] = minram beparams['maxmem'] = memory else: beparams['memory'] = memory vcpus = template.vcpus disk_size = template.disks[0]["size"] kwargs = { "os": template.os, "hypervisor": hv, "ip_check": template.ip_check, "name_check": template.name_check, "beparams": beparams, "no_install": template.no_install, "start": template.start, "hvparams": hvparams, } # Using auto allocator if template.iallocator: default_iallocator = cluster.info['default_iallocator'] kwargs.update(iallocator=default_iallocator) # Not using allocator, pass pnode else: kwargs.update(pnode=template.pnode) # Also pass in snode if it exists (drdb) if template.snode: kwargs.update(snode=template.snode) # secondary node isn't set but we're using drdb, so programming error # (this shouldn't happen if form validation is done correctly) elif template.disk_template == 'drdb': msg = 'Disk template set to drdb, but no secondary node set' raise RuntimeError(msg) job_id = cluster.rapi.CreateInstance('create', hostname, template.disk_template, template.disks, template.nics, **kwargs) vm = VirtualMachine() vm.cluster = cluster vm.hostname = hostname vm.ram = memory if has_balloonmem(cluster): vm.minram = minram vm.virtual_cpus = vcpus vm.disk_size = disk_size vm.owner = owner vm.ignore_cache = True # Do a dance to get the VM and the job referencing each other. vm.save() job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) job.save() vm.last_job = job vm.save() # Grant admin permissions to the owner. owner.permissable.grant('admin', vm) return vm
def create(request, cluster_slug=None): """ Create a new instance Store in DB and Create on given cluster """ user = request.user if not(user.is_superuser or user.has_any_perms(Cluster, ['admin', 'create_vm'])): raise Http403( _('You do not have permission to create virtual machines')) if cluster_slug is not None: cluster = get_object_or_404(Cluster, slug=cluster_slug) else: cluster = None if request.method == 'POST': form = NewVirtualMachineForm(user, request.POST) if form.is_valid(): data = form.cleaned_data start = data.get('start') no_install = data.get('no_install') owner = data.get('owner') grantee = data.get('grantee') cluster = data.get('cluster') hostname = data.get('hostname') disk_template = data.get('disk_template') # Default to not pass in pnode and snode # since these will be set if the form is correct pnode = None snode = None os = data.get('os') name_check = data.get('name_check') iallocator = data.get('iallocator') # Hidden fields iallocator_hostname = None if 'iallocator_hostname' in data: iallocator_hostname = data.get('iallocator_hostname') # BEPARAMS vcpus = data.get('vcpus') disks = data.get('disks') disk_size = data.get('disk_size') nics = data.get('nics') memory = data.get('memory') # If iallocator was not checked do not pass in the iallocator # name. If iallocator was checked don't pass snode,pnode. if not iallocator: iallocator_hostname = None pnode = data.get('pnode') # If drbd is being used assign the secondary node if disk_template == 'drbd' and pnode is not None: snode = data.get('snode') # Create dictionary of only parameters supposed to be in hvparams hv = data.get('hypervisor') hvparams = {} hvparam_fields = () if hv == 'xen-pvm': hvparam_fields = ('kernel_path', 'root_path') elif hv == 'xen-hvm': hvparam_fields = ( 'boot_order', 'disk_type', 'nic_type', 'cdrom_image_path', ) elif hv == 'kvm': hvparam_fields = [ 'kernel_path', 'root_path', 'serial_console', 'boot_order', 'disk_type', 'cdrom_image_path', 'nic_type', ] # Check before adding cdrom2; see #11655. if has_cdrom2(cluster): hvparam_fields.append('cdrom2_image_path') # Force cdrom disk type to IDE; see #9297. hvparams['cdrom_disk_type'] = 'ide' for field in hvparam_fields: hvparams[field] = data[field] # XXX attempt to load the virtual machine. This ensure that if # there was a previous vm with the same hostname, but had not # successfully been deleted, then it will be deleted now try: VirtualMachine.objects.get(cluster=cluster, hostname=hostname) except VirtualMachine.DoesNotExist: pass try: job_id = cluster.rapi.CreateInstance('create', hostname, disk_template, disks,nics, no_install=no_install, start=start, os=os, pnode=pnode, snode=snode, name_check=name_check, ip_check=name_check, iallocator=iallocator_hostname, hypervisor=hv, hvparams=hvparams, beparams={"memory": memory, "vcpus":vcpus}) except GanetiApiError, e: msg = '%s: %s' % (_('Error creating virtual machine on this cluster'),e) form._errors["cluster"] = form.error_class([msg]) else: # Check for a vm recovery, If it is not found then if 'vm_recovery' in data: vm = data['vm_recovery'] vm_template = vm.template else: vm_template = VirtualMachineTemplate() vm = VirtualMachine(owner=owner) vm.cluster = cluster vm.hostname = hostname vm.ram = memory vm.virtual_cpus = vcpus vm.disk_size = disk_size # save temporary template # XXX copy each property in data. Avoids errors from properties # that don't exist on the model for k,v in data.items(): setattr(vm_template, k, v) vm_template.save() vm.template = vm_template vm.ignore_cache = True # Do a dance to get the VM and the job referencing each other. vm.save() job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) job.save() vm.last_job = job vm.save() # grant admin permissions to the owner. Only do this for new # VMs. otherwise we run the risk of granting perms to a # different owner. We should be preventing that elsewhere, but # lets be extra careful since this check is cheap. if 'vm_recovery' in data: log_action('VM_RECOVER', user, vm, job) else: grantee.grant('admin', vm) log_action('CREATE', user, vm) return HttpResponseRedirect( reverse('instance-detail', args=[cluster.slug, vm.hostname])) cluster_defaults = {} if 'cluster' in request.POST and request.POST['cluster'] != '': try: cluster = Cluster.objects.get(pk=request.POST['cluster']) if cluster.info: cluster_defaults = cluster_default_info(cluster) except Cluster.DoesNotExist: pass