Commit 797e3954 authored by Alain Takoudjou's avatar Alain Takoudjou

Allow to setup certificate authority path

parent 1d0f62dc
......@@ -3,6 +3,7 @@
{% set ssl_parameter_dict = slapparameter_dict.get('ssl', {}) %}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{% set ca_path = slapparameter_dict['certificate-authority-path'] -%}
{#
XXX: This template only supports exactly one IPv4 and (if ipv6 is used) one IPv6
per partition. No more (undefined result), no less (IndexError).
......@@ -76,22 +77,6 @@ ipv6 = {{ zope_address.split(']:')[0][1:] }}
{% set next_port = next_port + 1 -%}
{% endfor -%}
[apache-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ parameter_dict['openssl'] }}/bin/openssl
ca-dir = ${directory:ca-dir}
requests-directory = ${directory:requests}
wrapper = ${directory:services}/apache-ca
ca-private = ${directory:private}
ca-certs = ${directory:certs}
ca-newcerts = ${directory:newcerts}
ca-crl = ${directory:crl}
country-code = {{ slapparameter_dict['country-code'] }}
email = {{ slapparameter_dict['email'] }}
state = {{ slapparameter_dict['state'] }}
city = {{ slapparameter_dict['city'] }}
company = {{ slapparameter_dict['company'] }}
[haproxy-cfg-parameter-dict]
socket-path = ${directory:run}/haproxy.sock
server-check-path = {{ dumps(slapparameter_dict['haproxy-server-check-path']) }}
......@@ -136,8 +121,8 @@ ssl-session-cache = ${directory:log}/apache-ssl-session-cache
ca-cert = {{ dumps(ssl_parameter_dict.get('ca-cert')) }}
crl = {{ dumps(ssl_parameter_dict.get('ca-crl')) }}
{% else -%}
ca-cert = ${apache-certificate-authority:ca-dir}/cacert.pem
crl = ${apache-certificate-authority:ca-crl}
ca-cert = {{ ca_path }}/cacert.pem
crl = {{ ca_path }}/crl
{% endif -%}
[apache-conf]
......@@ -189,19 +174,12 @@ services = ${:etc}/run
var = ${buildout:directory}/var
run = ${:var}/run
log = ${:var}/log
ca-dir = ${buildout:directory}/srv/ssl
requests = ${:ca-dir}/requests
private = ${:ca-dir}/private
certs = ${:ca-dir}/certs
newcerts = ${:ca-dir}/newcerts
crl = ${:ca-dir}/crl
[buildout]
extends = {{ parameter_dict['instance-logrotate-cfg'] }}
parts +=
publish
logrotate-apache
apache-certificate-authority
{{ part_list | join('\n ') }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
......
......@@ -71,6 +71,7 @@ return =
extra-config =
bt5
bt5-repository-url
ca-path
cloudooo-url
deadlock-debugger-password
developer-list
......@@ -98,6 +99,7 @@ extra-config =
zodb-storage-type
config-bt5 = {{ dumps(slapparameter_dict.get('bt5', 'erp5_full_text_myisam_catalog erp5_configurator_standard erp5_configurator_maxma_demo erp5_configurator_ung erp5_configurator_run_my_doc slapos_configurator')) }}
config-bt5-repository-url = {{ dumps(slapparameter_dict.get('bt5-repository-url', local_bt5_repository)) }}
config-ca-path = ${directory:ca-dir}
config-cloudooo-url = ${request-cloudooo:connection-url}
config-deadlock-debugger-password = ${deadlock-debugger-password:passwd}
config-developer-list = {{ dumps(slapparameter_dict.get('developer-list', [inituser_login])) }}
......@@ -176,11 +178,7 @@ extra-config =
ssl-authentication-dict
ssl
zope-family-dict
country-code
email
state
city
company
certificate-authority-path
{{ zope_address_list_id_dict.values() | join(' ') }}
return =
{%- for family in zope_family_dict %}
......@@ -197,11 +195,7 @@ config-{{ name }} = {{ ' ${' ~ zope_section_id ~ ':connection-zope-address-list}
# XXX: should those really be same for all families ?
config-haproxy-server-check-path = {{ dumps(balancer_dict.get('haproxy-server-check-path', '/') % {'site-id': site_id}) }}
config-ssl = {{ dumps(balancer_dict.get('ssl', {})) }}
config-country-code = {{ slapparameter_dict.get('country-code', 'ZZ') }}
config-email = {{ slapparameter_dict.get('email', 'nobody@example.com') }}
config-state = {{ slapparameter_dict.get('state', "('State',)") }}
config-city = {{ slapparameter_dict.get('city', 'City') }}
config-company = {{ slapparameter_dict.get('company', 'Compagny') }}
config-certificate-authority-path = ${directory:ca-dir}
[request-frontend-base]
{% if has_frontend -%}
......@@ -224,6 +218,39 @@ config-{{ name }} = {{ value }}
return = site_url
{% endif -%}
[directory]
recipe = slapos.cookbook:mkdirectory
{% if slapparameter_dict.get('certificate-authority-path', '') -%}
ca-dir = {{ slapparameter_dict.get('certificate-authority-path') }}
{% else -%}
ca-dir = ${buildout:directory}/srv/ssl
{% endif -%}
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
services = ${:etc}/run
requests = ${:ca-dir}/requests
private = ${:ca-dir}/private
certs = ${:ca-dir}/certs
newcerts = ${:ca-dir}/newcerts
crl = ${:ca-dir}/crl
[apache-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ openssl_location }}/bin/openssl
ca-dir = ${directory:ca-dir}
requests-directory = ${directory:requests}
wrapper = ${directory:services}/service-ca
ca-private = ${directory:private}
ca-certs = ${directory:certs}
ca-newcerts = ${directory:newcerts}
ca-crl = ${directory:crl}
country-code = {{ dumps(slapparameter_dict.get('country-code', 'ZZ')) }}
email = {{ dumps(slapparameter_dict.get('email', 'nobody@example.com')) }}
state = {{ dumps(slapparameter_dict.get('state', "('State',)")) }}
city = {{ dumps(slapparameter_dict.get('city', 'City')) }}
company = {{ dumps(slapparameter_dict.get('company', 'Compagny')) }}
[publish]
recipe = slapos.cookbook:publish.serialised
deadlock-debugger-password = ${deadlock-debugger-password:passwd}
......@@ -238,7 +265,9 @@ hosts-dict = {{ '${' ~ zope_address_list_id_dict.keys()[0] ~ ':connection-hosts-
{% endfor -%}
[buildout]
parts = publish
parts =
apache-certificate-authority
publish
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
{% endif %}
{% if slap_software_type == software_type -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{% set next_port = slapparameter_dict['port-base'] -%}
{% set site_id = slapparameter_dict['site-id'] -%}
{% set storage_type = slapparameter_dict['zodb-storage-type'] -%}
{% set node_id_base = slapparameter_dict['name'] -%}
{% set part_list = [] -%}
{% set publish_list = [] -%}
{% set zodb_dict = slapparameter_dict['zodb-dict'] -%}
{% set longrequest_logger_base_path = buildout_directory ~ '/var/log/longrequest_logger_' -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{#
XXX: This template only supports exactly one IPv4 and one IPv6 per
partition. No more (undefined result), no less (IndexError).
-#}
{% set ipv4 = (ipv4_set | list)[0] -%}
{% if slapparameter_dict['mysql-test-url-list'] -%}
[{{ section('test-runner') }}]
recipe = slapos.cookbook:erp5.test
certificate-authority-path = ${test-certificate-authority:ca-dir}
mysql-url-list = {{ dumps(slapparameter_dict['mysql-test-url-list']) }}
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
test-instance-path = ${directory:unit-test-path}
prepend-path = ${buildout:bin-directory}
run-unit-test = ${buildout:bin-directory}/runUnitTest
run-test-suite = ${buildout:bin-directory}/runTestSuite
openssl-binary = ${test-certificate-authority:openssl-binary}
run-unit-test-binary = {{ parameter_dict['bin-directory'] }}/runUnitTest
run-test-suite-binary = {{ parameter_dict['bin-directory'] }}/runTestSuite
[test-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
ca-dir = ${directory:test-ca-dir}
requests-directory = ${directory:test-ca-requests}
wrapper = ${directory:services}/test-ca
ca-private = ${directory:test-ca-private}
ca-certs = ${directory:test-ca-certs}
ca-newcerts = ${directory:test-ca-newcerts}
ca-crl = ${directory:test-ca-crl}
{%- endif %}
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
instance = ${:srv}/erp5shared
instance-constraint = ${:instance}/Constraint
instance-document = ${:instance}/Document
instance-etc = ${:instance}/etc
instance-etc-package-include = ${:instance}/etc/package-include
instance-extensions = ${:instance}/Extensions
instance-import = ${:instance}/import
instance-lib = ${:instance}/lib
instance-products = ${:instance}/Products
instance-propertysheet = ${:instance}/PropertySheet
instance-tests = ${:instance}/tests
log = ${:var}/log
run = ${:var}/run
services = ${:etc}/run
srv = ${buildout:directory}/srv
tmp = ${buildout:directory}/tmp
var = ${buildout:directory}/var
promises = ${:etc}/promise
unit-test-path = ${:srv}/test-instance/unit_test
test-ca-dir = ${:srv}/test-ca
test-ca-requests = ${:test-ca-dir}/requests
test-ca-private = ${:test-ca-dir}/private
test-ca-certs = ${:test-ca-dir}/certs
test-ca-newcerts = ${:test-ca-dir}/newcerts
test-ca-crl = ${:test-ca-dir}/crl
ca-dir = ${:srv}/ca
ca-requests = ${:ca-dir}/requests
ca-private = ${:ca-dir}/private
ca-certs = ${:ca-dir}/certs
ca-newcerts = ${:ca-dir}/newcerts
ca-crl = ${:ca-dir}/crl
[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:bin}
link-binary = {{ dumps(parameter_dict['link-binary']) }}
[certificate-authority-common]
requests-directory = ${directory:ca-requests}
ca-dir = ${directory:ca-dir}
ca-private = ${directory:ca-private}
ca-certs = ${directory:ca-certs}
ca-newcerts = ${directory:ca-newcerts}
ca-crl = ${directory:ca-crl}
[{{ section('certificate-authority') }}]
< = certificate-authority-common
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
wrapper = ${directory:services}/ca
{% if use_ipv6 -%}
{% set ipv6 = (ipv6_set | list)[0] -%}
[zeo-tunnel-base]
recipe = slapos.cookbook:ipv4toipv6
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}
{% if storage_type == 'zeoclient' -%}
{# ZEO needs tunelling for IPv6 (...until next version becomes current in Zope) -#}
{% set zeo_tunneling_dict = {} -%}
{% for _, _, storage_dict in zodb_dict.values() -%}
{% set storage_server = storage_dict['server'] -%}
{% if storage_server not in zeo_tunneling_dict -%}
{% set current_port = next_port + (zeo_tunneling_dict | length) -%}
{% do zeo_tunneling_dict.__setitem__(storage_server, current_port) -%}
[{{ section('zeo-tunnel-' ~ current_port) }}]
< = zeo-tunnel-base
base-name = {{ 'zeo-tunnel-' ~ current_port }}
ipv4-port = {{ current_port }}
ipv6-port = {{ storage_server.split(']:')[1] }}
ipv6 = {{ storage_server.split(']:')[0][1:] }}
{% endif -%}
{% do storage_dict.__setitem__('server', '' ~ ipv4 ~ ':' ~ zeo_tunneling_dict[storage_server]) -%}
{% endfor -%}
{% set next_port = next_port + (zeo_tunneling_dict | length) -%}
{% endif -%}
{% if slapparameter_dict.get('tidstorage-ip') -%}
[tidstorage-tunnel]
< = zeo-tunnel-base
base-name = tidstorage-tunnel
ipv4-port = {{ next_port }}
ipv6 = {{ dumps(slapparameter_dict.get('tidstorage-ip')) }}
ipv6-port = {{ dumps(slapparameter_dict.get('tidstorage-port')) }}
{% do slapparameter_dict.__setitem__('tidstorage-ip', ipv4) -%}
{% do slapparameter_dict.__setitem__('tidstorage-port', next_port) -%}
{% set next_port = next_port + 1 -%}
[{{ section("promise-tidstorage-tunnel") }}]
recipe = slapos.cookbook:check_port_listening
hostname = ${tidstorage-tunnel:ipv4}
port = ${tidstorage-tunnel:ipv4-port}
path = ${directory:promises}/tidstorage
{% endif -%}
[ipv6toipv4-base]
recipe = slapos.cookbook:ipv6toipv4
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}
ipv6 = {{ ipv6 }}
{% endif -%}
{% if slapparameter_dict.get('tidstorage-ip') -%}
[tidstorage]
ipv4 = {{ dumps(slapparameter_dict['tidstorage-ip']) }}
ipv4-port = {{ dumps(slapparameter_dict['tidstorage-port']) }}
{% else -%}
[tidstorage]
ipv4 =
ipv4-port =
{% endif -%}
{% set hosts_dict = {} -%}
{% for alias, url in (
('erp5-memcached-volatile', slapparameter_dict['memcached-url']),
('erp5-memcached-persistent', slapparameter_dict['kumofs-url']),
('erp5-cloudooo', slapparameter_dict['cloudooo-url']),
) -%}
{% do hosts_dict.__setitem__(
alias,
urlparse.urlparse(url).hostname,
) -%}
{%- endfor %}
{# jinja2 does not support enumerate... -#}
{% set catalog_counter = 0 %}
{% for url in slapparameter_dict['mysql-url-list'] -%}
{% do hosts_dict.__setitem__(
'erp5-catalog-' ~ catalog_counter,
urlparse.urlparse(url).hostname,
) -%}
{% set catalog_counter = catalog_counter + 1 -%}
{%- endfor %}
{% do hosts_dict.update(slapparameter_dict['hosts-dict']) -%}
[hosts-parameter]
host-dict = {{ dumps(hosts_dict) }}
[hosts]
recipe = slapos.recipe.template:jinja2
template = inline: {{ '
{% for alias, aliased in host_dict.items() -%}
{{ aliased }} {{ alias }}
{% endfor %}
' }}
rendered = ${directory:etc}/hosts
context = key host_dict hosts-parameter:host-dict
[preload-userhosts-runzope-parameter]
runzope-binary = {{ bin_directory }}/runzope
userhosts = {{ parameter_dict['userhosts'] }}
shell-path = {{ parameter_dict['dash'] }}/bin/dash
hosts = ${hosts:rendered}
[preload-userhosts-runzope]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:bin}/runzope_userhosts_preloaded
context = section parameter_dict preload-userhosts-runzope-parameter
template = {{ parameter_dict['runzope-userhosts-preloaded-template'] }}
mode = 755
[zope-base]
recipe = slapos.cookbook:generic.zope.zeo.client
inituser = ${directory:instance}/inituser
user = {{ dumps(slapparameter_dict['inituser-login']) }}
password = {{ dumps(slapparameter_dict['inituser-password']) }}
timezone = {{ dumps(slapparameter_dict['timezone']) }}
tmp-path = ${directory:tmp}
bin-path = ${directory:bin}
site-zcml = ${directory:instance-etc}/site.zcml
runzope-binary = ${preload-userhosts-runzope:rendered}
bt5-repository =
[zope-conf-parameter-base]
ip = {{ ipv4 }}
site-id = {{ site_id }}
{% set zodb_list = [] -%}
{% for key, (mount_point, cache_size, storage_dict) in zodb_dict.items() -%}
{% do zodb_list.append([key, mount_point, cache_size, storage_type, storage_dict]) -%}
{% endfor -%}
zodb-list = {{ dumps(zodb_list) }}
developer-list = {{ dumps(slapparameter_dict['developer-list']) }}
instance = ${directory:instance}
instance-products = ${directory:instance-products}
deadlock-path = /manage_debug_threads
deadlock-debugger-password = {{ dumps(slapparameter_dict['deadlock-debugger-password']) }}
tidstorage-ip = ${tidstorage:ipv4}
tidstorage-port = ${tidstorage:ipv4-port}
promise-path = ${erp5-promise:promise-path}
{% set thread_amount = slapparameter_dict['thread-amount'] -%}
thread-amount = {{ thread_amount }}
{% set webdav = slapparameter_dict['webdav'] -%}
webdav = {{ dumps(webdav) }}
{% if webdav -%}
{% set timerserver_interval = 0 -%}
{% else -%}
{% set timerserver_interval = slapparameter_dict['timerserver-interval'] -%}
{%- endif %}
timerserver-interval = {{ dumps(timerserver_interval) }}
[zope-conf-base]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['zope-conf-template'] }}
[logrotate-entry-base]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
{% macro zope(
index,
port,
longrequest_logger_timeout,
longrequest_logger_interval
) -%}
{% set name = 'zope-' ~ index -%}
{% set conf_name = name ~ '-conf' -%}
{% set conf_parameter_name = conf_name ~ '-param' -%}
{% set zope_tunnel_section_name = name ~ '-ipv6toipv4' -%}
{% set zope_tunnel_base_name = zope_tunnel_section_name -%}
[{{ conf_parameter_name }}]
< = zope-conf-parameter-base
pid-file = ${directory:run}/{{ name }}.pid
lock-file = ${directory:run}/{{ name }}.lock
port = {{ port }}
event-log = ${directory:log}/{{ name }}-event.log
z2-log = ${directory:log}/{{ name }}-Z2.log
node-id = {{ dumps(node_id_base ~ '-' ~ index) }}
[{{ conf_name }}]
< = zope-conf-base
rendered = ${directory:etc}/{{ name }}.conf
context =
section parameter_dict {{ conf_parameter_name }}
[{{ section(name) }}]
< = zope-base
{% if longrequest_logger_interval < 0 -%}
longrequest-logger-file =
longrequest-logger-timeout =
longrequest-logger-interval =
{% else -%}
longrequest-logger-file = {{ longrequest_logger_base_path ~ name ~ ".log" }}
longrequest-logger-timeout = {{ longrequest_logger_timeout }}
longrequest-logger-interval = {{ longrequest_logger_interval }}
{% endif -%}
wrapper = ${directory:services}/{{ name }}
configuration-file = {{ '${' ~ conf_name ~ ':rendered}' }}
[{{ section("promise-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ ipv4 }}
port = {{ port }}
path = ${directory:promises}/{{ name }}
{% if use_ipv6 -%}
[{{ zope_tunnel_section_name }}]
< = ipv6toipv4-base
base-name = {{ zope_tunnel_base_name }}
ipv6-port = {{ port }}
ipv4-port = {{ port }}
{% do publish_list.append(("[" ~ ipv6 ~ "]:" ~ port, thread_amount, webdav)) -%}
[{{ section("promise-tunnel-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6}' }}
port = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6-port}' }}
path = ${directory:promises}/{{ zope_tunnel_base_name }}
{% else -%}
{% do publish_list.append((ipv4 ~ ":" ~ port, thread_amount, webdav)) -%}
{% endif -%}
[{{ section('logrotate-entry-' ~ name) }}]
< = logrotate-entry-base
name = {{ name }}
log = {{ '${' ~ conf_parameter_name ~ ':event-log}' }} {{ '${' ~ conf_parameter_name ~ ':z2-log}' }} {{ '${' ~ name ~ ':longrequest-logger-file}' }}
post = {{ bin_directory }}/killpidfromfile {{ '${' ~ conf_parameter_name ~ ':pid-file}' }} SIGUSR2
{% endmacro -%}
{% for i in range(slapparameter_dict['instance-count']) -%}
{{ zope(
i,
next_port,
slapparameter_dict['longrequest-logger-timeout'],
slapparameter_dict['longrequest-logger-interval'],
) }}
{% set next_port = next_port + 1 -%}
{% endfor -%}
[publish-zope]
recipe = slapos.cookbook:publish.serialised
zope-address-list = {{ dumps(publish_list) }}
{#
Note: hosts_dist is generated at zope level rather than at erp5 (root partition)
level, as it is easier: we can access urls as python values trivially here.
This has the downside of making each zope partition publish the (hopefuly) same
dict toward erp5 partition, violating the DRY principle and making the intent
hard to guess.
-#}
hosts-dict = {{ dumps(hosts_dict) }}
[erp5-promise]
recipe = slapos.cookbook:erp5.promise
promise-path = ${directory:etc}/erp5promise.cfg
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
smtp-url = {{ dumps(slapparameter_dict['smtp-url']) }}
bt5 = {{ dumps(slapparameter_dict['bt5']) }}
bt5-repository-url = {{ dumps(slapparameter_dict['bt5-repository-url']) }}
{# if ca-path is set, we will allow activity node to configure certificate authority path -#}
{% if slapparameter_dict['timerserver-interval'] == 1 and slapparameter_dict.get('ca-path', '') -%}
certificate-authority-path = {{ dumps(slapparameter_dict['ca-path']) }}
{% endif -%}
[buildout]
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
extends =
{{ parameter_dict['instance-logrotate-cfg'] }}
parts +=
erp5-promise
{{ part_list | join('\n ') }}
publish-zope
versions = versions
[versions]
slapos.core = {{ slapos_core_version }}
{% endif %}
......@@ -34,6 +34,12 @@ repository = http://git.erp5.org/repos/slapos.core.git
branch = operation-control
git-executable = ${git:location}/bin/git
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = slapos-master-cluster
git-executable = ${git:location}/bin/git
[vifib-fix-products-paths]
recipe = plone.recipe.command
stop-on-error = true
......@@ -64,12 +70,17 @@ mode = 644
[template-erp5]
< = download-base-part
filename = instance-erp5.cfg.in
md5sum = e6e7e8add73df0bc7823dee2dd916d62
md5sum = 4f271175389a2e67f2092885b69c0208
[template-balancer]
< = download-base-part
filename = instance-balancer.cfg.in
md5sum = 08b9ef093af926378b58d384539b3417
md5sum = b4120ea2d07af771aeaa2ffe38d3bef9
[template-zope]
< = download-base-part
filename = instance-zope.cfg.in
md5sum = b1bf0f082a63530970e3e25ef256ff4f
[template-apache-conf]
< = download-base-part
......@@ -86,6 +97,7 @@ md5sum = 61824aab2172d21f1d6403a35cab47cd
python-memcached = 1.47
facebook-sdk = 0.4.0
google-api-python-client = 1.2
jsonschema = 2.4.0
# stick to Zope 2.12.22 because Zope 2.12.23's
# ObjectManager.__getitem__ is much slower for a module having lots of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment