# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Node ID 58521d4b7c7b6fae9fd3f82345d0e8df9e7ba0a1
# Parent 1b923f4a788a58b8c7e81d0866058e7e4d18c47c
[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@xxxxxxxxxxxxx>
---
tools/python/scripts/xapi.py | 19 +
tools/python/xen/xend/XendAPI.py | 263 ++++++++++++++++++++++++-
tools/python/xen/xend/XendAPIConstants.py | 2
tools/python/xen/xend/XendError.py | 2
tools/python/xen/xend/XendNode.py | 7
tools/python/xen/xend/XendStorageRepository.py | 5
6 files changed, 285 insertions(+), 13 deletions(-)
diff -r 1b923f4a788a -r 58521d4b7c7b tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py Thu Oct 12 18:01:32 2006 +0100
+++ b/tools/python/scripts/xapi.py Thu Oct 12 18:51:17 2006 +0100
@@ -96,6 +96,13 @@ def _read_python_cfg(filename):
execfile(filename, {}, cfg)
return cfg
+def resolve_vm(server, session, vm_name):
+ vm_uuid = execute(server.VM.get_by_label, session, vm_name)
+ if not vm_uuid:
+ return None
+ else:
+ return vm_uuid[0]
+
#
# Actual commands
#
@@ -116,7 +123,7 @@ def xapi_vm_uuid(*args):
raise OptionError("No domain name specified")
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, args[0])
+ vm_uuid = resolve_vm(server, session, args[0])
print vm_uuid
def xapi_vm_name(*args):
@@ -177,7 +184,7 @@ def xapi_vm_delete(*args):
raise OptionError("No domain name specified.")
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, args[0])
+ vm_uuid = resolve_vm(server, session, args[0])
print 'Destroying VM %s (%s)' % (args[0], vm_uuid)
success = execute(server.VM.destroy, session, vm_uuid)
print 'Done.'
@@ -198,7 +205,7 @@ def xapi_vm_shutdown(*args):
raise OptionError("No Domain name specified.")
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, args[0])
+ vm_uuid = resolve_vm(server, session, args[0])
print 'Shutting down VM %s (%s)' % (args[0], vm_uuid)
success = execute(server.VM.clean_shutdown, session, vm_uuid)
print 'Done.'
@@ -208,7 +215,7 @@ def xapi_vm_destroy(*args):
raise OptionError("No Domain name specified.")
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, args[0])
+ vm_uuid = resolve_vm(server, session, args[0])
print 'Shutting down VM with force %s (%s)' % (args[0], vm_uuid)
success = execute(server.VM.hard_shutdown, session, vm_uuid)
print 'Done.'
@@ -222,7 +229,7 @@ def xapi_vbd_create(*args):
cfg = _read_python_cfg(filename)
print 'Creating VBD from %s ..' % filename
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, domname)
+ vm_uuid = resolve_vm(server, session, domname)
cfg['VM'] = vm_uuid
vbd_uuid = execute(server.VBD.create, session, cfg)
print 'Done. (%s)' % vbd_uuid
@@ -236,7 +243,7 @@ def xapi_vif_create(*args):
cfg = _read_python_cfg(filename)
print 'Creating VIF from %s ..' % filename
server, session = _connect()
- vm_uuid = execute(server.VM.get_by_label, session, domname)
+ vm_uuid = resolve_vm(server, session, domname)
cfg['VM'] = vm_uuid
vif_uuid = execute(server.VIF.create, session, cfg)
print 'Done. (%s)' % vif_uuid
diff -r 1b923f4a788a -r 58521d4b7c7b tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Thu Oct 12 18:01:32 2006 +0100
+++ b/tools/python/xen/xend/XendAPI.py Thu Oct 12 18:51:17 2006 +0100
@@ -171,6 +171,51 @@ def valid_vif(func):
return check_vif_ref
+
+def valid_vdi(func):
+ """Decorator to verify if vdi_ref is valid before calling
+ method.
+
+ @param func: function with params: (self, session, vdi_ref)
+ @rtype: callable object
+ """
+ def check_vdi_ref(self, session, vdi_ref, *args, **kwargs):
+ xennode = XendNode.instance()
+ if type(vdi_ref) == type(str()) and \
+ xennode.get_sr().is_valid_vdi(vdi_ref):
+ return func(self, session, vdi_ref, *args, **kwargs)
+ else:
+ return {'Status': 'Failure',
+ 'ErrorDescription': XEND_ERROR_VDI_INVALID}
+
+ # make sure we keep the 'api' attribute
+ if hasattr(func, 'api'):
+ check_vdi_ref.api = func.api
+
+ return check_vdi_ref
+
+def valid_sr(func):
+ """Decorator to verify if sr_ref is valid before calling
+ method.
+
+ @param func: function with params: (self, session, sr_ref)
+ @rtype: callable object
+ """
+ def check_sr_ref(self, session, sr_ref, *args, **kwargs):
+ xennode = XendNode.instance()
+ if type(sr_ref) == type(str()) and \
+ xennode.get_sr().uuid == sr_ref:
+ return func(self, session, sr_ref, *args, **kwargs)
+ else:
+ return {'Status': 'Failure',
+ 'ErrorDescription': XEND_ERROR_SR_INVALID}
+
+ # make sure we keep the 'api' attribute
+ if hasattr(func, 'api'):
+ check_sr_ref.api = func.api
+
+ return check_sr_ref
+
def do_vm_func(fn_name, vm_ref, *args):
"""Helper wrapper func to abstract away from repeative code.
@@ -212,7 +257,9 @@ class XendAPI:
'host_cpu': (valid_host_cpu, session_required),
'VM': (valid_vm, session_required),
'VBD': (valid_vbd, session_required),
- 'VIF': (valid_vif, session_required)}
+ 'VIF': (valid_vif, session_required),
+ 'VDI': (valid_vdi, session_required),
+ 'SR': (valid_sr, session_required)}
# Cheat methods
# -------------
@@ -849,8 +896,9 @@ class XendAPI:
xendom = XendDomain.instance()
dom = xendom.domain_lookup_nr(label)
if dom:
- return xen_api_success(dom.get_uuid())
+ return xen_api_success([dom.get_uuid()])
return xen_api_error(XEND_ERROR_VM_INVALID)
+
def vm_create(self, session, vm_struct):
xendom = XendDomain.instance()
domuuid = xendom.create_domain(vm_struct)
@@ -1053,9 +1101,212 @@ class XendAPI:
return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
+ # Xen API: Class VDI
+ # ----------------------------------------------------------------
+ VDI_attr_ro = ['VBDs',
+ 'physical_utilisation',
+ 'sector_size',
+ 'type',
+ 'parent',
+ 'children']
+ VDI_attr_rw = ['name_label',
+ 'name_description',
+ 'SR',
+ 'virtual_size',
+ 'sharable',
+ 'read_only']
+ VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
+
+ VDI_methods = ['snapshot']
+ VDI_funcs = ['get_by_label']
+ def vdi_get_vbds(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_physical_utilisation(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_sector_size(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_type(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_parent(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_children(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_name_label(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_name_description(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_sr(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_virtual_size(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_sharable(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_read_only(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_uuid(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_set_name_label(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_set_name_description(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_set_sr(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_set_virtual_size(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_set_sharable(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_set_read_only(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def vdi_snapshot(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_destroy(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_to_xml(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_get_record(self, session, vdi_ref):
+ return xen_api_todo()
+ def vdi_create(self, session):
+ return xen_api_todo()
+ def vdi_get_by_uuid(self, session):
+ return xen_api_todo()
+ def vdi_get_all(self, session):
+ return xen_api_todo()
+ def vdi_get_by_label(self, session):
+ return xen_api_todo()
+
# Xen API: Class SR
# ----------------------------------------------------------------
- # NOT IMPLEMENTED
-
-
-
+ SR_attr_ro = ['VDIs',
+ 'virtual_allocation',
+ 'physical_utilisation',
+ 'physical_size',
+ 'type',
+ 'location']
+
+ SR_attr_rw = ['name_label',
+ 'name_description']
+
+ SR_attr_inst = ['physical_size',
+ 'type',
+ 'location',
+ 'name_label',
+ 'name_description']
+
+ SR_methods = ['clone']
+ SR_funcs = ['get_by_label']
+
+ # Class Functions
+ def sr_get_all(self, session):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success([sr.uuid])
+
+ def sr_get_by_label(self, session, label):
+ sr = XendNode.instance().get_sr()
+ if sr.name_label != label:
+ return xen_api_error(XEND_ERROR_SR_INVALID)
+ return xen_api_success([sr.uuid])
+
+ 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)
+ def sr_destroy(self, session, sr_ref):
+ return xen_api_error(XEND_ERROR_UNSUPPORTED)
+
+ def sr_to_xml(self, session, sr_ref):
+ return xen_api_todo()
+
+ def sr_get_record(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success({
+ 'uuid': sr.uuid,
+ 'name_label': sr.name_label,
+ 'name_description': sr.name_description,
+ 'VDIs': sr.list_images(),
+ 'virtual_allocation': sr.used_space_bytes(),
+ 'physical_utilisation': sr.used_space_bytes(),
+ 'physical_size': sr.total_space_bytes(),
+ 'type': sr.type,
+ 'location': sr.location
+ })
+
+ # Attribute acceess
+ def sr_get_vdis(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success(sr.list_images())
+
+ def sr_get_virtual_allocation(self, session, sr_ref):
+ return sr.used_space_bytes()
+
+ def sr_get_physical_utilisation(self, session, sr_ref):
+ return sr.used_space_bytes()
+
+ def sr_get_physical_size(self, session, sr_ref):
+ return sr.total_space_bytes()
+
+ def sr_get_type(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success(sr.type)
+
+ def sr_get_location(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success(sr.location)
+
+ def sr_get_name_label(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success(sr.name_label)
+
+ def sr_get_name_description(self, session, sr_ref):
+ sr = XendNode.instance().get_sr()
+ return xen_api_success(sr.name_description)
+
+ def sr_set_name_label(self, session, sr_ref, value):
+ sr = XendNode.instance().get_sr()
+ sr.name_label = value
+ return xen_api_success_void()
+
+ def sr_set_name_description(self, session, sr_ref, value):
+ sr = XendNode.instance().get_sr()
+ sr.name_description = value
+ return xen_api_success_void()
+
+#
+# Auto generate some stubs based on XendAPI introspection
+#
+if __name__ == "__main__":
+ def output(line):
+ print ' ' + line
+
+ classes = ['VDI', 'SR']
+ for cls in classes:
+ ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
+ rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
+ methods = getattr(XendAPI, '%s_methods' % cls, [])
+ funcs = getattr(XendAPI, '%s_funcs' % cls, [])
+
+ ref = '%s_ref' % cls.lower()
+
+ for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
+ getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
+ output('def %s(self, session, %s):' % (getter_name, ref))
+ output(' return xen_api_todo()')
+
+ for attr_name in rw_attrs + XendAPI.Base_attr_rw:
+ setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
+ output('def %s(self, session, %s, value):' % (setter_name, ref))
+ output(' return xen_api_todo()')
+
+ for method_name in methods + XendAPI.Base_methods:
+ method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
+ output('def %s(self, session, %s):' % (method_full_name, ref))
+ output(' return xen_api_todo()')
+
+ for func_name in funcs + XendAPI.Base_funcs:
+ func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
+ output('def %s(self, session):' % func_full_name)
+ output(' return xen_api_todo()')
diff -r 1b923f4a788a -r 58521d4b7c7b tools/python/xen/xend/XendAPIConstants.py
--- a/tools/python/xen/xend/XendAPIConstants.py Thu Oct 12 18:01:32 2006 +0100
+++ b/tools/python/xen/xend/XendAPIConstants.py Thu Oct 12 18:51:17 2006 +0100
@@ -71,5 +71,5 @@ XEN_API_BOOT_TYPE = [
]
XEN_API_VBD_MODE = ['RO', 'RW']
-
+XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
diff -r 1b923f4a788a -r 58521d4b7c7b tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py Thu Oct 12 18:01:32 2006 +0100
+++ b/tools/python/xen/xend/XendError.py Thu Oct 12 18:51:17 2006 +0100
@@ -47,4 +47,6 @@ XEND_ERROR_VM_INVALID = ('EVM
XEND_ERROR_VM_INVALID = ('EVMINVALID', 'VM Invalid')
XEND_ERROR_VBD_INVALID = ('EVBDINVALID', 'VBD Invalid')
XEND_ERROR_VIF_INVALID = ('EVIFINVALID', 'VIF Invalid')
+XEND_ERROR_VDI_INVALID = ('EVDIINVALID', 'VDI Invalid')
+XEND_ERROR_SR_INVALID = ('ESRINVALID', 'SR Invalid')
XEND_ERROR_TODO = ('ETODO', 'Lazy Programmer Error')
diff -r 1b923f4a788a -r 58521d4b7c7b tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Thu Oct 12 18:01:32 2006 +0100
+++ b/tools/python/xen/xend/XendNode.py Thu Oct 12 18:51:17 2006 +0100
@@ -68,6 +68,13 @@ class XendNode:
return (cpu_ref in self.cpus)
#
+ # Storage Repo
+ #
+
+ def get_sr(self):
+ return self.sr
+
+ #
# Host Functions
#
diff -r 1b923f4a788a -r 58521d4b7c7b
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py Thu Oct 12 18:01:32
2006 +0100
+++ b/tools/python/xen/xend/XendStorageRepository.py Thu Oct 12 18:51:17
2006 +0100
@@ -315,6 +315,8 @@ class XendStorageRepository:
def total_space_bytes(self):
return self.total_space_kb() * KB
+ def is_valid_vdi(self, vdi_uuid):
+ return (vdi_uuid in self.images)
# remove everything below this line!!
if __name__ == "__main__":
@@ -324,4 +326,7 @@ if __name__ == "__main__":
print xsr.create_image(10 * 1024)
print 'Delete all images:'
for image_uuid in xsr.list_images():
+ print image_uuid,
xsr.destroy_image(image_uuid)
+
+ print
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|