Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
commit ecefb9068acfc42cf65759505a3f1b3f234af5f8 Author: Peter Hatina phatina@redhat.com Date: Mon Jul 21 14:48:09 2014 +0200
allow LMIInstanceNames to call CIMMethods
cli/lmi/shell/LMICompleter.py | 1 + cli/lmi/shell/LMIDecorators.py | 29 ++++++++++++++++++++ cli/lmi/shell/LMIInstanceName.py | 27 +++++++++++++++++++ cli/lmi/shell/LMIMethod.py | 53 ++++++++++++++++++++++++++++++------- 4 files changed, 100 insertions(+), 10 deletions(-)
diff --git a/cli/lmi/shell/LMICompleter.py b/cli/lmi/shell/LMICompleter.py index b5a117b..2cd8609 100644 --- a/cli/lmi/shell/LMICompleter.py +++ b/cli/lmi/shell/LMICompleter.py @@ -97,6 +97,7 @@ class LMICompleter(rlcompleter.Completer): words.extend([m + "(" for m in obj.methods()]) words.extend(obj.properties()) elif isinstance(obj, LMIInstanceName): + words.extend([m + "(" for m in obj.methods()]) words.extend(obj.key_properties()) elif isinstance(obj, LMIMethod): words.extend([p + "Values" for p in obj.valuemap_parameters()]) diff --git a/cli/lmi/shell/LMIDecorators.py b/cli/lmi/shell/LMIDecorators.py index f35db2b..cc33605 100644 --- a/cli/lmi/shell/LMIDecorators.py +++ b/cli/lmi/shell/LMIDecorators.py @@ -18,6 +18,7 @@ from functools import wraps from lmi.shell.compat import *
from lmi.shell.LMIReturnValue import LMIReturnValue +from lmi.shell.LMIUtil import lmi_wrap_cim_class from lmi.shell.LMIUtil import lmi_raise_or_dump_exception
from lmi.shell.LMIExceptions import CIMError @@ -253,6 +254,34 @@ class lmi_class_fetch_lazy(object): return fn(self_wr, *args, **kwargs) return wrapped
+class lmi_instance_name_fetch_lazy(object): + """ + Decorator for :py:class:`.LMIInstanceName`, which first fetches a wrapped + :py:class:`wbem.CIMInstance` object and then executes a wrapped method. + + :param bool full_fetch: True, if :py:class:`wbem.CIMClass` should include + qualifiers and class origin. Default value is False. + """ + def __init__(self, full_fetch=False): + self._full_fetch = full_fetch + + def __call__(self, fn): + """ + Fetches a :py:class:`.LMIClass`, if necessary, and exeutes a wrapped + method. + + :param instancemethod fn: decorated method + """ + @wraps(fn) + def wrapped(self_wr, *args, **kwargs): + if self_wr._lmi_class is None: + self_wr._lmi_class = lmi_wrap_cim_class( + self_wr._conn, + self_wr._cim_instance_name.classname, + self_wr._cim_instance_name.namespace) + self_wr._lmi_class.fetch(self._full_fetch) + return fn(self_wr, *args, **kwargs) + return wrapped
# Default lmi_process_cim_exceptions error handler def return_lmi_rval(rval, exc): diff --git a/cli/lmi/shell/LMIInstanceName.py b/cli/lmi/shell/LMIInstanceName.py index db344dd..2e45a8b 100644 --- a/cli/lmi/shell/LMIInstanceName.py +++ b/cli/lmi/shell/LMIInstanceName.py @@ -19,7 +19,9 @@ from lmi.shell.compat import *
from lmi.shell.LMIObjectFactory import LMIObjectFactory from lmi.shell.LMIBaseObject import LMIWrapperBaseObject +from lmi.shell.LMIDecorators import lmi_instance_name_fetch_lazy from lmi.shell.LMIUtil import lmi_transform_to_lmi +from lmi.shell.LMIUtil import lmi_wrap_cim_method
class LMIInstanceName(LMIWrapperBaseObject): @@ -35,6 +37,7 @@ class LMIInstanceName(LMIWrapperBaseObject): # We use __dict__ to avoid recursion potentially caused by # combo __setattr__ and __getattr__ self.__dict__["_cim_instance_name"] = cim_instance_name + self.__dict__["_lmi_class"] = None super(LMIInstanceName, self).__init__(conn)
def __cmp__(self, other): @@ -71,6 +74,10 @@ class LMIInstanceName(LMIWrapperBaseObject): if isinstance(member, wbem.CIMInstanceName): member = lmi_transform_to_lmi(self._conn, member) return member + elif not self._conn.is_wsman() and name in self.methods(): + return lmi_wrap_cim_method(self._conn, name, self) + elif self._conn.is_wsman() and not name.startswith("_"): + return lmi_wrap_cim_method(self._conn, name, self) raise AttributeError(name)
def __setattr__(self, name, value): @@ -434,6 +441,26 @@ class LMIInstanceName(LMIWrapperBaseObject): return None return lmi_transform_to_lmi(self._conn, instance)
+ @lmi_instance_name_fetch_lazy() + def methods(self): + """ + Returns a list of :py:class:`wbem.CIMInstance` methods' names. + + :returns: list of :py:class:`wbem.CIMInstance` methods' names + + **Usage:** :ref:`instances_methods`. + """ + return self._lmi_class.methods() + + @lmi_instance_name_fetch_lazy() + def print_methods(self): + """ + Prints out the list of :py:class:`wbem.CIMInstance` methods' names. + + **Usage:** :ref:`instances_methods`. + """ + self._lmi_class.print_methods() + def key_properties(self): """ :returns: list of strings of key properties diff --git a/cli/lmi/shell/LMIMethod.py b/cli/lmi/shell/LMIMethod.py index 3aea5d6..7b9a316 100644 --- a/cli/lmi/shell/LMIMethod.py +++ b/cli/lmi/shell/LMIMethod.py @@ -47,6 +47,7 @@ from lmi.shell.LMIUtil import lmi_get_use_exceptions from lmi.shell.LMIUtil import lmi_raise_or_dump_exception from lmi.shell.LMIUtil import lmi_transform_to_cim_param from lmi.shell.LMIUtil import lmi_transform_to_lmi +from lmi.shell.LMIUtil import lmi_wrap_cim_class
from lmi.shell.LMIExceptions import *
@@ -141,8 +142,9 @@ class LMIMethod(LMIWrapperBaseObject): LMI wrapper class representing :py:class:`wbem.CIMMethod`.
:param LMIConnection conn: connection object - :param LMIInstance lmi_instance: :py:class:`.LMIInstance` object, on which - the method call will be issued + :param LMIInstance(Name) lmi_instance: :py:class:`.LMIInstance` or + :py:class:`.LMIInstanceName` object, on which the method call will be + issued :param string method_name: method name """ # 15 seconds sleep timeout for main waiting thread @@ -175,7 +177,11 @@ class LMIMethod(LMIWrapperBaseObject):
def __init__(self, conn, lmi_instance, method_name): super(LMIMethod, self).__init__(conn) - self._lmi_instance = lmi_instance.copy() + if not isinstance(lmi_instance, ( + LMIObjectFactory().LMIInstance, + LMIObjectFactory().LMIInstanceName)): + raise TypeError("lmi_instance must be LMIInstance(Name) type") + self._lmi_instance = lmi_instance self._sync_method = False self._method = None self._method_name = method_name @@ -190,8 +196,17 @@ class LMIMethod(LMIWrapperBaseObject): self._method_name = method_name[4:]
# We need to have CIMClass with qualifiers. Fetch full class. - lmi_class = self._lmi_instance._lmi_class + if isinstance(self._lmi_instance, LMIObjectFactory().LMIInstance): + # LMIInstance + lmi_class = self._lmi_instance._lmi_class + else: + # LMIInstanceName + lmi_class = lmi_wrap_cim_class( + self._conn, + self._lmi_instance.classname, + self._lmi_instance.namespace) lmi_class.fetch(True) + self._method = lmi_class._cim_class.methods[self._method_name]
# Store the constant values as a list. This can consume some time, if @@ -664,12 +679,15 @@ class LMIMethod(LMIWrapperBaseObject): return LMIReturnValue(rval=-1, errorstr=e.message) call_rparams = lmi_transform_to_lmi(self._conn, call_rparams)
- # Refresh the instance, within which the method was called - if refresh_requested and not self._lmi_instance.refresh(): - # NOTE: this is wrong! What should we do? - errorstr = "Could not update an LMI object after a method call" - lmi_raise_or_dump_exception(LMIMethodCallError(errorstr)) - return LMIReturnValue(rval=rval, errorstr=errorstr) + # Refresh is requested + if refresh_requested: + # Refresh the instance, within which the method was called + ref_rval, _, ref_errorstr = self.__refresh_instance() + if not ref_rval: + errorstr = "Could not update an LMI object after a method call" + lmi_raise_or_dump_exception(LMIMethodCallError(ref_errorstr)) + return LMIReturnValue(rval=ref_rval, errorstr=ref_errorstr) + return LMIReturnValue( rval=rval, rparams=call_rparams, errorstr=call_errorstr)
@@ -699,6 +717,21 @@ class LMIMethod(LMIWrapperBaseObject): cond.notify() cond.release()
+ def __refresh_instance(self): + """ + Refreshes nested :py:class:`.LMIInstance`. + + **NOTE:** This method refreshes only nested :py:class:`.LMIInstance`. + Objects of this class may also contain :py:class:`.LMIInstanceName`; in + this case, no refreshing is performed. + + :rtype: :py:class:`.LMIReturnValue` + """ + if not isinstance(self._lmi_instance, LMIObjectFactory().LMIInstance): + # There is nothing to refresh here. + return LMIReturnValue(rval=True) + return self._lmi_instance.refresh() + def doc(self): """ Prints out pretty verbose message with documentation for the class. If
cura-tools-devel@lists.fedorahosted.org