Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Merge pull request #543 from Kitware/settings
Browse files Browse the repository at this point in the history
Server settings in configuration file
  • Loading branch information
waxlamp committed Jan 25, 2016
2 parents b5d58cb + 0df14f0 commit 765a8fc
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ versioning](http://semver.org).
- Service functions ``tangelo.redirect()`` and ``tangelo.internal_redirect()``
to allow services to redirect to other resources
- Service function ``tangelo.file()`` to serve arbitrary files
- Configuration file takes CherryPy configuration options to apply at startup in
``server_settings`` property
- ``tangelo.util.set_server_setting()`` can be used to update CherryPy settings
at runtime

### Changed
- Documentation introduction is more focused; tutorials are more
Expand Down
17 changes: 15 additions & 2 deletions docs/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ key The path to the SSL key

cert The path to the SSL certificate ``None`` [#https]_ [#unset]_

plugins A list of plugins to load (see :ref:`plugin-config`) ``None`` [#plugins]_ [#unset]_
plugins A list of plugins to load (see :ref:`plugin-config`) ``None`` [#plugins_config]_ [#unset]_

server-settings A dictionary of server settings to apply when Tangelo starts. ``None`` [#plugins_config]_ [#settings]_ [#unset]_
================ ================================================================= =================================

.. rubric:: Footnotes
Expand All @@ -124,9 +126,20 @@ plugins A list of plugins to load (see :ref:`plugin-config`)
.. [#unset] That is to say, the option is simply unset by default, the
equivalent of not mentioning the option at all in a configuration file.

.. [#plugins] This option can *only* appear in the configuration file; there is
.. [#plugins_config] This option can *only* appear in the configuration file; there is
no command line equivalent.

.. [#settings] This option provides a method for specifying settings for the
server technology underlying Tangelo. For instance, using

.. code-block:: yaml

server_settings:
server.thread_pool: 1000

would direct Tangelo's CherryPy instance to adjust the number of simultaneous
requests that can be processed to 1000.

Administering a Tangelo Installation
====================================

Expand Down
10 changes: 9 additions & 1 deletion tangelo/tangelo/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ class Config(object):
"key": types.StringTypes,
"cert": types.StringTypes,
"root": types.StringTypes,
"plugins": [list]}
"plugins": [list],
"server_settings": [dict]}

def __init__(self, filename):
for option in Config.options:
Expand Down Expand Up @@ -478,6 +479,13 @@ def main():
"server.socket_host": hostname,
"server.socket_port": port})

# Dump in any other global configuration present in the configuration.
if config.server_settings:
tangelo.log_info("TANGELO", "User server settings:")
for setting, value in config.server_settings.iteritems():
tangelo.util.set_server_setting(setting, value)
tangelo.log_info("TANGELO", "\t%s -> %s" % (setting, cherrypy.config.get(setting)))

# Try to drop privileges if requested, since we've bound to whatever port
# superuser privileges were needed for already.
if drop_privileges:
Expand Down
4 changes: 4 additions & 0 deletions tangelo/tangelo/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ def error_report(code):
return {"message": "Error code: %s (give this code to your system administrator for more information)" % (code)}


def set_server_setting(key, value):
cherrypy.config.update({key: value})


def get_free_port():
# Bind a socket to port 0 (which directs the OS to find an unused port).
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand Down
42 changes: 42 additions & 0 deletions tests/tangelo-config-settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import fixture
import json
import nose
import requests


def start_tangelo():
"""Start tangelo with a some settings."""
config = {"server_settings": {"server.thread_pool": 1000}}
return fixture.start_tangelo("-c", json.dumps(config))


@nose.with_setup(start_tangelo, fixture.stop_tangelo)
def test_config_settings():
response = requests.get(fixture.url('settings'))
print response
assert 'pool="1000"' in response


@nose.with_setup(start_tangelo, fixture.stop_tangelo)
def test_config_settings_change():
response = requests.get(fixture.url('settings', pool='500'))
print response
assert 'pool="500"' in response


@nose.with_setup(fixture.start_tangelo, fixture.stop_tangelo)
def test_config_no_settings():
response = requests.get(fixture.url('settings'))
print response
assert 'pool="None"' in response


def test_config_wrong_type_settings():
config = {"server_settings": "Angosian"}
(_, _, stderr) = fixture.run_tangelo(
"-c", json.dumps(config), terminate=True)
stderr = "\n".join(stderr)

print stderr

assert "option server_settings must be of type dict" in stderr
2 changes: 1 addition & 1 deletion tests/tangelo-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def test_bad_config():
signal = "ERROR while parsing"

print "Expected: '%s' in third line of log" % (signal)
print "Received: %s" % (stderr[1] if len(stderr) > 1 else "")
print "Received: %s" % (stderr[2] if len(stderr) > 2 else "")

assert len(stderr) > 1
assert signal in stderr[2]
Expand Down
10 changes: 10 additions & 0 deletions tests/web/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import cherrypy
import tangelo


# This service reports the value of cherrypy's thread pool setting
def run(**kwargs):
if kwargs.get('pool'):
tangelo.util.set_server_setting('server.thread_pool', int(kwargs['pool']))
response = 'pool="%r"' % cherrypy.config.get('server.thread_pool')
return response

0 comments on commit 765a8fc

Please sign in to comment.