Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit 5cd5cb2cce891892fb04a5599387a3928787f954
Author: Peter Hatina <phatina(a)redhat.com>
Date: Mon Sep 30 07:52:00 2013 +0200
introduce lmi_associators()
This function should speed up associations traversal by pulling all the instances referenced by association class and joining them by hand.
>---------------------------------------------------------------
cli/lmi/shell/LMIConsole.py | 2 +
cli/lmi/shell/LMIUtil.py | 59 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/cli/lmi/shell/LMIConsole.py b/cli/lmi/shell/LMIConsole.py
index bebcce3..13e74e4 100644
--- a/cli/lmi/shell/LMIConsole.py
+++ b/cli/lmi/shell/LMIConsole.py
@@ -37,6 +37,7 @@ from LMIConnection import connect as connect_internal
from LMIUtil import lmi_set_use_exceptions
from LMIUtil import lmi_get_use_exceptions
+from LMIUtil import lmi_associators
from LMIUtil import lmi_isinstance
from LMIHelper import LMIHelper
@@ -66,6 +67,7 @@ class LMIConsole(code.InteractiveConsole):
"LMIInstanceName" : LMIObjectFactory().LMIInstanceName,
"LMIMethod" : LMIObjectFactory().LMIMethod,
"use_exceptions" : lmi_set_use_exceptions,
+ "lmi_associators" : lmi_associators,
"lmi_isinstance" : lmi_isinstance,
"help" : LMIHelper()
}
diff --git a/cli/lmi/shell/LMIUtil.py b/cli/lmi/shell/LMIUtil.py
index 94f38b4..4f85db4 100644
--- a/cli/lmi/shell/LMIUtil.py
+++ b/cli/lmi/shell/LMIUtil.py
@@ -15,6 +15,7 @@
import os
import sys
+import hashlib
import pywbem
from LMIObjectFactory import LMIObjectFactory
@@ -301,3 +302,61 @@ def lmi_script_name():
Returns a string of executed script.
"""
return os.path.basename(sys.argv[0])
+
+def lmi_associators(assoc_classes):
+ """
+ Helper function to speed up associator traversal. Returns a list of tuples,
+ where each tuple contains LMIInstance objects, which are in association.
+
+ Arguments:
+ assoc_classes -- list of LMIClass objects, for which the associations
+ will be returned
+ """
+ def make_key(path):
+ path.host = None
+ return hashlib.md5(path.classname + path.namespace + str(path.keybindings)).hexdigest()
+
+ result = []
+
+ instances = {}
+ for assoc_class in assoc_classes:
+ conn = assoc_class._conn
+ assoc_class.fetch()
+
+ # Reference properties
+ ref_props = [
+ ref_prop_name \
+ for (ref_prop_name, ref_prop) in assoc_class._cim_class.properties.iteritems() \
+ if ref_prop.type == "reference"
+ ]
+
+ # Reference class names
+ ref_class_names = [
+ assoc_class._cim_class.properties[ref_prop].reference_class for ref_prop in ref_props
+ ]
+
+ # Get instances, which will be joined as associators
+ for ref_class_name in ref_class_names:
+ if not ref_class_name in instances:
+ (inst_list, out, err) = conn._client._get_instances(ref_class_name)
+ instances.update({ make_key(inst.path) : inst for inst in inst_list })
+
+ # Join associated objects
+ (assoc_instance_names, out, err) = conn._client._get_instance_names(assoc_class.classname)
+ for assoc in assoc_instance_names:
+ ref_list = []
+ for ref_prop in ref_props:
+ path = assoc[ref_prop]
+ # XXX: Some association classes report in key property a class, which its
+ # instances do not refer to.
+ inst = instances.get(make_key(path), None)
+ if inst:
+ ref_list.append(
+ lmi_wrap_cim_instance(conn, inst, inst.classname,
+ inst.path.namespace)
+ )
+
+ if len(ref_list) == len(ref_class_names):
+ result.append(tuple(ref_list))
+
+ return result
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit 4059d9d468124792323aa0db642150b11e701b55
Author: Peter Hatina <phatina(a)redhat.com>
Date: Fri Sep 20 14:30:57 2013 +0200
make instance refreshing after method call optional
>---------------------------------------------------------------
cli/lmi/shell/LMIMethod.py | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/cli/lmi/shell/LMIMethod.py b/cli/lmi/shell/LMIMethod.py
index 80f422e..92faf65 100644
--- a/cli/lmi/shell/LMIMethod.py
+++ b/cli/lmi/shell/LMIMethod.py
@@ -351,8 +351,14 @@ class LMIMethod(LMIWrapperBaseObject):
Arguments:
method_args -- dictionary containing CIMMethod arguments
kwargs -- CIMMethod keyword arguments (method_args preffered)
+
+ Keyword Arguments:
+ RefreshInstance -- bool flag, which tells the LMIShell, whether
+ the instance should be refreshed after a method call. Default
+ value is False.
"""
synchro_method_polling = kwargs.pop("PreferPolling", False)
+ refresh_requested = kwargs.pop("RefreshInstance", False)
if method_args is None:
method_args = {}
method_args.update(kwargs)
@@ -408,7 +414,7 @@ class LMIMethod(LMIWrapperBaseObject):
lmi_raise_or_dump_exception(e)
return LMIReturnValue(rval=-1, errorstr=e.message)
call_rparams = lmi_transform_to_lmi(self._conn, call_rparams)
- if not self._lmi_instance.refresh():
+ 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))
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit dc480bc5786abb9c87bdd422b1d7008c6a8c7279
Author: Peter Hatina <phatina(a)redhat.com>
Date: Wed Sep 11 10:30:45 2013 +0200
introduce passing arguments to method call by dictionary
>---------------------------------------------------------------
cli/lmi/shell/LMIMethod.py | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/cli/lmi/shell/LMIMethod.py b/cli/lmi/shell/LMIMethod.py
index 8168ca4..80f422e 100644
--- a/cli/lmi/shell/LMIMethod.py
+++ b/cli/lmi/shell/LMIMethod.py
@@ -328,10 +328,14 @@ class LMIMethod(LMIWrapperBaseObject):
# have a "fresh" one.
return self.__return_synchro_method_call(job_inst, False)
- def __call__(self, *args, **kwargs):
+ def __call__(self, method_args=None, **kwargs):
"""
Perform a method call.
+ Method arguments are preferrably passed by dictionary (parameter : value). Using
+ former means of passing arguments, by keyword arguments, to a method call works
+ too.
+
If performing a synchronous method call, passing PreferPolling can be used
to select which method should be used -- either subscribing to an indication
or polling method. Returns LMIReturnValue object with rval set to remote method
@@ -345,21 +349,24 @@ class LMIMethod(LMIWrapperBaseObject):
LMISynchroMethodCallError
Arguments:
- args -- CIMMethod arguments
- kwargs -- CIMMethod keyword arguments
+ method_args -- dictionary containing CIMMethod arguments
+ kwargs -- CIMMethod keyword arguments (method_args preffered)
"""
synchro_method_polling = kwargs.pop("PreferPolling", False)
- for (param, value) in kwargs.iteritems():
+ if method_args is None:
+ method_args = {}
+ method_args.update(kwargs)
+ for (param, value) in method_args.iteritems():
if param in self._method.parameters:
t = self._method.parameters[param].type
- kwargs[param] = lmi_cast_to_cim(t, value)
+ method_args[param] = lmi_cast_to_cim(t, value)
else:
# NOTE: maybe we could check for pywbem type and not to exit prematurely
errorstr = "Unknown parameter '%s' supplied for method '%s'" % (param, self._method.name)
lmi_raise_or_dump_exception(LMIUnknownParameterError(errorstr))
return LMIReturnValue(rval=-1, errorstr=errorstr)
(rval, call_rparams, call_errorstr) = self._conn._client._call_method_raw(self._lmi_instance,
- self._method.name, **kwargs)
+ self._method.name, **method_args)
rval = lmi_transform_to_lmi(self._conn, rval)
if call_rparams:
call_rparams = lmi_transform_to_lmi(self._conn, call_rparams)
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit 6470ac05a94445f7b294e552f82622bcf22c1dba
Author: Roman Rakus <rrakus(a)redhat.com>
Date: Mon Sep 9 13:13:34 2013 +0200
Completion: bash completion for lmi shell
It allow to complete:
- LMI Shell options (short and long)
- files with .lmi and .py extension
- directories
Signed-off-by: Roman Rakus <rrakus(a)redhat.com>
>---------------------------------------------------------------
cli/completion/lmishell.bash | 56 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/cli/completion/lmishell.bash b/cli/completion/lmishell.bash
new file mode 100644
index 0000000..07958f0
--- /dev/null
+++ b/cli/completion/lmishell.bash
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Roman Rakus <rrakus(a)redhat.com>
+#
+# Bash completion for LMI Shell
+
+
+_lmishell() {
+ oldifs=$IFS
+ IFS=$'\n'
+ local options=(-h -i -v -m -q -n --help --interact --verbose --more-verbose --quiet --noverify)
+ local current="${COMP_WORDS[$COMP_CWORD]}"
+ local hasfile=no
+ for (( i=1; i < ${#COMP_WORDS[@]} - 1; i++ )); do
+ [[ ${COMP_WORDS[$i]} != -* && ${COMP_WORDS[$i]} ]] && hasfile=yes
+ done
+ if [[ $hasfile == no ]]; then
+ if [[ $current =~ ^- ]]; then
+ COMPREPLY=( $(compgen "-W ${options[*]}" -- "$current" ) )
+ else
+ COMPREPLY=( $(compgen -f -o plusdirs -X '!*.lmi' -- "$current") )
+ COMPREPLY+=( $(compgen -f -X '!*.py' -- "$current") )
+ fi
+ fi
+ # for directories add slash
+ # for others add space
+ for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
+ # using printf %q because we need to escape nonprintable chars
+ if [[ -d ${COMPREPLY[$i]} ]]; then
+ COMPREPLY[$i]=$(printf '%q/' "${COMPREPLY[$i]}")
+ else
+ COMPREPLY[$i]=$(printf '%q ' "${COMPREPLY[$i]}")
+ fi
+ done
+ IFS=$oldifs
+}
+
+# nospace because of directories
+# for dirs it will add /
+# for others it will add space manually
+complete -o nospace -F _lmishell lmishell
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit 21525bac11f0b9ddc8af4aeecbcd1adf9822d759
Author: Peter Hatina <phatina(a)redhat.com>
Date: Tue Sep 3 13:45:05 2013 +0200
fix class fetching for root class in lmi_isinstance() when caching enabled
>---------------------------------------------------------------
cli/lmi/shell/LMIShellCache.py | 19 ++++++++++++++++---
cli/lmi/shell/LMIShellClient.py | 7 +++----
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/cli/lmi/shell/LMIShellCache.py b/cli/lmi/shell/LMIShellCache.py
index 986f3e9..ef0a966 100644
--- a/cli/lmi/shell/LMIShellCache.py
+++ b/cli/lmi/shell/LMIShellCache.py
@@ -76,17 +76,30 @@ class LMIShellCache(object):
"""
self._class_dict[cim_class.classname] = cim_class
- def get_superclass(self, classname, namespace):
+ def has_superclass(self, classname, namespace):
"""
- Returns a cached superclass to the given class name.
+ Returns True, if the cache contains superclass to the given
+ class name, False otherwise.
Arguments:
classname -- string containing a cached class name
namespace -- string containing a namespace name
"""
if not namespace in self._class_superclass_dict:
- return None
+ return False
if not classname in self._class_superclass_dict[namespace]:
+ return False
+ return True
+
+ def get_superclass(self, classname, namespace):
+ """
+ Returns a cached superclass to the given class name.
+
+ Arguments:
+ classname -- string containing a cached class name
+ namespace -- string containing a namespace name
+ """
+ if not self.has_superclass(classname, namespace):
return None
return self._class_superclass_dict[namespace][classname]
diff --git a/cli/lmi/shell/LMIShellClient.py b/cli/lmi/shell/LMIShellClient.py
index 4ebeba1..d2203b9 100644
--- a/cli/lmi/shell/LMIShellClient.py
+++ b/cli/lmi/shell/LMIShellClient.py
@@ -154,11 +154,10 @@ class LMIShellClient(LMIBaseClient):
namespace -- string containing the namespace of CIMClass
"""
if self._cache.active:
- superclass = self._cache.get_superclass(classname, namespace)
- if superclass is None:
+ if self._cache.has_superclass(classname, namespace):
+ superclass = self._cache.get_superclass(classname, namespace)
+ else:
superclass = LMIBaseClient._get_superclass(self, classname, namespace)
- if not superclass:
- return None
self._cache.add_superclass(classname, superclass, namespace)
return superclass
return LMIBaseClient._get_superclass(self, classname, namespace)