diff options
| author | Barry Warsaw | 2009-05-03 15:35:29 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2009-05-03 15:35:29 -0400 |
| commit | e920c98c72fc9674316ae32c26a81fe571964ea5 (patch) | |
| tree | 905de48fe2f08c939b77e13f0fcf35ad1b6e8efa | |
| parent | 443aba66658347d0b747ff84ec1750cfb8c71924 (diff) | |
| download | mailman-e920c98c72fc9674316ae32c26a81fe571964ea5.tar.gz mailman-e920c98c72fc9674316ae32c26a81fe571964ea5.tar.zst mailman-e920c98c72fc9674316ae32c26a81fe571964ea5.zip | |
| -rw-r--r-- | src/mailman/bin/qrunner.py | 16 | ||||
| -rw-r--r-- | src/mailman/config/mailman.cfg | 3 | ||||
| -rw-r--r-- | src/mailman/config/schema.cfg | 3 | ||||
| -rw-r--r-- | src/mailman/queue/rest.py | 50 | ||||
| -rw-r--r-- | src/mailman/rest/configure.zcml | 8 | ||||
| -rw-r--r-- | src/mailman/rest/urls.py | 34 | ||||
| -rw-r--r-- | src/mailman/rest/webservice.py | 20 |
7 files changed, 111 insertions, 23 deletions
diff --git a/src/mailman/bin/qrunner.py b/src/mailman/bin/qrunner.py index 62e943aad..0016d082b 100644 --- a/src/mailman/bin/qrunner.py +++ b/src/mailman/bin/qrunner.py @@ -202,12 +202,16 @@ def main(): options.initialize() if options.options.list: - prefixlen = max(len(shortname) - for shortname in config.qrunner_shortcuts) - for shortname in sorted(config.qrunner_shortcuts): - runnername = config.qrunner_shortcuts[shortname] - shortname = (' ' * (prefixlen - len(shortname))) + shortname - print _('$shortname runs $runnername') + descriptions = {} + for section in config.qrunner_configs: + shortname = section.name.rsplit('.', 1)[-1] + classname = getattr(section, 'class').rsplit('.', 1)[-1] + descriptions[shortname] = classname + longest = max(len(name) for name in descriptions) + for shortname in sorted(descriptions): + classname = descriptions[shortname] + name = (' ' * (longest - len(shortname))) + shortname + print _('$name runs $classname') sys.exit(0) # Fast track for one infinite runner diff --git a/src/mailman/config/mailman.cfg b/src/mailman/config/mailman.cfg index d68099ca3..58dcdd4e8 100644 --- a/src/mailman/config/mailman.cfg +++ b/src/mailman/config/mailman.cfg @@ -54,6 +54,9 @@ class: mailman.queue.outgoing.OutgoingRunner [qrunner.pipeline] class: mailman.queue.pipeline.PipelineRunner +[qrunner.rest] +class: mailman.queue.rest.RESTRunner + [qrunner.retry] class: mailman.queue.retry.RetryRunner sleep_time: 15m diff --git a/src/mailman/config/schema.cfg b/src/mailman/config/schema.cfg index a2003d034..73a2ff34e 100644 --- a/src/mailman/config/schema.cfg +++ b/src/mailman/config/schema.cfg @@ -211,6 +211,9 @@ failure: $msgid delivery to $recip failed with code $smtpcode, $smtpmsg # The hostname at which admin web service resources are exposed. hostname: localhost +# The port at which the admin web service resources are exposed. +port: 8001 + # Whether or not requests to the web service are secured through SSL. use_https: no diff --git a/src/mailman/queue/rest.py b/src/mailman/queue/rest.py new file mode 100644 index 000000000..3d0eb3bae --- /dev/null +++ b/src/mailman/queue/rest.py @@ -0,0 +1,50 @@ +# Copyright (C) 2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Start the administrative HTTP server.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'RESTRunner', + ] + + +import sys +import errno +import select +import signal +import logging + +from mailman.queue import Runner +from mailman.rest.webservice import start + + + +class RESTRunner(Runner): + def run(self): + try: + start() + except KeyboardInterrupt: + sys.exit(signal.SIGTERM) + except select.error as (errcode, message): + if errcode == errno.EINTR: + sys.exit(signal.SIGTERM) + raise + except: + raise diff --git a/src/mailman/rest/configure.zcml b/src/mailman/rest/configure.zcml index edd444d0d..70155bf67 100644 --- a/src/mailman/rest/configure.zcml +++ b/src/mailman/rest/configure.zcml @@ -10,11 +10,11 @@ <webservice:register module="mailman.interfaces.system" /> - <adapter factory="mailman.rest.urls.AbsoluteURLMapper" /> - <adapter - factory="mailman.rest.root.AdminWebServiceRootAbsoluteURL" - name="absolute_url" + for="zope.interface.Interface + mailman.rest.webservice.AdminWebServiceRequest" + provides="zope.traversing.browser.interfaces.IAbsoluteURL" + factory="mailman.rest.urls.AbsoluteURLMapper" /> <utility diff --git a/src/mailman/rest/urls.py b/src/mailman/rest/urls.py index 0cd51e5f6..8d82fe2c6 100644 --- a/src/mailman/rest/urls.py +++ b/src/mailman/rest/urls.py @@ -29,25 +29,49 @@ from zope.component import adapts from zope.interface import implements, Interface from zope.traversing.browser.interfaces import IAbsoluteURL +from mailman.config import config +from mailman.core.system import system +from mailman.rest.configuration import AdminWebServiceConfiguration +from mailman.rest.webservice import AdminWebServiceApplication + class AbsoluteURLMapper: """Generic absolute url mapper.""" implements(IAbsoluteURL) - adapts(Interface, IAbsoluteURL) def __init__(self, context, request): """Initialize with respect to a context and request.""" - # Avoid circular imports. - from mailman.rest.configuration import AdminWebServiceConfiguration + self.context = context + self.request = request self.webservice_config = AdminWebServiceConfiguration() - self.version = webservice_config.service_version_uri_prefix + self.version = self.webservice_config.service_version_uri_prefix self.schema = ('https' if self.webservice_config.use_https else 'http') self.hostname = config.webservice.hostname + self.port = int(config.webservice.port) def __str__(self): """Return the semi-hard-coded URL to the service root.""" - return '{0.schema}://{0.hostname}/{0.version}'.format(self) + path = self[self.context] + return '{0.schema}://{0.hostname}:{0.port}/{0.version}/{1}'.format( + self, path) __call__ = __str__ + + def __getitem__(self, ob): + """Return the path component for the object. + + :param ob: The object we're looking for. + :type ob: anything + :return: The path component. + :rtype: string + :raises KeyError: if no path component can be found. + """ + # Special cases. + if isinstance(ob, AdminWebServiceApplication): + return '' + urls = { + system: 'sys', + } + return urls[ob] diff --git a/src/mailman/rest/webservice.py b/src/mailman/rest/webservice.py index 8203b0439..fe14513b9 100644 --- a/src/mailman/rest/webservice.py +++ b/src/mailman/rest/webservice.py @@ -36,6 +36,7 @@ from zope.interface import implements from zope.publisher.browser import BrowserRequest from zope.publisher.publish import publish +from mailman.config import config from mailman.core.system import system from mailman.interfaces.rest import IResolvePathNames from mailman.rest.publication import AdminWebServicePublication @@ -52,6 +53,11 @@ class AdminWebServiceApplication: implements(IResolvePathNames) def __init__(self, environ, start_response): + self.environ = environ + self.start_response = start_response + + def __iter__(self): + environ = self.environ # Create the request based on the HTTP method used. method = environ.get('REQUEST_METHOD', 'GET').upper() request = AdminWebServiceRequest(environ['wsgi.input'], environ) @@ -63,9 +69,9 @@ class AdminWebServiceApplication: request = publish(request, handle_errors=handle_errors) # Start the WSGI server response. response = request.response - start_response(response.getStatusString(), response.getHeaders()) + self.start_response(response.getStatusString(), response.getHeaders()) # Return the result body iterable. - return response.consumeBodyIter() + return iter(response.consumeBodyIter()) def get(self, name): """Maps root names to resources.""" @@ -80,9 +86,7 @@ def start(): """Start the WSGI admin REST service.""" zcml = resource_string('mailman.rest', 'configure.zcml') xmlconfig.string(zcml) - server = make_server('', 8001, AdminWebServiceApplication) - return server - - -if __name__ == '__main__': - start().serve_forever() + host = config.webservice.hostname + port = int(config.webservice.port) + server = make_server(host, port, AdminWebServiceApplication) + server.serve_forever() |
