summaryrefslogtreecommitdiffstats
path: root/lmi/scripts/common/command/session.py
diff options
context:
space:
mode:
Diffstat (limited to 'lmi/scripts/common/command/session.py')
-rw-r--r--lmi/scripts/common/command/session.py206
1 files changed, 0 insertions, 206 deletions
diff --git a/lmi/scripts/common/command/session.py b/lmi/scripts/common/command/session.py
deleted file mode 100644
index 9d88bbe..0000000
--- a/lmi/scripts/common/command/session.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-# The views and conclusions contained in the software and documentation are
-# those of the authors and should not be interpreted as representing official
-# policies, either expressed or implied, of the FreeBSD Project.
-#
-# Authors: Michal Minar <miminar@redhat.com>
-#
-"""
-Defines a base class for all command classes operating upon a
-:py:class:`~lmi.scripts.common.session.Session` object.
-"""
-import abc
-from collections import OrderedDict
-
-from lmi.scripts.common import get_logger
-from lmi.scripts.common.command import meta
-from lmi.scripts.common.command.endpoint import LmiEndPointCommand
-from lmi.scripts.common.configuration import Configuration
-from lmi.scripts.common.session import Session
-from lmi.shell import LMIConnection
-from lmi.shell import LMIUtil
-
-LOG = get_logger(__name__)
-
-class LmiSessionCommand(LmiEndPointCommand):
- """
- Base class for end-point commands operating upon a session object.
-
- Using metaclass: :py:class:`~.meta.SessionCommandMetaClass`.
- """
- __metaclass__ = meta.SessionCommandMetaClass
-
- @classmethod
- def cim_namespace(cls):
- """
- This returns default cim namespace, the connection object will be
- nested into before being passed to associated function.
- It can be overriden in few ways:
-
- 1. by setting ``[CIM] Namespace`` option in configuration
- 2. by giving ``--namespace`` argument on command line to the
- ``lmi`` meta-command
- 3. by setting ``NAMESPACE`` property in declaration of command
-
- Higher number means higher priority.
- """
- return Configuration.get_instance().namespace
-
- @classmethod
- def dest_pos_args_count(cls):
- """
- There is a namespace/connection object passed as the first positional
- argument.
- """
- return LmiEndPointCommand.dest_pos_args_count.im_func(cls) + 1
-
- def process_session(self, session, args, kwargs):
- """
- Process each host of given session, call the associated command
- function, collect results and print it to standard output.
-
- :param session: Session object with set of hosts.
- :type session: :py:class:`~lmi.scripts.common.session.Session`
- :param list args: Positional arguments to pass to associated function
- in command library.
- :param dictionary kwargs: Keyword arguments as a dictionary.
- :returns: Exit code of application.
- :rtype: integer
- """
- if not isinstance(session, Session):
- raise TypeError("session must be an object of Session, not %s"
- % repr(session))
- # { ( hostname : (passed, result) ), ... }
- # where passed is a boolean and result is returned value if passed is
- # True and exception otherwise
- results = OrderedDict()
- for connection in session:
- try:
- result = self.take_action(connection, args, kwargs)
- # result may be a generator which may throw in the following
- # function
- results[connection.uri] = (True, result)
- self.process_host_result(connection.uri, True, result)
- except Exception as exc:
- if len(session) > 1:
- LOG().exception('Invocation failed for host "%s": %s',
- connection.uri, exc)
- else:
- LOG().exception(exc)
- results[connection.uri] = (False, exc)
- self.process_host_result(connection.uri, False, exc)
- self.process_session_results(session, results)
- return all(r[0] for r in results.values())
-
- def process_host_result(self, hostname, success, result):
- """
- Called from :py:meth:`process_session` after single host gets
- processed. By default this prints obtained *result* with default
- formatter if the execution was successful. Children of this class may
- want to override this.
-
- :param string hostname: Name of host involved.
- :param boolean success: Whether the action on host succeeded.
- :param result: Either the value returned by associated function upon a
- successful invocation or an exception.
- """
- if success:
- if len(self.session) > 1:
- self.formatter.print_host(hostname)
- self.produce_output(result)
-
- def process_session_results(self, session, results):
- """
- Called at the end of :py:meth:`process_session`'s execution. It's
- supposed to do any summary work upon results from all hosts. By default
- it just prints errors in a form of list.
-
- :param session: Session object.
- :type session: :py:class:`lmi.scripts.common.session.Session`
- :param dictionary results: Dictionary of form: ::
-
- { 'hostname' : (success_flag, result), ... }
-
- where *result* is either an exception or returned value of
- associated function, depending on *success_flag*. See the
- :py:meth:`process_host_result`.
- """
- if not isinstance(session, Session):
- raise TypeError("session must be a Session object")
- if not isinstance(results, dict):
- raise TypeError("results must be a dictionary")
- # check whether any output has been produced
- if ( len(session.get_unconnected())
- or any(not r[0] for r in results.values())):
- data = []
- for hostname in session.get_unconnected():
- data.append((hostname, ['failed to connect']))
- for hostname, (success, error) in results.items():
- if not success:
- data.append((hostname, [error]))
- if len(session) > 1:
- self._print_errors(data,
- new_line=any(r[0] for r in results.values()))
-
- @abc.abstractmethod
- def take_action(self, connection, args, kwargs):
- """
- Executes an action on single host and collects results.
-
- :param connection: Connection to a single host.
- :type connection: :py:class:`lmi.shell.LMIConnection`
- :param list args: Positional arguments for associated function.
- :param dictionary kwargs: Keyword arguments for associated function.
- :returns: Column names and item list as a pair.
- :rtype: tuple
- """
- raise NotImplementedError("take_action must be implemented in subclass")
-
- def execute_on_connection(self, connection, *args, **kwargs):
- """
- Wraps the :py:meth:`~.endpoint.LmiEndPointCommand.execute` method with
- connection adjustments. Connection object is not usually passed
- directly to associated function. Mostly it's the namespace object that
- is expected. This method checks, whether the namespace object is
- desired and modifies connection accordingly.
-
- :param connection: Connection to single host.
- :type connection: :py:class:`lmi.shell.LMIConnection`
- :param list args: Arguments handed over to associated function.
- :param dictionary kwargs: Keyword arguments handed over to associated
- function.
- """
- if not isinstance(connection, LMIConnection):
- raise TypeError("expected an instance of LMIConnection for"
- " connection argument, not %s" % repr(connection))
- namespace = self.cim_namespace()
- if namespace is not None:
- connection = LMIUtil.lmi_wrap_cim_namespace(
- connection, namespace)
- return self.execute(connection, *args, **kwargs)
-
- def run_with_args(self, args, kwargs):
- return self.process_session(self.session, args, kwargs)
-