diff options
-rwxr-xr-x | ipa | 9 | ||||
-rw-r--r-- | ipalib/cli.py | 28 | ||||
-rw-r--r-- | ipalib/errors2.py | 14 | ||||
-rw-r--r-- | ipalib/rpc.py | 5 | ||||
-rw-r--r-- | ipaserver/rpcserver.py | 5 | ||||
-rwxr-xr-x | lite-xmlrpc2.py | 36 |
6 files changed, 58 insertions, 39 deletions
@@ -30,12 +30,5 @@ from ipalib import api from ipalib.cli import CLI if __name__ == '__main__': - # If we can't explicitly determin the encoding, we assume UTF-8: - if sys.stdin.encoding is None: - encoding = 'UTF-8' - else: - encoding = sys.stdin.encoding - cli = CLI(api, - (s.decode(encoding) for s in sys.argv[1:]) - ) + cli = CLI(api, sys.argv[1:]) sys.exit(cli.run()) diff --git a/ipalib/cli.py b/ipalib/cli.py index 62b8b9304..6b3ab7e5b 100644 --- a/ipalib/cli.py +++ b/ipalib/cli.py @@ -34,12 +34,11 @@ import struct import frontend import backend -import errors -import errors2 import plugable import util +from errors2 import PublicError, CommandError from constants import CLI_TAB -from parameters import Password +from parameters import Password, Bytes def to_cli(name): @@ -120,9 +119,10 @@ class textui(backend.Backend): """ Decode text from stdin. """ - assert type(str_buffer) is str - encoding = self.__get_encoding(sys.stdin) - return str_buffer.decode(encoding) + if type(str_buffer) is str: + encoding = self.__get_encoding(sys.stdin) + return str_buffer.decode(encoding) + return str_buffer def encode(self, unicode_text): """ @@ -535,7 +535,7 @@ class CLI(object): print '' self.api.log.info('operation aborted') sys.exit() - except errors2.PublicError, e: + except PublicError, e: self.api.log.error(e.strerror) sys.exit(e.errno) @@ -573,7 +573,7 @@ class CLI(object): return key = self.cmd_argv[0] if key not in self: - raise errors.UnknownCommandError(key) + raise CommandError(name=key) self.run_cmd(self[key]) # FIXME: Stuff that might need special handling still: @@ -782,7 +782,17 @@ class CLI(object): list(self.cmd_argv[1:]), KWCollector() ) options = kwc.__todict__() - return cmd.args_options_2_params(*args, **options) + kw = cmd.args_options_2_params(*args, **options) + return dict(self.params_iter(cmd, kw)) + + def params_iter(self, cmd, kw): + for (key, value) in kw.iteritems(): + param = cmd.params[key] + if isinstance(param, Bytes): + yield (key, value) + else: + yield (key, self.textui.decode(value)) + def build_parser(self, cmd): parser = optparse.OptionParser( diff --git a/ipalib/errors2.py b/ipalib/errors2.py index dccdbe6a3..042580936 100644 --- a/ipalib/errors2.py +++ b/ipalib/errors2.py @@ -370,27 +370,19 @@ class NetworkError(PublicError): For example: - >>> raise NetworkError(uri='ldap://localhost:389') + >>> raise NetworkError(uri='ldap://localhost:389', error='Connection refused') Traceback (most recent call last): ... - NetworkError: cannot connect to 'ldap://localhost:389' + NetworkError: cannot connect to 'ldap://localhost:389': Connection refused """ errno = 907 - format = _('cannot connect to %(uri)r') + format = _('cannot connect to %(uri)r: %(error)s') class ServerNetworkError(PublicError): """ **908** Raised when client catches a `NetworkError` from server. - - For example: - - >>> e = NetworkError(uri='ldap://localhost:389') - >>> raise ServerNetworkError(error=e.message, server='https://localhost') - Traceback (most recent call last): - ... - ServerNetworkError: error on server 'https://localhost': cannot connect to 'ldap://localhost:389' """ errno = 908 diff --git a/ipalib/rpc.py b/ipalib/rpc.py index aa8002094..55f3ea954 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -32,10 +32,11 @@ Also see the `ipaserver.rpcserver` module. from types import NoneType import threading +import socket from xmlrpclib import Binary, Fault, dumps, loads, ServerProxy, SafeTransport import kerberos from ipalib.backend import Backend -from ipalib.errors2 import public_errors, PublicError, UnknownError +from ipalib.errors2 import public_errors, PublicError, UnknownError, NetworkError from ipalib.request import context @@ -265,3 +266,5 @@ class xmlclient(Backend): error=e.faultString, server=self.env.xmlrpc_uri, ) + except socket.error, e: + raise NetworkError(uri=self.env.xmlrpc_uri, error=e.args[1]) diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py index f5fb3c623..7bc57751d 100644 --- a/ipaserver/rpcserver.py +++ b/ipaserver/rpcserver.py @@ -66,8 +66,11 @@ class xmlserver(Backend): print 'okay' except Exception, e: if not isinstance(e, PublicError): + self.exception( + '%s: %s', e.__class__.__name__, str(e) + ) e = InternalError() assert isinstance(e, PublicError) - self.debug('Returning %r exception', e.__class__.__name__) + self.info('%s: %s', e.__class__.__name__, str(e)) response = Fault(e.errno, e.strerror) return xml_dumps(response, methodresponse=True) diff --git a/lite-xmlrpc2.py b/lite-xmlrpc2.py index cb216456c..49aa6828b 100755 --- a/lite-xmlrpc2.py +++ b/lite-xmlrpc2.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python2.4 # Authors: # Jason Gerard DeRose <jderose@redhat.com> @@ -23,7 +23,8 @@ In-tree XML-RPC server using SimpleXMLRPCServer. """ -from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +import sys +from SimpleXMLRPCServer import SimpleXMLRPCServer from ipalib import api api.bootstrap_with_global_options(context='server') @@ -31,24 +32,41 @@ api.finalize() class Instance(object): + """ + Just used for `Instance._listMethods()`. + """ + def _listMethods(self): + """ + Provides list of names for ``system.listMethods``. + """ return list(api.Command) class Server(SimpleXMLRPCServer): + """ + Custom server implementing `Server._marshaled_dispatch()`. + """ + def _marshaled_dispatch(self, data, dispatch_method=None): + """ + Use `ipaserver.rpcserver.xmlserver.execute()` to do the real work. + """ return api.Backend.xmlserver.execute(data) -address = ('', api.env.lite_xmlrpc_port) -server = Server(address, - logRequests=False, - allow_none=True, - encoding='UTF-8', -) +kw = dict(logRequests=False) +if sys.version_info[:2] != (2, 4): + kw.update(dict(encoding='UTF-8', allow_none=True)) +server = Server(('', api.env.lite_xmlrpc_port), **kw) +api.log.info('Logging to file %r', api.env.log) +api.log.info('Listening on port %d', api.env.lite_xmlrpc_port) server.register_introspection_functions() server.register_instance(Instance()) + try: server.serve_forever() except KeyboardInterrupt: - api.log.info('Server stopped') + api.log.info('KeyboardInterrupt: shutting down server...') + server.server_close() + api.log.info('Server shutdown.') |