Newer
Older
from StringIO import StringIO
from xml.etree import cElementTree as et
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
logger = logging.getLogger(__name__)
NetworkInterface = namedtuple('NetworkInterface', ('source', 'mac', 'model'))
class VirtualMachine(object):
"""Represent a VM instance."""
"""
:param dom: libvirt domain instance
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))
# 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
i = 0
for nic in self.iter_nics():
for t in (
Tag('nic%s_mac' % i, nic.mac),
Tag('nic%s_source' % i, nic.source),
Tag('nic%s_model' %i, nic.model),
):
self.tags[t.name] = t
@property
def name(self):
return self.lv_dom.name()
@property
def lv_dom(self):
"""Libvirt domain instance."""
return _libvirt.connection.lookupByUUIDString(self.uuid)
def start():
pass
def stop():
pass
def pause():
pass
def define():
pass
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@property
def nics(self):
return list(self.iter_nics())
def iter_nics(self):
for nic in et.ElementTree().parse(
StringIO(self.lv_dom.XMLDesc(0))
).findall('devices/interface'):
if nic.get('type') == 'bridge':
try:
mac = nic.find('mac').get('address')
except AttributeError:
mac = None
try:
model = nic.find('model').get('type')
except AttributeError:
model = None
try:
source = nic.find('source').get('bridge')
except AttributeError:
source = None
yield NetworkInterface(
mac=mac,
source=source,
model=model,
)