Exemplo n.º 1
0
Arquivo: cache.py Projeto: bsu/GWM
def _update_cache():
    """
    Updates the cache for all all VirtualMachines in all clusters.  This method
    processes the data in bulk, where possible, to reduce runtime.  Generally
    this should be faster than refreshing individual VirtualMachines.
    """
    timer = Timer()
    print '------[cache update]-------------------------------'
    for cluster in Cluster.objects.all():
        print '%s:' % cluster.hostname
        base = cluster.virtual_machines.all()
        infos = cluster.instances(bulk=True)
        timer.tick('info fetched from ganeti     ')
        updated = 0
        
        mtimes = base.values_list('hostname', 'id', 'mtime', 'status')
        d = {}
        for name, id, mtime, status in mtimes:
            d[name] = (id, float(mtime) if mtime else None, status)
        timer.tick('mtimes fetched from db       ')
        
        for info in infos:
            name = info['name']
            if name in d:
                id, mtime, status = d[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
                    data = VirtualMachine.parse_persistent_info(info)
                    VirtualMachine.objects.filter(pk=id) \
                        .update(serialized_info=cPickle.dumps(info), **data)
                    updated += 1
            else:
                # new vm
                vm = VirtualMachine(cluster=cluster, hostname=info['name'])
                vm.info = info
                vm.save() 
        
        # batch update the cache updated time for all VMs in this cluster. This
        # will set the last updated time for both VMs that were modified and for
        # those that weren't.  even if it wasn't modified we want the last
        # updated time to be up to date.
        #
        # XXX don't bother checking to see whether this query needs to run.  It
        # normal usage it will almost always need to
        base.update(cached=datetime.now())
        
        timer.tick('records or timestamps updated')
    print '    updated: %s out of %s' % (updated, len(infos))
    timer.stop()
    return timer.ticks
Exemplo n.º 2
0
 def test_used_resources(self):
     """
     Tests retrieving dictionary of resources used by a cluster user
     """
     owner = ClusterUser(name='owner')
     owner.save()
     c = Cluster(hostname='testing')
     c.save()
     
     vm0 = VirtualMachine(hostname='one', owner=owner, cluster=c)
     vm1 = VirtualMachine(hostname='two', ram=1, virtual_cpus=3, disk_size=5, owner=owner, cluster=c)
     vm2 = VirtualMachine(hostname='three', ram=2, virtual_cpus=4, disk_size=6, owner=owner, cluster=c)
     vm3 = VirtualMachine(hostname='four', ram=3, virtual_cpus=5, disk_size=7, cluster=c)
     vm0.save()
     vm1.save()
     vm2.save()
     vm3.save()
     
     used = owner.used_resources
     self.assertEqual(1+2, used['ram'])
     self.assertEqual(3+4, used['virtual_cpus'])
     self.assertEqual(5+6, used['disk'])
Exemplo n.º 3
0
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'])):
        return render_403(request,
            '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, None, request.POST)
        if form.is_valid():
            data = form.cleaned_data
            start = data.get('start')
            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')
            disk_size = data.get('disk_size')
            memory = data.get('memory')
            nic_mode = data.get('nic_mode')
            nic_link = data.get('nic_link')
            nic_type = data.get('nic_type')
            # 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
            hvparams = dict()
            hvparam_fields = ('kernel_path', 'root_path', 'serial_console',
                'boot_order', 'disk_type', 'cdrom_image_path',)
            for field in hvparam_fields:
                hvparams[field] = data[field]

            try:
                # 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

                job_id = cluster.rapi.CreateInstance('create', hostname,
                        disk_template,
                        [{"size": disk_size, }],[{'mode':nic_mode, 'link':nic_link, }],
                        start=start, os=os, vcpus=vcpus,
                        pnode=pnode, snode=snode,
                        name_check=name_check, ip_check=name_check,
                        iallocator=iallocator_hostname,
                        hvparams=hvparams,
                        beparams={"memory": memory})

                # 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
                vm.save()
                job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster)
                VirtualMachine.objects.filter(pk=vm.pk).update(last_job=job)



                # 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)
                else:
                    grantee.grant('admin', vm)
                    log_action('CREATE', user, vm)

                return HttpResponseRedirect(
                reverse('instance-detail', args=[cluster.slug, vm.hostname]))

            except GanetiApiError, e:
                msg = 'Error creating virtual machine on this cluster: %s' % e
                form._errors["cluster"] = form.error_class([msg])
Exemplo n.º 4
0
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'])):
        return render_403(request, '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, None, request.POST)
        if form.is_valid():
            data = form.cleaned_data
            owner = data['owner']
            cluster = data['cluster']
            hostname = data['hostname']
            disk_template = data['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['os']
            name_check = data['name_check']
            iallocator = data['iallocator']
            # Hidden fields
            iallocator_hostname = None
            if 'iallocator_hostname' in data:
                iallocator_hostname = data['iallocator_hostname']
            # BEPARAMS
            vcpus = data['vcpus']
            disk_size = data['disk_size']
            ram = data['ram']
            nicmode = data['nicmode']
            niclink = data['niclink']
            nictype = data['nictype']
            # HVPARAMS
            disktype = data['disk_type']

            kernelpath = data['kernelpath']
            rootpath = data['rootpath']
            serialconsole = data['serialconsole']
            bootorder = data['bootorder']
            imagepath = data['imagepath']

            # 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['pnode']

            # If drbd is being used assign the secondary node
            if disk_template == 'drbd' and pnode is not None:
                snode = data['snode']

            try:
                job_id = cluster.rapi.CreateInstance('create', hostname,
                        disk_template,
                        [{"size": disk_size, }],[{'mode':nicmode, 'link':niclink, }],
                        os=os, vcpus=vcpus,
                        pnode=pnode, snode=snode,
                        name_check=name_check, ip_check=name_check,
                        iallocator=iallocator_hostname,
                        hvparams={'kernel_path': kernelpath, \
                            'root_path': rootpath, \
                            'serial_console':serialconsole, \
                            'boot_order':bootorder, \
                            'nic_type':nictype, \
                            'disk_type':disktype,\
                            'cdrom_image_path':imagepath},
                        beparams={"memory": ram})


                # Wait for job to process as the error will not happen
                #  right away
                sleep(2)
                jobstatus = cluster.rapi.GetJobStatus(job_id)

                # raise an exception if there was an error in the job
                if jobstatus["status"] == 'error':
                    raise GanetiApiError(jobstatus["opresult"])

                vm = VirtualMachine(cluster=cluster, owner=owner,
                                    hostname=hostname, disk_size=disk_size,
                                    ram=ram, virtual_cpus=vcpus)
                vm.ignore_cache = True
                vm.save()
                job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster)
                VirtualMachine.objects.filter(id=vm.id).update(last_job=job)

                # log information about creating the machine
                log_action(user, vm, "created")

                # grant admin permissions to the owner
                data['grantee'].grant('admin', vm)

                return HttpResponseRedirect( \
                reverse('instance-detail', args=[cluster.slug, vm.hostname]))

            except GanetiApiError, e:
                msg = 'Error creating virtual machine on this cluster: %s' % e
                form._errors["cluster"] = form.error_class([msg])