Make XenServer VM diagnostics available through nova.virt.xenapi.

This commit is contained in:
Armando Migliaccio 2010-12-09 20:09:14 +00:00 committed by Tarmac
commit 1a759c3722
3 changed files with 68 additions and 0 deletions

View File

@ -20,15 +20,21 @@ their attributes like VDIs, VIFs, as well as their lookup functions.
"""
import logging
import urllib
from twisted.internet import defer
from xml.dom import minidom
from nova import flags
from nova import utils
from nova.auth.manager import AuthManager
from nova.compute import instance_types
from nova.compute import power_state
from nova.virt import images
FLAGS = flags.FLAGS
XENAPI_POWER_STATE = {
'Halted': power_state.SHUTDOWN,
'Running': power_state.RUNNING,
@ -44,6 +50,15 @@ class VMHelper():
The class that wraps the helper methods together.
"""
def __init__(self):
return
@classmethod
def late_import(cls):
"""
Load the XenAPI module in for helper class, if required.
This is to avoid to install the XenAPI library when other
hypervisors are used
"""
global XenAPI
if XenAPI is None:
XenAPI = __import__('XenAPI')
@ -214,3 +229,40 @@ class VMHelper():
'mem': long(record['memory_dynamic_max']) >> 10,
'num_cpu': record['VCPUs_max'],
'cpu_time': 0}
@classmethod
def compile_diagnostics(cls, session, record):
"""Compile VM diagnostics data"""
try:
host = session.get_xenapi_host()
host_ip = session.get_xenapi().host.get_record(host)["address"]
metrics = session.get_xenapi().VM_guest_metrics.get_record(
record["guest_metrics"])
diags = {
"Kernel": metrics["os_version"]["uname"],
"Distro": metrics["os_version"]["name"]}
xml = get_rrd(host_ip, record["uuid"])
if xml:
rrd = minidom.parseString(xml)
for i, node in enumerate(rrd.firstChild.childNodes):
# We don't want all of the extra garbage
if i >= 3 and i <= 11:
ref = node.childNodes
# Name and Value
diags[ref[0].firstChild.data] = ref[6].firstChild.data
return diags
except XenAPI.Failure as e:
return {"Unable to retrieve diagnostics": e}
def get_rrd(host, uuid):
"""Return the VM RRD XML as a string"""
try:
xml = urllib.urlopen("http://%s:%s@%s/vm_rrd?uuid=%s" % (
FLAGS.xenapi_connection_username,
FLAGS.xenapi_connection_password,
host,
uuid))
return xml.read()
except IOError:
return None

View File

@ -24,6 +24,7 @@ from twisted.internet import defer
from nova import db
from nova import context
from nova.auth.manager import AuthManager
from nova.virt.xenapi.network_utils import NetworkHelper
from nova.virt.xenapi.vm_utils import VMHelper
@ -40,6 +41,8 @@ class VMOps(object):
if XenAPI is None:
XenAPI = __import__('XenAPI')
self._session = session
# Load XenAPI module in the helper class
VMHelper.late_import()
def list_instances(self):
""" List VM instances """
@ -128,6 +131,15 @@ class VMOps(object):
rec = self._session.get_xenapi().VM.get_record(vm)
return VMHelper.compile_info(rec)
@defer.inlineCallbacks
def get_diagnostics(self, instance_id):
"""Return data about VM diagnostics"""
vm = yield VMHelper.lookup(self._session, instance_id)
if vm is None:
raise Exception("instance not present %s" % instance_id)
rec = yield self._session.get_xenapi().VM.get_record(vm)
defer.returnValue(VMHelper.compile_diagnostics(self._session, rec))
def get_console_output(self, instance):
""" Return snapshot of console """
# TODO: implement this to fix pylint!

View File

@ -126,6 +126,10 @@ class XenAPIConnection(object):
""" Return data about VM instance """
return self._vmops.get_info(instance_id)
def get_diagnostics(self, instance_id):
"""Return data about VM diagnostics"""
return self._vmops.get_diagnostics(instance_id)
def get_console_output(self, instance):
""" Return snapshot of console """
return self._vmops.get_console_output(instance)