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.itervalues():
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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):
self.event_loop = EventLoop()
# This tells libvirt what event loop implementation it
# should use
libvirt.virEventRegisterImpl(
self.event_loop.add_handle,
self.event_loop.update_handle,
self.event_loop.remove_handle,
self.event_loop.add_timer,
self.event_loop.update_timer,
self.event_loop.remove_timer,
)
self.event_loop.start()
# TODO cleanup connection on stop
_libvirt.connection = libvirt.open('qemu:///system') # currently only support KVM
#: domains: vms, containers...
self.domains = dict()
# find defined domains
for dom_name in _libvirt.connection.listDefinedDomains():
dom = _libvirt.connection.lookupByName(dom_name)
self.domains[dom.UUID()] = VirtualMachine(dom)
# find started domains
for dom_id in _libvirt.connection.listDomainsID():
dom = _libvirt.connection.lookupByID(dom_id)
self.domains[dom.UUID()] = VirtualMachine(dom)
logger.debug('Domains: %s', self.domains)
self.event_loop.register_callbacks(self.callback)
def callback(self, conn, dom, event, detail, opaque):
"""Callback for libvirt event loop."""
logger.debug("myDomainEventCallback1 EVENT: Domain %s(%s) %s %d" % (dom.name(), dom.UUIDString(), EVENTS[event], detail))
event = EVENTS[event]
if event == 'Added':
self.domains[dom.UUID()] = VirtualMachine(dom)
def get_domain_by_name(self, name):
"""Get a domain by name."""
if d.name == name:
return d
return None
def _count_domain(self, filter=lambda d: True):
count = 0
for dom in self.domains.itervalues():
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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