instance-erp5.cfg.in 19.5 KB
Newer Older
1
{% import "root_common" as root_common with context -%}
2
{% import "caucase" as caucase with context %}
3
{% set frontend_dict = slapparameter_dict.get('frontend', {}) -%}
4 5
{% set has_frontend = frontend_dict.get('software-url', '') != '' -%}
{% set site_id = slapparameter_dict.get('site-id', 'erp5') -%}
6 7
{% set inituser_login = slapparameter_dict.get('inituser-login', 'zope') -%}
{% set publish_dict = {'site-id': site_id, 'inituser-login': inituser_login} -%}
8
{% set has_posftix = slapparameter_dict.get('smtp', {}).get('postmaster') -%}
9
{% set jupyter_dict = slapparameter_dict.get('jupyter', {}) -%}
10
{% set has_jupyter = jupyter_dict.get('enable', jupyter_enable_default.lower() in ('true', 'yes')) -%}
11
{% set jupyter_zope_family = jupyter_dict.get('zope-family', '') -%}
12 13 14 15 16 17 18 19 20 21
{% set test_runner_enabled = slapparameter_dict.get('test-runner', {}).get('enabled', True) -%}
{% set test_runner_node_count = slapparameter_dict.get('test-runner', {}).get('node-count', 3) -%}
{% set test_runner_extra_database_count = slapparameter_dict.get('test-runner', {}).get('extra-database-count', 3) -%}
{% set test_runner_total_database_count = test_runner_node_count * (1 + test_runner_extra_database_count) -%}
{# Backward compatibility for mariadb.test-database-amount #}
{% set mariadb_test_database_amount = slapparameter_dict.get('mariadb', {}).get('test-database-amount') -%}
{% if mariadb_test_database_amount is not none -%}
{%   set test_runner_total_database_count = mariadb_test_database_amount %}
{%   set test_runner_enabled = mariadb_test_database_amount > 0 %}
{% endif -%}
22
{% set monitor_base_url_dict = {} -%}
23
{% set monitor_dict = slapparameter_dict.get('monitor', {}) %}
24
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
25
[request-common]
26
<= request-common-base
27
config-use-ipv6 = {{ dumps(slapparameter_dict.get('use-ipv6', False)) }}
28
config-computer-memory-percent-threshold = {{ dumps(monitor_dict.get('computer-memory-percent-threshold', 80)) }}
29
{% set caucase_url = slapparameter_dict.get('caucase', {}).pop('url', '') -%}
30

31
{% macro request(name, software_type, config_key, config, ret={'url': True}, key_config={}) -%}
32 33 34
{% do config.update(slapparameter_dict.get(config_key, {})) -%}
{% set section = 'request-' ~ name -%}
[{{ section }}]
35
<= request-common
36 37
name = {{ name }}
software-type = {{ software_type }}
38 39
return = {{ ' '.join(ret) }}
{% for ret, publish in ret.iteritems() -%}
40
{%   if publish -%}
41 42 43
{%     do publish_dict.__setitem__(name ~ '-' ~ ret, '${' ~ section ~ ':connection-' ~ ret ~ '}') %}
{%   endif -%}
{%   if ret == "monitor-base-url" -%}
44
{%     do monitor_base_url_dict.__setitem__(section, '${' ~ section ~ ':connection-' ~ ret ~ '}') -%}
45 46
{%   endif -%}
{% endfor -%}
47
{{ root_common.sla(name) }}
48 49
{% for k, v in config.iteritems() -%}
config-{{ k }} = {{ dumps(v) }}
50
{% endfor -%}
51 52 53
{% for k, v in key_config.iteritems() -%}
config-{{ k }} = {{ '${' ~ v ~ '}' }}
{% endfor -%}
54
config-name = {{ name }}
55
{% endmacro -%}
56

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
promise = ${:etc}/promise
service-on-watch = ${:etc}/service
srv = ${buildout:directory}/srv
backup-caucased = ${:srv}/backup/caucased

{% set caucase_dict = slapparameter_dict.get('caucase', {}) -%}
{% set caucase_url = caucase_dict.get('url') -%}
{% if not caucase_url -%}
{%   if use_ipv6 -%}
{%     set caucase_host = '[' ~ (ipv6_set | list)[0] ~ ']' %}
{%-  else -%}
{%     set caucase_host = (ipv4_set | list)[0] %}
{%-  endif %}
{%   set caucase_port = caucase_dict.get('base-port', 8890) -%}
{%   set caucase_netloc = caucase_host ~ ':' ~ caucase_port -%}
{%   set caucase_url = 'http://' ~ caucase_netloc -%}
{{   caucase.caucased(
       prefix='caucased',
       buildout_bin_directory=bin_directory,
       caucased_path='${directory:service-on-watch}/caucased',
       backup_dir='${directory:backup-caucased}',
       data_dir='${directory:srv}/caucased',
       netloc=caucase_netloc,
       service_auto_approve_count=caucase_dict.get('service-auto-approve-amount', 1),
       user_auto_approve_count=caucase_dict.get('user-auto-approve-amount', 0),
       key_len=caucase_dict.get('key-length', 2048),
       promise='${directory:promise}/caucased',
)}}
{% do root_common.section('caucased') -%}
{% do root_common.section('caucased-promise') -%}
{% endif -%}
{% do publish_dict.__setitem__('caucase-http-url', caucase_url) -%}
{% set balancer_dict = slapparameter_dict.get('balancer', {}) -%}
{% do balancer_dict.setdefault('ssl', {}).setdefault('caucase-url', caucase_url) -%}

95 96
{{ request('memcached-persistent', 'kumofs', 'kumofs', {'tcpv4-port': 2000}, {'url': True, 'monitor-base-url': False}, key_config={'monitor-passwd': 'monitor-htpasswd:passwd'}) }}
{{ request('memcached-volatile', 'kumofs', 'memcached', {'tcpv4-port': 2010, 'ram-storage-size': 64}, {'url': True, 'monitor-base-url': False}, key_config={'monitor-passwd': 'monitor-htpasswd:passwd'}) }}
97 98 99 100 101 102 103 104 105 106 107 108 109 110
{{ request('mariadb', 'mariadb', 'mariadb',
  {
    'tcpv4-port': 2099,
    'max-slowqueries-threshold': monitor_dict.get('max-slowqueries-threshold', 1000),
    'slowest-query-threshold': monitor_dict.get('slowest-query-threshold', ''),
    'test-database-amount': test_runner_total_database_count,
  },
  {
    'database-list': True,
    'test-database-list': True,
    'monitor-base-url': False,
  },
  key_config={'monitor-passwd': 'monitor-htpasswd:passwd'},
) }}
111
{% if has_posftix -%}
112
{{   request('smtp', 'postfix', 'smtp', {'tcpv4-port': 2025, 'smtpd-sasl-user': 'erp5@nowhere'}, key_config={'smtpd-sasl-password': 'publish-early:smtpd-sasl-password', 'monitor-passwd': 'monitor-htpasswd:passwd'}) }}
113 114 115 116 117
{%- else %}
[request-smtp]
# Placeholder smtp service URL
connection-url = smtp://127.0.0.2:0/
{%- endif %}
118 119 120 121 122 123 124 125

{# ZODB -#}
{% set zodb_dict = {} -%}
{% set storage_dict = {} -%}
{% set mountpoints = set() -%}
{% for zodb in slapparameter_dict.get('zodb') or ({'type': 'zeo', 'server': {}},) -%}
{%   do mountpoints.add(zodb.setdefault('mount-point', '/')) -%}
{%   set name = zodb.pop('name', 'root') -%}
126
{%   do assert(name not in zodb_dict, name, zodb_dict) -%}
127 128 129 130 131
{%   do zodb_dict.__setitem__(name, zodb) -%}
{%   if 'server' in zodb -%}
{%     do storage_dict.setdefault(zodb['type'], {}).__setitem__(name, zodb.pop('server')) -%}
{%   endif -%}
{% endfor -%}
132 133
{% do assert(len(mountpoints) == len(zodb_dict)) -%}
{% set neo = [] -%}
134
{% for server_type, server_dict in storage_dict.iteritems() -%}
135 136
{%   if server_type == 'neo' -%}
{%     set ((name, server_dict),) = server_dict.items() -%}
137
{%     do neo.append(server_dict.get('cluster')) -%}
138
{%     do server_dict.update(cluster='${publish-early:neo-cluster}') -%}
139
{{     root_common.request_neo(server_dict, 'zodb-neo', 'neo-') }}
140 141 142 143
{%     set client_dict = zodb_dict[name].setdefault('storage-dict', {}) -%}
{%     for k in 'ssl', '_ca', '_cert', '_key' -%}
{%       do k in server_dict and client_dict.setdefault(k, server_dict[k]) -%}
{%     endfor -%}
144 145
{%   else -%}
{{     assert(server_type == 'zeo', server_type) -}}
146
{# BBB: for compatibility, keep 'zodb' as partition_reference for ZEO -#}
147
{{     request('zodb', 'zodb-' ~ server_type, 'zodb-' ~ server_type, {'tcpv4-port': 2100, 'zodb-dict': server_dict}, dict.fromkeys(('storage-dict', 'tidstorage-ip', 'tidstorage-port', 'monitor-base-url')), key_config={'monitor-passwd': 'monitor-htpasswd:passwd'}) }}
148
{%   endif -%}
149
{% endfor -%}
150

151

152 153 154 155
{% set zope_partition_dict = slapparameter_dict.get('zope-partition-dict', {'1': {}}) -%}
{% set zope_address_list_id_dict = {} -%}
{% if zope_partition_dict -%}

156
[request-zope-base]
157
<= request-common
158 159
return =
  zope-address-list
160
  hosts-dict
161
  monitor-base-url
162 163 164
{%- if test_runner_enabled %}
  test-runner-address-list
{% endif %}
165
{% set bt5_default_list = 'erp5_full_text_mroonga_catalog erp5_configurator_standard erp5_configurator_maxma_demo erp5_configurator_run_my_doc' -%}
166 167 168 169
{% if has_jupyter -%}
{%   set bt5_default_list = bt5_default_list + ' erp5_data_notebook' -%}
{% endif -%}
config-bt5 = {{ dumps(slapparameter_dict.get('bt5', bt5_default_list)) }}
170
config-bt5-repository-url = {{ dumps(slapparameter_dict.get('bt5-repository-url', local_bt5_repository)) }}
171
config-cloudooo-url = {{ dumps(slapparameter_dict.get('cloudooo-url', default_cloudooo_url)) }}
172
config-caucase-url = {{ dumps(caucase_url) }}
173
config-deadlock-debugger-password = ${publish-early:deadlock-debugger-password}
174
config-developer-list = {{ dumps(slapparameter_dict.get('developer-list', [inituser_login])) }}
175
config-saucelabs-dict = {{ dumps(slapparameter_dict.get('saucelabs-dict', {})) }}
176
config-hosts-dict = {{ dumps(slapparameter_dict.get('hosts-dict', {})) }}
177
config-hostalias-dict = {{ dumps(slapparameter_dict.get('hostalias-dict', {})) }}
178
config-id-store-interval = {{ dumps(slapparameter_dict.get('id-store-interval')) }}
179 180
config-zope-longrequest-logger-error-threshold = {{ dumps(monitor_dict.get('zope-longrequest-logger-error-threshold', 20)) }}
config-zope-longrequest-logger-maximum-delay = {{ dumps(monitor_dict.get('zope-longrequest-logger-maximum-delay', 0)) }}
181
config-inituser-login = {{ dumps(inituser_login) }}
182
config-inituser-password = ${publish-early:inituser-password}
183 184
config-kumofs-url = ${request-memcached-persistent:connection-url}
config-memcached-url = ${request-memcached-volatile:connection-url}
185
config-monitor-passwd = ${monitor-htpasswd:passwd}
186 187 188
config-mysql-test-url-list = ${request-mariadb:connection-test-database-list}
config-mysql-url-list = ${request-mariadb:connection-database-list}
config-site-id = {{ dumps(site_id) }}
189
config-smtp-url = ${request-smtp:connection-url}
190
config-timezone = {{ dumps(slapparameter_dict.get('timezone', 'UTC')) }}
191
config-cloudooo-retry-count = {{ slapparameter_dict.get('cloudooo-retry-count', 2) }}
192
config-wendelin-core-zblk-fmt = {{ dumps(slapparameter_dict.get('wendelin-core-zblk-fmt', '')) }}
193
config-zodb-dict = {{ dumps(zodb_dict) }}
194
config-test-runner-enabled = {{ dumps(test_runner_enabled) }}
195
config-test-runner-node-count = {{ dumps(test_runner_node_count) }}
196 197
{% for server_type, server_dict in storage_dict.iteritems() -%}
{%   if server_type == 'neo' -%}
198
config-neo-cluster = ${publish-early:neo-cluster}
199 200 201
config-neo-name = {{ server_dict.keys()[0] }}
config-neo-masters = ${neo-0-final:connection-masters}
{%   else -%}
202
config-zodb-zeo = ${request-zodb:connection-storage-dict}
203 204
config-tidstorage-ip = ${request-zodb:connection-tidstorage-ip}
config-tidstorage-port = ${request-zodb:connection-tidstorage-port}
205 206
{%   endif -%}
{% endfor -%}
207
software-type = zope
208 209

{% set zope_family_dict = {} -%}
210
{% set zope_family_name_list = [] -%}
211 212
{% set zope_backend_path_dict = {} -%}
{% set ssl_authentication_dict = {} -%}
213
{% set jupyter_zope_family_default = [] -%}
214
{% for custom_name, zope_parameter_dict in zope_partition_dict.items() -%}
215 216
{%   set partition_name = 'zope-' ~ custom_name -%}
{%   set section_name = 'request-' ~ partition_name -%}
217
{%   set zope_family = zope_parameter_dict.get('family', 'default') -%}
218
{%   do zope_family_name_list.append(zope_family) %}
219
{%   set backend_path = zope_parameter_dict.get('backend-path', '') % {'site-id': site_id} %}
220 221 222 223 224 225
{#   # default jupyter zope family is first zope family. -#}
{#   # use list.append() to update it, because in jinja2 set changes only local scope. -#}
{%   if not jupyter_zope_family_default -%}
{%     do jupyter_zope_family_default.append(zope_family) -%}
{%   endif -%}
{%   do zope_family_dict.setdefault(zope_family, []).append(section_name) -%}
226 227
{%   do zope_backend_path_dict.__setitem__(zope_family, backend_path) -%}
{%   do ssl_authentication_dict.__setitem__(zope_family, zope_parameter_dict.get('ssl-authentication', False)) -%}
228
[{{ section_name }}]
229
<= request-zope-base
230
name = {{ partition_name }}
231
{% do monitor_base_url_dict.__setitem__(section_name, '${' ~ section_name ~ ':connection-monitor-base-url}') -%}
232
{{ root_common.sla(partition_name) }}
233
config-name = {{ dumps(custom_name) }}
234
config-instance-count = {{ dumps(zope_parameter_dict.get('instance-count', 1)) }}
235
config-private-dev-shm = {{ zope_parameter_dict.get('private-dev-shm', '') }}
236
config-thread-amount = {{ dumps(zope_parameter_dict.get('thread-amount', 4)) }}
237 238 239
config-timerserver-interval = {{ dumps(zope_parameter_dict.get('timerserver-interval', 5)) }}
config-longrequest-logger-interval = {{ dumps(zope_parameter_dict.get('longrequest-logger-interval', -1)) }}
config-longrequest-logger-timeout = {{ dumps(zope_parameter_dict.get('longrequest-logger-timeout', 1)) }}
240
config-large-file-threshold = {{ dumps(zope_parameter_dict.get('large-file-threshold', "10MB")) }}
241
config-port-base = {{ dumps(zope_parameter_dict.get('port-base', 2200)) }}
242
config-webdav = {{ dumps(zope_parameter_dict.get('webdav', False)) }}
243
config-wsgi = {{ dumps(slapparameter_dict.get('wsgi', False)) }}
244
{%   if test_runner_enabled -%}
245
config-test-runner-apache-url-list = ${publish-early:{{ zope_family }}-test-runner-url-list}
246
{%   endif -%}
247 248
{% endfor -%}

249 250 251 252 253 254
{# if not explicitly configured, connect jupyter to first zope family, which  -#}
{# will be 'default' if zope families are not configured also -#}
{% if not jupyter_zope_family and jupyter_zope_family_default -%}
{%   set jupyter_zope_family = jupyter_zope_family_default[0] -%}
{% endif -%}

255 256 257 258 259 260 261 262 263 264
{# We need to concatenate lists that we cannot read as lists, so this gets hairy. -#}
{% set zope_family_parameter_dict = {} -%}
{% for family_name, zope_section_id_list in zope_family_dict.items() -%}
{%   for zope_section_id in zope_section_id_list -%}
{%     set parameter_name = 'zope-family-entry-' ~ zope_section_id -%}
{%     do zope_address_list_id_dict.__setitem__(zope_section_id, parameter_name) -%}
{%     do zope_family_parameter_dict.setdefault(family_name, []).append(parameter_name) -%}
{%   endfor -%}
{%   if has_frontend -%}
{%     set frontend_name = 'frontend-' ~ family_name -%}
265
{%     do publish_dict.__setitem__('family-' ~ family_name, '${' ~ frontend_name ~ ':connection-site_url}' ) -%}
266
[{{ frontend_name }}]
267
<= request-frontend-base
268
name = {{ frontend_name }}
269
config-url = ${request-balancer:connection-{{ family_name }}-v6}
270
{%   else -%}
271 272
{%     do publish_dict.__setitem__('family-' ~ family_name, '${request-balancer:connection-' ~ family_name ~ '}' ) -%}
{%     do publish_dict.__setitem__('family-' ~ family_name ~ '-v6', '${request-balancer:connection-' ~ family_name ~ '-v6}' ) -%}
273 274 275
{%   endif -%}
{% endfor -%}

276 277 278 279 280 281 282 283 284 285 286 287 288 289
{% if has_jupyter -%}
{# request jupyter connected to balancer of proper zope family -#}
{{   request('jupyter', 'jupyter', 'jupyter', {}, key_config={'erp5-url': 'request-balancer:connection-' ~ jupyter_zope_family}) }}

{%   if has_frontend -%}
[frontend-jupyter]
<= request-frontend-base
name = frontend-jupyter
config-url = ${request-jupyter:connection-url}
{#     # override jupyter-url in publish_dict with frontend address -#}
{%     do publish_dict.__setitem__('jupyter-url', '${frontend-jupyter:connection-site_url}') -%}
{%   endif -%}
{%- endif %}

290
[request-balancer]
291
<= request-common
292 293
name = balancer
software-type = balancer
294
{{ root_common.sla('balancer') }}
295
return =
296
  monitor-base-url
297 298 299
{%- for family in zope_family_dict %}
  {{ family }}
  {{ family }}-v6
300 301 302
  {% if test_runner_enabled %}
  {{ family }}-test-runner-url-list
  {% endif %}
303
{% endfor -%}
304
{% do monitor_base_url_dict.__setitem__('request-balancer', '${' ~ 'request-balancer' ~ ':connection-monitor-base-url}') -%}
305
config-zope-family-dict = {{ dumps(zope_family_parameter_dict) }}
306
config-tcpv4-port = {{ dumps(balancer_dict.get('tcpv4-port', 2150)) }}
307 308
{% for zope_section_id, name in zope_address_list_id_dict.items() -%}
config-{{ name }} = {{ ' ${' ~ zope_section_id ~ ':connection-zope-address-list}' }}
309 310 311
{%   if test_runner_enabled -%}
config-{{ name }}-test-runner-address-list = {{ ' ${' ~ zope_section_id ~ ':connection-test-runner-address-list}' }}
{%   endif -%}
312 313
{% endfor -%}
# XXX: should those really be same for all families ?
314
config-haproxy-server-check-path = {{ dumps(balancer_dict.get('haproxy-server-check-path', '/') % {'site-id': site_id}) }}
315
config-monitor-passwd = ${monitor-htpasswd:passwd}
316
config-ssl = {{ dumps(balancer_dict['ssl']) }}
317
config-name = ${:name}
318 319
config-backend-path-dict = {{ dumps(zope_backend_path_dict) }}
config-ssl-authentication-dict = {{ dumps(ssl_authentication_dict) }}
320 321
config-apachedex-promise-threshold = {{ dumps(monitor_dict.get('apachedex-promise-threshold', 70)) }}
config-apachedex-configuration = {{ dumps(monitor_dict.get('apachedex-configuration',
322
'--erp5-base +erp5 .*/VirtualHostRoot/erp5(/|\\?|$) --base +other / --skip-user-agent Zabbix --error-detail --js-embed --quiet')) }}
323

324 325
[request-frontend-base]
{% if has_frontend -%}
326
<= request-common
Roque's avatar
Roque committed
327
recipe = slapos.cookbook:request
328 329
software-url = {{ dumps(frontend_dict['software-url']) }}
software-type = {{ dumps(frontend_dict.get('software-type', 'RootSoftwareInstance')) }}
330
{{ root_common.sla('frontend', True) }}
331 332 333 334 335 336 337
slave = true
{% set config_dict = {
  'type': 'zope',
} -%}
{%   if frontend_dict.get('domain') -%}
{%     do config_dict.__setitem__('custom_domain', frontend_dict['domain']) -%}
{%   endif -%}
338 339 340 341 342 343
{%   if frontend_dict.get('virtualhostroot-http-port') -%}
{%     do config_dict.__setitem__('virtualhostroot-http-port', frontend_dict['virtualhostroot-http-port']) -%}
{%   endif -%}
{%   if frontend_dict.get('virtualhostroot-https-port') -%}
{%     do config_dict.__setitem__('virtualhostroot-https-port', frontend_dict['virtualhostroot-https-port']) -%}
{%   endif -%}
344 345 346 347 348
{%   for name, value in config_dict.items() -%}
config-{{ name }} = {{ value }}
{%   endfor -%}
return = site_url
{% endif -%}
349

350 351
{% endif -%}{# if zope_partition_dict -#}

352
[publish]
353
<= monitor-publish
354
recipe = slapos.cookbook:publish.serialised
355
-extends = publish-early
356 357 358 359
{% if 'neo' in storage_dict -%}
neo-masters = ${neo-0-final:connection-masters}
neo-admins = ${neo-0-final:connection-admins}
{% endif  -%}
360
{% if zope_address_list_id_dict -%}
361 362 363 364 365
{#
Pick any published hosts-dict, they are expected to be identical - and there is
no way to check here.
-#}
hosts-dict = {{ '${' ~ zope_address_list_id_dict.keys()[0] ~ ':connection-hosts-dict}' }}
366
{% endif -%}
367
{% for name, value in publish_dict.items() -%}
368
{{   name }} = {{ value }}
369
{% endfor -%}
370 371
{% if test_runner_enabled -%}
{%   for zope_family_name in zope_family_name_list -%}
372
{{ zope_family_name }}-test-runner-url-list = ${request-balancer:connection-{{ zope_family_name }}-test-runner-url-list}
373 374
{%   endfor -%}
{% endif -%}
375 376 377 378 379 380 381 382 383 384


[publish-early]
recipe = slapos.cookbook:publish-early
-init =
  inituser-password gen-password:passwd
  deadlock-debugger-password gen-deadlock-debugger-password:passwd
{%- if has_posftix %}
  smtpd-sasl-password gen-smtpd-sasl-password:passwd
{%- endif %}
385 386
{% if test_runner_enabled -%}
{%   for zope_family_name in zope_family_name_list %}
387
  {{ zope_family_name }}-test-runner-url-list default-balancer-test-runner-url-list:default
388 389
{%   endfor -%}
{% endif -%}
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
{%- if neo %}
  neo-cluster gen-neo-cluster:name
{%-  if neo[0] %}
neo-cluster = {{ dumps(neo[0]) }}
{%-  endif %}
{%- endif %}
{%- set inituser_password = slapparameter_dict.get('inituser-password') %}
{%- if inituser_password %}
inituser-password = {{ dumps(inituser_password) }}
{%- endif %}
{%- set deadlock_debugger_password = slapparameter_dict.get('deadlock-debugger-password') -%}
{%- if deadlock_debugger_password %}
deadlock-debugger-password = {{ dumps(deadlock_debugger_password) }}
{%- endif %}


[default-balancer-test-runner-url-list]
recipe =
default = not-ready

[gen-password]
recipe = slapos.cookbook:generate.password
storage-path =

[gen-deadlock-debugger-password]
<= gen-password

[gen-neo-cluster-base]
<= gen-password

[gen-neo-cluster]
name = neo-${gen-neo-cluster-base:passwd}

[gen-smtpd-sasl-password]
< = gen-password
425

426
{{ root_common.common_section() }}
427 428

[monitor-conf-parameters]
429
monitor-title = ERP5
430 431 432 433 434 435
password = ${monitor-htpasswd:passwd}

[monitor-base-url-dict]
{% for key, value in monitor_base_url_dict.items() -%}
{{ key }} = {{ value }}
{% endfor %}