Newer
Older
# This file is part of CloudControl.
#
# CloudControl is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CloudControl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with CloudControl. If not, see <http://www.gnu.org/licenses/>.
import logging
from functools import wraps
from xml.etree import cElementTree as et
from StringIO import StringIO
logger = logging.getLogger(__name__)
def _vir_tag(func):
"""Catches libvirt related exception.
Decorator used for tag declarations that interacts with libvirt.
"""
@wraps(func)
def decorated(dom):
if not dom.hypervisor.handler.virt_connected:
return
try:
except libvirt.libvirtError as exc:
if 'Domain not found' in str(exc):
# sometimes, libvirt tells us too late when a domain is removed
# we just ignore the error and remove the domain
logger.exception('Unexpected libvirt error')
dom.hypervisor.handler.virt_connect_restart()
return decorated
def uuid(dom):
"""Unique identifier of the domain."""
def status(dom):
return dom.state
def hv(dom):
return dom.hypervisor.name
def htype(dom):
return dom.hypervisor.type
def arch(dom):
"""VM CPU architecture."""
try:
return dict(i686='x86', x86_64='x64')[et.ElementTree().parse(
StringIO(dom.lv_dom.XMLDesc(0))).find('os/type').get('arch')]
except Exception:
logger.exception('Error while get Architecture tag')
def h(dom):
"""Name of the VM."""
return dom.name
def t(dom):
"""Title of the VM (or name if title is not defined)."""
if dom.title is None:
return dom.name
else:
return dom.title
def cpu(dom):
"""Number of CPU of the VM."""
return dom.lv_dom.info()[3]
@_vir_tag
def cpuuse(dom):
"""Represent CPU use in percent average on 5 seconds."""
state, _, _, vcpu, cpu_time = dom.lv_dom.info()
if state != 1: # if VM is not running
return None
old_cpu_stats = dom.cpu_stats
dom.cpu_stats = (dom.hypervisor.handler.main.evloop.now(), cpu_time)
# calculate CPU percentage, code is from virt-manager in domain.py:1210
return '%.2f' % max(0., min(100., ((cpu_time - old_cpu_stats[1]) * 100.) / (
(dom.cpu_stats[0] - old_cpu_stats[0]) * 1000. * 1000. * 1000.) / vcpu))
if dom.state == 'stopped':
return dom.lv_dom.info()[1] * 1024
else:
return dom.lv_dom.info()[2] * 1024
def memmax(dom):
"""Maximum memory allocation."""
return dom.lv_dom.info()[1] * 1024
def vncport(dom):
"""VNC port for the VM console access."""
try:
StringIO(dom.lv_dom.XMLDesc(0))
).find('devices/graphics').get('port')
except Exception:
logger.exception('VNCPort')
try:
if 0 < int(port) < 65536:
return port
except (TypeError, ValueError):
pass
return u' '.join(map(str, xrange(len(dom.disks)))) or None
def nic(dom):
"""VM network interfaces."""
return u' '.join(map(str, xrange(len(dom.nics)))) or None
@refresh(10)
@_vir_tag
def autostart(dom):
"""Autostart status."""
return {True: 'yes', False: 'no'}[bool(dom.lv_dom.autostart())]