Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for running Plone on PaaS providers such as Heroku #39

Merged
merged 2 commits into from
Apr 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ Breaking changes:

New features:

- *add item here*
- Added support for setting `instance-home` option.
[zupo]

- Added support for setting CGI environment variables.
[zupo]

Bug fixes:

Expand Down
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ environment-vars
zope_i18n_allowed_languages en
zope_i18n_compile_mo_files true

cgi-environment-vars
Define arbitrary key-value pairs for use as CGI environment variables during
Zope's run cycle. Example::

cgi-environment-vars =
HTTPS ON

initialization
Specify some Python initialization code to include within the generated
``sitecustomize.py`` script (Buildout >= 1.5) or within the instance script
Expand Down Expand Up @@ -341,6 +348,10 @@ before-storage
normally running site in order for changes to be made to the
database.

instance-home
Sets the instancehome for the generated instance.
Defaults to ${buildout:directory}/parts/<name of the section>.

client-home
Sets the clienthome for the generated instance.
Defaults to ${buildout:directory}/var/<name of the section>.
Expand Down
49 changes: 33 additions & 16 deletions src/plone/recipe/zope2instance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ def indent(snippet, amount):
return "\n".join(ws + s if s else "" for s in snippet.split('\n'))


def handle_singleline_env_vars(vars_):
# if the vars are all given on one line we need to do some work
if not '\n' in vars_:
keys = []
values = []
env_vars = vars_.split()
# split out the odd and even items into keys, values
for var in env_vars:
if divmod(env_vars.index(var) + 1, 2)[1]:
keys.append(var)
else:
values.append(var)
env_vars = zip(keys, values)
return '\n'.join(
["%s %s" % (env_var[0], env_var[1]) for env_var in env_vars])
return vars_


class Recipe(Scripts):

def __init__(self, buildout, name, options):
Expand Down Expand Up @@ -161,7 +179,7 @@ def build_zope_conf(self):
if not os.path.exists(var_dir):
os.makedirs(var_dir)

instance_home = location
instance_home = options.get('instance-home', location)
client_home = options.get('client-home', os.path.join(var_dir,
self.name))
if not os.path.exists(client_home):
Expand Down Expand Up @@ -229,21 +247,12 @@ def build_zope_conf(self):
ip_address = 'ip-address %s' % ip_address
environment_vars = options.get('environment-vars', '')
if environment_vars:
# if the vars are all given on one line we need to do some work
if not '\n' in environment_vars:
keys = []
values = []
env_vars = environment_vars.split()
# split out the odd and even items into keys, values
for var in env_vars:
if divmod(env_vars.index(var) + 1, 2)[1]:
keys.append(var)
else:
values.append(var)
env_vars = zip(keys, values)
environment_vars = '\n'.join(["%s %s" % (env_var[0], env_var[1])
for env_var in env_vars])
environment_vars = environment_template % environment_vars
environment_vars = environment_template % \
handle_singleline_env_vars(environment_vars)
cgi_environment_vars = options.get('cgi-environment-vars', '')
if cgi_environment_vars:
cgi_environment_vars = cgi_environment_template % \
handle_singleline_env_vars(cgi_environment_vars)

deprecation_warnings = options.get('deprecation-warnings', '')
if deprecation_warnings:
Expand Down Expand Up @@ -593,6 +602,7 @@ def is_rs_option(name):
pid_file = pid_file,
lock_file = lock_file,
environment_vars = environment_vars,
cgi_environment_vars = cgi_environment_vars,
deprecation_warnings = deprecation_warnings,
python_check_interval = python_check_interval,
enable_products = enable_products,
Expand Down Expand Up @@ -990,6 +1000,12 @@ def render_file_storage(self, file_storage, blob_storage,
</environment>
"""

cgi_environment_template = """
<cgi-environment>
%s
</cgi-environment>
"""

# The template used to build zope.conf
zope_conf_template="""\
%(imports_lines)s
Expand All @@ -1009,6 +1025,7 @@ def render_file_storage(self, file_storage, blob_storage,
%(ip_address)s
%(zserver_threads)s
%(environment_vars)s
%(cgi_environment_vars)s
%(deprecation_warnings)s

%(mailinglogger_import)s
Expand Down
38 changes: 38 additions & 0 deletions src/plone/recipe/zope2instance/tests/zope2instance.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,44 @@ Our environment variables should be set now::
>>> re.search(env_vars, zope_conf).group('vars')
'TZ US/Eastern\nTMP /var/tmp\nDISABLE_PTS True'

We can also specify CGI environment variables for Zope. This comes handy when
hosting on PaaS providers, such as Heroku, where we don't have a reverse-proxy
in front of Zope. For example, we can configure Zope to run in HTTPS mode::

>>> write('buildout.cfg',
... '''
... [buildout]
... parts = instance
... find-links = %(sample_buildout)s/eggs
...
... [instance]
... recipe = plone.recipe.zope2instance
... eggs =
... user = me:me
... cgi-environment-vars = HTTPS ON
... ''' % options)

Let's run it::

>>> print system(join('bin', 'buildout')),
Uninstalling instance.
Installing instance.
Generated script '...instance'.
Generated interpreter '.../parts/instance/bin/interpreter'.
...

Our CGI environment variables should be set now::

>>> instance = os.path.join(sample_buildout, 'parts', 'instance')
>>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
>>> zope_conf = zope_conf.replace('\\', '/')
>>> print zope_conf
%define INSTANCEHOME .../sample-buildout/parts/instance
...
<cgi-environment>
HTTPS ON
</cgi-environment>
...

HTTP server
===========
Expand Down