Skip to content
__init__.py 3.49 KiB
Newer Older
import logging

import libvirt

from ccnode.host import Handler as HostHandler
from ccnode.tags import tag_inspector, get_tags
from ccnode.hypervisor import tags
from ccnode.hypervisor import lib as _libvirt
from ccnode.hypervisor.lib import EVENTS, EventLoop
from ccnode.hypervisor.domains import VirtualMachine


logger = logging.getLogger(__name__)


class Handler(HostHandler):
    def __init__(self, *args, **kwargs):
        """
        :param proxy: sjRpc proxy
        """
        HostHandler.__init__(self, *args, **kwargs)

        for t in tag_inspector(tags):
            self.tags[t.name] = t

        # set tag hv
        # self.tags['hv'] = Tag('hv', )

        # initialize hypervisor instance
        global hypervisor
        if hypervisor is None:
            hypervisor = Hypervisor()

        # register domains
        proxy = kwargs.pop('proxy')
        for dom in hypervisor.domains:
            name = dom.name
            logger.debug(u'Registered domain %s' % name)
            proxy.register(name, 'vm')

    def sub_tags(self, sub_id, tags=None, noresolve_tags=None):
        """Get subtags."""
        global hypervisor

        domain = hypervisor.get_domain_by_name(sub_id)

        if domain is None:
            logger.debug(u'Failed to find domain with name %s.' % sub_id)
            return

        return get_tags(domain, tags, noresolve_tags)

    def vm_define(self, name):
        pass

    def vm_undefine(self, name):
        pass

    def vm_export(self, name, format='xml'):
        pass

    def vm_stop(self, vm_names=None, force=False):
        pass

    def vm_start(self, vm_names=None):
        pass

    def vm_suspend(self, vm_names=None):
        pass

    def vm_resume(self, vm_names=None):
        pass


class Hypervisor(object):
    """Container for all hypervisor related state."""
    def __init__(self):
        # initialize connection to libvirt
        _libvirt.connection = libvirt.open('qemu:///system')  # currently only support KVM

        #: domains: vms, containers...
        self.domains = [
            VirtualMachine(
                _libvirt.connection.lookupByID(id),
            ) for id in _libvirt.connection.listDomainsID()
        ]

        self.event_loop = EventLoop()
        self.event_loop.start()
        self.event_loop.register_callbacks(self.callback)

        # TODO cleanup connection on stop

    def callback(self, conn, dom, event, detail, opaque):
        """Callback for libvrit event loop."""
        logger.debug("myDomainEventCallback1 EVENT: Domain %s(%s) %s %d" % (dom.name(), dom.UUIDString(), EVENTS[event], detail))

    def get_domain_by_name(self, name):
        """Get a domain by name."""
        for d in self.domains:
            if d.name == name:
                return d

        return None

    def _count_domain(self, filter=lambda d: True):
        count = 0

        for dom in self.domains:
            if filter(dom):
                count += 1

        return count

    @property
    def vm_started(self):
        """Number of VMs started."""
        return self._count_domain(lambda d: d.status == 'started')

    @property
    def vm_stopped(self):
        """Number of VMs stopped."""
        return self._count_domain(lambda d: d.status == 'stopped')

    @property
    def vm_paused(self):
        """Number of VMs paused."""
        return self._count_domain(lambda d: d.status == 'paused')

    @property
    def vm_total(self):
        """Total number of VMs on the hypervisor."""
        return self._count_domain()


hypervisor = None