xen/13616_xenapi.patch

310 lines
12 KiB
Diff

Index: xen-3.0.4-testing/tools/python/xen/xend/server/DevController.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/server/DevController.py
+++ xen-3.0.4-testing/tools/python/xen/xend/server/DevController.py
@@ -75,7 +75,7 @@ class DevController:
def __init__(self, vm):
self.vm = vm
-
+ self.hotplug = True
def createDevice(self, config):
"""Trigger the creation of a device with the given configuration.
@@ -151,6 +151,9 @@ class DevController:
def waitForDevice(self, devid):
log.debug("Waiting for %s.", devid)
+
+ if not self.hotplug:
+ return
status = self.waitForBackend(devid)
Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPIConstants.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPIConstants.py
+++ xen-3.0.4-testing/tools/python/xen/xend/XendAPIConstants.py
@@ -74,3 +74,4 @@ XEN_API_VBD_MODE = ['RO', 'RW']
XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
XEN_API_VBD_TYPE = ['CD', 'Disk']
+XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp']
Index: xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendAPI.py
+++ xen-3.0.4-testing/tools/python/xen/xend/XendAPI.py
@@ -227,6 +227,27 @@ def valid_vtpm(func):
return check_vtpm_ref
+def valid_console(func):
+ """Decorator to verify if console_ref is valid before calling method.
+
+ @param func: function with params: (self, session, console_ref, ...)
+ @rtype: callable object
+ """
+ def check_console_ref(self, session, console_ref, *args, **kwargs):
+ xendom = XendDomain.instance()
+ if type(console_ref) == type(str()) and \
+ xendom.is_valid_dev('console', console_ref):
+ return func(self, session, console_ref, *args, **kwargs)
+ else:
+ return {'Status': 'Failure',
+ 'ErrorDescription': ('ECONSOLEINVALID', 'Console Invalid')}
+
+ # make sure we keep the 'api' attribute
+ if hasattr(func, 'api'):
+ check_console_ref.api = func.api
+
+ return check_console_ref
+
def valid_sr(func):
"""Decorator to verify if sr_ref is valid before calling
method.
@@ -299,6 +320,7 @@ class XendAPI:
'VIF': (valid_vif, session_required),
'VDI': (valid_vdi, session_required),
'VTPM':(valid_vtpm, session_required),
+ 'console':(valid_console, session_required),
'SR': (valid_sr, session_required)}
# Cheat methods
@@ -719,14 +741,18 @@ class XendAPI:
def VM_get_VTPMs(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vtpms())
+
+ def VM_get_consoles(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success(dom.get_consoles())
def VM_get_PCI_bus(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo() # unsupported by xc
+ return dom.get_pci_bus()
def VM_get_tools_version(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
+ return dom.get_tools_version()
# attributes (rw)
def VM_get_name_label(self, session, vm_ref):
@@ -1507,6 +1533,55 @@ class XendAPI:
return xen_api_success(vtpms)
+ # Xen API: Class console
+ # ----------------------------------------------------------------
+
+
+ console_attr_ro = ['uri', 'protocol', 'VM']
+ console_attr_rw = []
+
+ def console_get_all(self, session):
+ xendom = XendDomain.instance()
+ cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
+ cons = reduce(lambda x, y: x + y, cons)
+ return xen_api_success(cons)
+
+ def console_get_uri(self, session, console_ref):
+ return xen_api_success(xendom.get_dev_property_by_uuid('console',
+ console_ref,
+ 'uri'))
+
+ def console_get_protocol(self, session, console_ref):
+ return xen_api_success(xendom.get_dev_property_by_uuid('console',
+ console_ref,
+ 'protocol'))
+
+ def console_get_VM(self, session, console_ref):
+ xendom = XendDomain.instance()
+ vm = xendom.get_vm_with_dev_uuid('console', console_ref)
+ return xen_api_success(vm.get_uuid())
+
+ # object methods
+ def console_get_record(self, session, console_ref):
+ xendom = XendDomain.instance()
+ vm = xendom.get_vm_with_dev_uuid('console', console_ref)
+ if not vm:
+ return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
+ cfg = vm.get_dev_xenapi_config('console', console_ref)
+ if not cfg:
+ return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
+
+ valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
+ self.Base_attr_ro + self.Base_attr_rw
+
+ return_cfg = {}
+ for k in cfg.keys():
+ if k in valid_console_keys:
+ return_cfg[k] = cfg[k]
+
+ return xen_api_success(return_cfg)
+
+
# Xen API: Class SR
# ----------------------------------------------------------------
SR_attr_ro = ['VDIs',
Index: xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-3.0.4-testing/tools/python/xen/xend/XendConfig.py
@@ -900,8 +900,7 @@ class XendConfig(dict):
if target == None:
target = self
- if dev_type not in XendDevices.valid_devices() and \
- dev_type not in XendDevices.pseudo_devices():
+ if dev_type not in XendDevices.valid_devices():
raise XendConfigError("XendConfig: %s not a valid device type" %
dev_type)
@@ -909,10 +908,10 @@ class XendConfig(dict):
raise XendConfigError("XendConfig: device_add requires some "
"config.")
- if cfg_sxp:
- log.debug("XendConfig.device_add: %s" % str(cfg_sxp))
- if cfg_xenapi:
- log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
+ #if cfg_sxp:
+ # log.debug("XendConfig.device_add: %s" % str(cfg_sxp))
+ #if cfg_xenapi:
+ # log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
if cfg_sxp:
if sxp.child0(cfg_sxp) == 'device':
@@ -952,6 +951,11 @@ class XendConfig(dict):
target['vbd_refs'] = []
if dev_uuid not in target['vbd_refs']:
target['vbd_refs'].append(dev_uuid)
+ elif dev_type in ('console',):
+ if 'console_refs' not in target:
+ target['console_refs'] = []
+ if dev_uuid not in target['console_refs']:
+ target['console_refs'].append(dev_uuid)
return dev_uuid
@@ -1012,6 +1016,25 @@ class XendConfig(dict):
return ''
+ def console_add(self, protocol, uri):
+ dev_uuid = uuid.createString()
+ dev_info = {
+ 'uuid': dev_uuid,
+ 'protocol': protocol,
+ 'uri': uri
+ }
+ if 'devices' not in self:
+ self['devices'] = {}
+
+ self['devices'][dev_uuid] = ('console', dev_info)
+ self['console_refs'].append(dev_uuid)
+ return dev_info
+
+ def console_get_all(self, protocol):
+ consoles = [dinfo for dtype, dinfo in self['devices'].values()
+ if dtype == 'console']
+ return [c for c in consoles if c.get('protocol') == protocol]
+
def device_update(self, dev_uuid, cfg_sxp):
"""Update an existing device with the new configuration.
Index: xen-3.0.4-testing/tools/python/xen/xend/XendDevices.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDevices.py
+++ xen-3.0.4-testing/tools/python/xen/xend/XendDevices.py
@@ -21,6 +21,7 @@
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif
from xen.xend.server.BlktapController import BlktapController
+from xen.xend.server.ConsoleController import ConsoleController
class XendDevices:
""" An ugly halfway point between the module local device name
@@ -43,6 +44,7 @@ class XendDevices:
'tap': BlktapController,
'vfb': vfbif.VfbifController,
'vkbd': vfbif.VkbdifController,
+ 'console': ConsoleController,
}
#@classmethod
@@ -51,11 +53,6 @@ class XendDevices:
valid_devices = classmethod(valid_devices)
#@classmethod
- def pseudo_devices(cls):
- return ['console']
- pseudo_devices = classmethod(pseudo_devices)
-
- #@classmethod
def make_controller(cls, name, domain):
"""Factory function to make device controllers per domain.
Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -680,6 +680,29 @@ class XendDomainInfo:
for device in devices:
self.info.device_add(device[0], cfg_sxp = device)
+ self._update_consoles()
+
+ def _update_consoles(self):
+ if self.domid == None or self.domid == 0:
+ return
+
+ # Update VT100 port if it exists
+ self.console_port = self.readDom('console/port')
+ if self.console_port is not None:
+ serial_consoles = self.info.console_get_all('vt100')
+ if not serial_consoles:
+ cfg = self.info.console_add('vt100', self.console_port)
+ self._createDevice('console', cfg)
+
+ # Update VNC port if it exists
+ vnc_port = self.readDom('console/vnc-port')
+ if vnc_port is not None:
+ vnc_consoles = self.info.console_get_all('rfb')
+ if not vnc_consoles:
+ cfg = self.info.console_add('rfb', 'localhost:%s' %
+ str(vnc_port))
+ self._createDevice('console', cfg)
+
#
# Function to update xenstore /vm/*
#
@@ -1825,7 +1848,8 @@ class XendDomainInfo:
# TODO: we should eventually get rid of old_dom_states
self.info.update_config(info)
-
+ self._update_consoles()
+
if refresh:
self.refreshShutdown(info)
@@ -1837,11 +1861,11 @@ class XendDomainInfo:
ignore_devices = ignore_store,
legacy_only = legacy_only)
- if not ignore_store and self.dompath:
- vnc_port = self.readDom('console/vnc-port')
- if vnc_port is not None:
- result.append(['device',
- ['console', ['vnc-port', str(vnc_port)]]])
+ #if not ignore_store and self.dompath:
+ # vnc_port = self.readDom('console/vnc-port')
+ # if vnc_port is not None:
+ # result.append(['device',
+ # ['console', ['vnc-port', str(vnc_port)]]])
return result