Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
commit 8c77c75459c31c5a0383b9d1053d3ec62d26f714 Author: Peter Hatina phatina@redhat.com Date: Tue Mar 5 16:18:14 2013 +0100
introduce indications handling
cli-tools/lmi/lmi_client_shell.py | 131 +++++++++++++++++++++++++++++++++++++ cli-tools/lmi/lmi_listener.py | 57 ++++++++++++++++ cli-tools/lmi/makefile.am | 1 + cli-tools/lmishell | 8 ++- 4 files changed, 195 insertions(+), 2 deletions(-)
diff --git a/cli-tools/lmi/lmi_client_shell.py b/cli-tools/lmi/lmi_client_shell.py index a30da25..731cdea 100644 --- a/cli-tools/lmi/lmi_client_shell.py +++ b/cli-tools/lmi/lmi_client_shell.py @@ -17,13 +17,18 @@ import os import abc import new import sys +import atexit import pywbem import textwrap import tempfile import subprocess from xml.dom.minicompat import NodeList +from urlparse import urlparse from lmi_client_base import LmiBaseClient from lmi_client_base import LmiReturnValue +from lmi_listener import LmiIndicationListener + +_lmi_indications = {}
class LmiDeletedObjectError(Exception): """Raised, when there is an attempt to access properties @@ -43,6 +48,9 @@ class LmiMethodCallError(Exception): class LmiNoPagerError(Exception): """Raised, when tere is no default pager like less or more"""
+class LmiIndicationError(Exception): + """Raised, if an error occurs while subscribing to/removing an indication""" + def cast_lmi_to_cim(t, value): cast = { "sint8" : lambda x: pywbem.Sint8(x), @@ -62,6 +70,38 @@ def cast_lmi_to_cim(t, value): return tuple(map(cast_func, value)) return cast_func(value)
+# Register _lmi_indications_cleanup at script exit, +# so we drop all the indication subscriptions for now +def _lmi_indications_cleanup(): + "cleaning subscriptions" + global _lmi_indications + for subscription in _lmi_indications.values(): + subscription.delete() + _lmi_indications = [] + +def _lmi_delete_indication(indication_name): + if not indication_name in _lmi_indications: + errorstr = "No such indication subscribed" + if LmiBaseClient._get_use_exceptions(): + raise LmiIndicationError(errorstr) + return LmiReturnValue( + hostname = "No Hostname", + use_display_hook = True, + rval = False, + rparams = {}, + errorstr = errorstr) + indication = _lmi_indications[indication_name] + indication.delete() + _lmi_indications.pop(indication_name) + return LmiReturnValue( + hostname = indication._client.hostname, + use_display_hook = True, + rval = True, + rparams = {}, + errorstr = "") + +atexit.register(_lmi_indications_cleanup) + class _LmiTextFormatter(object): def __init__(self, text): self._text = text @@ -276,6 +316,23 @@ class BaseObject(object): def __call__(self): pass
+class _LmiSubscription(BaseObject): + def __init__(self, client, cim_filter, cim_handler, cim_subscription, listener): + self._client = client + self._cim_filter = cim_filter + self._cim_handler = cim_handler + self._cim_subscription = cim_subscription + self._listener = listener + + def __lt__(self, other): + name < other._name + + def delete(self): + self._client._delete_instance(self._cim_subscription.path) + self._client._delete_instance(self._cim_filter.path) + self._client._delete_instance(self._cim_handler.path) + self._listener.stop() + class _LmiNamespace(BaseObject): def __init__(self, client, name): self._client = client @@ -335,6 +392,80 @@ class _LmiNamespace(BaseObject): return [] return self.__transform_cim_to_lmi(inst_list)
+ def create_indication(self, **kwargs): + _return_value = lambda rval, errorstr: LmiReturnValue( + hostname = self._client.hostname, + use_display_hook = True, + rval = rval, + rparams = {}, + errorstr = errorstr) + try: + global _lmi_indications + system_name = self._client.hostname + filter_props = { + "CreationClassName" : kwargs["FilterCreationClassName"], + "SystemCreationClassName" : kwargs["FilterSystemCreationClassName"], + "SourceNamespace" : kwargs["FilterSourceNamespace"], + "SystemName" : system_name, + "Query" : kwargs["Query"], + "QueryLanguage" : kwargs["QueryLanguage"], + "Name" : kwargs["Name"] + "-filter" + } + handler_props = { + "CreationClassName" : kwargs["HandlerCreationClassName"], + "SystemCreationClassName" : kwargs["HandlerSystemCreationClassName"], + "SystemName" : system_name, + "Destination" : kwargs["Destination"], + "Name" : kwargs["Name"] + "-handler" + } + handler = kwargs["Handler"] + (cim_filter, _, errorstr) = self._client._create_instance( + "CIM_IndicationFilter", self._name, filter_props) + if not cim_filter: + if LmiBaseClient._get_use_exceptions(): + raise LmiIndicationError(errorstr) + return _return_value(False, errorstr) + (cim_handler, _, errorstr) = self._client._create_instance( + "CIM_IndicationHandlerCIMXML", self._name, handler_props) + if not cim_handler: + self._client._delete_instance(cim_filter.path) + if LmiBaseClient._get_use_exceptions(): + raise LmiIndicationError(errorstr) + return _return_value(False, errorstr) + subscription_props = { + "Filter" : cim_filter.path, + "Handler" : cim_handler.path + } + (cim_subscription, _, errorstr) = self._client._create_instance( + "CIM_IndicationSubscription", self._name, subscription_props) + if not cim_subscription: + self._client._delete_instance(cim_filter.path) + self._client._delete_instance(cim_handler.path) + if LmiBaseClient._get_use_exceptions(): + raise LmiIndicationError(errorstr) + return _return_value(False, errorstr) + dest_parse_result = urlparse(kwargs["Destination"]) + listener = LmiIndicationListener( + dest_parse_result.hostname, + dest_parse_result.port, + handler, + certfile = kwargs["CertFile"] if "CertFile" in kwargs else None, + keyfile = kwargs["KeyFile"] if "KeyFile" in kwargs else None) + try: + listener.start() + except socket.error, e: + if LmiBaseClient._get_use_exceptions(): + raise + return _return_value(False, e.args[1]) + _lmi_indications[kwargs["Name"]] = _LmiSubscription(self._client, + cim_filter, cim_handler, cim_subscription, listener) + except KeyError, e: + errorstr = "Not all necessary parameters supported" + if LmiBaseClient._get_use_exceptions(): + raise LmiIndicationError(errorstr) + return _return_value(False, errorstr) + return _return_value(True, "") + @property def name(self): return self._name diff --git a/cli-tools/lmi/lmi_listener.py b/cli-tools/lmi/lmi_listener.py new file mode 100644 index 0000000..d9cdcb9 --- /dev/null +++ b/cli-tools/lmi/lmi_listener.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# Copyright (C) 2012-2013 Peter Hatina phatina@redhat.com +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see http://www.gnu.org/licenses/. + +import sys +import ssl +import time +import pywbem +import socket +import threading +from SocketServer import BaseRequestHandler +from SocketServer import ThreadingMixIn +from BaseHTTPServer import HTTPServer +from BaseHTTPServer import BaseHTTPRequestHandler + +class LmiIndicationHandler(BaseHTTPRequestHandler): + def do_POST(self): + self.server._handler(self.rfile.read()) + +class LmiIndicationServer(ThreadingMixIn, HTTPServer): + pass + +class LmiIndicationListener(object): + def __init__(self, hostname, port, handler, **kwargs): + self._handler = handler + self._hostname = hostname + self._port = port + self._certfile = kwargs["certfile"] if "certfile" in kwargs else None + self._keyfile = kwargs["keyfile"] if "keyfile" in kwargs else None + + def start(self): + self._server = LmiIndicationServer((self._hostname, self._port), LmiIndicationHandler) + self._server._handler = self._handler + self._server_thread = threading.Thread(target = self._server.serve_forever) + self._server_thread.daemon = True + if self._certfile: + self._server.socket = ssl.wrap_socket( + self._server.socket, + certfile = self._certfile, + keyfile = self._keyfile, + server_side = True) + self._server_thread.start() + + def stop(self): + self._server.shutdown() diff --git a/cli-tools/lmi/makefile.am b/cli-tools/lmi/makefile.am index ecc2e2c..9b92504 100644 --- a/cli-tools/lmi/makefile.am +++ b/cli-tools/lmi/makefile.am @@ -6,6 +6,7 @@ lmi_PYTHON = \ lmi_client_service.py \ lmi_client_shell.py \ lmi_client_user.py \ + lmi_listener.py \ lmi_options.py \ __init__.py
diff --git a/cli-tools/lmishell b/cli-tools/lmishell index aaa5c30..0ff58ca 100755 --- a/cli-tools/lmishell +++ b/cli-tools/lmishell @@ -29,6 +29,7 @@ from lmi.lmi_client_shell import _LmiNamespaceRoot from lmi.lmi_client_shell import _LmiClass from lmi.lmi_client_shell import _LmiInstance from lmi.lmi_client_shell import _LmiInstanceName +from lmi.lmi_client_shell import _lmi_delete_indication
def get_item_or_default(dic, item, default): return dic[item] if item in dic else default @@ -39,7 +40,8 @@ def _lmi_displayhook(o): __builtin__._ = None if isinstance(o, LmiReturnValue) and o.use_display_hook: o.use_display_hook = False - if o.rval == 0 or (o.rval == 4096 and o.instance_classname == "LMI_PowerManagementService"): + if (type(o.rval) == int and o.rval == 0) or (type(o.rval) == bool and o.rval == True) \ + or (o.rval == 4096 and o.instance_classname == "LMI_PowerManagementService"): result_str = "ok" else: result_str = "fail" @@ -185,6 +187,7 @@ class LmiInteractiveShell(code.InteractiveConsole): locals["clear_history"] = self.clear_history locals["use_display_sugar"] = _use_display_sugar locals["use_exceptions"] = _use_exceptions + locals["delete_indication"] = _lmi_delete_indication code.InteractiveConsole.__init__(self, locals) self._completer = _LmiCompleter(self.locals) self.load_config(get_item_or_default(kwargs, "config", LmiInteractiveShell.DEFAULT_CONFIG_FILE)) @@ -336,7 +339,8 @@ if __name__ == "__main__": locals = { "LmiConnection" : LmiConnection, "connect" : _connect_noninteractive, - "use_exceptions" : _use_exceptions + "use_exceptions" : _use_exceptions, + "delete_indication" : _lmi_delete_indication } sys.argv = options.script_args try:
cura-tools-devel@lists.fedorahosted.org