# HG changeset patch # User Alastair Tse # Date 1169648721 0 # Node ID bea3d48576c66663e559fbba1bcd9f840a3d1b25 # Parent 6a54b1d8d1053c4facfef8c3c1da871950a5b29c [XEND] Add missing Xen API methods * Added session.get_all, task.get_by_name_label, host.get_by_name_label, VM.add_to_otherConfig, VM.remove_from_otherConfig * Added implementations for VM.get_VCPUs_policy, VM.get_platform_std_vga, VM.get_vm_by_uuid, VM.get_platform_localtime, VM.get_platform_clock_offset, VM.get_platform_enable_audio, VM.get_platform_keymap, VM.get_otherConfig, VM.set_actions_after_shutdown, VM.set_actions_after_reboot, VM.set_actions_after_suspend, VM.set_actions_after_crash, VM.set_platform_std_VGA, VM.set_platform_serial, VM.set_platform_keymap, VM.set_platform_localtime, VM.set_platform_clock_offset, VM.set_platform_enable_audio, VM.set_otherConfig, VBD.destroy, VBD.get_io_read_kbs, VBD.get_io_write_kbs, VBD.get_all, VIF.destroy, VIF.get_VM, VIF.get_name, VIF.get_MTU, VIF.get_MAC, VIF.get_type, VIF.get_device, VIF.get_io_read_kbs, VIF.get_io_write_kbs, VIF.get_all, VTPM.destroy, VTPM.get_all * Save devid of a device on creation in XendDomainInfo Signed-off-by: Alastair Tse 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 @@ -406,7 +406,6 @@ class XendAPI: return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED) session_login_with_password.api = 'session.login_with_password' - # object methods def session_logout(self, session): auth_manager().logout(session) @@ -417,7 +416,9 @@ class XendAPI: record = {'this_host': XendNode.instance().uuid, 'this_user': auth_manager().get_user(session)} return xen_api_success(record) - + def session_get_all(self): + return xen_api_error(XEND_ERROR_UNSUPPORTED) + # attributes (ro) def session_get_this_host(self, session): return xen_api_success(XendNode.instance().uuid) @@ -504,6 +505,11 @@ class XendAPI: return xen_api_success((XendNode.instance().uuid,)) def host_create(self, session, struct): return xen_api_error(XEND_ERROR_UNSUPPORTED) + def host_get_by_name_label(self, session, name): + if XendNode.instance().name == name: + return xen_api_success((XendNode.instance().uuid,)) + return xen_api_success([]) + # Xen API: Class Host_CPU # ---------------------------------------------------------------- @@ -514,9 +520,6 @@ class XendAPI: 'utilisation'] # attributes - def host_cpu_get_uuid(self, session, host_cpu_ref): - uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref) - return xen_api_success(uuid) def host_cpu_get_host(self, session, host_cpu_ref): return xen_api_success(XendNode.instance().uuid) def host_cpu_get_features(self, session, host_cpu_ref): @@ -752,7 +755,7 @@ class XendAPI: def VM_get_VCPUs_policy(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() # need to access scheduler + return dom.get_vcpus_policy() def VM_get_VCPUs_params(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -776,7 +779,7 @@ class XendAPI: def VM_get_actions_after_suspend(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success(dom.get_on_suspend()) + return xen_api_success(dom.get_on_suspend()) def VM_get_actions_after_crash(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -802,31 +805,30 @@ class XendAPI: def VM_get_platform_std_VGA(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_std_vga()) def VM_get_platform_serial(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_serial()) def VM_get_platform_localtime(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_localtime()) def VM_get_platform_clock_offset(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_clock_offset()) def VM_get_platform_enable_audio(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_enable_audio()) def VM_get_platform_keymap(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return xen_api_success(dom.get_platform_keymap()) def VM_get_otherConfig(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() + return self.VM_get('otherConfig', session, vm_ref) def VM_set_name_label(self, session, vm_ref, label): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) @@ -870,20 +872,24 @@ class XendAPI: return xen_api_success_void() def VM_set_actions_after_shutdown(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + if action not in XEN_API_ON_NORMAL_EXIST: + return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) + return self.VM_set('actions_after_shutdown', session, vm_ref, action) def VM_set_actions_after_reboot(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + if action not in XEN_API_ON_NORMAL_EXIST: + return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) + return self.VM_set('actions_after_reboot', session, vm_ref, action) def VM_set_actions_after_suspend(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + if action not in XEN_API_ON_NORMAL_EXIT: + return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref]) + return self.VM_set('actions_after_suspend', session, vm_ref, action) def VM_set_actions_after_crash(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + if action not in XEN_API_ON_CRASH_BEHAVIOUR: + return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref]) + return self.VM_set('actions_after_crash', session, vm_ref, action) def VM_set_HVM_boot(self, session, vm_ref, value): return self.VM_set('HVM_boot', session, vm_ref, value) @@ -903,29 +909,26 @@ class XendAPI: def VM_set_PV_bootloader_args(self, session, vm_ref, value): return self.VM_set('PV_bootloader_args', session, vm_ref, value) - def VM_set_platform_std_VGA(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() - - def VM_set_platform_serial(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + def VM_set_platform_std_VGA(self, session, vm_ref, value): + return self.VM_set('platform_std_vga', session, vm_ref, value) - def VM_set_platform_localtime(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + def VM_set_platform_serial(self, session, vm_ref, value): + return self.VM_set('platform_serial', session, vm_ref, value) + + def VM_set_platform_keymap(self, session, vm_ref, value): + return self.VM_set('platform_keymap', session, vm_ref, value) + + def VM_set_platform_localtime(self, session, vm_ref, value): + return self.VM_set('platform_localtime', session, vm_ref, value) - def VM_set_platform_clock_offset(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + def VM_set_platform_clock_offset(self, session, vm_ref, value): + return self.VM_set('platform_clock_offset', session, vm_ref, value) - def VM_set_platform_enable_audio(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + def VM_set_platform_enable_audio(self, session, vm_ref, value): + return self.VM_set('platform_enable_audio', session, vm_ref, value) - def VM_set_otherConfig(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_success_void() + def VM_set_otherConfig(self, session, vm_ref, value): + return self.VM_set('otherconfig', session, vm_ref, value) # class methods def VM_get_all(self, session): @@ -995,7 +998,7 @@ class XendAPI: 'platform_keymap': xeninfo.get_platform_keymap(), 'PCI_bus': xeninfo.get_pci_bus(), 'tools_version': xeninfo.get_tools_version(), - 'otherConfig': xeninfo.get_other_config() + 'otherConfig': xeninfo.info.get('otherconfig'), } return xen_api_success(record) @@ -1030,8 +1033,6 @@ class XendAPI: # Xen API: Class VBD # ---------------------------------------------------------------- - # Note: accepts a non-API standard 'image' attribute to emulate - # regular xm created VBDs VBD_attr_ro = ['image', 'io_read_kbs', @@ -1097,6 +1098,16 @@ class XendAPI: xendom.managed_config_save(dom) return xen_api_success(vbd_ref) + + def VBD_destroy(self, session, vbd_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref) + if not vm: + return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref]) + + vm.destroy_vbd(vbd_ref) + return xen_api_success_void() + # attributes (rw) def VBD_get_VM(self, session, vbd_ref): xendom = XendDomain.instance() @@ -1123,6 +1134,18 @@ class XendAPI: return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref, 'type')) + def VBD_get_io_read_kbs(self, session, vbd_ref): + return xen_api_todo() + + def VBD_get_io_write_kbs(self, session, vbd_ref): + return xen_api_todo() + + def VBD_get_all(self, session): + xendom = XendDomain.instance() + vbds = [d.get_vbds() for d in XendDomain.instance().list('all')] + vbds = reduce(lambda x, y: x + y, vbds) + return xen_api_success(vbds) + # Xen API: Class VIF # ---------------------------------------------------------------- @@ -1173,6 +1196,59 @@ class XendAPI: return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + def VIF_destroy(self, session, vif_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) + if not vm: + return xen_api_error(['VIF_HANDLE_INVALID', vif_ref]) + + vm.destroy_vif(vif_ref) + return xen_api_success_void() + + # getters/setters + def VIF_get_VM(self, session, vif_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) + return xen_api_success(vm.get_uuid()) + + def VIF_get_name(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'name')) + def VIF_get_MTU(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'MTU')) + def VIF_get_MAC(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'MAC')) + + def VIF_get_type(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'type')) + + + def VIF_get_device(self, session, vif_ref): + xendom = XendDomain.instance() + return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref, + 'device')) + + + def VIF_get_io_read_kbs(self, session, vif_ref): + return xen_api_todo() + + def VIF_get_io_write_kbs(self, session, vif_ref): + return xen_api_todo() + + def VIF_get_all(self, session): + xendom = XendDomain.instance() + vifs = [d.get_vifs() for d in XendDomain.instance().list('all')] + vifs = reduce(lambda x, y: x + y, vifs) + return xen_api_success(vifs) + + # Xen API: Class VDI # ---------------------------------------------------------------- VDI_attr_ro = ['VBDs', @@ -1401,6 +1477,15 @@ class XendAPI: xendom = XendDomain.instance() return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM')) + def VTPM_destroy(self, session, vtpm_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) + if not vm: + return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref]) + + vm.destroy_vtpm(vtpm_ref) + return xen_api_success_void() + # class methods def VTPM_create(self, session, vtpm_struct): xendom = XendDomain.instance() @@ -1415,6 +1500,12 @@ class XendAPI: else: return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + def VTPM_get_all(self, session): + xendom = XendDomain.instance() + vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')] + vtpms = reduce(lambda x, y: x + y, vtpms) + return xen_api_success(vtpms) + # Xen API: Class SR # ---------------------------------------------------------------- @@ -1451,9 +1542,6 @@ class XendAPI: def SR_create(self, session): return xen_api_error(XEND_ERROR_UNSUPPORTED) - def SR_get_by_uuid(self, session): - return xen_api_success(XendNode.instance().get_sr().uuid) - # Class Methods def SR_clone(self, session, sr_ref): return xen_api_error(XEND_ERROR_UNSUPPORTED) 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 @@ -954,6 +954,8 @@ class XendConfig(dict): # dev_info['vifname'] = cfg_xenapi.get('device') if cfg_xenapi.get('type'): dev_info['type'] = cfg_xenapi.get('type') + if cfg_xenapi.get('name'): + dev_info['name'] = cfg_xenapi.get('name') dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) dev_info['uuid'] = dev_uuid 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 @@ -525,8 +525,6 @@ class XendDomainInfo: return self.getDeviceController(deviceClass).destroyDevice(devid, force) - - def getDeviceSxprs(self, deviceClass): if self.state == DOM_STATE_RUNNING: return self.getDeviceController(deviceClass).sxprs() @@ -1215,7 +1213,12 @@ class XendDomainInfo: devclass, config = self.info['devices'][dev_uuid] if devclass in XendDevices.valid_devices(): log.info("createDevice: %s : %s" % (devclass, scrub_password(config))) - self._createDevice(devclass, config) + dev_uuid = config.get('uuid') + devid = self._createDevice(devclass, config) + + # store devid in XendConfig for caching reasons + if dev_uuid in self.info['devices']: + self.info['devices'][dev_uuid][1]['devid'] = devid if self.image: self.image.createDeviceModel() @@ -1887,11 +1890,9 @@ class XendDomainInfo: def get_platform_keymap(self): return self.info.get('platform_keymap', '') def get_pci_bus(self): - return '' # TODO + return self.info.get('pci_bus', '') def get_tools_version(self): - return {} # TODO - def get_other_config(self): - return {} # TODO + return self.info.get('tools_version', {}) def get_on_shutdown(self): after_shutdown = self.info.get('action_after_shutdown') @@ -2112,6 +2113,32 @@ class XendDomainInfo: return dev_uuid + def destroy_device_by_uuid(self, dev_type, dev_uuid): + if dev_uuid not in self.info['devices']: + raise XendError('Device does not exist') + + try: + if self.state == XEN_API_VM_POWER_STATE_RUNNING: + _, config = self.info['devices'][dev_uuid] + devid = config.get('devid') + if devid != None: + self.getDeviceController(dev_type).destroyDevice(devid, force = False) + else: + raise XendError('Unable to get devid for device: %s:%s' % + (dev_type, dev_uuid)) + finally: + del self.info['devices'][dev_uuid] + self.info['%s_refs' % dev_type].remove(dev_uuid) + + def destroy_vbd(self, dev_uuid): + self.destroy_device_by_uuid('vbd', dev_uuid) + + def destroy_vif(self, dev_uuid): + self.destroy_device_by_uuid('vif', dev_uuid) + + def destroy_vtpm(self, dev_uuid): + self.destroy_device_by_uuid('vtpm', dev_uuid) + def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()])