def __init__(self, instance, *args, **kwargs): super(ReplaceDisksForm, self).__init__(*args, **kwargs) self.instance = instance # set disk choices based on the instance disk_choices = [(i, 'disk/%s' % i) for i, v in enumerate(instance.info['disk.sizes'])] self.fields['disks'].choices = disk_choices # set choices based on the instances cluster cluster = instance.cluster nodelist = [ str(h) for h in cluster.nodes.values_list('hostname', flat=True) ] nodes = zip(nodelist, nodelist) nodes.insert(0, self.empty_field) self.fields['node'].choices = nodes defaults = cluster_default_info(cluster, get_hypervisor(instance)) if defaults['iallocator'] != '': self.fields['iallocator'].initial = True self.fields['iallocator_hostname'] = forms.CharField( initial=defaults['iallocator'], required=False, widget=forms.HiddenInput())
def modify(request, cluster_slug, instance): vm, cluster = get_vm_and_cluster_or_404(cluster_slug, instance) user = request.user if not (user.is_superuser or user.has_any_perms(vm, ['admin', 'modify']) or user.has_perm('admin', cluster)): raise Http403( 'You do not have permissions to edit this virtual machine') hv = get_hypervisor(vm) if hv == 'kvm': hv_form = KvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_kvm.html' elif hv == 'xen-pvm': hv_form = PvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_pvm.html' elif hv == 'xen-hvm': hv_form = HvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_hvm.html' else: hv_form = None template = 'ganeti/virtual_machine/edit_base.html' # XXX no matter what, we're gonna call hv_form() and die. Let's do it # louder than usual. >:3 msg = "Hey, guys, implementation error in views/vm.py:modify" raise RuntimeError(msg) if request.method == 'POST': form = hv_form(vm, request.POST) form.owner = vm.owner form.vm = vm form.cluster = cluster if form.is_valid(): data = form.cleaned_data request.session['edit_form'] = data request.session['edit_vm'] = vm.id return HttpResponseRedirect( reverse('instance-modify-confirm', args=[cluster.slug, vm.hostname])) elif request.method == 'GET': if 'edit_form' in request.session \ and vm.id == request.session['edit_vm']: form = hv_form(vm, request.session['edit_form']) else: form = hv_form(vm) return render_to_response( template, {'cluster': cluster, 'instance': vm, 'form': form, 'balloon': has_balloonmem(cluster) }, context_instance=RequestContext(request), )
def modify(request, cluster_slug, instance): vm, cluster = get_vm_and_cluster_or_404(cluster_slug, instance) user = request.user if not (user.is_superuser or user.has_any_perms(vm, ['admin','modify']) or user.has_perm('admin', cluster)): return render_403(request, 'You do not have permissions to edit this virtual machine') hv_form = None hv = get_hypervisor(vm) if hv == 'kvm': hv_form = KvmModifyVirtualMachineForm elif hv == 'xen-pvm': hv_form = PvmModifyVirtualMachineForm elif hv == 'xen-hvm': hv_form = HvmModifyVirtualMachineForm if request.method == 'POST': form = hv_form(vm, request.POST) form.owner = vm.owner form.vm = vm form.cluster = cluster if form.is_valid(): data = form.cleaned_data request.session['edit_form'] = data request.session['edit_vm'] = vm.id return HttpResponseRedirect( reverse('instance-modify-confirm', args=[cluster.slug, vm.hostname])) elif request.method == 'GET': if 'edit_form' in request.session and vm.id == request.session['edit_vm']: form = hv_form(vm, request.session['edit_form']) else: form = hv_form(vm) # Select template depending on hypervisor # Default to edit_base if hv == 'kvm': template = 'ganeti/virtual_machine/edit_kvm.html' elif hv == 'xen-hvm': template = 'ganeti/virtual_machine/edit_hvm.html' elif hv == 'xen-pvm': template = 'ganeti/virtual_machine/edit_pvm.html' else: template = 'ganeti/virtual_machine/edit_base.html' return render_to_response(template, { 'cluster': cluster, 'instance': vm, 'form': form, }, context_instance=RequestContext(request), )
def modify(request, cluster_slug, instance): vm, cluster = get_vm_and_cluster_or_404(cluster_slug, instance) user = request.user if not (user.is_superuser or user.has_any_perms(vm, ['admin','modify']) or user.has_perm('admin', cluster)): raise Http403( 'You do not have permissions to edit this virtual machine') hv = get_hypervisor(vm) if hv == 'kvm': hv_form = KvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_kvm.html' elif hv == 'xen-pvm': hv_form = PvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_pvm.html' elif hv == 'xen-hvm': hv_form = HvmModifyVirtualMachineForm template = 'ganeti/virtual_machine/edit_hvm.html' else: hv_form = None template = 'ganeti/virtual_machine/edit_base.html' # XXX no matter what, we're gonna call hv_form() and die. Let's do it # louder than usual. >:3 msg = "Hey, guys, implementation error in views/vm.py:modify" raise RuntimeError(msg) if request.method == 'POST': form = hv_form(vm, request.POST) form.owner = vm.owner form.vm = vm form.cluster = cluster if form.is_valid(): data = form.cleaned_data request.session['edit_form'] = data request.session['edit_vm'] = vm.id return HttpResponseRedirect( reverse('instance-modify-confirm', args=[cluster.slug, vm.hostname])) elif request.method == 'GET': if 'edit_form' in request.session and vm.id == request.session['edit_vm']: form = hv_form(vm, request.session['edit_form']) else: form = hv_form(vm) return render_to_response(template, { 'cluster': cluster, 'instance': vm, 'form': form, }, context_instance=RequestContext(request), )
def test_get_hypervisor(self): class VirtualMachineTest(object): info = None def __init__(self, info): self.info = info kvm = VirtualMachineTest(INSTANCE) pvm = VirtualMachineTest(XEN_PVM_INSTANCE) hvm = VirtualMachineTest(XEN_HVM_INSTANCE) foo = VirtualMachineTest({'hvparams': 'asdfaf'}) hv = get_hypervisor(kvm) self.assertEqual(hv, 'kvm') hv = get_hypervisor(pvm) self.assertEqual(hv, 'xen-pvm') hv = get_hypervisor(hvm) self.assertEqual(hv, 'xen-hvm') hv = get_hypervisor(foo) self.assertEqual(hv, None)
def __init__(self, instance, *args, **kwargs): super(ReplaceDisksForm, self).__init__(*args, **kwargs) self.instance = instance # set disk choices based on the instance disk_choices = [(i, 'disk/%s' % i) for i,v in enumerate(instance.info['disk.sizes'])] self.fields['disks'].choices = disk_choices # set choices based on the instances cluster cluster = instance.cluster nodelist = [str(h) for h in cluster.nodes.values_list('hostname', flat=True)] nodes = zip(nodelist, nodelist) nodes.insert(0, self.empty_field) self.fields['node'].choices = nodes defaults = cluster_default_info(cluster, get_hypervisor(instance)) if defaults['iallocator'] != '' : self.fields['iallocator'].initial = True self.fields['iallocator_hostname'] = forms.CharField( initial=defaults['iallocator'], required=False, widget = forms.HiddenInput())
def modify_confirm(request, cluster_slug, instance): vm, cluster = get_vm_and_cluster_or_404(cluster_slug, instance) hv = get_hypervisor(vm) if hv == 'kvm': hv_form = KvmModifyVirtualMachineForm elif hv == 'xen-pvm': hv_form = PvmModifyVirtualMachineForm elif hv == 'xen-hvm': hv_form = HvmModifyVirtualMachineForm else: hv_form = None # XXX no matter what, we're gonna call hv_form() and die. Let's do it # louder than usual. >:3 msg = "Hey, guys, implementation error in views/vm.py:modify_confirm" raise RuntimeError(msg) user = request.user power = user.is_superuser or user.has_any_perms(vm, ['admin', 'power']) if not (user.is_superuser or user.has_any_perms(vm, ['admin', 'modify']) or user.has_perm('admin', cluster)): raise Http403( _('You do not have permissions to edit this virtual machine')) if request.method == "POST": if 'edit' in request.POST: return HttpResponseRedirect( reverse("instance-modify", args=[cluster.slug, vm.hostname])) elif 'reboot' in request.POST or 'save' in request.POST: form = ModifyConfirmForm(request.POST) form.session = request.session form.owner = vm.owner form.vm = vm form.cluster = cluster if form.is_valid(): beparams = {} data = form.cleaned_data rapi_dict = data['rapi_dict'] nics = rapi_dict.pop('nics') beparams['vcpus'] = rapi_dict.pop('vcpus') if has_balloonmem(cluster): beparams['maxmem'] = rapi_dict.pop('maxmem') beparams['minmem'] = rapi_dict.pop('minmem') else: beparams['memroy'] = rapi_dict.pop('memory') os_name = rapi_dict.pop('os') job_id = cluster.rapi.ModifyInstance( instance, nics=nics, os_name=os_name, hvparams=rapi_dict, beparams=beparams) # Create job and update message on virtual machine detail page job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) VirtualMachine.objects \ .filter(id=vm.id).update(last_job=job, ignore_cache=True) # log information about modifying this instance log_action('EDIT', user, vm) if 'reboot' in request.POST and vm.info['status'] == 'running': if power: # Reboot the vm job = vm.reboot() log_action('VM_REBOOT', user, vm, job) else: raise Http403( _("Sorry, but you do not have permission " "to reboot this machine.")) # Redirect to instance-detail return HttpResponseRedirect( reverse("instance-detail", args=[cluster.slug, vm.hostname])) elif 'cancel' in request.POST: # Remove session variables. if 'edit_form' in request.session: del request.session['edit_form'] # Redirect to instance-detail return HttpResponseRedirect( reverse("instance-detail", args=[cluster.slug, vm.hostname])) elif request.method == "GET": form = ModifyConfirmForm() session = request.session if not 'edit_form' in request.session: return HttpResponseBadRequest('Incorrect Session Data') data = session['edit_form'] info = vm.info hvparams = info['hvparams'] old_set = dict( vcpus=info['beparams']['vcpus'], os=info['os'], ) if has_balloonmem(cluster): old_set['maxmem'] = info['beparams']['maxmem'] old_set['minmem'] = info['beparams']['minmem'] else: old_set['memory'] = info['beparams']['memory'] nic_count = len(info['nic.links']) for i in xrange(nic_count): old_set['nic_link_%s' % i] = info['nic.links'][i] old_set['nic_mac_%s' % i] = info['nic.macs'][i] # Add hvparams to the old_set old_set.update(hvparams) instance_diff = {} fields = hv_form(vm, data).fields for key in data.keys(): if key in ['memory', 'maxmem', 'minmem']: diff = compare(render_storage(old_set[key]), render_storage(data[key])) elif key == 'os': oses = os_prettify([old_set[key], data[key]]) if len(oses) > 1: """ XXX - Special case for a cluster with two different types of optgroups (i.e. Image, Debootstrap). The elements at 00 and 10: The optgroups The elements at 010 and 110: Tuple containing the OS Name and OS value. The elements at 0101 and 1101: String containing the OS Name """ oses[0][1][0] = list(oses[0][1][0]) oses[1][1][0] = list(oses[1][1][0]) oses[0][1][0][1] = '%s (%s)' % (oses[0][1][0][1], oses[0][0]) oses[1][1][0][1] = '%s (%s)' % (oses[1][1][0][1], oses[1][0]) oses = oses[0][1] + oses[1][1] diff = compare(oses[0][1], oses[1][1]) else: oses = oses[0][1] diff = compare(oses[0][1], oses[1][1]) #diff = compare(oses[0][1], oses[1][1]) if key in ['nic_count', 'nic_count_original']: continue elif key not in old_set.keys(): diff = "" instance_diff[fields[key].label] = _('Added') else: diff = compare(old_set[key], data[key]) if diff != "": label = fields[key].label instance_diff[label] = diff # remove mac if it has not changed for i in xrange(nic_count): if fields['nic_mac_%s' % i].label not in instance_diff: del data['nic_mac_%s' % i] # Repopulate form with changed values form.fields['rapi_dict'] = CharField(widget=HiddenInput, initial=json.dumps(data)) return render_to_response( 'ganeti/virtual_machine/edit_confirm.html', { 'cluster': cluster, 'form': form, 'instance': vm, 'instance_diff': instance_diff, 'power': power, }, context_instance=RequestContext(request), )
def modify_confirm(request, cluster_slug, instance): vm, cluster = get_vm_and_cluster_or_404(cluster_slug, instance) hv = get_hypervisor(vm) if hv == 'kvm': hv_form = KvmModifyVirtualMachineForm elif hv == 'xen-pvm': hv_form = PvmModifyVirtualMachineForm elif hv == 'xen-hvm': hv_form = HvmModifyVirtualMachineForm else: hv_form = None # XXX no matter what, we're gonna call hv_form() and die. Let's do it # louder than usual. >:3 msg = "Hey, guys, implementation error in views/vm.py:modify_confirm" raise RuntimeError(msg) user = request.user power = user.is_superuser or user.has_any_perms(vm, ['admin','power']) if not (user.is_superuser or user.has_any_perms(vm, ['admin','modify']) or user.has_perm('admin', cluster)): raise Http403( _('You do not have permissions to edit this virtual machine')) if request.method == "POST": if 'edit' in request.POST: return HttpResponseRedirect( reverse("instance-modify", args=[cluster.slug, vm.hostname])) elif 'reboot' in request.POST or 'save' in request.POST: form = ModifyConfirmForm(request.POST) form.session = request.session form.owner = vm.owner form.vm = vm form.cluster = cluster if form.is_valid(): data = form.cleaned_data rapi_dict = data['rapi_dict'] nics = rapi_dict.pop('nics') vcpus = rapi_dict.pop('vcpus') memory = rapi_dict.pop('memory') os_name = rapi_dict.pop('os') job_id = cluster.rapi.ModifyInstance(instance, nics=nics, os_name=os_name, hvparams=rapi_dict, beparams={'vcpus':vcpus,'memory':memory} ) # Create job and update message on virtual machine detail page job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) VirtualMachine.objects.filter(id=vm.id).update(last_job=job, ignore_cache=True) # log information about modifying this instance log_action('EDIT', user, vm) if 'reboot' in request.POST and vm.info['status'] == 'running': if power: # Reboot the vm job = vm.reboot() log_action('VM_REBOOT', user, vm, job) else: raise Http403( _("Sorry, but you do not have permission to reboot this machine.")) # Redirect to instance-detail return HttpResponseRedirect( reverse("instance-detail", args=[cluster.slug, vm.hostname])) elif 'cancel' in request.POST: # Remove session variables. if 'edit_form' in request.session: del request.session['edit_form'] # Redirect to instance-detail return HttpResponseRedirect( reverse("instance-detail", args=[cluster.slug, vm.hostname])) elif request.method == "GET": form = ModifyConfirmForm() session = request.session if not 'edit_form' in request.session: return HttpResponseBadRequest('Incorrect Session Data') data = session['edit_form'] info = vm.info hvparams = info['hvparams'] old_set = dict( memory=info['beparams']['memory'], vcpus=info['beparams']['vcpus'], os=info['os'], ) nic_count = len(info['nic.links']) for i in xrange(nic_count): old_set['nic_link_%s' % i] = info['nic.links'][i] old_set['nic_mac_%s' % i] = info['nic.macs'][i] # Add hvparams to the old_set old_set.update(hvparams) instance_diff = {} fields = hv_form(vm, data).fields for key in data.keys(): if key == 'memory': diff = compare(render_storage(old_set[key]), render_storage(data[key])) elif key == 'os': oses = os_prettify([old_set[key], data[key]]) if len(oses) > 1: """ XXX - Special case for a cluster with two different types of optgroups (i.e. Image, Debootstrap). The elements at 00 and 10: The optgroups The elements at 010 and 110: Tuple containing the OS Name and OS value. The elements at 0101 and 1101: String containing the OS Name """ oses[0][1][0] = list(oses[0][1][0]) oses[1][1][0] = list(oses[1][1][0]) oses[0][1][0][1] = '%s (%s)' % (oses[0][1][0][1], oses[0][0]) oses[1][1][0][1] = '%s (%s)' % (oses[1][1][0][1], oses[1][0]) oses = oses[0][1] + oses[1][1] diff = compare(oses[0][1], oses[1][1]) else: oses = oses[0][1] diff = compare(oses[0][1], oses[1][1]) #diff = compare(oses[0][1], oses[1][1]) if key in ['nic_count','nic_count_original']: continue elif key not in old_set.keys(): diff = "" instance_diff[fields[key].label] = _('Added') else: diff = compare(old_set[key], data[key]) if diff != "": label = fields[key].label instance_diff[label] = diff # remove mac if it has not changed for i in xrange(nic_count): if fields['nic_mac_%s' % i].label not in instance_diff: del data['nic_mac_%s' % i] # Repopulate form with changed values form.fields['rapi_dict'] = CharField(widget=HiddenInput, initial=json.dumps(data)) return render_to_response( 'ganeti/virtual_machine/edit_confirm.html', { 'cluster': cluster, 'form': form, 'instance': vm, 'instance_diff': instance_diff, 'power':power, }, context_instance=RequestContext(request), )
def test_get_hypervisor_unknown(self): self.disp.info = {"hvparams": "asdfaf"} self.assertEqual(get_hypervisor(self.disp), None)
def test_get_hypervisor_hvm(self): self.disp.info = XEN_HVM_INSTANCE self.assertEqual(get_hypervisor(self.disp), "xen-hvm")
def test_get_hypervisor_kvm(self): self.disp.info = INSTANCE self.assertEqual(get_hypervisor(self.disp), "kvm")