[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEND] Preliminary console support in Xen API



# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Date 1169751265 0
# Node ID b111908dd70b82edda1a0e61de6a269a9bff890d
# Parent  3bb7136c8fb4be315e9cd7222c986e33442cbb71
[XEND] Preliminary console support in Xen API

Made serial/vnc consoles a 'fake' device so that we can take advantage
of storing state information in xenstore.

Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx>
---
 tools/python/scripts/xapi.py                  |   29 ++++++++++
 tools/python/xen/xend/XendAPI.py              |   69 +++++++++++++++++++++++++-
 tools/python/xen/xend/XendAPIConstants.py     |    1 
 tools/python/xen/xend/XendConfig.py           |   40 +++++++++++----
 tools/python/xen/xend/XendDevices.py          |    8 +--
 tools/python/xen/xend/XendDomainInfo.py       |   36 +++++++++++--
 tools/python/xen/xend/server/DevController.py |    5 +
 7 files changed, 164 insertions(+), 24 deletions(-)

diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py      Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/scripts/xapi.py      Thu Jan 25 18:54:25 2007 +0000
@@ -40,6 +40,7 @@ VBD_LIST_FORMAT = '%(device)-6s %(uuid)-
 VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
 TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
 VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
+CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(uri)-32s'
 
 COMMANDS = {
     'host-info': ('', 'Get Xen Host Info'),
@@ -485,7 +486,8 @@ def xapi_vbd_list(args, async = False):
     for vbd in vbds:
         vbd_struct = execute(server, 'VBD.get_record', (session, vbd))
         print VBD_LIST_FORMAT % vbd_struct
-
+        
+        
 def xapi_vbd_stats(args, async = False):
     server, session = connect()
     domname = args[0]
@@ -518,6 +520,31 @@ def xapi_vif_list(args, async = False):
         for vif in vifs:
             vif_struct = execute(server, 'VIF.get_record', (session, vif))
             pprint(vif_struct)
+
+def xapi_console_list(args, async = False):
+    server, session = connect()
+    opts, args = parse_args('vdi-list', args, set_defaults = True)
+    is_long = opts and opts.long
+    
+    domname = args[0]
+    
+    dom_uuid = resolve_vm(server, session, domname)
+    consoles = execute(server, 'VM.get_consoles', (session, dom_uuid))
+
+    if not is_long:
+        print CONSOLE_LIST_FORMAT % {'protocol': 'Protocol',
+                                     'uri': 'URI',
+                                     'uuid': 'UUID'}
+
+        for console in consoles:
+            console_struct = execute(server, 'console.get_record',
+                                     (session, console))
+            print CONSOLE_LIST_FORMAT % console_struct
+    else:
+        for console in consoles:
+            console_struct = execute(server, 'console.get_record',
+                                     (session, console))
+            pprint(console_struct)            
 
 
 def xapi_vdi_list(args, async = False):
diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Thu Jan 25 18:54:25 2007 +0000
@@ -228,6 +228,18 @@ def valid_vtpm(func):
            _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
                       'VTPM_HANDLE_INVALID', func, *args, **kwargs)
 
+
+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
+    """
+    return lambda *args, **kwargs: \
+           _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
+                                                                   r),
+                      'CONSOLE_HANDLE_INVALID', func, *args, **kwargs)
+
 def valid_sr(func):
     """Decorator to verify if sr_ref is valid before calling method.
 
@@ -346,6 +358,7 @@ class XendAPI(object):
             'VIF'     : valid_vif,
             'VDI'     : valid_vdi,
             'VTPM'    : valid_vtpm,
+            'console' : valid_console,
             'SR'      : valid_sr,
             'PIF'     : valid_pif,
             'task'    : valid_task,
@@ -983,14 +996,18 @@ class XendAPI(object):
     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):
@@ -1784,6 +1801,54 @@ class XendAPI(object):
         vtpms = reduce(lambda x, y: x + y, vtpms)
         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
     # ----------------------------------------------------------------
diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/xen/xend/XendAPIConstants.py
--- a/tools/python/xen/xend/XendAPIConstants.py Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/xen/xend/XendAPIConstants.py Thu Jan 25 18:54:25 2007 +0000
@@ -75,3 +75,4 @@ XEN_API_DRIVER_TYPE = ['ioemu', 'paravir
 XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
 XEN_API_VBD_TYPE = ['CD', 'Disk']
 XEN_API_TASK_STATUS_TYPE = ['pending', 'success', 'failure']
+XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp']
diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Thu Jan 25 18:54:25 2007 +0000
@@ -918,8 +918,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)
 
@@ -927,10 +926,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':
@@ -971,7 +970,12 @@ 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
 
         if cfg_xenapi:
@@ -1031,7 +1035,25 @@ class XendConfig(dict):
 
         # no valid device to add
         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.
@@ -1211,7 +1233,7 @@ class XendConfig(dict):
                     self[apikey] = val
 
 
-        
+
 #
 # debugging 
 #
diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/xen/xend/XendDevices.py
--- a/tools/python/xen/xend/XendDevices.py      Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/xen/xend/XendDevices.py      Thu Jan 25 18:54:25 2007 +0000
@@ -21,6 +21,8 @@
 
 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,17 +45,13 @@ class XendDevices:
         'tap': BlktapController,
         'vfb': vfbif.VfbifController,
         'vkbd': vfbif.VkbdifController,
+        'console': ConsoleController,
     }
 
     #@classmethod
     def valid_devices(cls):
         return cls.controllers.keys()
     valid_devices = classmethod(valid_devices)
-
-    #@classmethod
-    def pseudo_devices(cls):
-        return ['console']
-    pseudo_devices = classmethod(pseudo_devices)
 
     #@classmethod
     def make_controller(cls, name, domain):
diff -r 3bb7136c8fb4 -r b111908dd70b tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Jan 25 18:50:08 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Jan 25 18:54:25 2007 +0000
@@ -682,6 +682,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/*
     #
@@ -1892,7 +1915,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)
 
@@ -1904,11 +1928,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
 
diff -r 3bb7136c8fb4 -r b111908dd70b 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Thu Jan 25 18:50:08 
2007 +0000
+++ b/tools/python/xen/xend/server/DevController.py     Thu Jan 25 18:54:25 
2007 +0000
@@ -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)
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.