Loading cloudcontrol/node/hypervisor/__init__.py +73 −5 Original line number Diff line number Diff line Loading @@ -602,7 +602,7 @@ class Hypervisor(object): self.vir_con = libvirt.open('qemu:///system') # currently only support KVM # findout storage self.storage = StorageIndex(self.vir_con) self.storage = StorageIndex(handler, self.vir_con) logger.debug('Storages: %s', self.storage.paths) Loading Loading @@ -652,6 +652,8 @@ class Hypervisor(object): event = EVENTS[event] if event == 'Added': # update Storage pools in case VM has volumes that were created self.storage.update() if dom.name() in self.domains: # sometimes libvirt send us the same event multiple times # this can be the result of a change in the domain configuration Loading @@ -667,6 +669,8 @@ class Hypervisor(object): vm = self.domains.pop(dom.name()) logger.info('Removed domain %s', vm.name) self.handler.tag_db.remove_sub_object(vm.name) # update Storage pools in case VM had volumes that were deleted self.storage.update() elif event in ('Started', 'Suspended', 'Resumed', 'Stopped', 'Saved', 'Restored'): vm = self.domains.get(dom.name()) Loading Loading @@ -726,10 +730,13 @@ class Hypervisor(object): class StorageIndex(object): """Keep an index of all storage volume paths.""" def __init__(self, lv_con): def __init__(self, handler, lv_con): """ :param handler: Hypervisor handler instance :param lv_con: Libvirt connection """ self.handler = handler self.lv_con = lv_con self.storages = dict( (s.name, s) for s in imap( Storage, Loading @@ -743,6 +750,40 @@ class StorageIndex(object): ), ) self.paths = None self.update_path_index() def update(self): """Update storage pools and volumes.""" # go through all storage pools and check if it is already in the index for lv_storage in imap( self.lv_con.storagePoolLookupByName, chain( self.lv_con.listDefinedStoragePools(), self.lv_con.listStoragePools(), ), ): if lv_storage.name() in self.storages: # update self.storages[lv_storage.name()].update() else: # add storage pool s = Storage(lv_storage) self.storages[s.name] = s # add tags self.handler.tag_db.add_tags(( Tag('sto%s_state' % s.name, lambda: s.state, 5, 5), Tag('sto%s_size' % s.name, lambda: s.capacity, 5, 5), Tag('sto%s_free' % s.name, lambda: s.available, 5, 5), Tag('sto%s_used' % s.name, lambda: s.capacity - s.available, 5, 5), Tag('sto%s_type' % s.name, lambda: s.type, 5, 5), )) self.update_path_index() def update_path_index(self): self.paths = dict( (v.path, v) for v in chain.from_iterable(imap( lambda s: s.volumes.itervalues(), Loading Loading @@ -825,8 +866,8 @@ class Storage(object): self.name = lv_storage.name() self.lv_storage = lv_storage self.state, self.capacity, self.allocation, self.available = lv_storage.info() self.state = STORAGE_STATES[self.state] self.state, self.capacity = None, None self.allocation, self.available = None, None self.type = et.ElementTree().parse( StringIO(lv_storage.XMLDesc(0))).get('type') Loading @@ -837,6 +878,29 @@ class Storage(object): lv_storage.listVolumes()), )) self.update_attr() def update(self): self.update_attr() # update volumes for vol_name in self.lv_storage.listVolumes(): if vol_name in self.volumes: # update volume self.volumes[vol_name].update() else: # add volume v = Volume(self.lv_storage.storageVolLookupByName(vol_name)) self.volumes[v.name] = v def update_attr(self): self.state, self.capacity, self.allocation, self.available = self.lv_storage.info() self.state = STORAGE_STATES[self.state] self.type = et.ElementTree().parse( StringIO(self.lv_storage.XMLDesc(0))).get('type') class Volume(object): """Volume abstraction.""" Loading @@ -847,5 +911,9 @@ class Volume(object): self.storage = lv_volume.storagePoolLookupByVolume().name() self.path = lv_volume.path() self.name = lv_volume.name() self.capacity, self.allocation = lv_volume.info()[1:] self.capacity, self.allocation = None, None self.lv_volume = lv_volume self.update() def update(self): self.capacity, self.allocation = self.lv_volume.info()[1:] Loading
cloudcontrol/node/hypervisor/__init__.py +73 −5 Original line number Diff line number Diff line Loading @@ -602,7 +602,7 @@ class Hypervisor(object): self.vir_con = libvirt.open('qemu:///system') # currently only support KVM # findout storage self.storage = StorageIndex(self.vir_con) self.storage = StorageIndex(handler, self.vir_con) logger.debug('Storages: %s', self.storage.paths) Loading Loading @@ -652,6 +652,8 @@ class Hypervisor(object): event = EVENTS[event] if event == 'Added': # update Storage pools in case VM has volumes that were created self.storage.update() if dom.name() in self.domains: # sometimes libvirt send us the same event multiple times # this can be the result of a change in the domain configuration Loading @@ -667,6 +669,8 @@ class Hypervisor(object): vm = self.domains.pop(dom.name()) logger.info('Removed domain %s', vm.name) self.handler.tag_db.remove_sub_object(vm.name) # update Storage pools in case VM had volumes that were deleted self.storage.update() elif event in ('Started', 'Suspended', 'Resumed', 'Stopped', 'Saved', 'Restored'): vm = self.domains.get(dom.name()) Loading Loading @@ -726,10 +730,13 @@ class Hypervisor(object): class StorageIndex(object): """Keep an index of all storage volume paths.""" def __init__(self, lv_con): def __init__(self, handler, lv_con): """ :param handler: Hypervisor handler instance :param lv_con: Libvirt connection """ self.handler = handler self.lv_con = lv_con self.storages = dict( (s.name, s) for s in imap( Storage, Loading @@ -743,6 +750,40 @@ class StorageIndex(object): ), ) self.paths = None self.update_path_index() def update(self): """Update storage pools and volumes.""" # go through all storage pools and check if it is already in the index for lv_storage in imap( self.lv_con.storagePoolLookupByName, chain( self.lv_con.listDefinedStoragePools(), self.lv_con.listStoragePools(), ), ): if lv_storage.name() in self.storages: # update self.storages[lv_storage.name()].update() else: # add storage pool s = Storage(lv_storage) self.storages[s.name] = s # add tags self.handler.tag_db.add_tags(( Tag('sto%s_state' % s.name, lambda: s.state, 5, 5), Tag('sto%s_size' % s.name, lambda: s.capacity, 5, 5), Tag('sto%s_free' % s.name, lambda: s.available, 5, 5), Tag('sto%s_used' % s.name, lambda: s.capacity - s.available, 5, 5), Tag('sto%s_type' % s.name, lambda: s.type, 5, 5), )) self.update_path_index() def update_path_index(self): self.paths = dict( (v.path, v) for v in chain.from_iterable(imap( lambda s: s.volumes.itervalues(), Loading Loading @@ -825,8 +866,8 @@ class Storage(object): self.name = lv_storage.name() self.lv_storage = lv_storage self.state, self.capacity, self.allocation, self.available = lv_storage.info() self.state = STORAGE_STATES[self.state] self.state, self.capacity = None, None self.allocation, self.available = None, None self.type = et.ElementTree().parse( StringIO(lv_storage.XMLDesc(0))).get('type') Loading @@ -837,6 +878,29 @@ class Storage(object): lv_storage.listVolumes()), )) self.update_attr() def update(self): self.update_attr() # update volumes for vol_name in self.lv_storage.listVolumes(): if vol_name in self.volumes: # update volume self.volumes[vol_name].update() else: # add volume v = Volume(self.lv_storage.storageVolLookupByName(vol_name)) self.volumes[v.name] = v def update_attr(self): self.state, self.capacity, self.allocation, self.available = self.lv_storage.info() self.state = STORAGE_STATES[self.state] self.type = et.ElementTree().parse( StringIO(self.lv_storage.XMLDesc(0))).get('type') class Volume(object): """Volume abstraction.""" Loading @@ -847,5 +911,9 @@ class Volume(object): self.storage = lv_volume.storagePoolLookupByVolume().name() self.path = lv_volume.path() self.name = lv_volume.name() self.capacity, self.allocation = lv_volume.info()[1:] self.capacity, self.allocation = None, None self.lv_volume = lv_volume self.update() def update(self): self.capacity, self.allocation = self.lv_volume.info()[1:]