Exemplo n.º 1
0
    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())
Exemplo n.º 2
0
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),
    )
Exemplo n.º 3
0
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),
    )
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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())
Exemplo n.º 7
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),
    )
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),
    )
Exemplo n.º 9
0
 def test_get_hypervisor_unknown(self):
     self.disp.info = {"hvparams": "asdfaf"}
     self.assertEqual(get_hypervisor(self.disp), None)
Exemplo n.º 10
0
 def test_get_hypervisor_hvm(self):
     self.disp.info = XEN_HVM_INSTANCE
     self.assertEqual(get_hypervisor(self.disp), "xen-hvm")
Exemplo n.º 11
0
 def test_get_hypervisor_kvm(self):
     self.disp.info = INSTANCE
     self.assertEqual(get_hypervisor(self.disp), "kvm")
Exemplo n.º 12
0
 def test_get_hypervisor_unknown(self):
     self.disp.info = {"hvparams": "asdfaf"}
     self.assertEqual(get_hypervisor(self.disp), None)
Exemplo n.º 13
0
 def test_get_hypervisor_hvm(self):
     self.disp.info = XEN_HVM_INSTANCE
     self.assertEqual(get_hypervisor(self.disp), "xen-hvm")
Exemplo n.º 14
0
 def test_get_hypervisor_kvm(self):
     self.disp.info = INSTANCE
     self.assertEqual(get_hypervisor(self.disp), "kvm")