{% 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.get('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 logrotate-backup = ${:var}/logrotate [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 [{{ section('monitor-current-log-access') }}] < = monitor-directory-access source = ${directory:log} [{{ section('monitor-backup-log-access') }}] < = monitor-directory-access source = ${directory:logrotate-backup} [monitor-parameters] port = {{ slapparameter_dict['port-base'] + 5000 }} {% 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 = slapparameter_dict.get('zodb-extern', []) -%} {% for key, (mount_point, cache_size, storage_dict) in zodb_dict.items() -%} {% do zodb_list.append({'name': key, 'mount-point': mount_point, 'storage-type': storage_type, 'storage-dict': storage_dict}) -%} {% if cache_size >= 0 -%} {% do zodb_list[-1].__setitem__('cache-size', cache_size) -%} {% endif -%} {% endfor -%} 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) }} {% set log_list = [] -%} {% set import_set = {} -%} {% for zodb in zodb_list -%} {% if zodb.setdefault('storage-type', 'NEOStorage') == 'NEOStorage' -%} {% do import_set.__setitem__('neo.client', None) -%} {% set log = buildout_directory ~ '/var/log/' ~ name ~ '-neo-' ~ zodb.get('name', 'main') ~ '.log' -%} {% do log_list.append(log) -%} {% do zodb.setdefault('storage-dict', {}).__setitem__('logfile', log) -%} {% endif -%} {% endfor -%} import-list = {{ dumps(import_set.keys()) }} zodb-list = {{ dumps(zodb_list) }} [{{ 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}' }} {{ ' '.join(log_list) }} post = {{ bin_directory }}/slapos-kill --pidfile {{ '${' ~ conf_parameter_name ~ ':pid-file}' }} -s USR2 {% 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) }} monitor-url = ${monitor-parameters:url} [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']) }} [buildout] extends = {{ logrotate_cfg }} {{ parameter_dict['template-monitor'] }} parts += erp5-promise certificate-authority cron-entry-monitor cron-entry-rss deploy-index setup-static-files certificate-authority public-symlink cgi-httpd-wrapper cgi-httpd-graceful-wrapper monitor-promise monitor-instance-log-access {{ part_list | join('\n ') }} publish-zope versions = versions [versions] slapos.core = {{ slapos_core_version }}