ia64/xen-unstable

changeset 12123:58521d4b7c7b

[XEND] Adding API stub generation to XendAPI + SR implementation for
Xen API.

Fixed *get_by_label functions to return a Set rather than only one
result.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Thu Oct 12 18:51:17 2006 +0100 (2006-10-12)
parents 1b923f4a788a
children 91c7ee18c978
files tools/python/scripts/xapi.py tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendAPIConstants.py tools/python/xen/xend/XendError.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/XendStorageRepository.py
line diff
     1.1 --- a/tools/python/scripts/xapi.py	Thu Oct 12 18:01:32 2006 +0100
     1.2 +++ b/tools/python/scripts/xapi.py	Thu Oct 12 18:51:17 2006 +0100
     1.3 @@ -96,6 +96,13 @@ def _read_python_cfg(filename):
     1.4      execfile(filename, {}, cfg)
     1.5      return cfg
     1.6  
     1.7 +def resolve_vm(server, session, vm_name):
     1.8 +    vm_uuid = execute(server.VM.get_by_label, session, vm_name)
     1.9 +    if not vm_uuid:
    1.10 +        return None
    1.11 +    else:
    1.12 +        return vm_uuid[0]
    1.13 +
    1.14  #
    1.15  # Actual commands
    1.16  #
    1.17 @@ -116,7 +123,7 @@ def xapi_vm_uuid(*args):
    1.18          raise OptionError("No domain name specified")
    1.19      
    1.20      server, session = _connect()
    1.21 -    vm_uuid = execute(server.VM.get_by_label, session, args[0])
    1.22 +    vm_uuid = resolve_vm(server, session, args[0])
    1.23      print vm_uuid
    1.24  
    1.25  def xapi_vm_name(*args):
    1.26 @@ -177,7 +184,7 @@ def xapi_vm_delete(*args):
    1.27          raise OptionError("No domain name specified.")
    1.28      
    1.29      server, session = _connect()
    1.30 -    vm_uuid = execute(server.VM.get_by_label, session, args[0])
    1.31 +    vm_uuid = resolve_vm(server, session, args[0])    
    1.32      print 'Destroying VM %s (%s)' % (args[0], vm_uuid)
    1.33      success = execute(server.VM.destroy, session, vm_uuid)
    1.34      print 'Done.'
    1.35 @@ -198,7 +205,7 @@ def xapi_vm_shutdown(*args):
    1.36          raise OptionError("No Domain name specified.")
    1.37  
    1.38      server, session = _connect()
    1.39 -    vm_uuid = execute(server.VM.get_by_label, session, args[0])
    1.40 +    vm_uuid = resolve_vm(server, session, args[0])
    1.41      print 'Shutting down VM %s (%s)' % (args[0], vm_uuid)
    1.42      success = execute(server.VM.clean_shutdown, session, vm_uuid)
    1.43      print 'Done.'
    1.44 @@ -208,7 +215,7 @@ def xapi_vm_destroy(*args):
    1.45          raise OptionError("No Domain name specified.")
    1.46  
    1.47      server, session = _connect()
    1.48 -    vm_uuid = execute(server.VM.get_by_label, session, args[0])
    1.49 +    vm_uuid = resolve_vm(server, session, args[0])
    1.50      print 'Shutting down VM with force %s (%s)' % (args[0], vm_uuid)
    1.51      success = execute(server.VM.hard_shutdown, session, vm_uuid)
    1.52      print 'Done.'    
    1.53 @@ -222,7 +229,7 @@ def xapi_vbd_create(*args):
    1.54      cfg = _read_python_cfg(filename)
    1.55      print 'Creating VBD from %s ..' % filename
    1.56      server, session = _connect()
    1.57 -    vm_uuid = execute(server.VM.get_by_label, session, domname)
    1.58 +    vm_uuid = resolve_vm(server, session, domname)
    1.59      cfg['VM'] = vm_uuid
    1.60      vbd_uuid = execute(server.VBD.create, session, cfg)
    1.61      print 'Done. (%s)' % vbd_uuid
    1.62 @@ -236,7 +243,7 @@ def xapi_vif_create(*args):
    1.63      cfg = _read_python_cfg(filename)
    1.64      print 'Creating VIF from %s ..' % filename
    1.65      server, session = _connect()
    1.66 -    vm_uuid = execute(server.VM.get_by_label, session, domname)
    1.67 +    vm_uuid = resolve_vm(server, session, domname)
    1.68      cfg['VM'] = vm_uuid
    1.69      vif_uuid = execute(server.VIF.create, session, cfg)
    1.70      print 'Done. (%s)' % vif_uuid
     2.1 --- a/tools/python/xen/xend/XendAPI.py	Thu Oct 12 18:01:32 2006 +0100
     2.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Oct 12 18:51:17 2006 +0100
     2.3 @@ -171,6 +171,51 @@ def valid_vif(func):
     2.4          
     2.5      return check_vif_ref
     2.6  
     2.7 +
     2.8 +def valid_vdi(func):
     2.9 +    """Decorator to verify if vdi_ref is valid before calling
    2.10 +    method.
    2.11 +
    2.12 +    @param func: function with params: (self, session, vdi_ref)
    2.13 +    @rtype: callable object
    2.14 +    """
    2.15 +    def check_vdi_ref(self, session, vdi_ref, *args, **kwargs):
    2.16 +        xennode = XendNode.instance()
    2.17 +        if type(vdi_ref) == type(str()) and \
    2.18 +               xennode.get_sr().is_valid_vdi(vdi_ref):
    2.19 +            return func(self, session, vdi_ref, *args, **kwargs)
    2.20 +        else:
    2.21 +            return {'Status': 'Failure',
    2.22 +                    'ErrorDescription': XEND_ERROR_VDI_INVALID}
    2.23 +
    2.24 +    # make sure we keep the 'api' attribute
    2.25 +    if hasattr(func, 'api'):
    2.26 +        check_vdi_ref.api = func.api
    2.27 +        
    2.28 +    return check_vdi_ref
    2.29 +
    2.30 +def valid_sr(func):
    2.31 +    """Decorator to verify if sr_ref is valid before calling
    2.32 +    method.
    2.33 +
    2.34 +    @param func: function with params: (self, session, sr_ref)
    2.35 +    @rtype: callable object
    2.36 +    """
    2.37 +    def check_sr_ref(self, session, sr_ref, *args, **kwargs):
    2.38 +        xennode = XendNode.instance()
    2.39 +        if type(sr_ref) == type(str()) and \
    2.40 +               xennode.get_sr().uuid == sr_ref:
    2.41 +            return func(self, session, sr_ref, *args, **kwargs)
    2.42 +        else:
    2.43 +            return {'Status': 'Failure',
    2.44 +                    'ErrorDescription': XEND_ERROR_SR_INVALID}
    2.45 +
    2.46 +    # make sure we keep the 'api' attribute
    2.47 +    if hasattr(func, 'api'):
    2.48 +        check_sr_ref.api = func.api
    2.49 +        
    2.50 +    return check_sr_ref
    2.51 +
    2.52  def do_vm_func(fn_name, vm_ref, *args):
    2.53      """Helper wrapper func to abstract away from repeative code.
    2.54  
    2.55 @@ -212,7 +257,9 @@ class XendAPI:
    2.56              'host_cpu': (valid_host_cpu, session_required),
    2.57              'VM': (valid_vm, session_required),
    2.58              'VBD': (valid_vbd, session_required),
    2.59 -            'VIF': (valid_vif, session_required)}
    2.60 +            'VIF': (valid_vif, session_required),
    2.61 +            'VDI': (valid_vdi, session_required),
    2.62 +            'SR':  (valid_sr, session_required)}
    2.63          
    2.64          # Cheat methods
    2.65          # -------------
    2.66 @@ -849,8 +896,9 @@ class XendAPI:
    2.67          xendom = XendDomain.instance()
    2.68          dom = xendom.domain_lookup_nr(label)
    2.69          if dom:
    2.70 -            return xen_api_success(dom.get_uuid())
    2.71 +            return xen_api_success([dom.get_uuid()])
    2.72          return xen_api_error(XEND_ERROR_VM_INVALID)
    2.73 +    
    2.74      def vm_create(self, session, vm_struct):
    2.75          xendom = XendDomain.instance()
    2.76          domuuid = xendom.create_domain(vm_struct)
    2.77 @@ -1053,9 +1101,212 @@ class XendAPI:
    2.78              return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
    2.79  
    2.80  
    2.81 +    # Xen API: Class VDI
    2.82 +    # ----------------------------------------------------------------
    2.83 +    VDI_attr_ro = ['VBDs',
    2.84 +                   'physical_utilisation',
    2.85 +                   'sector_size',
    2.86 +                   'type',
    2.87 +                   'parent',
    2.88 +                   'children']
    2.89 +    VDI_attr_rw = ['name_label',
    2.90 +                   'name_description',
    2.91 +                   'SR',
    2.92 +                   'virtual_size',
    2.93 +                   'sharable',
    2.94 +                   'read_only']
    2.95 +    VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
    2.96 +
    2.97 +    VDI_methods = ['snapshot']
    2.98 +    VDI_funcs = ['get_by_label']
    2.99 +    def vdi_get_vbds(self, session, vdi_ref):
   2.100 +        return xen_api_todo()
   2.101 +    def vdi_get_physical_utilisation(self, session, vdi_ref):
   2.102 +        return xen_api_todo()
   2.103 +    def vdi_get_sector_size(self, session, vdi_ref):
   2.104 +        return xen_api_todo()
   2.105 +    def vdi_get_type(self, session, vdi_ref):
   2.106 +        return xen_api_todo()
   2.107 +    def vdi_get_parent(self, session, vdi_ref):
   2.108 +        return xen_api_todo()
   2.109 +    def vdi_get_children(self, session, vdi_ref):
   2.110 +        return xen_api_todo()
   2.111 +    def vdi_get_name_label(self, session, vdi_ref):
   2.112 +        return xen_api_todo()
   2.113 +    def vdi_get_name_description(self, session, vdi_ref):
   2.114 +        return xen_api_todo()
   2.115 +    def vdi_get_sr(self, session, vdi_ref):
   2.116 +        return xen_api_todo()
   2.117 +    def vdi_get_virtual_size(self, session, vdi_ref):
   2.118 +        return xen_api_todo()
   2.119 +    def vdi_get_sharable(self, session, vdi_ref):
   2.120 +        return xen_api_todo()
   2.121 +    def vdi_get_read_only(self, session, vdi_ref):
   2.122 +        return xen_api_todo()
   2.123 +    def vdi_get_uuid(self, session, vdi_ref):
   2.124 +        return xen_api_todo()
   2.125 +    def vdi_set_name_label(self, session, vdi_ref, value):
   2.126 +        return xen_api_todo()
   2.127 +    def vdi_set_name_description(self, session, vdi_ref, value):
   2.128 +        return xen_api_todo()
   2.129 +    def vdi_set_sr(self, session, vdi_ref, value):
   2.130 +        return xen_api_todo()
   2.131 +    def vdi_set_virtual_size(self, session, vdi_ref, value):
   2.132 +        return xen_api_todo()
   2.133 +    def vdi_set_sharable(self, session, vdi_ref, value):
   2.134 +        return xen_api_todo()
   2.135 +    def vdi_set_read_only(self, session, vdi_ref, value):
   2.136 +        return xen_api_todo()
   2.137 +    def vdi_snapshot(self, session, vdi_ref):
   2.138 +        return xen_api_todo()
   2.139 +    def vdi_destroy(self, session, vdi_ref):
   2.140 +        return xen_api_todo()
   2.141 +    def vdi_to_xml(self, session, vdi_ref):
   2.142 +        return xen_api_todo()
   2.143 +    def vdi_get_record(self, session, vdi_ref):
   2.144 +        return xen_api_todo()
   2.145 +    def vdi_create(self, session):
   2.146 +        return xen_api_todo()
   2.147 +    def vdi_get_by_uuid(self, session):
   2.148 +        return xen_api_todo()
   2.149 +    def vdi_get_all(self, session):
   2.150 +        return xen_api_todo()
   2.151 +    def vdi_get_by_label(self, session):
   2.152 +        return xen_api_todo()
   2.153 +
   2.154      # Xen API: Class SR
   2.155      # ----------------------------------------------------------------
   2.156 -    # NOT IMPLEMENTED
   2.157 +    SR_attr_ro = ['VDIs',
   2.158 +                  'virtual_allocation',
   2.159 +                  'physical_utilisation',
   2.160 +                  'physical_size',
   2.161 +                  'type',
   2.162 +                  'location']
   2.163 +    
   2.164 +    SR_attr_rw = ['name_label',
   2.165 +                  'name_description']
   2.166 +    
   2.167 +    SR_attr_inst = ['physical_size',
   2.168 +                    'type',
   2.169 +                    'location',
   2.170 +                    'name_label',
   2.171 +                    'name_description']
   2.172 +    
   2.173 +    SR_methods = ['clone']
   2.174 +    SR_funcs = ['get_by_label']
   2.175 +
   2.176 +    # Class Functions
   2.177 +    def sr_get_all(self, session):
   2.178 +        sr = XendNode.instance().get_sr()
   2.179 +        return xen_api_success([sr.uuid])
   2.180 +
   2.181 +    def sr_get_by_label(self, session, label):
   2.182 +        sr = XendNode.instance().get_sr()
   2.183 +        if sr.name_label != label:
   2.184 +            return xen_api_error(XEND_ERROR_SR_INVALID)
   2.185 +        return xen_api_success([sr.uuid])
   2.186 +
   2.187 +    def sr_create(self, session):
   2.188 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
   2.189 +
   2.190 +    def sr_get_by_uuid(self, session):
   2.191 +        return xen_api_success(XendNode.instance().get_sr().uuid)
   2.192 +
   2.193 +    # Class Methods
   2.194 +    def sr_clone(self, session, sr_ref):
   2.195 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
   2.196 +    def sr_destroy(self, session, sr_ref):
   2.197 +        return xen_api_error(XEND_ERROR_UNSUPPORTED)
   2.198 +    
   2.199 +    def sr_to_xml(self, session, sr_ref):
   2.200 +        return xen_api_todo()
   2.201 +    
   2.202 +    def sr_get_record(self, session, sr_ref):
   2.203 +        sr = XendNode.instance().get_sr()
   2.204 +        return xen_api_success({
   2.205 +            'uuid': sr.uuid,
   2.206 +            'name_label': sr.name_label,
   2.207 +            'name_description': sr.name_description,
   2.208 +            'VDIs': sr.list_images(),
   2.209 +            'virtual_allocation': sr.used_space_bytes(),
   2.210 +            'physical_utilisation': sr.used_space_bytes(),
   2.211 +            'physical_size': sr.total_space_bytes(),
   2.212 +            'type': sr.type,
   2.213 +            'location': sr.location
   2.214 +            })
   2.215 +
   2.216 +    # Attribute acceess
   2.217 +    def sr_get_vdis(self, session, sr_ref):
   2.218 +        sr = XendNode.instance().get_sr()
   2.219 +        return xen_api_success(sr.list_images())
   2.220 +
   2.221 +    def sr_get_virtual_allocation(self, session, sr_ref):
   2.222 +        return sr.used_space_bytes()
   2.223  
   2.224 +    def sr_get_physical_utilisation(self, session, sr_ref):
   2.225 +        return sr.used_space_bytes()
   2.226  
   2.227 +    def sr_get_physical_size(self, session, sr_ref):
   2.228 +        return sr.total_space_bytes()
   2.229      
   2.230 +    def sr_get_type(self, session, sr_ref):
   2.231 +        sr = XendNode.instance().get_sr()
   2.232 +        return xen_api_success(sr.type)
   2.233 +
   2.234 +    def sr_get_location(self, session, sr_ref):
   2.235 +        sr = XendNode.instance().get_sr()
   2.236 +        return xen_api_success(sr.location)
   2.237 +
   2.238 +    def sr_get_name_label(self, session, sr_ref):
   2.239 +        sr = XendNode.instance().get_sr()
   2.240 +        return xen_api_success(sr.name_label)      
   2.241 +    
   2.242 +    def sr_get_name_description(self, session, sr_ref):
   2.243 +        sr = XendNode.instance().get_sr()
   2.244 +        return xen_api_success(sr.name_description)        
   2.245 +
   2.246 +    def sr_set_name_label(self, session, sr_ref, value):
   2.247 +        sr = XendNode.instance().get_sr()
   2.248 +        sr.name_label = value
   2.249 +        return xen_api_success_void()
   2.250 +    
   2.251 +    def sr_set_name_description(self, session, sr_ref, value):
   2.252 +        sr = XendNode.instance().get_sr()
   2.253 +        sr.name_description = value
   2.254 +        return xen_api_success_void()
   2.255 +
   2.256 +#   
   2.257 +# Auto generate some stubs based on XendAPI introspection
   2.258 +#
   2.259 +if __name__ == "__main__":
   2.260 +    def output(line):
   2.261 +        print '    ' + line
   2.262 +    
   2.263 +    classes = ['VDI', 'SR']
   2.264 +    for cls in classes:
   2.265 +        ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
   2.266 +        rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
   2.267 +        methods  = getattr(XendAPI, '%s_methods' % cls, [])
   2.268 +        funcs    = getattr(XendAPI, '%s_funcs' % cls, [])
   2.269 +
   2.270 +        ref = '%s_ref' % cls.lower()
   2.271 +
   2.272 +        for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
   2.273 +            getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
   2.274 +            output('def %s(self, session, %s):' % (getter_name, ref))
   2.275 +            output('    return xen_api_todo()')
   2.276 +
   2.277 +        for attr_name in rw_attrs + XendAPI.Base_attr_rw:
   2.278 +            setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
   2.279 +            output('def %s(self, session, %s, value):' % (setter_name, ref))
   2.280 +            output('    return xen_api_todo()')
   2.281 +
   2.282 +        for method_name in methods + XendAPI.Base_methods:
   2.283 +            method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
   2.284 +            output('def %s(self, session, %s):' % (method_full_name, ref))
   2.285 +            output('    return xen_api_todo()')
   2.286 +
   2.287 +        for func_name in funcs + XendAPI.Base_funcs:
   2.288 +            func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
   2.289 +            output('def %s(self, session):' % func_full_name)
   2.290 +            output('    return xen_api_todo()')
     3.1 --- a/tools/python/xen/xend/XendAPIConstants.py	Thu Oct 12 18:01:32 2006 +0100
     3.2 +++ b/tools/python/xen/xend/XendAPIConstants.py	Thu Oct 12 18:51:17 2006 +0100
     3.3 @@ -71,5 +71,5 @@ XEN_API_BOOT_TYPE = [
     3.4  ]
     3.5  
     3.6  XEN_API_VBD_MODE = ['RO', 'RW']
     3.7 -
     3.8 +XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
     3.9  XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
     4.1 --- a/tools/python/xen/xend/XendError.py	Thu Oct 12 18:01:32 2006 +0100
     4.2 +++ b/tools/python/xen/xend/XendError.py	Thu Oct 12 18:51:17 2006 +0100
     4.3 @@ -47,4 +47,6 @@ XEND_ERROR_UNSUPPORTED           = ('EUN
     4.4  XEND_ERROR_VM_INVALID            = ('EVMINVALID', 'VM Invalid')
     4.5  XEND_ERROR_VBD_INVALID           = ('EVBDINVALID', 'VBD Invalid')
     4.6  XEND_ERROR_VIF_INVALID           = ('EVIFINVALID', 'VIF Invalid')
     4.7 +XEND_ERROR_VDI_INVALID           = ('EVDIINVALID', 'VDI Invalid')
     4.8 +XEND_ERROR_SR_INVALID           = ('ESRINVALID', 'SR Invalid')
     4.9  XEND_ERROR_TODO                  = ('ETODO', 'Lazy Programmer Error')
     5.1 --- a/tools/python/xen/xend/XendNode.py	Thu Oct 12 18:01:32 2006 +0100
     5.2 +++ b/tools/python/xen/xend/XendNode.py	Thu Oct 12 18:51:17 2006 +0100
     5.3 @@ -68,6 +68,13 @@ class XendNode:
     5.4          return (cpu_ref in self.cpus)
     5.5  
     5.6      #
     5.7 +    # Storage Repo
     5.8 +    #
     5.9 +
    5.10 +    def get_sr(self):
    5.11 +        return self.sr
    5.12 +
    5.13 +    #
    5.14      # Host Functions
    5.15      #
    5.16  
     6.1 --- a/tools/python/xen/xend/XendStorageRepository.py	Thu Oct 12 18:01:32 2006 +0100
     6.2 +++ b/tools/python/xen/xend/XendStorageRepository.py	Thu Oct 12 18:51:17 2006 +0100
     6.3 @@ -315,6 +315,8 @@ class XendStorageRepository:
     6.4      def total_space_bytes(self):
     6.5          return self.total_space_kb() * KB
     6.6  
     6.7 +    def is_valid_vdi(self, vdi_uuid):
     6.8 +        return (vdi_uuid in self.images)
     6.9  
    6.10  # remove everything below this line!!
    6.11  if __name__ == "__main__":
    6.12 @@ -324,4 +326,7 @@ if __name__ == "__main__":
    6.13      print xsr.create_image(10 * 1024)
    6.14      print 'Delete all images:'
    6.15      for image_uuid in xsr.list_images():
    6.16 +        print image_uuid,
    6.17          xsr.destroy_image(image_uuid)
    6.18 +
    6.19 +    print