Commit bd19d54a authored by Thibault VINCENT's avatar Thibault VINCENT
Browse files

add storage tags for hypervisor

parent daaebce1
Loading
Loading
Loading
Loading
+79 −36
Original line number Diff line number Diff line
@@ -23,38 +23,43 @@ TAG_NOT_FOUND_ERROR = 'Tag %s requested but unknown in node handler'

# Hypervisor

HV_TAG_MAP = {
HV_TAG_WRAP_MAP = {
    'h'         : 'get_name',
    'hv'        : 'get_name',
    'hvtype'    : 'get_hv_type',
    'hvver'     : 'get_hv_version',
    'arch'      : 'get_arch_type',
    'cpu' : 'get_nb_cpu',
    'cpu'       : 'get_cpu',
    'cpufreq'   : 'get_cpu_frequency',
    'cpuuse'    : 'get_cpu_percent',
    'status'    : 'get_status',
    'mem' : 'get_total_mem',
    'memused' : 'get_used_mem',
    'memfree' : 'get_free_mem',
    'sto' : 'get_storage_total_capacity',
    'stofree' : 'get_storage_total_free',
    'stoused' : 'get_storage_total_used',
    'mem'       : 'get_mem',
    'memused'   : 'get_mem_used',
    'memfree'   : 'get_mem_free',
}

HV_TAG_HELPER_LIST = [
    'disk',
    'sto',
]

# Vm

VM_TAG_MAP = {
VM_TAG_WRAP_MAP = {
    'h'         : 'get_name',
    'vm'        : 'get_name',
    'hv'        : 'get_hv_name',
    'vcpus' : 'get_vcpu',
    'cpu'       : 'get_cpu',
    'vmstatus'  : 'get_status',
    'cpu' : 'get_cpu_percent',
    'mem' : 'get_total_mem',
    'usedmem' : 'get_used_mem',
    'freemem' : 'get_free_mem',
    'mem'       : 'get_mem',
    'memused'   : 'get_mem_used',
    'memfree'   : 'get_mem_free',
}

VM_TAG_HELPER_LIST = [
    'disk',
]


class NodeHandler(RpcHandler):
    '''
@@ -86,8 +91,10 @@ class NodeHandler(RpcHandler):
        :param method: the method to be called
        :type method: :class:`str`
        '''
        result = getattr(self.hv_handle, HV_TAG_MAP[method])()
        return result
        return getattr(self.hv_handle, HV_TAG_WRAP_MAP[method])()
    
    def _call_hv_helper(self, method):
        return getattr(self, "_helper_hv_" + method)()
    
    def _call_vm_method(self, vm, method):
        '''
@@ -99,7 +106,42 @@ class NodeHandler(RpcHandler):
        :param method: the method to be called
        :type method: :class:`str`
        '''
        result = getattr(vm, VM_TAG_MAP[method])()
        return getattr(vm, VM_TAG_WRAP_MAP[method])()
    
    def _call_vm_helper(self, method):
        return getattr(self, "_helper_vm_" + method)()
    
    def _helper_hv_sto(self):
        result = {}
        hv = self.hv_handle
        # fetch pool list
        pools = hv.get_storage_pools()
        result['sto'] = " ".join(pools)
        # get pool info
        for pool in pools:
            # pool size
            result['sto%s_size' % pool] = hv.get_storage_capacity(pool)
            # pool used space
            result['sto%s_used' % pool] = hv.get_storage_used(pool)
            # pool free space
            result['sto%s_free' % pool] = hv.get_storage_free(pool)
        return result
    
    def _helper_hv_disk(self):
        return {}
    
    def _helper_vm_disk(self):
        result = {}
        hv = self.hv_handle
        # fetch disk list
        disks = hv.get_vm_disks()
        result['disk'] = " ".join([d['name'] for d in disks])
        # add disk info
        for n, disk in enumerate(disks):
            # disk path to real storage
            result['disk%i_path' % n] = disk['path']
            # disk size
            result['disk%i_size' % n] = disk['size']
        return result
    
    @pure
@@ -112,10 +154,9 @@ class NodeHandler(RpcHandler):
        :type tags: :class:`list` 
        '''
        result = {}
        logging.debug('get_tags: Fetching tags -> %s' % tags)
        if tags is None:
            tags = HV_TAG_MAP.keys()
        logging.debug('get_tags: processing tags %s' % tags)
            tags = HV_TAG_WRAP_MAP.keys()
        # direct wrapping
        for tag in tags:
            try:
                result[tag] = self._call_hv_method(tag)
@@ -124,8 +165,10 @@ class NodeHandler(RpcHandler):
            except KeyError:
                logging.warning(TAG_NOT_FOUND_ERROR % tag)
            except NotImplementedError:
                logging.debug('get_tags: no method in hypervisor to handle %s' % tag)
        logging.debug('get_tags: returning -> %s' % result)
                logging.debug('get_tags: no mehod in hypervisor to handle %s' % tag)
        # tag aggregations from wrapping helpers
        for helper in HV_TAG_HELPER_LIST:
            result.update(self._call_hv_helper(helper))
        return result

    @pure
+65 −42
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ class LibvirtVm(VM):
            self._pid = int(result.pop())
        else:
            self._pid = None
    
    def get_pid(self):
        return self._pid

@@ -154,6 +155,23 @@ class LibvirtVm(VM):
        else:
            return 0
    
    def get_disks(self):
        result = []
        # we parse xml description of the vm to get this info
        xml_string = self._domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
        root = xml.dom.minidom.parseString(xml_string)
        domain = root.getElementsByTagName('domain').pop()
        devices = domain.getElementsByTagName('devices').pop()
        for disk in devices.getElementsByTagName('disk'):
            if disk.getAttribute('device') == 'disk':
                d = {}
                if disk.getAttribute('type') == 'file':
                    d['path'] = disk.getElementsByTagName('source').pop().getAttribute('file')
                elif disk.getAttribute('type') == 'block':
                    d['path'] = disk.getElementsByTagName('source').pop().getAttribute('dev')
                results.append(d)
        return result
    
    def get_status(self):
        return VM_STATUS[self._domain.info()[0]]
    
@@ -169,7 +187,6 @@ class LibvirtVm(VM):
        except libvirt.libvirtError:
            raise VMError('%s is not running !' % self.get_name())
    

    def start(self):
        try:
            self._domain.create()
@@ -188,21 +205,6 @@ class LibvirtVm(VM):
        except libvirt.libvirtError:
            raise VMError('%s is not running !' % self.get_name())
    
    def get_disk_path(self):
        '''
        Returns the path to the disk atached to the vm
        '''
        # We parse xml description of the vm to get this info
        xml_string = self._domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
        dom = xml.dom.minidom.parseString(xml_string)
        disk = dom.getElementsByTagName('disk').pop()
        #FIXME Currently only handles file type backend, must add other backends
        path = disk.getElementsByTagName('source').pop()
        path = path.getAttribute('file')
        return path
            
        

    def get_uuid(self):
        '''
        Returns the uuid string of the vm
@@ -330,24 +332,45 @@ class LibvirtHypervisor(Hypervisor):
    def get_cpu_percent(self):
        return '%2.0f' % psutil.cpu_percent()
    
    def get_storage_total_capacity(self):
    def get_storage_pools(self):
        return self._storage.get_pools().keys()
    
    def get_storage_capacity(self, pool=None):
        capacity = 0
        if pool is None:
            # for all pool available
            for pool in self._storage.get_pools().iteritems():
                capacity = capacity + self._storage.get_pool_space_total(pool[1])
        else:
            # get the capacity of a specific pool
            capacity = self._storage.get_pool_space_total(
                                            self._storage.get_pools()[pool])
        return capacity
    
    def get_storage_total_free(self):
        free = 0
        for pool in self._storage.get_pools().iteritems():
            free = free + self._storage.get_pool_space_available(pool[1])
        return free
    
    def get_storage_total_used(self):
    def get_storage_used(self, pool=None):
        used = 0       
        if pool is None:
            # for all pool available
            for pool in self._storage.get_pools().iteritems():
                used = used + self._storage.get_pool_space_used(pool[1])
        else:
            # get the used space of a specific pool
            used = self._storage.get_pool_space_used(
                                            self._storage.get_pools()[pool])
        return used
    
    def get_storage_free(self, pool=None):
        free = 0
        if pool is None:
            # for all pool available
            for pool in self._storage.get_pools().iteritems():
                free = free + self._storage.get_pool_space_free(pool[1])
        else:
            # get the free space of a specific pool
            free = self._storage.get_pool_space_available(
                                            self._storage.get_pools()[pool])
        return free

    def get_status(self):
        raise NotImplementedError()