⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xendapi.py

📁 xen 3.2.2 源码
💻 PY
📖 第 1 页 / 共 5 页
字号:
    @rtype: callable object    """        return lambda *args, **kwargs: \           _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),                      'VIF_metrics', func, *args, **kwargs)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    """    return lambda *args, **kwargs: \           _check_ref(XendNode.instance().is_valid_vdi,                      'VDI', func, *args, **kwargs)def valid_vtpm(func):    """Decorator to verify if vtpm_ref is valid before calling method.    @param func: function with params: (self, session, vtpm_ref, ...)    @rtype: callable object    """    return lambda *args, **kwargs: \           _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),                      'VTPM', func, *args, **kwargs)def valid_console(func):    """Decorator to verify if console_ref is valid before calling method.    @param func: function with params: (self, session, console_ref, ...)    @rtype: callable object    """    return lambda *args, **kwargs: \           _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',                                                                   r),                      'console', func, *args, **kwargs)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    """    return lambda *args, **kwargs: \           _check_ref(lambda r: XendNode.instance().is_valid_sr,                      'SR', func, *args, **kwargs)def valid_task(func):    """Decorator to verify if task_ref is valid before calling    method.    @param func: function with params: (self, session, task_ref)    @rtype: callable object    """    return lambda *args, **kwargs: \           _check_ref(XendTaskManager.get_task,                      'task', func, *args, **kwargs)def valid_debug(func):    """Decorator to verify if task_ref is valid before calling    method.    @param func: function with params: (self, session, task_ref)    @rtype: callable object    """    return lambda *args, **kwargs: \           _check_ref(lambda r: r in XendAPI._debug,                      'debug', func, *args, **kwargs)def valid_object(class_name):    """Decorator to verify if object is valid before calling    method.    @param func: function with params: (self, session, pif_ref)    @rtype: callable object    """    return lambda func: \           lambda *args, **kwargs: \           _check_ref(lambda r: \                          XendAPIStore.get(r, class_name) is not None,                      'PIF', func, *args, **kwargs)# -----------------------------# Bridge to Legacy XM API calls# -----------------------------def do_vm_func(fn_name, vm_ref, *args, **kwargs):    """Helper wrapper func to abstract away from repetitive code.    @param fn_name: function name for XendDomain instance    @type fn_name: string    @param vm_ref: vm_ref    @type vm_ref: string    @param *args: more arguments    @type *args: tuple    """    try:        xendom = XendDomain.instance()        fn = getattr(xendom, fn_name)        xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)        return xen_api_success_void()    except VMBadState, exn:        return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,                              exn.actual])classes = {    'session'      : None,    'event'        : None,    'host'         : valid_host,    'host_cpu'     : valid_host_cpu,    'host_metrics' : valid_host_metrics,    'VM'           : valid_vm,    'VBD'          : valid_vbd,    'VBD_metrics'  : valid_vbd_metrics,    'VIF'          : valid_vif,    'VIF_metrics'  : valid_vif_metrics,    'VDI'          : valid_vdi,    'VTPM'         : valid_vtpm,    'console'      : valid_console,    'SR'           : valid_sr,    'task'         : valid_task,    'XSPolicy'     : valid_object("XSPolicy"),    'ACMPolicy'    : valid_object("ACMPolicy"),    'debug'        : valid_debug,    'network'      : valid_object("network"),    'PIF'          : valid_object("PIF"),    'VM_metrics'   : valid_object("VM_metrics"),    'PBD'          : valid_object("PBD"),    'PIF_metrics'  : valid_object("PIF_metrics")}autoplug_classes = {    'network'     : XendNetwork,    'PIF'         : XendPIF,    'VM_metrics'  : XendVMMetrics,    'PBD'         : XendPBD,    'PIF_metrics' : XendPIFMetrics,    'XSPolicy'    : XendXSPolicy,    'ACMPolicy'   : XendACMPolicy,}class XendAPI(object):    """Implementation of the Xen-API in Xend. Expects to be    used via XMLRPCServer.    All methods that need a valid session are marked with    a L{session_required} decorator that will    transparently perform the required session authentication.    We need to support Python <2.4, so we use the old decorator syntax.    All XMLRPC accessible methods require an 'api' attribute and    is set to the XMLRPC function name which the method implements.    """    __decorated__ = False    __init_lock__ = threading.Lock()    _debug = {}        def __new__(cls, *args, **kwds):        """ Override __new__ to decorate the class only once.        Lock to make sure the classes are not decorated twice.        """        cls.__init_lock__.acquire()        try:            if not cls.__decorated__:                cls._decorate()                cls.__decorated__ = True                            return object.__new__(cls, *args, **kwds)        finally:            cls.__init_lock__.release()                def _decorate(cls):        """ Decorate all the object methods to have validators        and appropriate function attributes.        This should only be executed once for the duration of the        server.        """        global_validators = [session_required, catch_typeerror]        # Cheat methods        # -------------        # Methods that have a trivial implementation for all classes.        # 1. get_by_uuid == getting by ref, so just return uuid for        #    all get_by_uuid() methods.                for api_cls in classes.keys():            # We'll let the autoplug classes implement these functions            # themselves - its much cleaner to do it in the base class            if api_cls == 'session' or api_cls in autoplug_classes.keys():                continue                        get_by_uuid = '%s_get_by_uuid' % api_cls            get_uuid = '%s_get_uuid' % api_cls            get_all_records = '%s_get_all_records' % api_cls                def _get_by_uuid(_1, _2, ref):                return xen_api_success(ref)            def _get_uuid(_1, _2, ref):                return xen_api_success(ref)            def unpack(v):                return v.get('Value')            def _get_all_records(_api_cls):                return lambda s, session: \                    xen_api_success(dict([(ref, unpack(getattr(cls, '%s_get_record' % _api_cls)(s, session, ref)))\                                          for ref in unpack(getattr(cls, '%s_get_all' % _api_cls)(s, session))]))            setattr(cls, get_by_uuid, _get_by_uuid)            setattr(cls, get_uuid,    _get_uuid)            setattr(cls, get_all_records, _get_all_records(api_cls))        # Autoplugging classes        # --------------------        # These have all of their methods grabbed out from the implementation        # class, and wrapped up to be compatible with the Xen-API.        def getter(ref, type):            return XendAPIStore.get(ref, type)                for api_cls, impl_cls in autoplug_classes.items():            def doit(n):                           dot_n = '%s.%s' % (api_cls, n)                full_n = '%s_%s' % (api_cls, n)                if not hasattr(cls, full_n):                    f = getattr(impl_cls, n)                    argcounts[dot_n] = f.func_code.co_argcount + 1                    g = lambda api_cls: \                    setattr(cls, full_n, \                            lambda s, session, ref, *args: \                               xen_api_success( \                                   f(getter(ref, api_cls), *args)))                    g(api_cls) # Force api_cls to be captured                                def doit_func(n):                           dot_n = '%s.%s' % (api_cls, n)                full_n = '%s_%s' % (api_cls, n)                if not hasattr(cls, full_n):                    f = getattr(impl_cls, n)                    argcounts[dot_n] = f.func_code.co_argcount                    setattr(cls, full_n, \                            lambda s, session, *args: \                               xen_api_success( \                                   f(*args)))            ro_attrs = impl_cls.getAttrRO()            rw_attrs = impl_cls.getAttrRW()            methods  = impl_cls.getMethods()            funcs    = impl_cls.getFuncs()                        for attr_name in ro_attrs + rw_attrs:                doit('get_%s' % attr_name)            for attr_name in rw_attrs:                doit('set_%s' % attr_name)            for method in methods:                doit('%s' % method)            for func in funcs:                doit_func('%s' % func)        def wrap_method(name, new_f):            try:                f = getattr(cls, name)                wrapped_f = (lambda *args: new_f(f, *args))                wrapped_f.api = f.api                wrapped_f.async = f.async                setattr(cls, name, wrapped_f)            except AttributeError:                # Logged below (API call: %s not found)                pass        def setter_event_wrapper(api_cls, attr_name):            setter_name = '%s_set_%s' % (api_cls, attr_name)            wrap_method(                setter_name,                lambda setter, s, session, ref, *args:                _setter_event_dispatch(s, setter, api_cls, attr_name,                                       session, ref, args))        def ctor_event_wrapper(api_cls):            ctor_name = '%s_create' % api_cls            wrap_method(                ctor_name,                lambda ctor, s, session, *args:                _ctor_event_dispatch(s, ctor, api_cls, session, args))        def dtor_event_wrapper(api_cls):            dtor_name = '%s_destroy' % api_cls            wrap_method(                dtor_name,                lambda dtor, s, session, ref, *args:                _dtor_event_dispatch(s, dtor, api_cls, session, ref, args))        # Wrapping validators around XMLRPC calls        # ---------------------------------------        for api_cls, validator in classes.items():            def doit(n, takes_instance, async_support = False,                     return_type = None):                n_ = n.replace('.', '_')                try:                    f = getattr(cls, n_)                    if n not in argcounts:                        argcounts[n] = f.func_code.co_argcount - 1                                        validators = takes_instance and validator and \                                 [validator] or []                    validators += global_validators                    for v in validators:                        f = v(f)                        f.api = n                        f.async = async_support                        if return_type:                            f.return_type = return_type                                        setattr(cls, n_, f)                except AttributeError:                    log.warn("API call: %s not found" % n)            if api_cls in autoplug_classes.keys():                impl_cls = autoplug_classes[api_cls]                ro_attrs = impl_cls.getAttrRO()                rw_attrs = impl_cls.getAttrRW()                methods  = map(lambda x: (x, ""), impl_cls.getMethods())                funcs    = map(lambda x: (x, ""), impl_cls.getFuncs())            else:                ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) \                           + cls.Base_attr_ro                rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) \                           + cls.Base_attr_rw                methods  = getattr(cls, '%s_methods' % api_cls, []) \                           + cls.Base_methods                funcs    = getattr(cls, '%s_funcs'   % api_cls, []) \                           + cls.Base_funcs

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -