direct-io.hg

changeset 13585:bea3d48576c6

[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 <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Wed Jan 24 14:25:21 2007 +0000 (2007-01-24)
parents 6a54b1d8d105
children 665be23d7fe9
files tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py
line diff
     1.1 --- a/tools/python/xen/xend/XendAPI.py	Wed Jan 24 13:58:06 2007 +0000
     1.2 +++ b/tools/python/xen/xend/XendAPI.py	Wed Jan 24 14:25:21 2007 +0000
     1.3 @@ -329,7 +329,6 @@ class XendAPI:
     1.4              return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
     1.5      session_login_with_password.api = 'session.login_with_password'
     1.6  
     1.7 -
     1.8      # object methods
     1.9      def session_logout(self, session):
    1.10          auth_manager().logout(session)
    1.11 @@ -340,7 +339,9 @@ class XendAPI:
    1.12          record = {'this_host': XendNode.instance().uuid,
    1.13                    'this_user': auth_manager().get_user(session)}
    1.14          return xen_api_success(record)
    1.15 -
    1.16 +    def session_get_all(self):
    1.17 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
    1.18 +    
    1.19      # attributes (ro)
    1.20      def session_get_this_host(self, session):
    1.21          return xen_api_success(XendNode.instance().uuid)
    1.22 @@ -429,6 +430,9 @@ class XendAPI:
    1.23          task = XendTaskManager.get_task(task_ref)
    1.24          return xen_api_success(task.get_record())
    1.25  
    1.26 +    def task_get_by_name_label(self, session, name):
    1.27 +        return xen_api_success(XendTaskManager.get_task_by_name(name))
    1.28 +
    1.29      # Xen API: Class Host
    1.30      # ----------------------------------------------------------------    
    1.31  
    1.32 @@ -497,6 +501,11 @@ class XendAPI:
    1.33          return xen_api_success((XendNode.instance().uuid,))
    1.34      def host_create(self, session, struct):
    1.35          return xen_api_error(XEND_ERROR_UNSUPPORTED)
    1.36 +    def host_get_by_name_label(self, session, name):
    1.37 +        if XendNode.instance().name == name:
    1.38 +            return xen_api_success((XendNode.instance().uuid,))
    1.39 +        return xen_api_success([])
    1.40 +    
    1.41  
    1.42      # Xen API: Class Host_CPU
    1.43      # ----------------------------------------------------------------
    1.44 @@ -507,9 +516,6 @@ class XendAPI:
    1.45                          'utilisation']
    1.46  
    1.47      # attributes
    1.48 -    def host_cpu_get_uuid(self, session, host_cpu_ref):
    1.49 -        uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref)
    1.50 -        return xen_api_success(uuid)
    1.51      def host_cpu_get_host(self, session, host_cpu_ref):
    1.52          return xen_api_success(XendNode.instance().uuid)
    1.53      def host_cpu_get_features(self, session, host_cpu_ref):
    1.54 @@ -749,7 +755,9 @@ class XendAPI:
    1.55                    ('hard_shutdown', None),
    1.56                    ('hard_reboot', None),
    1.57                    ('suspend', None),
    1.58 -                  ('resume', None)]
    1.59 +                  ('resume', None),
    1.60 +                  ('add_to_otherConfig', None),
    1.61 +                  ('remove_from_otherConfig', None)]
    1.62      
    1.63      VM_funcs  = [('create', 'VM'),
    1.64                   ('get_by_name_label', 'Set(VM)')]
    1.65 @@ -884,7 +892,7 @@ class XendAPI:
    1.66      
    1.67      def VM_get_VCPUs_policy(self, session, vm_ref):
    1.68          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.69 -        return xen_api_todo() # need to access scheduler
    1.70 +        return dom.get_vcpus_policy()
    1.71      
    1.72      def VM_get_VCPUs_params(self, session, vm_ref):
    1.73          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.74 @@ -908,7 +916,7 @@ class XendAPI:
    1.75      
    1.76      def VM_get_actions_after_suspend(self, session, vm_ref):
    1.77          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.78 -        return xen_api_success(dom.get_on_suspend())
    1.79 +        return xen_api_success(dom.get_on_suspend())        
    1.80      
    1.81      def VM_get_actions_after_crash(self, session, vm_ref):
    1.82          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.83 @@ -934,31 +942,30 @@ class XendAPI:
    1.84      
    1.85      def VM_get_platform_std_VGA(self, session, vm_ref):
    1.86          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.87 -        return xen_api_todo()
    1.88 +        return xen_api_success(dom.get_platform_std_vga())
    1.89      
    1.90      def VM_get_platform_serial(self, session, vm_ref):
    1.91          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.92 -        return xen_api_todo()
    1.93 +        return xen_api_success(dom.get_platform_serial())        
    1.94      
    1.95      def VM_get_platform_localtime(self, session, vm_ref):
    1.96          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.97 -        return xen_api_todo()
    1.98 +        return xen_api_success(dom.get_platform_localtime())
    1.99      
   1.100      def VM_get_platform_clock_offset(self, session, vm_ref):
   1.101          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.102 -        return xen_api_todo()
   1.103 +        return xen_api_success(dom.get_platform_clock_offset())        
   1.104      
   1.105      def VM_get_platform_enable_audio(self, session, vm_ref):
   1.106          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.107 -        return xen_api_todo()
   1.108 +        return xen_api_success(dom.get_platform_enable_audio())        
   1.109      
   1.110      def VM_get_platform_keymap(self, session, vm_ref):
   1.111          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.112 -        return xen_api_todo()
   1.113 +        return xen_api_success(dom.get_platform_keymap())
   1.114      
   1.115      def VM_get_otherConfig(self, session, vm_ref):
   1.116 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.117 -        return xen_api_todo()
   1.118 +        return self.VM_get('otherConfig', session, vm_ref)        
   1.119  
   1.120      def VM_set_name_label(self, session, vm_ref, label):
   1.121          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.122 @@ -1002,20 +1009,24 @@ class XendAPI:
   1.123          return xen_api_todo()
   1.124      
   1.125      def VM_set_actions_after_shutdown(self, session, vm_ref, action):
   1.126 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.127 -        return xen_api_todo()
   1.128 +        if action not in XEN_API_ON_NORMAL_EXIST:
   1.129 +            return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
   1.130 +        return self.VM_set('actions_after_shutdown', session, vm_ref, action)
   1.131      
   1.132      def VM_set_actions_after_reboot(self, session, vm_ref, action):
   1.133 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.134 -        return xen_api_todo()
   1.135 +        if action not in XEN_API_ON_NORMAL_EXIST:
   1.136 +            return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
   1.137 +        return self.VM_set('actions_after_reboot', session, vm_ref, action)
   1.138      
   1.139      def VM_set_actions_after_suspend(self, session, vm_ref, action):
   1.140 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.141 -        return xen_api_todo()
   1.142 +        if action not in XEN_API_ON_NORMAL_EXIT:
   1.143 +            return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
   1.144 +        return self.VM_set('actions_after_suspend', session, vm_ref, action)
   1.145      
   1.146      def VM_set_actions_after_crash(self, session, vm_ref, action):
   1.147 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.148 -        return xen_api_success_void()
   1.149 +        if action not in XEN_API_ON_CRASH_BEHAVIOUR:
   1.150 +            return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
   1.151 +        return self.VM_set('actions_after_crash', session, vm_ref, action)
   1.152  
   1.153      def VM_set_HVM_boot(self, session, vm_ref, value):
   1.154          return self.VM_set('HVM_boot', session, vm_ref, value)
   1.155 @@ -1035,29 +1046,39 @@ class XendAPI:
   1.156      def VM_set_PV_bootloader_args(self, session, vm_ref, value):
   1.157          return self.VM_set('PV_bootloader_args', session, vm_ref, value)
   1.158  
   1.159 -    def VM_set_platform_std_VGA(self, session, vm_ref):
   1.160 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.161 -        return xen_api_todo()
   1.162 +    def VM_set_platform_std_VGA(self, session, vm_ref, value):
   1.163 +        return self.VM_set('platform_std_vga', session, vm_ref, value)
   1.164      
   1.165 -    def VM_set_platform_serial(self, session, vm_ref, serial):
   1.166 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.167 -        return xen_api_todo()
   1.168 +    def VM_set_platform_serial(self, session, vm_ref, value):
   1.169 +        return self.VM_set('platform_serial', session, vm_ref, value)
   1.170 +
   1.171 +    def VM_set_platform_keymap(self, session, vm_ref, value):
   1.172 +        return self.VM_set('platform_keymap', session, vm_ref, value)
   1.173      
   1.174 -    def VM_set_platform_localtime(self, session, vm_ref, localtime):
   1.175 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.176 -        return xen_api_todo()
   1.177 +    def VM_set_platform_localtime(self, session, vm_ref, value):
   1.178 +        return self.VM_set('platform_localtime', session, vm_ref, value)
   1.179 +    
   1.180 +    def VM_set_platform_clock_offset(self, session, vm_ref, value):
   1.181 +        return self.VM_set('platform_clock_offset', session, vm_ref, value)
   1.182      
   1.183 -    def VM_set_platform_clock_offset(self, session, vm_ref, clock_offset):
   1.184 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.185 -        return xen_api_todo()
   1.186 +    def VM_set_platform_enable_audio(self, session, vm_ref, value):
   1.187 +        return self.VM_set('platform_enable_audio', session, vm_ref, value)
   1.188      
   1.189 -    def VM_set_platform_enable_audio(self, session, vm_ref, enable_audio):
   1.190 +    def VM_set_otherConfig(self, session, vm_ref, value):
   1.191 +        return self.VM_set('otherconfig', session, vm_ref, value)
   1.192 +
   1.193 +    def VM_add_to_otherConfig(self, session, vm_ref, key, value):
   1.194          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.195 -        return xen_api_todo()
   1.196 -    
   1.197 -    def VM_set_otherConfig(self, session, vm_ref):
   1.198 +        if dom and 'otherconfig' in dom.info:
   1.199 +            dom.info['otherconfig'][key] = value
   1.200 +        return xen_api_success_void()
   1.201 +
   1.202 +    def VM_remove_from_otherConfig(self, session, vm_ref, key):
   1.203          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
   1.204 -        return xen_api_todo()
   1.205 +        if dom and 'otherconfig' in dom.info \
   1.206 +               and key in dom.info['otherconfig']:
   1.207 +            del dom.info['otherconfig'][key]
   1.208 +        return xen_api_success_void()        
   1.209      
   1.210      # class methods
   1.211      def VM_get_all(self, session):
   1.212 @@ -1128,7 +1149,7 @@ class XendAPI:
   1.213              'platform_keymap': xeninfo.get_platform_keymap(),
   1.214              'PCI_bus': xeninfo.get_pci_bus(),
   1.215              'tools_version': xeninfo.get_tools_version(),
   1.216 -            'otherConfig': xeninfo.get_other_config()
   1.217 +            'otherConfig': xeninfo.info.get('otherconfig'),
   1.218          }
   1.219          return xen_api_success(record)
   1.220  
   1.221 @@ -1181,8 +1202,6 @@ class XendAPI:
   1.222  
   1.223      # Xen API: Class VBD
   1.224      # ----------------------------------------------------------------
   1.225 -    # Note: accepts a non-API standard 'image' attribute to emulate
   1.226 -    #       regular xm created VBDs
   1.227  
   1.228      VBD_attr_ro = ['image',
   1.229                     'io_read_kbs',
   1.230 @@ -1249,6 +1268,16 @@ class XendAPI:
   1.231          xendom.managed_config_save(dom)
   1.232          return xen_api_success(vbd_ref)
   1.233  
   1.234 +
   1.235 +    def VBD_destroy(self, session, vbd_ref):
   1.236 +        xendom = XendDomain.instance()
   1.237 +        vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
   1.238 +        if not vm:
   1.239 +            return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
   1.240 +
   1.241 +        vm.destroy_vbd(vbd_ref)
   1.242 +        return xen_api_success_void()
   1.243 +
   1.244      # attributes (rw)
   1.245      def VBD_get_VM(self, session, vbd_ref):
   1.246          xendom = XendDomain.instance()
   1.247 @@ -1278,6 +1307,18 @@ class XendAPI:
   1.248          return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
   1.249                                                                'type'))        
   1.250  
   1.251 +    def VBD_get_io_read_kbs(self, session, vbd_ref):
   1.252 +        return xen_api_todo()
   1.253 +    
   1.254 +    def VBD_get_io_write_kbs(self, session, vbd_ref):
   1.255 +        return xen_api_todo()
   1.256 +    
   1.257 +    def VBD_get_all(self, session):
   1.258 +        xendom = XendDomain.instance()
   1.259 +        vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
   1.260 +        vbds = reduce(lambda x, y: x + y, vbds)
   1.261 +        return xen_api_success(vbds)
   1.262 +
   1.263      # Xen API: Class VIF
   1.264      # ----------------------------------------------------------------
   1.265  
   1.266 @@ -1331,6 +1372,59 @@ class XendAPI:
   1.267              return xen_api_error(['VM_HANDLE_INVALID', vif_struct['VM']])
   1.268  
   1.269  
   1.270 +    def VIF_destroy(self, session, vif_ref):
   1.271 +        xendom = XendDomain.instance()
   1.272 +        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
   1.273 +        if not vm:
   1.274 +            return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
   1.275 +
   1.276 +        vm.destroy_vif(vif_ref)
   1.277 +        return xen_api_success_void()
   1.278 +
   1.279 +    # getters/setters
   1.280 +    def VIF_get_VM(self, session, vif_ref):
   1.281 +        xendom = XendDomain.instance()        
   1.282 +        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)        
   1.283 +        return xen_api_success(vm.get_uuid())
   1.284 +    
   1.285 +    def VIF_get_name(self, session, vif_ref):
   1.286 +        xendom = XendDomain.instance()
   1.287 +        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
   1.288 +                                                               'name'))
   1.289 +    def VIF_get_MTU(self, session, vif_ref):
   1.290 +        xendom = XendDomain.instance()
   1.291 +        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
   1.292 +                                                               'MTU'))
   1.293 +    def VIF_get_MAC(self, session, vif_ref):
   1.294 +        xendom = XendDomain.instance()
   1.295 +        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
   1.296 +                                                               'MAC'))
   1.297 +
   1.298 +    def VIF_get_type(self, session, vif_ref):
   1.299 +        xendom = XendDomain.instance()
   1.300 +        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
   1.301 +                                                               'type'))
   1.302 +    
   1.303 +
   1.304 +    def VIF_get_device(self, session, vif_ref):
   1.305 +        xendom = XendDomain.instance()
   1.306 +        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
   1.307 +                                                               'device'))
   1.308 +    
   1.309 + 
   1.310 +    def VIF_get_io_read_kbs(self, session, vif_ref):
   1.311 +        return xen_api_todo()
   1.312 +    
   1.313 +    def VIF_get_io_write_kbs(self, session, vif_ref):
   1.314 +        return xen_api_todo()
   1.315 +    
   1.316 +    def VIF_get_all(self, session):
   1.317 +        xendom = XendDomain.instance()
   1.318 +        vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
   1.319 +        vifs = reduce(lambda x, y: x + y, vifs)
   1.320 +        return xen_api_success(vifs)
   1.321 +
   1.322 +    
   1.323      # Xen API: Class VDI
   1.324      # ----------------------------------------------------------------
   1.325      VDI_attr_ro = ['VBDs',
   1.326 @@ -1445,9 +1539,10 @@ class XendAPI:
   1.327      # Class Functions    
   1.328      def VDI_create(self, session, vdi_struct):
   1.329          sr = XendNode.instance().get_sr()
   1.330 -        sr_ref = vdi_struct['SR']
   1.331 +        sr_ref = vdi_struct.get('SR')
   1.332 +
   1.333          if sr.uuid != sr_ref:
   1.334 -            return xen_api_error(['SR_HANDLE_INVALID', vdi_struct['SR']])
   1.335 +            return xen_api_error(['SR_HANDLE_INVALID', vdi_struct.get('SR')])
   1.336  
   1.337          vdi_uuid = sr.create_image(vdi_struct)
   1.338          return xen_api_success(vdi_uuid)
   1.339 @@ -1542,6 +1637,15 @@ class XendAPI:
   1.340          return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
   1.341                                                                vtpm_ref, 'VM'))
   1.342  
   1.343 +    def VTPM_destroy(self, session, vtpm_ref):
   1.344 +        xendom = XendDomain.instance()
   1.345 +        vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
   1.346 +        if not vm:
   1.347 +            return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
   1.348 +
   1.349 +        vm.destroy_vtpm(vtpm_ref)
   1.350 +        return xen_api_success_void()    
   1.351 +
   1.352      # class methods
   1.353      def VTPM_create(self, session, vtpm_struct):
   1.354          xendom = XendDomain.instance()
   1.355 @@ -1556,6 +1660,12 @@ class XendAPI:
   1.356          else:
   1.357              return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
   1.358  
   1.359 +    def VTPM_get_all(self, session):
   1.360 +        xendom = XendDomain.instance()
   1.361 +        vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
   1.362 +        vtpms = reduce(lambda x, y: x + y, vtpms)
   1.363 +        return xen_api_success(vtpms)
   1.364 +
   1.365  
   1.366      # Xen API: Class SR
   1.367      # ----------------------------------------------------------------
   1.368 @@ -1593,9 +1703,6 @@ class XendAPI:
   1.369      def SR_create(self, session):
   1.370          return xen_api_error(XEND_ERROR_UNSUPPORTED)
   1.371  
   1.372 -    def SR_get_by_uuid(self, session):
   1.373 -        return xen_api_success(XendNode.instance().get_sr().uuid)
   1.374 -
   1.375      # Class Methods
   1.376      def SR_clone(self, session, sr_ref):
   1.377          return xen_api_error(XEND_ERROR_UNSUPPORTED)
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Wed Jan 24 13:58:06 2007 +0000
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Wed Jan 24 14:25:21 2007 +0000
     2.3 @@ -984,6 +984,8 @@ class XendConfig(dict):
     2.4                  #    dev_info['vifname'] = cfg_xenapi.get('device')
     2.5                  if cfg_xenapi.get('type'):
     2.6                      dev_info['type'] = cfg_xenapi.get('type')
     2.7 +                if cfg_xenapi.get('name'):
     2.8 +                    dev_info['name'] = cfg_xenapi.get('name')
     2.9                  
    2.10                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
    2.11                  dev_info['uuid'] = dev_uuid
     3.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 24 13:58:06 2007 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 24 14:25:21 2007 +0000
     3.3 @@ -548,8 +548,6 @@ class XendDomainInfo:
     3.4                  
     3.5          return self.getDeviceController(deviceClass).destroyDevice(devid, force)
     3.6  
     3.7 -
     3.8 -
     3.9      def getDeviceSxprs(self, deviceClass):
    3.10          if self.state == DOM_STATE_RUNNING:
    3.11              return self.getDeviceController(deviceClass).sxprs()
    3.12 @@ -1221,7 +1219,12 @@ class XendDomainInfo:
    3.13          for (devclass, config) in self.info.get('devices', {}).values():
    3.14              if devclass in XendDevices.valid_devices():            
    3.15                  log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
    3.16 -                self._createDevice(devclass, config)
    3.17 +                dev_uuid = config.get('uuid')
    3.18 +                devid = self._createDevice(devclass, config)
    3.19 +                
    3.20 +                # store devid in XendConfig for caching reasons
    3.21 +                if dev_uuid in self.info['devices']:
    3.22 +                    self.info['devices'][dev_uuid][1]['devid'] = devid
    3.23  
    3.24          if self.image:
    3.25              self.image.createDeviceModel()
    3.26 @@ -1951,11 +1954,9 @@ class XendDomainInfo:
    3.27      def get_platform_keymap(self):
    3.28          return self.info.get('platform_keymap', '')
    3.29      def get_pci_bus(self):
    3.30 -        return '' # TODO
    3.31 +        return self.info.get('pci_bus', '')
    3.32      def get_tools_version(self):
    3.33 -        return {} # TODO
    3.34 -    def get_other_config(self):
    3.35 -        return {} # TODO
    3.36 +        return self.info.get('tools_version', {})
    3.37      
    3.38      def get_on_shutdown(self):
    3.39          after_shutdown = self.info.get('action_after_shutdown')
    3.40 @@ -2203,6 +2204,32 @@ class XendDomainInfo:
    3.41  
    3.42          return dev_uuid
    3.43  
    3.44 +    def destroy_device_by_uuid(self, dev_type, dev_uuid):
    3.45 +        if dev_uuid not in self.info['devices']:
    3.46 +            raise XendError('Device does not exist')
    3.47 +
    3.48 +        try:
    3.49 +            if self.state == XEN_API_VM_POWER_STATE_RUNNING:
    3.50 +                _, config = self.info['devices'][dev_uuid]
    3.51 +                devid = config.get('devid')
    3.52 +                if devid != None:
    3.53 +                    self.getDeviceController(dev_type).destroyDevice(devid, force = False)
    3.54 +                else:
    3.55 +                    raise XendError('Unable to get devid for device: %s:%s' %
    3.56 +                                    (dev_type, dev_uuid))
    3.57 +        finally:
    3.58 +            del self.info['devices'][dev_uuid]
    3.59 +            self.info['%s_refs' % dev_type].remove(dev_uuid)
    3.60 +
    3.61 +    def destroy_vbd(self, dev_uuid):
    3.62 +        self.destroy_device_by_uuid('vbd', dev_uuid)
    3.63 +
    3.64 +    def destroy_vif(self, dev_uuid):
    3.65 +        self.destroy_device_by_uuid('vif', dev_uuid)
    3.66 +
    3.67 +    def destroy_vtpm(self, dev_uuid):
    3.68 +        self.destroy_device_by_uuid('vtpm', dev_uuid)
    3.69 +            
    3.70      def has_device(self, dev_class, dev_uuid):
    3.71          return (dev_uuid in self.info['%s_refs' % dev_class.lower()])
    3.72