Newer
Older
from StringIO import StringIO
from xml.etree import cElementTree as et
from cloudcontrol.node.tags import Tag, tag_inspector
from cloudcontrol.node.hypervisor import lib as _libvirt
from cloudcontrol.node.hypervisor.lib import DOMAIN_STATES as STATE
from cloudcontrol.node.hypervisor.domains import vm_tags
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.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, 10),
Tag('disk%s_path' % i, v.path, 10),
Tag('disk%s_pool' % i, v.storage, 10), # FIXME: change
Tag('disk%s_vol' % i, v.name, 10),
i = 0
for nic in self.iter_nics():
for t in (
Tag('nic%s_mac' % i, nic.mac, 10),
Tag('nic%s_source' % i, nic.source, 10),
Tag('nic%s_model' %i, nic.model, 10),
@property
def state(self):
return self._state
@state.setter
def state(self, value):
self._state = value
@property
def lv_dom(self):
"""Libvirt domain instance."""
return self.hypervisor.vir_con.lookupByUUIDString(self.uuid)
def start(self):
self.lv_dom.create()
def stop(self):
self.lv_dom.shutdown()
def undefine(self):
self.lv_dom.undefine()
@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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
@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,
)