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

Implemented disk related tags for VMs.

parent 09557c17
No related branches found
No related tags found
No related merge requests found
import logging
import weakref
from functools import partial
from itertools import chain, imap
import libvirt
......@@ -100,6 +102,12 @@ class Hypervisor(object):
# TODO cleanup connection on stop
_libvirt.connection = libvirt.open('qemu:///system') # currently only support KVM
# findout storage
self.storage = StorageIndex(_libvirt.connection)
logger.debug('Storages: %s', self.storage.paths)
#: domains: vms, containers...
self.domains = dict()
# find defined domains
......@@ -162,3 +170,66 @@ class Hypervisor(object):
hypervisor = None
class StorageIndex(object):
"""Keep an index of all storage volume paths."""
def __init__(self, lv_con):
"""
:param lv_con: Libvirt connection
"""
self.storages = dict(
(s.name, s) for s in imap(
Storage,
imap(
lv_con.storagePoolLookupByName,
chain(
lv_con.listDefinedStoragePools(),
lv_con.listStoragePools(),
),
),
),
)
self.paths = dict(
(v.path, v) for v in chain.from_iterable(map(
lambda s: s.volumes,
self.storages.itervalues(),
)),
)
def get_volume(self, path):
return self.paths.get(path)
def get_storage(self, name):
return self.Storage.get(name)
class Storage(object):
"""Storage abstraction."""
def __init__(self, lv_storage):
"""
:param lv_storage: Libvirt pool storage instance
"""
self.uuid = lv_storage.UUID()
self.name = lv_storage.name()
self.volumes = map(
partial(Volume, storage=self),
(lv_storage.storageVolLookupByName(n) for n in
lv_storage.listVolumes()),
)
class Volume(object):
"""Volume abstraction."""
def __init__(self, lv_volume, storage):
"""
:param lv_volume: Libvirt volume instance
:param storage: parent storage instance
"""
# self.storage = None if storage is None else weakref.proxy(storage)
self.storage = lv_volume.storagePoolLookupByVolume().name()
self.path = lv_volume.path()
self.name = lv_volume.name()
self.capacity, self.allocation = lv_volume.info()[1:]
import logging
import weakref
from StringIO import StringIO
from xml.etree import cElementTree as et
from ccnode.tags import tag_inspector
from ccnode.tags import Tag, tag_inspector
from ccnode.hypervisor import lib as _libvirt
from ccnode.hypervisor.lib import DOMAIN_STATES as STATE
from ccnode.hypervisor.domains import vm_tags
......@@ -17,15 +19,28 @@ class VirtualMachine(object):
:param dom: libvirt domain instance
:param hypervisor: hypervisor where the VM is
"""
self.hypervisor = weakref.proxy(hypervisor)
#: UUID string of domain
self.uuid = dom.UUIDString()
#: state of VM: started, stoped, paused
self.state = STATE[dom.info()[0]]
#: tags for this VM
self.tags = dict((t.name, t) for t in tag_inspector(vm_tags, self))
logger.debug(self.tags)
# define dynamic tags
i = 0
for v in self.iter_disks():
for t in (
Tag('disk%s_size' % i, v.capacity),
Tag('disk%s_path' % i, v.path),
Tag('disk%s_pool' % i, v.storage), # FIXME: change
Tag('disk%s_vol' % i, v.name),
):
self.tags[t.name] = t
self.hypervisor = weakref.proxy(hypervisor)
i += 1
logger.debug(self.tags)
@property
def name(self):
......@@ -50,3 +65,26 @@ class VirtualMachine(object):
def undefined():
pass
@property
def disks(self):
return list(self.iter_disks())
def iter_disks(self):
for d in et.ElementTree().parse(
StringIO(self.lv_dom.XMLDesc(0))
).findall('devices/disk'):
if d.get('device') != 'disk':
continue
type_ = d.get('type')
if type_ not in ('file', 'block'):
continue
path = d.find('source').get(dict(file='file', block='dev')[type_])
volume = self.hypervisor.storage.get_volume(path)
if volume is None:
continue
yield volume
from xml.etree import cElementTree as et
from StringIO import StringIO
from ccnode.tags import DynamicTags
def uuid(dom):
"""Unique identifier of the domain."""
......@@ -71,21 +69,7 @@ status.ttl = 1
def disk(dom):
"""Get backend disks."""
try:
return et.ElementTree().parse(
StringIO(dom.lv_dom.XMLDesc(0))
).find('devices/disk').get('port')
except Exception:
logger.exception('VNCPort')
class Disks(DynamicTags):
def __init__(self):
for d in et.ElementTree().parse(
StringIO(dom.lv_dom.XMLDesc(0))
).findall('devices/disk'):
# self.disks[] = plop
pass
return u' '.join(map(str, xrange(len(dom.disks))))
def nic_():
......
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