Example #1
0
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),
    )
Example #2
0
 def test_render_storage(self):
     self.assertEqual(tags.render_storage(1), "1 MiB")
     self.assertEqual(tags.render_storage(1025), "1.00 GiB")
     self.assertEqual(tags.render_storage(1049600), "1.0010 TiB")
Example #3
0
 def test_render_storage(self):
     self.assertEqual(tags.render_storage(1), "1 MiB")
     self.assertEqual(tags.render_storage(1025), "1.00 GiB")
     self.assertEqual(tags.render_storage(1049600), "1.0010 TiB")
Example #4
0
 def render_ram(self, value):
     return render_storage(value)
Example #5
0
 def render_disk_size(self, value):
     return render_storage(value)
Example #6
0
 def render_memory(self, value):
     return render_storage(value)
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),
    )