[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |