Skip to content
Snippets Groups Projects
Commit 83adf2c3 authored by Anael Beutot's avatar Anael Beutot
Browse files

Update storage pools when VMs are created or removed.

parent 72e028f2
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......@@ -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
......@@ -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())
......@@ -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,
......@@ -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(),
......@@ -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')
......@@ -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."""
......@@ -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:]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment