Skip to content
__init__.py 2.24 KiB
Newer Older
Anael Beutot's avatar
Anael Beutot committed
import logging
import weakref
from StringIO import StringIO
from xml.etree import cElementTree as et
Anael Beutot's avatar
Anael Beutot committed

from ccnode.tags import Tag, tag_inspector
from ccnode.hypervisor import lib as _libvirt
from ccnode.hypervisor.lib import DOMAIN_STATES as STATE
Anael Beutot's avatar
Anael Beutot committed
from ccnode.hypervisor.domains import vm_tags


logger = logging.getLogger(__name__)


class VirtualMachine(object):
    """Represent a VM instance."""
Anael Beutot's avatar
Anael Beutot committed
    def __init__(self, dom, hypervisor):
        """
        :param dom: libvirt domain instance
Anael Beutot's avatar
Anael Beutot committed
        :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
Anael Beutot's avatar
Anael Beutot committed
        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
Anael Beutot's avatar
Anael Beutot committed

            i += 1

        logger.debug(self.tags)

    @property
    def name(self):
Anael Beutot's avatar
Anael Beutot committed
        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