diff options
| -rwxr-xr-x | bin/keystone | 81 | ||||
| -rwxr-xr-x | bin/keystone-admin | 35 | ||||
| -rwxr-xr-x | bin/keystone-auth | 35 | ||||
| -rw-r--r-- | keystone/__init__.py | 131 | ||||
| -rw-r--r-- | keystone/test/__init__.py | 75 |
5 files changed, 176 insertions, 181 deletions
diff --git a/bin/keystone b/bin/keystone index db4d1dca..d79189db 100755 --- a/bin/keystone +++ b/bin/keystone @@ -36,16 +36,18 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')): import keystone.tools.tracer # @UnusedImport # module runs on import import keystone -from keystone.common import config, wsgi +from keystone.common import config if __name__ == '__main__': + # Initialize a parser for our configuration paramaters + # since we have special handling for --admin-port argument parser = optparse.OptionParser(version='%%prog %s' % keystone.version) common_group = config.add_common_options(parser) config.add_log_options(parser) # Handle a special argument to support starting two endpoints - common_group.add_option( + option = common_group.add_option( '-a', '--admin-port', dest="admin_port", metavar="PORT", help="specifies port for Admin API to listen on (default is 35357)") @@ -54,67 +56,22 @@ if __name__ == '__main__': # Start services try: - # Load Service API server - conf, app = config.load_paste_app( - 'keystone-legacy-auth', options, args) - admin_conf, admin_app = config.load_paste_app( - 'admin', options, args) - - debug = options.get('debug') or conf.get('debug', False) - debug = debug in [True, "True", "1"] - verbose = options.get('verbose') or conf.get('verbose', False) - verbose = verbose in [True, "True", "1"] - - # Safely get SSL options - service_ssl = conf.get('service_ssl', False) - service_ssl = service_ssl in [True, "True", "1"] - admin_ssl = conf.get('admin_ssl', False) - admin_ssl = admin_ssl in [True, "True", "1"] - cert_required = conf.get('cert_required', False) - cert_required = cert_required in [True, "True", "1"] - certfile = conf.get('certfile') - keyfile = conf.get('keyfile') - ca_certs = conf.get('ca_certs') - - if debug or verbose: - config_file = config.find_config_file(options, args) - print "Using config file:", config_file - - port = int(options.get('bind_port') or conf.get('service_port', 5000)) - host = options.get('bind_host', conf.get('service_host', '0.0.0.0')) - - # Load Service API server - if service_ssl: - server = wsgi.SslServer() - server.start(app, port, host, - certfile=certfile, keyfile=keyfile, - ca_certs=ca_certs, - cert_required=cert_required) - else: - server = wsgi.Server() - server.start(app, port, host) - - print "Service API (ssl=%s) listening on %s:%s" % ( - service_ssl, host, port) + # Load Service API Server + service = keystone.Server(name="Service API", + config_name='keystone-legacy-auth', + options=options, args=args) + service.start(wait=False) + except RuntimeError, e: + sys.exit("ERROR: %s" % e) + try: # Load Admin API server - port = int(options.get('admin_port') or conf.get('admin_port', 35357)) - host = options.get('bind_host', conf.get('admin_host', '0.0.0.0')) - - if admin_ssl: - admin_server = wsgi.SslServer() - admin_server.start(admin_app, port, host, - certfile=certfile, keyfile=keyfile, - ca_certs=ca_certs, - cert_required=cert_required) - else: - admin_server = wsgi.Server() - admin_server.start(admin_app, port, host) - - print "Admin API (ssl=%s) listening on %s:%s" % ( - admin_ssl, host, port) - - # Wait until done - server.wait() + port = options.get('admin_port', None) + host = options.get('bind_host', None) + admin = keystone.Server(name='Admin API', config_name='admin', + options=options, args=args) + admin.start(host=host, port=port, wait=True) except RuntimeError, e: sys.exit("ERROR: %s" % e) + finally: + service.stop() diff --git a/bin/keystone-admin b/bin/keystone-admin index fd5c6ef9..68549303 100755 --- a/bin/keystone-admin +++ b/bin/keystone-admin @@ -19,7 +19,7 @@ # under the License. """ -Keystone Identity Server - Admin API +Keystone Identity Server - Admin API """ import optparse @@ -36,40 +36,11 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')): import keystone.tools.tracer # @UnusedImport # module runs on import import keystone -from keystone.common import config, wsgi - if __name__ == '__main__': - # Initialize a parser for our configuration paramaters - parser = optparse.OptionParser(version='%%prog %s' % keystone.version) - common_group = config.add_common_options(parser) - config.add_log_options(parser) - - # Parse arguments and load config - (options, args) = config.parse_options(parser) - config_file = config.find_config_file(options, args) - - # Start services try: # Load Admin API server - conf, app = config.load_paste_app('admin', options, args) - - debug = options.get('debug') or conf.get('debug', False) - debug = debug in [True, "True", "1"] - verbose = options.get('verbose') or conf.get('verbose', False) - verbose = verbose in [True, "True", "1"] - if debug or verbose: - print "Using config file:", config_file - - server = wsgi.Server() - - port = int(options['bind_port'] or conf['admin_port'] or 35357) - host = options['bind_host'] or conf['admin_host'] - - server.start(app, port, host) - - print "Admin API listening on %s:%s" % (host, port) - - server.wait() + admin = keystone.Server(name='Admin API', config_name='admin') + admin.start(wait=True) except RuntimeError, e: sys.exit("ERROR: %s" % e) diff --git a/bin/keystone-auth b/bin/keystone-auth index 73d43863..287482a0 100755 --- a/bin/keystone-auth +++ b/bin/keystone-auth @@ -36,41 +36,12 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')): import keystone.tools.tracer # @UnusedImport # module runs on import import keystone -from keystone.common import config, wsgi - if __name__ == '__main__': - # Initialize a parser for our configuration paramaters - parser = optparse.OptionParser(version='%%prog %s' % keystone.version) - common_group = config.add_common_options(parser) - config.add_log_options(parser) - - # Parse arguments and load config - (options, args) = config.parse_options(parser) - - # Start services try: # Load Service API server - conf, app = config.load_paste_app('keystone-legacy-auth', - options, args) - - debug = options.get('debug') or conf.get('debug', False) - debug = debug in [True, "True", "1"] - verbose = options.get('verbose') or conf.get('verbose', False) - verbose = verbose in [True, "True", "1"] - if debug or verbose: - config_file = config.find_config_file(options, args) - print "Using config file:", config_file - - server = wsgi.Server() - - port = int(options['bind_port'] or conf['service_port'] or 5000) - host = options['bind_host'] or conf['service_host'] - - server.start(app, port, host) - - print "Service API listening on %s:%s" % (host, port) - - server.wait() + admin = keystone.Server(name='Service API', + config_name='keystone-legacy-auth') + admin.start(wait=True) except RuntimeError, e: sys.exit("ERROR: %s" % e) diff --git a/keystone/__init__.py b/keystone/__init__.py index 226b09ae..30ee337f 100644 --- a/keystone/__init__.py +++ b/keystone/__init__.py @@ -13,6 +13,10 @@ # limitations under the License. import gettext +import optparse +import sys + +from keystone.common import config, wsgi API_VERSION = "2.0" @@ -37,3 +41,130 @@ def version(): # This installs the _(...) function as a built-in so all other modules # don't need to. gettext.install('keystone') + + +class Server(): + """Used to start and stop Keystone servers + + This class is called from shell and command-line scripts and is the + entry-point for starting and stopping Keystone servers. + + The initializer can take option and argument overrides, but otherwise will + parse arguments and configuration files itself to determine how to start + the server. + """ + + def __init__(self, name='admin', config_name=None, + options=None, args=None): + """Initizalizer which takes the following paramaters: + + :param name: A cosmetic name for the server (ex. Admin API) + :param config: the paste config name to look for when starting the + server + :param options: a mapping of option key/str(value) pairs passed to + config.load_paste_app + :param args: override for sys.argv (otherwise sys.argv is used) + """ + self.options = options + if args: + self.args = args + else: + self.args = sys.argv + + if options is None or args is None: + # Initialize a parser for our configuration paramaters + parser = optparse.OptionParser(version='%%prog %s' % + version) + common_group = config.add_common_options(parser) + config.add_log_options(parser) + + # Parse arguments and load config + (poptions, pargs) = config.parse_options(parser) + + if options is None: + self.options = poptions + else: + self.options = options + + if args is None: + self.args = pargs + else: + self.args = args + + self.name = name + self.config = config_name or self.name + + def start(self, host=None, port=None, wait=True): + """Starts the Keystone server + + :param host: the IP address to listen on + :param port: the TCP/IP port to listen on + :param wait: whether to wait (block) for the server to terminate or + return to the caller without waiting + """ + # Load Service API server + conf, app = config.load_paste_app( + self.config, self.options, self.args) + + debug = self.options.get('debug') or conf.get('debug', False) + debug = debug in [True, "True", "1"] + verbose = self.options.get('verbose') or conf.get('verbose', False) + verbose = verbose in [True, "True", "1"] + + if debug or verbose: + config_file = config.find_config_file(self.options, self.args) + print "Starting '%s' with config: %s" % (self.config, config_file) + + if port is None: + if self.config == 'admin': + # Legacy + port = int(self.options.get('bind_port') or + conf.get('admin_port', 35357)) + else: + port = int(self.options.get('bind_port') or + conf.get('service_port', 5000)) + if host is None: + host = self.options.get('bind_host', + conf.get('service_host', '0.0.0.0')) + + self.key = "%s-%s:%s" % (self.name, host, port) + + # Safely get SSL options + service_ssl = conf.get('service_ssl', False) + service_ssl = service_ssl in [True, "True", "1"] + + # Load the server + if service_ssl: + cert_required = conf.get('cert_required', False) + cert_required = cert_required in [True, "True", "1"] + certfile = conf.get('certfile') + keyfile = conf.get('keyfile') + ca_certs = conf.get('ca_certs') + + self.server = wsgi.SslServer() + self.server.start(app, port, host, + certfile=certfile, keyfile=keyfile, + ca_certs=ca_certs, + cert_required=cert_required, + key=self.key) + else: + self.server = wsgi.Server() + self.server.start(app, port, host, + key="%s-%s:%s" % (self.config, host, port)) + + print "%s listening on %s://%s:%s" % ( + self.name, ['http', 'https'][service_ssl], host, port) + + # Wait until done + if wait: + self.server.wait() + + def stop(self): + """Stops the Keystone server + + This should be called always to release the network socket + """ + if self.server is not None: + if self.key in self.server.threads: + self.server.threads[self.key].kill() + self.server = None diff --git a/keystone/test/__init__.py b/keystone/test/__init__.py index 915eaf15..3765bfba 100644 --- a/keystone/test/__init__.py +++ b/keystone/test/__init__.py @@ -65,7 +65,7 @@ cgitb.enable(format="text") from functional.common import HttpTestCase import keystone from keystone.common import config, wsgi -from keystone import backends +from keystone import backends, Server TEST_DIR = os.path.abspath(os.path.dirname(__file__)) BASE_DIR = os.path.abspath(os.path.join(TEST_DIR, os.pardir, os.pardir)) @@ -399,61 +399,28 @@ class KeystoneTest(object): (options, args) = config.parse_options(parser) options['config_file'] = self.conf_fp.name - # Start services try: - # Load Service API server - conf, app = config.load_paste_app( - 'keystone-legacy-auth', options, args) - admin_conf, admin_app = config.load_paste_app( - 'admin', options, args) - - port = int(options['bind_port'] or conf['service_port'] or 5000) - host = options['bind_host'] or conf['service_host'] - - if (self.isSsl == True): - server = wsgi.SslServer() - server.start(app, port, host, - certfile=conf['certfile'], - keyfile=conf['keyfile'], - ca_certs=conf['ca_certs'], - cert_required=conf['cert_required']) - # Load Admin API server - port = int(options['admin_port'] or conf['admin_port'] - or 35357) - host = options['bind_host'] or conf['admin_host'] - - admin_server = wsgi.SslServer() - admin_server.start(admin_app, - port, host, - certfile=conf['certfile'], - keyfile=conf['keyfile'], - ca_certs=conf['ca_certs'], - cert_required=conf['cert_required']) - - else: - server = wsgi.Server() - server.start(app, port, host, key="Test") - - print "Service API (ssl=%s) listening on %s:%s" % ( - conf['service_ssl'], host, port) - - # Load Admin API server - port = int(options['admin_port'] or conf['admin_port'] - or 35357) - host = options['bind_host'] or conf['admin_host'] - - admin_server = wsgi.Server() - admin_server.start(admin_app, port, host, key="Test") - - print "Admin API (ssl=%s) listening on %s:%s" % ( - conf['admin_ssl'], host, port) + # Load Service API Server + service = keystone.Server(name="Service API", + config_name='keystone-legacy-auth', + options=options, args=args) + service.start(wait=False) + except RuntimeError, e: + sys.exit("ERROR: %s" % e) + try: + # Load Admin API server + port = options.get('admin_port', None) + host = options.get('bind_host', None) + admin = keystone.Server(name='Admin API', config_name='admin', + options=options, args=args) + admin.start(host=host, port=port, wait=False) except RuntimeError, e: - print e + service.stop() sys.exit("ERROR: %s" % e) - self.server = server - self.admin_server = admin_server + self.server = service + self.admin_server = admin # Load sample data from keystone.test import sampledata @@ -465,12 +432,10 @@ class KeystoneTest(object): print "Stopping the keystone server..." try: if self.server is not None: - if 'Test' in self.server.threads: - self.server.threads['Test'].kill() + self.server.stop() self.server = None if self.admin_server is not None: - if 'Test' in self.admin_server.threads: - self.admin_server.threads['Test'].kill() + self.admin_server.stop() self.admin_server = None self.conf_fp.close() self.conf_fp = None |
