Make XenServer VM diagnostics available through nova.virt.xenapi.
This commit is contained in:
commit
1a759c3722
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue