ia64/xen-unstable

changeset 13596:9292da5e9a27

Test scripts for Xen API updated to support Async support
author Alastair Tse <atse@xensource.com>
date Wed Jan 24 13:49:25 2007 +0000 (2007-01-24)
parents 248a9c36d816
children f06f8e134c48
files tools/python/scripts/test_vm_create.py tools/python/scripts/xapi.py
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/python/scripts/test_vm_create.py	Wed Jan 24 13:49:25 2007 +0000
     1.3 @@ -0,0 +1,177 @@
     1.4 +#!/usr/bin/python
     1.5 +
     1.6 +vm_cfg = {
     1.7 +    'name_label': 'APIVM',
     1.8 +    'user_version': 1,
     1.9 +    'is_a_template': False,
    1.10 +    'auto_power_on': False, # TODO
    1.11 +
    1.12 +    'memory_static_min': 64,    
    1.13 +    'memory_static_max': 128,
    1.14 +    #'memory_dynamic_min': 64,
    1.15 +    #'memory_dynamic_max': 128,
    1.16 +    
    1.17 +    
    1.18 +    'VCPUs_policy': 'credit',
    1.19 +    'VCPUs_params': '',
    1.20 +    'VCPUs_number': 2,
    1.21 +    'VCPUs_features_required': '',
    1.22 +    'VCPUs_features_can_use': '',
    1.23 +    'VCPUs_features_force_on': '',
    1.24 +    'VCPUs_features_force_off': '',
    1.25 +
    1.26 +    'actions_after_shutdown': 'destroy',
    1.27 +    'actions_after_reboot': 'restart',
    1.28 +    'actions_after_suspend': 'destroy',
    1.29 +    'actions_after_crash': 'destroy',
    1.30 +    
    1.31 +    'PV_bootloader': '',
    1.32 +    'PV_bootloader_args': '',
    1.33 +    
    1.34 +    'PV_kernel': '/boot/vmlinuz-2.6.18-xenU',
    1.35 +    'PV_ramdisk': '',
    1.36 +    'PV_args': 'root=/dev/sda1 ro',
    1.37 +
    1.38 +    #'HVM_boot': '',
    1.39 +    'platform_std_VGA': False,
    1.40 +    'platform_serial': '',
    1.41 +    'platform_localtime': False,
    1.42 +    'platform_clock_offset': False,
    1.43 +    'platform_enable_audio': False,
    1.44 +    'PCI_bus': ''
    1.45 +}
    1.46 +
    1.47 +vdi_cfg = {
    1.48 +    'name_label': 'API_VDI',
    1.49 +    'name_description': '',
    1.50 +    'virtual_size': 100 * 1024,
    1.51 +    'sector_size': 1024,
    1.52 +    'type': 'system',
    1.53 +    'parent': '',    
    1.54 +    'sharable': False,
    1.55 +    'read_only': False,
    1.56 +}
    1.57 +
    1.58 +vbd_cfg = {
    1.59 +    'VDI': '',
    1.60 +    'VM': '',
    1.61 +    'device': 'sda2',
    1.62 +    'mode': 'RW',
    1.63 +    'type': 'disk',
    1.64 +    'driver': 'paravirtualised',
    1.65 +}
    1.66 +
    1.67 +local_vbd_cfg = {
    1.68 +    'VDI': '',
    1.69 +    'VM': '',
    1.70 +    'device': 'sda1',
    1.71 +    'mode': 'RW',
    1.72 +    'type': 'disk',
    1.73 +    'driver': 'paravirtualised',
    1.74 +    'image': 'file:/root/gentoo.amd64.img'
    1.75 +}
    1.76 +
    1.77 +vif_cfg = {
    1.78 +    'name': 'API_VIF',
    1.79 +    'type': 'paravirtualised',
    1.80 +    'device': '',
    1.81 +    'network': '',
    1.82 +    'MAC': '',
    1.83 +    'MTU': 1500,
    1.84 +}    
    1.85 +
    1.86 +import sys
    1.87 +import time
    1.88 +sys.path.append('/usr/lib/python')
    1.89 +
    1.90 +from xapi import connect, execute
    1.91 +
    1.92 +def test_vm_create():
    1.93 +    server, session = connect()
    1.94 +    vm_uuid = None
    1.95 +    vdi_uuid = None
    1.96 +    local_vbd_uuid = None
    1.97 +    vbd_uuid = None
    1.98 +    vif_uuid = None
    1.99 +    
   1.100 +    # List all VMs
   1.101 +    vm_list = execute(server, 'VM.get_all', (session,))
   1.102 +    vm_names = []
   1.103 +    for vm_uuid in vm_list:
   1.104 +        vm_record = execute(server, 'VM.get_record', (session, vm_uuid))
   1.105 +        vm_names.append(vm_record['name_label'])
   1.106 +
   1.107 +    # Get default SR
   1.108 +    sr_list = execute(server, 'SR.get_by_name_label', (session, 'Local'))
   1.109 +    sr_uuid = sr_list[0]
   1.110 +
   1.111 +    # Get default network
   1.112 +    net_list = execute(server, 'network.get_all', (session,))
   1.113 +    net_uuid = net_list[0]
   1.114 +
   1.115 +    try:
   1.116 +        # Create a new VM
   1.117 +        vm_uuid = execute(server, 'VM.create', (session, vm_cfg))
   1.118 +        
   1.119 +        # Create a new VDI
   1.120 +        vdi_cfg['SR'] = sr_uuid
   1.121 +        vdi_uuid = execute(server, 'VDI.create', (session, vdi_cfg))
   1.122 +
   1.123 +        # Create a VDI backed VBD
   1.124 +        vbd_cfg['VM'] = vm_uuid
   1.125 +        vbd_cfg['VDI'] = vdi_uuid
   1.126 +        vbd_uuid = execute(server, 'VBD.create', (session, vbd_cfg))
   1.127 +
   1.128 +        # Create a new VBD (Local)
   1.129 +        local_vbd_cfg['VM'] = vm_uuid
   1.130 +        local_vbd_cfg['VDI'] = ''
   1.131 +        local_vbd_uuid = execute(server, 'VBD.create',
   1.132 +                                 (session, local_vbd_cfg))
   1.133 +        
   1.134 +        # Create a new VIF
   1.135 +        vif_cfg['network'] = net_uuid
   1.136 +        vif_cfg['VM'] = vm_uuid
   1.137 +        vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
   1.138 +
   1.139 +        # Start the VM
   1.140 +        execute(server, 'VM.start', (session, vm_uuid, False))
   1.141 +
   1.142 +        time.sleep(30)
   1.143 +
   1.144 +        print 'Suspending VM..'
   1.145 +        execute(server, 'VM.suspend', (session, vm_uuid))
   1.146 +        print 'Suspended VM.'
   1.147 +        time.sleep(5)
   1.148 +        print 'Resuming VM ...'
   1.149 +        execute(server, 'VM.resume', (session, vm_uuid, False))
   1.150 +        print 'Resumed VM.'
   1.151 +
   1.152 +        # Wait for user to say we're good to shut it down
   1.153 +        while True:
   1.154 +            destroy = raw_input('destroy VM? ')
   1.155 +            if destroy[0] in ('y', 'Y'):
   1.156 +                break
   1.157 +
   1.158 +    finally:
   1.159 +        # Clean up
   1.160 +        if vif_uuid:
   1.161 +            execute(server, 'VIF.destroy', (session, vif_uuid))
   1.162 +        if local_vbd_uuid:
   1.163 +            execute(server, 'VBD.destroy', (session, local_vbd_uuid))
   1.164 +        if vbd_uuid:
   1.165 +            execute(server, 'VBD.destroy', (session, vbd_uuid))
   1.166 +        if vdi_uuid:
   1.167 +            execute(server, 'VDI.destroy', (session, vdi_uuid))
   1.168 +        if vm_uuid:
   1.169 +            try:
   1.170 +                execute(server, 'VM.hard_shutdown', (session, vm_uuid))
   1.171 +                time.sleep(2)
   1.172 +            except:
   1.173 +                pass
   1.174 +                
   1.175 +            execute(server, 'VM.destroy', (session, vm_uuid))
   1.176 +
   1.177 +
   1.178 +if __name__ == "__main__":
   1.179 +    test_vm_create()
   1.180 +    
     2.1 --- a/tools/python/scripts/xapi.py	Wed Jan 24 13:26:26 2007 +0000
     2.2 +++ b/tools/python/scripts/xapi.py	Wed Jan 24 13:49:25 2007 +0000
     2.3 @@ -17,6 +17,8 @@
     2.4  #============================================================================
     2.5  
     2.6  import sys
     2.7 +import time
     2.8 +import re
     2.9  sys.path.append('/usr/lib/python')
    2.10  
    2.11  from xen.util.xmlrpclib2 import ServerProxy
    2.12 @@ -35,8 +37,9 @@ SR_LIST_FORMAT = '%(name_label)-18s %(uu
    2.13                   '%(type)-10s'
    2.14  VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
    2.15                    '%(sector_size)-8s'
    2.16 -VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\
    2.17 -                  '%(image)-8s'
    2.18 +VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s %(image)-8s'
    2.19 +TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
    2.20 +VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
    2.21  
    2.22  COMMANDS = {
    2.23      'host-info': ('', 'Get Xen Host Info'),
    2.24 @@ -49,7 +52,7 @@ COMMANDS = {
    2.25      'vdi-create': ('<pycfg> [opts]', 'Create a VDI'),
    2.26      'vdi-list'  : ('', 'List all VDI'),
    2.27      'vdi-rename': ('<vdi_uuid> <new_name>', 'Rename VDI'),
    2.28 -    'vdi-delete': ('<vdi_uuid>', 'Delete VDI'),
    2.29 +    'vdi-destroy': ('<vdi_uuid>', 'Delete VDI'),
    2.30      'vif-create': ('<domname> <pycfg>', 'Create VIF attached to domname'),
    2.31      'vtpm-create' : ('<domname> <pycfg>', 'Create VTPM attached to domname'),
    2.32  
    2.33 @@ -61,6 +64,7 @@ COMMANDS = {
    2.34      'vm-shutdown': ('<name> [opts]', 'Shutdown VM with name'),
    2.35      'vm-start':  ('<name>', 'Start VM with name'),
    2.36      'vm-uuid':   ('<name>', 'UUID of a domain by name.'),
    2.37 +    'async-vm-start': ('<name>', 'Start VM asynchronously'),
    2.38  }
    2.39  
    2.40  OPTIONS = {
    2.41 @@ -140,8 +144,13 @@ def parse_args(cmd_name, args, set_defau
    2.42                                            values = defaults)
    2.43      return opts, extraargs
    2.44  
    2.45 -def execute(fn, *args):
    2.46 -    result = fn(*args)
    2.47 +def execute(server, fn, args, async = False):
    2.48 +    if async:
    2.49 +        func = eval('server.Async.%s' % fn)
    2.50 +    else:
    2.51 +        func = eval('server.%s' % fn)
    2.52 +        
    2.53 +    result = func(*args)
    2.54      if type(result) != DictType:
    2.55          raise TypeError("Function returned object of type: %s" %
    2.56                          str(type(result)))
    2.57 @@ -152,14 +161,14 @@ def execute(fn, *args):
    2.58  _initialised = False
    2.59  _server = None
    2.60  _session = None
    2.61 -def _connect(*args):
    2.62 +def connect(*args):
    2.63      global _server, _session, _initialised
    2.64      if not _initialised:
    2.65 -        _server = ServerProxy('httpu:///var/run/xend/xen-api.sock')
    2.66 +        _server = ServerProxy('http://localhost:9363/')
    2.67          login = raw_input("Login: ")
    2.68          password = getpass()
    2.69          creds = (login, password)
    2.70 -        _session = execute(_server.session.login_with_password, *creds)
    2.71 +        _session = execute(_server.session, 'login_with_password', creds)
    2.72          _initialised = True
    2.73      return (_server, _session)
    2.74  
    2.75 @@ -172,14 +181,14 @@ def _read_python_cfg(filename):
    2.76      return cfg
    2.77  
    2.78  def resolve_vm(server, session, vm_name):
    2.79 -    vm_uuid = execute(server.VM.get_by_name_label, session, vm_name)
    2.80 +    vm_uuid = execute(server, 'VM.get_by_name_label', (session, vm_name))
    2.81      if not vm_uuid:
    2.82          return None
    2.83      else:
    2.84          return vm_uuid[0]
    2.85  
    2.86  def resolve_vdi(server, session, vdi_name):
    2.87 -    vdi_uuid = execute(server.VDI.get_by_name_label, session, vdi_name)
    2.88 +    vdi_uuid = execute(server, 'VDI.get_by_name_label', (session, vdi_name))
    2.89      if not vdi_uuid:
    2.90          return None
    2.91      else:
    2.92 @@ -189,11 +198,11 @@ def resolve_vdi(server, session, vdi_nam
    2.93  # Actual commands
    2.94  #
    2.95  
    2.96 -def xapi_host_info(*args):
    2.97 -    server, session = _connect()
    2.98 -    hosts = execute(server.host.get_all, session)
    2.99 +def xapi_host_info(args, async = False):
   2.100 +    server, session = connect()
   2.101 +    hosts = execute(server, 'host.get_all', (session,))
   2.102      for host in hosts: # there is only one, but ..
   2.103 -        hostinfo = execute(server.host.get_record, session, host)
   2.104 +        hostinfo = execute(server, 'host.get_record', (session, host))
   2.105          print HOST_INFO_FORMAT % ('Name', hostinfo['name_label'])
   2.106          print HOST_INFO_FORMAT % ('Version', hostinfo['software_version'])
   2.107          print HOST_INFO_FORMAT % ('CPUs', len(hostinfo['host_CPUs']))
   2.108 @@ -201,44 +210,44 @@ def xapi_host_info(*args):
   2.109          print HOST_INFO_FORMAT % ('UUID', host)        
   2.110  
   2.111          for host_cpu_uuid in hostinfo['host_CPUs']:
   2.112 -            host_cpu = execute(server.host_cpu.get_record, session,
   2.113 -                               host_cpu_uuid)
   2.114 +            host_cpu = execute(server, 'host_cpu.get_record',
   2.115 +                               (session, host_cpu_uuid))
   2.116              print 'CPU %s Util: %.2f' % (host_cpu['number'],
   2.117                                           float(host_cpu['utilisation']))
   2.118          
   2.119 -def xapi_host_set_name(*args):
   2.120 +def xapi_host_set_name(args, async = False):
   2.121      if len(args) < 1:
   2.122          raise OptionError("No hostname specified")
   2.123      
   2.124 -    server, session = _connect()
   2.125 -    hosts = execute(server.host.get_all, session)
   2.126 +    server, session = connect()
   2.127 +    hosts = execute(server, 'host.get_all', (session,))
   2.128      if len(hosts) > 0:
   2.129 -        execute(server.host.set_name_label, session, hosts[0], args[0])
   2.130 -        print 'Hostname: %s' % execute(server.host.get_name_label, session,
   2.131 -                                       hosts[0])
   2.132 +        execute(server, 'host.set_name_label', (session, hosts[0], args[0]))
   2.133 +        print 'Hostname: %s' % execute(server, 'host.get_name_label',
   2.134 +                                       (session, hosts[0]))
   2.135  
   2.136 -def xapi_vm_uuid(*args):
   2.137 +def xapi_vm_uuid(args, async = False):
   2.138      if len(args) < 1:
   2.139          raise OptionError("No domain name specified")
   2.140      
   2.141 -    server, session = _connect()
   2.142 +    server, session = connect()
   2.143      vm_uuid = resolve_vm(server, session, args[0])
   2.144      print vm_uuid
   2.145  
   2.146 -def xapi_vm_name(*args):
   2.147 +def xapi_vm_name(args, async = False):
   2.148      if len(args) < 1:
   2.149          raise OptionError("No UUID specified")
   2.150      
   2.151 -    server, session = _connect()
   2.152 -    vm_name = execute(server.VM.get_name_label, session, args[0])
   2.153 +    server, session = connect()
   2.154 +    vm_name = execute(server, 'VM.get_name_label', (session, args[0]))
   2.155      print vm_name
   2.156  
   2.157 -def xapi_vm_list(*args):
   2.158 +def xapi_vm_list(args, async = False):
   2.159      opts, args = parse_args('vm-list', args, set_defaults = True)
   2.160      is_long = opts and opts.long
   2.161      
   2.162 -    server, session = _connect()
   2.163 -    vm_uuids = execute(server.VM.get_all, session)
   2.164 +    server, session = connect()
   2.165 +    vm_uuids = execute(server, 'VM.get_all', (session,))
   2.166      if not is_long:
   2.167          print VM_LIST_FORMAT % {'name_label':'Name',
   2.168                                  'memory_actual':'Mem',
   2.169 @@ -247,7 +256,7 @@ def xapi_vm_list(*args):
   2.170                                  'uuid': 'UUID'}
   2.171  
   2.172      for uuid in vm_uuids:
   2.173 -        vm_info = execute(server.VM.get_record, session, uuid)
   2.174 +        vm_info = execute(server, 'VM.get_record', (session, uuid))
   2.175          if is_long:
   2.176              vbds = vm_info['VBDs']
   2.177              vifs = vm_info['VIFs']
   2.178 @@ -256,13 +265,13 @@ def xapi_vm_list(*args):
   2.179              vbd_infos = []
   2.180              vtpm_infos = []
   2.181              for vbd in vbds:
   2.182 -                vbd_info = execute(server.VBD.get_record, session, vbd)
   2.183 +                vbd_info = execute(server, 'VBD.get_record', (session, vbd))
   2.184                  vbd_infos.append(vbd_info)
   2.185              for vif in vifs:
   2.186 -                vif_info = execute(server.VIF.get_record, session, vif)
   2.187 +                vif_info = execute(server, 'VIF.get_record', (session, vif))
   2.188                  vif_infos.append(vif_info)
   2.189              for vtpm in vtpms:
   2.190 -                vtpm_info = execute(server.VTPM.get_record, session, vtpm)
   2.191 +                vtpm_info = execute(server, 'VTPM.get_record', (session, vtpm))
   2.192                  vtpm_infos.append(vtpm_info)
   2.193              vm_info['VBDs'] = vbd_infos
   2.194              vm_info['VIFs'] = vif_infos
   2.195 @@ -271,7 +280,7 @@ def xapi_vm_list(*args):
   2.196          else:
   2.197              print VM_LIST_FORMAT % _stringify(vm_info)
   2.198  
   2.199 -def xapi_vm_create(*args):
   2.200 +def xapi_vm_create(args, async = False):
   2.201      if len(args) < 1:
   2.202          raise OptionError("Configuration file not specified")
   2.203  
   2.204 @@ -279,49 +288,129 @@ def xapi_vm_create(*args):
   2.205      cfg = _read_python_cfg(filename)
   2.206  
   2.207      print 'Creating VM from %s ..' % filename
   2.208 -    server, session = _connect()
   2.209 -    uuid = execute(server.VM.create, session, cfg)
   2.210 +    server, session = connect()
   2.211 +    uuid = execute(server, 'VM.create', (session, cfg), async = async)
   2.212      print 'Done. (%s)' % uuid
   2.213      print uuid
   2.214  
   2.215 -def xapi_vm_destroy(*args):
   2.216 +def xapi_vm_destroy(args, async = False):
   2.217      if len(args) < 1:
   2.218          raise OptionError("No domain name specified.")
   2.219      
   2.220 -    server, session = _connect()
   2.221 +    server, session = connect()
   2.222      vm_uuid = resolve_vm(server, session, args[0])    
   2.223      print 'Destroying VM %s (%s)' % (args[0], vm_uuid)
   2.224 -    success = execute(server.VM.destroy, session, vm_uuid)
   2.225 +    success = execute(server, 'VM.destroy', (session, vm_uuid), async = async)
   2.226      print 'Done.'
   2.227      
   2.228  
   2.229 -def xapi_vm_start(*args):
   2.230 +def xapi_vm_start(args, async = False):
   2.231      if len(args) < 1:
   2.232          raise OptionError("No Domain name specified.")
   2.233      
   2.234 -    server, session = _connect()
   2.235 +    server, session = connect()
   2.236      vm_uuid = resolve_vm(server, session, args[0])
   2.237      print 'Starting VM %s (%s)' % (args[0], vm_uuid)
   2.238 -    success = execute(server.VM.start, session, vm_uuid, False)
   2.239 -    print 'Done.'
   2.240 +    success = execute(server, 'VM.start', (session, vm_uuid, False), async = async)
   2.241 +    if async:
   2.242 +        print 'Task started: %s' % success
   2.243 +    else:
   2.244 +        print 'Done.'
   2.245  
   2.246 -def xapi_vm_shutdown(*args):
   2.247 +def xapi_vm_suspend(args, async = False):
   2.248 +    if len(args) < 1:
   2.249 +        raise OptionError("No Domain name specified.")
   2.250 +    
   2.251 +    server, session = connect()
   2.252 +    vm_uuid = resolve_vm(server, session, args[0])
   2.253 +    print 'Suspending VM %s (%s)' % (args[0], vm_uuid)
   2.254 +    success = execute(server, 'VM.suspend', (session, vm_uuid), async = async)
   2.255 +    if async:
   2.256 +        print 'Task started: %s' % success
   2.257 +    else:
   2.258 +        print 'Done.'        
   2.259 +
   2.260 +
   2.261 +def xapi_vm_resume(args, async = False):
   2.262 +    if len(args) < 1:
   2.263 +        raise OptionError("No Domain name specified.")
   2.264 +    
   2.265 +    server, session = connect()
   2.266 +    vm_uuid = resolve_vm(server, session, args[0])
   2.267 +    print 'Resuming VM %s (%s)' % (args[0], vm_uuid)
   2.268 +    success = execute(server, 'VM.resume', (session, vm_uuid, False), async = async)
   2.269 +    if async:
   2.270 +        print 'Task started: %s' % success
   2.271 +    else:
   2.272 +        print 'Done.'
   2.273 +
   2.274 +def xapi_vm_pause(args, async = False):
   2.275 +    if len(args) < 1:
   2.276 +        raise OptionError("No Domain name specified.")
   2.277 +    
   2.278 +    server, session = connect()
   2.279 +    vm_uuid = resolve_vm(server, session, args[0])
   2.280 +    print 'Pausing VM %s (%s)' % (args[0], vm_uuid)
   2.281 +    success = execute(server, 'VM.pause', (session, vm_uuid), async = async)
   2.282 +    if async:
   2.283 +        print 'Task started: %s' % success
   2.284 +    else:
   2.285 +        print 'Done.'
   2.286 +
   2.287 +def xapi_vm_unpause(args, async = False):
   2.288 +    if len(args) < 1:
   2.289 +        raise OptionError("No Domain name specified.")
   2.290 +    
   2.291 +    server, session = connect()
   2.292 +    vm_uuid = resolve_vm(server, session, args[0])
   2.293 +    print 'Pausing VM %s (%s)' % (args[0], vm_uuid)
   2.294 +    success = execute(server, 'VM.unpause', (session, vm_uuid), async = async)
   2.295 +    if async:
   2.296 +        print 'Task started: %s' % success
   2.297 +    else:
   2.298 +        print 'Done.'                        
   2.299 +
   2.300 +def xapi_task_list(args, async = False):
   2.301 +    server, session = connect()
   2.302 +    all_tasks = execute(server, 'task.get_all', (session,))
   2.303 +
   2.304 +    print TASK_LIST_FORMAT % {'name_label': 'Task Name',
   2.305 +                              'uuid': 'UUID',
   2.306 +                              'status': 'Status',
   2.307 +                              'progress': '%'}
   2.308 +    
   2.309 +    for task_uuid in all_tasks:
   2.310 +        task = execute(server, 'task.get_record', (session, task_uuid))
   2.311 +        print TASK_LIST_FORMAT % task
   2.312 +
   2.313 +def xapi_task_clear(args, async = False):
   2.314 +    server, session = connect()
   2.315 +    all_tasks = execute(server, 'task.get_all', (session,))
   2.316 +    for task_uuid in all_tasks:
   2.317 +        success = execute(server, 'task.destroy', (session, task_uuid))
   2.318 +        print 'Destroyed Task %s' % task_uuid
   2.319 +
   2.320 +def xapi_vm_shutdown(args, async = False):
   2.321      opts, args = parse_args("vm-shutdown", args, set_defaults = True)
   2.322      
   2.323      if len(args) < 1:
   2.324          raise OptionError("No Domain name specified.")
   2.325  
   2.326 -    server, session = _connect()
   2.327 +    server, session = connect()
   2.328      vm_uuid = resolve_vm(server, session, args[0])
   2.329      if opts.force:
   2.330          print 'Forcefully shutting down VM %s (%s)' % (args[0], vm_uuid)
   2.331 -        success = execute(server.VM.hard_shutdown, session, vm_uuid)
   2.332 +        success = execute(server, 'VM.hard_shutdown', (session, vm_uuid), async = async)
   2.333      else:
   2.334          print 'Shutting down VM %s (%s)' % (args[0], vm_uuid)
   2.335 -        success = execute(server.VM.clean_shutdown, session, vm_uuid)
   2.336 -    print 'Done.'
   2.337 +        success = execute(server, 'VM.clean_shutdown', (session, vm_uuid), async = async)
   2.338  
   2.339 -def xapi_vbd_create(*args):
   2.340 +    if async:
   2.341 +        print 'Task started: %s' % success
   2.342 +    else:
   2.343 +        print 'Done.'
   2.344 +
   2.345 +def xapi_vbd_create(args, async = False):
   2.346      opts, args = parse_args('vbd-create', args)
   2.347  
   2.348      if len(args) < 2:
   2.349 @@ -339,13 +428,16 @@ def xapi_vbd_create(*args):
   2.350          cfg[opt] = val
   2.351      
   2.352      print 'Creating VBD ...',
   2.353 -    server, session = _connect()
   2.354 +    server, session = connect()
   2.355      vm_uuid = resolve_vm(server, session, domname)
   2.356      cfg['VM'] = vm_uuid
   2.357 -    vbd_uuid = execute(server.VBD.create, session, cfg)
   2.358 -    print 'Done. (%s)' % vbd_uuid
   2.359 +    vbd_uuid = execute(server, 'VBD.create', (session, cfg), async = async)
   2.360 +    if async:
   2.361 +        print 'Task started: %s' % vbd_uuid
   2.362 +    else:
   2.363 +        print 'Done. (%s)' % vbd_uuid
   2.364  
   2.365 -def xapi_vif_create(*args):
   2.366 +def xapi_vif_create(args, async = False):
   2.367      if len(args) < 2:
   2.368          raise OptionError("Configuration file not specified")
   2.369  
   2.370 @@ -354,34 +446,53 @@ def xapi_vif_create(*args):
   2.371      cfg = _read_python_cfg(filename)
   2.372      
   2.373      print 'Creating VIF from %s ..' % filename
   2.374 -    server, session = _connect()
   2.375 +    server, session = connect()
   2.376      vm_uuid = resolve_vm(server, session, domname)
   2.377      cfg['VM'] = vm_uuid
   2.378 -    vif_uuid = execute(server.VIF.create, session, cfg)
   2.379 -    print 'Done. (%s)' % vif_uuid
   2.380 +    vif_uuid = execute(server, 'VIF.create', (session, cfg), async = async)
   2.381 +    if async:
   2.382 +        print 'Task started: %s' % vif_uuid
   2.383 +    else:
   2.384 +        print 'Done. (%s)' % vif_uuid
   2.385  
   2.386 -def xapi_vbd_list(*args):
   2.387 -    server, session = _connect()
   2.388 +def xapi_vbd_list(args, async = False):
   2.389 +    server, session = connect()
   2.390      domname = args[0]
   2.391      
   2.392      dom_uuid = resolve_vm(server, session, domname)
   2.393 -    vbds = execute(server.VM.get_VBDs, session, dom_uuid)
   2.394 +    vbds = execute(server, 'VM.get_VBDs', (session, dom_uuid))
   2.395      
   2.396 -    print VBD_LIST_FORMAT % {'name_label': 'VDI Label',
   2.397 +    print VBD_LIST_FORMAT % {'device': 'Device',
   2.398                               'uuid' : 'UUID',
   2.399                               'VDI': 'VDI',
   2.400                               'image': 'Image'}
   2.401      
   2.402      for vbd in vbds:
   2.403 -        vbd_struct = execute(server.VBD.get_record, session, vbd)
   2.404 +        vbd_struct = execute(server, 'VBD.get_record', (session, vbd))
   2.405          print VBD_LIST_FORMAT % vbd_struct
   2.406 + 
   2.407 +def xapi_vif_list(args, async = False):
   2.408 +    server, session = connect()
   2.409 +    domname = args[0]
   2.410 +    
   2.411 +    dom_uuid = resolve_vm(server, session, domname)
   2.412 +    vifs = execute(server, 'VM.get_VIFs', (session, dom_uuid))
   2.413 +    
   2.414 +    print VIF_LIST_FORMAT % {'name': 'Name',
   2.415 +                             'device': 'Device',
   2.416 +                             'uuid' : 'UUID',
   2.417 +                             'MAC': 'MAC'}
   2.418 +    
   2.419 +    for vif in vifs:
   2.420 +        vif_struct = execute(server, 'VIF.get_record', (session, vif))
   2.421 +        print VIF_LIST_FORMAT % vif_struct       
   2.422  
   2.423 -def xapi_vdi_list(*args):
   2.424 +def xapi_vdi_list(args, async = False):
   2.425      opts, args = parse_args('vdi-list', args, set_defaults = True)
   2.426      is_long = opts and opts.long
   2.427  
   2.428 -    server, session = _connect()
   2.429 -    vdis = execute(server.VDI.get_all, session)
   2.430 +    server, session = connect()
   2.431 +    vdis = execute(server, 'VDI.get_all', (session,))
   2.432  
   2.433      if not is_long:
   2.434          print VDI_LIST_FORMAT % {'name_label': 'VDI Label',
   2.435 @@ -390,21 +501,20 @@ def xapi_vdi_list(*args):
   2.436                                   'sector_size': 'Sector Size'}
   2.437          
   2.438          for vdi in vdis:
   2.439 -            vdi_struct = execute(server.VDI.get_record, session, vdi)
   2.440 +            vdi_struct = execute(server, 'VDI.get_record', (session, vdi))
   2.441              print VDI_LIST_FORMAT % vdi_struct
   2.442  
   2.443      else:
   2.444 -
   2.445          for vdi in vdis:
   2.446 -            vdi_struct = execute(server.VDI.get_record, session, vdi)
   2.447 +            vdi_struct = execute(server, 'VDI.get_record', (session, vdi))
   2.448              pprint(vdi_struct)
   2.449  
   2.450 -def xapi_sr_list(*args):
   2.451 +def xapi_sr_list(args, async = False):
   2.452      opts, args = parse_args('sr-list', args, set_defaults = True)
   2.453      is_long = opts and opts.long
   2.454      
   2.455 -    server, session = _connect()
   2.456 -    srs = execute(server.SR.get_all, session)
   2.457 +    server, session = connect()
   2.458 +    srs = execute(server, 'SR.get_all', (session,))
   2.459      if not is_long:
   2.460          print SR_LIST_FORMAT % {'name_label': 'SR Label',
   2.461                                  'uuid' : 'UUID',
   2.462 @@ -412,20 +522,20 @@ def xapi_sr_list(*args):
   2.463                                  'type': 'Type'}
   2.464          
   2.465          for sr in srs:
   2.466 -            sr_struct = execute(server.SR.get_record, session, sr)
   2.467 +            sr_struct = execute(server, 'SR.get_record', (session, sr))
   2.468              sr_struct['physical_size'] = int(sr_struct['physical_size'])/MB
   2.469              print SR_LIST_FORMAT % sr_struct
   2.470      else:
   2.471          for sr in srs:
   2.472 -            sr_struct = execute(server.SR.get_record, session, sr)        
   2.473 +            sr_struct = execute(server, 'SR.get_record', (session, sr))  
   2.474              pprint(sr_struct)
   2.475  
   2.476 -def xapi_sr_rename(*args):
   2.477 -    server, session = _connect()
   2.478 -    sr = execute(server.SR.get_by_name_label, session, args[0])
   2.479 -    execute(server.SR.set_name_label, session, sr[0], args[1])
   2.480 +def xapi_sr_rename(args, async = False):
   2.481 +    server, session = connect()
   2.482 +    sr = execute(server, 'SR.get_by_name_label', (session, args[0]))
   2.483 +    execute(server, 'SR.set_name_label', (session, sr[0], args[1]))
   2.484  
   2.485 -def xapi_vdi_create(*args):
   2.486 +def xapi_vdi_create(args, async = False):
   2.487      opts, args = parse_args('vdi-create', args)
   2.488  
   2.489      if len(args) > 0:
   2.490 @@ -436,66 +546,86 @@ def xapi_vdi_create(*args):
   2.491      for opt, val in opts:
   2.492          cfg[opt] = val
   2.493  
   2.494 -    server, session = _connect()
   2.495 -    srs = execute(server.SR.get_all, session)
   2.496 +    server, session = connect()
   2.497 +    srs = execute(server, 'SR.get_all', (session,))
   2.498      sr = srs[0]
   2.499      cfg['SR'] = sr
   2.500  
   2.501      size = (cfg['virtual_size'] * cfg['sector_size'])/MB
   2.502      print 'Creating VDI of size: %dMB ..' % size,
   2.503 -    uuid = execute(server.VDI.create, session, cfg)
   2.504 -    print 'Done. (%s)' % uuid
   2.505 +    uuid = execute(server, 'VDI.create', (session, cfg), async = async)
   2.506 +    if async:
   2.507 +        print 'Task started: %s' % uuid
   2.508 +    else:
   2.509 +        print 'Done. (%s)' % uuid
   2.510 +    
   2.511  
   2.512 -def xapi_vdi_delete(*args):
   2.513 -    server, session = _connect()
   2.514 +def xapi_vdi_destroy(args, async = False):
   2.515 +    server, session = connect()
   2.516      if len(args) < 1:
   2.517          raise OptionError('Not enough arguments')
   2.518  
   2.519      vdi_uuid = args[0]
   2.520      print 'Deleting VDI %s' % vdi_uuid
   2.521 -    result = execute(server.VDI.destroy, session, vdi_uuid)
   2.522 -    print 'Done.'
   2.523 +    result = execute(server, 'VDI.destroy', (session, vdi_uuid), async = async)
   2.524 +    if async:
   2.525 +        print 'Task started: %s' % result
   2.526 +    else:
   2.527 +        print 'Done.'
   2.528  
   2.529 -def xapi_vdi_rename(*args):
   2.530 -    server, session = _connect()
   2.531 +def xapi_vdi_rename(args, async = False):
   2.532 +    server, session = connect()
   2.533      if len(args) < 2:
   2.534          raise OptionError('Not enough arguments')
   2.535  
   2.536 -    vdi_uuid = execute(server.VDI.get_by_name_label, session, args[0])
   2.537 +    vdi_uuid = execute(server, 'VDI.get_by_name_label', session, args[0])
   2.538      vdi_name = args[1]
   2.539      
   2.540      print 'Renaming VDI %s to %s' % (vdi_uuid[0], vdi_name)
   2.541 -    result = execute(server.VDI.set_name_label, session, vdi_uuid[0], vdi_name)
   2.542 -    print 'Done.'
   2.543 +    result = execute(server, 'VDI.set_name_label',
   2.544 +                     (session, vdi_uuid[0], vdi_name), async = async)
   2.545 +    if async:
   2.546 +        print 'Task started: %s' % result
   2.547 +    else:
   2.548 +        print 'Done.'
   2.549  
   2.550  
   2.551 -def xapi_vtpm_create(*args):
   2.552 -    server, session = _connect()
   2.553 +
   2.554 +def xapi_vtpm_create(args, async = False):
   2.555 +    server, session = connect()
   2.556      domname = args[0]
   2.557      cfg = _read_python_cfg(args[1])
   2.558  
   2.559      vm_uuid = resolve_vm(server, session, domname)
   2.560      cfg['VM'] = vm_uuid
   2.561      print "Creating vTPM with cfg = %s" % cfg
   2.562 -    vtpm_uuid = execute(server.VTPM.create, session, cfg)
   2.563 +    vtpm_uuid = execute(server, 'VTPM.create', (session, cfg))
   2.564      print "Done. (%s)" % vtpm_uuid
   2.565 -    vtpm_id = execute(server.VTPM.get_instance, session, vtpm_uuid)
   2.566 +    vtpm_id = execute(server, 'VTPM.get_instance', (session, vtpm_uuid))
   2.567      print "Has instance number '%s'" % vtpm_id
   2.568 -    vtpm_be = execute(server.VTPM.get_backend, session, vtpm_uuid)
   2.569 +    vtpm_be = execute(server, 'VTPM.get_backend', (session, vtpm_uuid))
   2.570      print "Has backend in '%s'" % vtpm_be
   2.571 -    driver = execute(server.VTPM.get_driver, session, vtpm_uuid)
   2.572 +    driver = execute(server, 'VTPM.get_driver', (session, vtpm_uuid))
   2.573      print "Has driver type '%s'" % driver
   2.574 -    vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
   2.575 +    vtpm_rec = execute(server, 'VTPM.get_record', (session, vtpm_uuid))
   2.576      print "Has vtpm record '%s'" % vtpm_rec
   2.577  
   2.578  
   2.579 -def xapi_pif_list(*args):
   2.580 -    server, session = _connect()
   2.581 -    pif_uuids = execute(server.PIF.get_all, session)
   2.582 +def xapi_pif_list(args, async = False):
   2.583 +    server, session = connect()
   2.584 +    pif_uuids = execute(server, 'PIF.get_all', (session,))
   2.585      for pif_uuid in pif_uuids:
   2.586 -        pif = execute(server.PIF.get_record, session, pif_uuid)
   2.587 +        pif = execute(server, 'PIF.get_record', (session, pif_uuid))
   2.588          print pif
   2.589 -    
   2.590 +
   2.591 +
   2.592 +def xapi_debug_wait(args, async = False):
   2.593 +    secs = 10
   2.594 +    if len(args) > 0:
   2.595 +        secs = int(args[0])
   2.596 +    server, session = connect()
   2.597 +    task_uuid = execute(server, 'Debug.wait', (session, secs), async=async)
   2.598 +    print 'Task UUID: %s' % task_uuid
   2.599  
   2.600  #
   2.601  # Command Line Utils
   2.602 @@ -514,12 +644,17 @@ class XenAPICmd(cmd.Cmd):
   2.603          words = shlex.split(line)
   2.604          if len(words) > 0:
   2.605              cmd_name = words[0].replace('-', '_')
   2.606 +            is_async = 'async' in cmd_name
   2.607 +            if is_async:
   2.608 +                cmd_name = re.sub('async_', '', cmd_name)
   2.609 +                
   2.610              func_name = 'xapi_%s' % cmd_name
   2.611              func = globals().get(func_name)
   2.612 +            
   2.613              if func:
   2.614                  try:
   2.615                      args = tuple(words[1:])
   2.616 -                    func(*args)
   2.617 +                    func(args, async = is_async)
   2.618                      return True
   2.619                  except SystemExit:
   2.620                      return False
   2.621 @@ -555,7 +690,7 @@ class XenAPICmd(cmd.Cmd):
   2.622              return line
   2.623  
   2.624  def shell():
   2.625 -    server, session = _connect()
   2.626 +    server, session = connect()
   2.627      x = XenAPICmd(server, session)
   2.628      x.cmdloop('Xen API Prompt. Type "help" for a list of functions')
   2.629  
   2.630 @@ -582,8 +717,11 @@ def main(args):
   2.631          usage()
   2.632          sys.exit(1)
   2.633  
   2.634 -    subcmd = args[0]
   2.635 -    subcmd_func_name = 'xapi_' + subcmd.replace('-', '_')
   2.636 +    subcmd = args[0].replace('-', '_')
   2.637 +    is_async = 'async' in subcmd
   2.638 +    if is_async:
   2.639 +        subcmd = re.sub('async_', '', subcmd)
   2.640 +    subcmd_func_name = 'xapi_' + subcmd
   2.641      subcmd_func = globals().get(subcmd_func_name, None)
   2.642  
   2.643      if subcmd == 'shell':
   2.644 @@ -598,7 +736,7 @@ def main(args):
   2.645          sys.exit(1)
   2.646          
   2.647      try:
   2.648 -        subcmd_func(*args[1:])
   2.649 +        subcmd_func(args[1:], async = is_async)
   2.650      except XenAPIError, e:
   2.651          print 'Error: %s' % str(e.args[0])
   2.652          sys.exit(2)