Commit de56364c authored by Anael Beutot's avatar Anael Beutot
Browse files

Basic hypervisor working with listing VMs.

parent 85073695
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ from subprocess import Popen, PIPE, STDOUT
from sjrpc.utils import pure

from ccnode.node import DefaultHandler
from ccnode.tags import Tag, DynamicTags, tag_inspector
from ccnode.tags import tag_inspector
from ccnode.host import tags


@@ -16,7 +16,7 @@ class Handler(DefaultHandler):
    def __init__(self, *args, **kwargs):
        DefaultHandler.__init__(self, *args, **kwargs)

        for t in tag_inspector(tags, 'ccnode.host.tags'):
        for t in tag_inspector(tags):
            self.tags[t.name] = t

    @pure
+136 −0
Original line number Diff line number Diff line
import logging

import libvirt
from sjrpc.utils import pure

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.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')

    @pure
    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)

    @pure
    def vm_define(self, name):
        pass

    @pure
    def vm_undefine(self, name):
        pass

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

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

    @pure
    def vm_start(self, vm_names=None):
        pass

    @pure
    def vm_suspend(self, vm_names=None):
        pass

    @pure
    def vm_resume(self, vm_names=None):
        pass


class Hypervisor(object):
    """Container for all hypervisor related state."""
    def __init__(self):
        # initialize connection to libvirt
        logger.debug(u'Connecting 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()
        ]
        logger.debug(u'Domains: %s' % unicode(self.domains))

    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
+38 −0
Original line number Diff line number Diff line
from ccnode.tags import Tag
from ccnode.hypervisor import lib as _libvirt
from ccnode.hypervisor.lib import DOMAIN_STATES as STATE


class VirtualMachine(object):
    """Represent a VM instance."""
    def __init__(self, dom):
        """
        :param dom: libvirt domain instance
        """
        #: 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(
            test=Tag('test', 'plop'),
        )

    @property
    def name(self):
        return _libvirt.connection.lookupByUUIDString(self.uuid).name()

    def start():
        pass

    def stop():
        pass

    def pause():
        pass

    def define():
        pass

    def undefined():
        pass
+17 −0
Original line number Diff line number Diff line
"""Helpers for libvirt."""

#: connection to the libvirt
connection = None  # TODO create a watcher thread for this

#: corresponding name for enum state of libvirt domains
# see http://libvirt.org/html/libvirt-libvirt.html#virDomainState
DOMAIN_STATES = (
    'stopped',  # 0 no state
    'running',  # 1 running
    'running',  # 2 blocked
    'paused',  # 3 paused
    'running',  # 4 shutdown
    'stopped',  # 5 shuttoff
    'stopped',  # 6 crashed
    'unknown',  # 7 ??
)
+74 −0
Original line number Diff line number Diff line
from ccnode.utils import and_


# hypervisor related tags
def htype():
    """Hypervisor type."""
    # FIXME for other support
    return u'kvm'


def hv():
    """Hypervisor name."""
    # What is the point of this tag ? if the information not already in a and id
    # ?


def hvm():
    """Hardware virtualization enable."""
    # see
    # http://www.linux-kvm.org/page/FAQ#How_can_I_tell_if_I_have_Intel_VT_or_AMD-V.3F
    # or
    # http://www.cyberciti.biz/faq/linux-xen-vmware-kvm-intel-vt-amd-v-support/
    # if we are in a xen hypervisor we won't see vt in /proc/cpuinfo
    result = {True: u'yes', False: u'no'}

    if htype() == u'kvm':
        # findout in /proc/cpuinfo if all CPUs have virtualisation enabled
        return result[and_(
            set(
                'vmx',  # Intel VT
                'svm',  # AMD 
            ) & set(
                l.split(': ')[-1].split()
            ) for l in open('/proc/cpuinfo').readline() if l.startswith('Tags')
        )]

    return None


def hvver():
    """Hypervisor version."""


def libvirtver():
    """Version of running libvirt."""


# jobs
def rjobs():
    """Number of currently running jobs."""


# storage pools
def sto():
    """Storage pool names."""


# dynamic sto

# Vm related tags
def nvm():
    """Number of VMS in the current hypervisor."""


def vmpaused():
    """Count of VMs paused."""


def vmstarted():
    """Count of VMs started."""


def vmstopped():
    """Count of VMs Stopped."""
Loading