instance-frontend.cfg.in 44.9 KB
Newer Older
1
{% import "caucase" as caucase with context %}
Łukasz Nowak's avatar
Łukasz Nowak committed
2
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
3 4 5 6 7 8 9
{%- set HTTP3_PORT = instance_parameter_dict.get('configuration.http3-port', '443') %}
{%- if instance_parameter_dict.get('configuration.enable-http3', 'false').lower() in TRUE_VALUES %}
{%-   set FRONTEND_HTTP3 = True %}
{%- else %}
{%-   set FRONTEND_HTTP3 = False %}
{%- endif %}
{%- if FRONTEND_HTTP3 %}
10 11 12 13 14
{%-   set FRONTEND_HAPROXY_EXECUTABLE = software_parameter_dict['haproxy_quic_executable'] %}
{%- else %}
{%-   set FRONTEND_HAPROXY_EXECUTABLE = software_parameter_dict['haproxy_executable'] %}
{%- endif %}
{%- set BACKEND_HAPROXY_EXECUTABLE = software_parameter_dict['haproxy_executable'] %}
15 16
[buildout]
extends =
17 18 19
  {{ software_parameter_dict['profile_common'] }}
  {{ software_parameter_dict['profile_monitor'] }}
  {{ software_parameter_dict['profile_logrotate_base'] }}
20 21 22

parts =
  directory
23
  software-py
24
  switch-frontend-softwaretype
25
  caucase-updater
26
  caucase-updater-promise
27 28
  backend-client-caucase-updater
  backend-client-caucase-updater-promise
29
  promise-logrotate-setup
30 31 32 33 34 35 36 37

  trafficserver-launcher
  trafficserver-reload
  trafficserver-configuration-directory
  trafficserver-records-config
  trafficserver-remap-config
  trafficserver-plugin-config
  trafficserver-storage-config
38
  trafficserver-ip-allow-config
39
  trafficserver-logging-yaml
40 41
  trafficserver-promise-listen-port
  trafficserver-promise-cache-availability
42
  cron-entry-logrotate-trafficserver
43
## Monitor
44 45 46
  monitor-base
  monitor-ats-cache-stats-wrapper
  monitor-traffic-summary-last-stats-wrapper
47
{%- if instance_parameter_dict.get('configuration.re6st-verification-url', None) %}
48
  monitor-verify-re6st-connectivity
49
{%- endif %}
50

51 52 53 54 55 56 57 58 59 60 61
  frontend-haproxy-rsyslogd-configuration
  frontend-haproxy-rsyslogd
  logrotate-entry-frontend-haproxy
  frontend-haproxy
  frontend-haproxy-graceful
  promise-frontend-frontend-haproxy-configuration
  promise-frontend-haproxy-v4-https
  promise-frontend-haproxy-v4-http
  promise-frontend-haproxy-v6-https
  promise-frontend-haproxy-v6-http

62 63 64
  backend-haproxy-rsyslogd-configuration
  backend-haproxy-rsyslogd
  logrotate-entry-backend-haproxy
65 66 67 68 69 70
  backend-haproxy
  backend-haproxy-graceful
  promise-backend-haproxy-http
  promise-backend-haproxy-https
  promise-backend-haproxy-configuration

71 72 73 74 75
  slave-introspection-frontend
  slave-introspection-graceful
  promise-slave-introspection-https
  promise-slave-introspection-configuration
  logrotate-entry-slave-introspection
76
  backend-haproxy-statistic-frontend-promise
77

78 79
[software-py]
recipe = software
80

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
[frontend-node-id]
# Store id file in top of hierarchy, so it does not depend on directory creation
file = ${buildout:directory}/.frontend-node-id.txt
recipe = slapos.recipe.build
init =
  import os
  import secrets
  if not os.path.exists(options['file']):
    with open(options['file'], 'w') as fh:
      fh.write(secrets.token_urlsafe(4))
  with open(options['file'], 'r') as fh:
    options['value'] = fh.read()

[frontend-node-private-salt]
# Private, not communicated, stable hash, which can be used to salt other
# hashes, so their values are connected to the node, but practicaly impossible
# to crack (until the node is hacked itself, but then those values are
# stolen anyway)
recipe = slapos.recipe.build
init =
  import os
  import uuid
  if not os.path.exists(options['file']):
    with open(options['file'], 'w') as fh:
      fh.write(uuid.uuid4().hex)
  with open(options['file'], 'r') as fh:
    options['value'] = fh.read()
file = ${buildout:directory}/.frontend-node-private-salt.txt

[version-hash]
recipe = slapos.recipe.build
software-release-url = ${slap-connection:software-release-url}
hash-salt = ${frontend-node-private-salt:value}
init =
  import hashlib
  import base64
117
  options['value'] = base64.urlsafe_b64encode(hashlib.md5(''.join([options['software-release-url'].strip(), options['hash-salt']]).encode()).digest()).decode()
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

[frontend-node-information]
recipe = slapos.recipe.build
file = ${buildout:directory}/.frontend-node-information.json
node-id = ${frontend-node-id:value}
current-hash = ${version-hash:value}
current-software-release-url = ${version-hash:software-release-url}
init =
  import json
  changed = False
  try:
    with open(options['file'], 'r') as fh:
      data = json.load(fh)
  except Exception:
    changed = True
    data = {
      'node-id': options['node-id'],
      'version-hash-history': {options['current-hash']: options['current-software-release-url']}
    }
  if 'node-id' not in data:
    data['node-id'] = options['node-id']
    changed = True
  if 'version-hash-history' not in data:
    data['version-hash-history'] = {}
    changed = True
  if options['current-hash'] not in data['version-hash-history']:
    data['version-hash-history'][options['current-hash']] = options['current-software-release-url']
    changed = True
  if changed:
    with open(options['file'], 'w') as fh:
      json.dump(data, fh)
  options['value'] = data
150 151 152 153 154 155 156 157
# Create all needed directories
[directory]
recipe = slapos.cookbook:mkdirectory

bin = ${buildout:directory}/bin/
etc = ${buildout:directory}/etc/
srv = ${buildout:directory}/srv/
var = ${buildout:directory}/var/
158
tmp = ${:var}/tmp
159 160 161 162 163
template = ${buildout:directory}/template/

backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
164
backend-haproxy-rsyslogd-spool = ${:run}/backend-haproxy-rsyslogd-spool
165
frontend-haproxy-rsyslogd-spool = ${:run}/frontend-haproxy-rsyslogd-spool
166 167 168 169
service = ${:etc}/service
etc-run = ${:etc}/run

ca-dir = ${:srv}/ssl
170
backend-client-dir = ${:srv}/backend-client
171 172 173
# BBB: SlapOS Master non-zero knowledge BEGIN
bbb-ssl-dir = ${:srv}/bbb-ssl
# BBB: SlapOS Master non-zero knowledge END
174

175 176
frontend_cluster = ${:var}/frontend_cluster

177
# CSR publication
178 179
expose-csr = ${:srv}/expose-csr
expose-csr-etc = ${:etc}/expose-csr
180
expose-csr-var = ${:var}/expose-csr
181

182 183 184
# slave introspection
slave-introspection-var = ${:var}/slave-introspection

185
[switch-frontend-softwaretype]
186
recipe = slapos.cookbook:switch-softwaretype
187
default = dynamic-custom-personal-profile-slave-list:output
188
RootSoftwareInstance = ${:default}
189 190
single-default = dynamic-custom-personal-profile-slave-list:output
single-custom-personal = dynamic-custom-personal-profile-slave-list:output
191 192

[frontend-configuration]
193
ip-access-certificate = ${self-signed-ip-access:certificate}
194 195 196
slave-introspection-configuration = ${directory:etc}/slave-introspection-httpd-nginx.conf
slave-introspection-https-port = ${configuration:slave-introspection-https-port}
slave-introspection-secure_access = ${slave-introspection-frontend:connection-secure_access}
197

198 199 200 201
[self-signed-ip-access]
# Self Signed certificate for HTTPS IP accesses to the frontend
recipe = plone.recipe.command
update-command = ${:command}
202
ipv6 = ${slap-configuration:ipv6-random}
203
ipv4 = {{instance_parameter_dict['ipv4-random']}}
204
certificate = ${frontend-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
205
{#- Can be stopped on error, as does not rely on self provided service #}
206 207
stop-on-error = True
command =
208 209
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
210
  /bin/bash -c ' \
211
  {{ software_parameter_dict['openssl'] }} req \
212
     -new -newkey rsa -sha256 \
213
     -nodes -x509 -days 36500 \
214
     -keyout ${:certificate} \
215 216 217
     -subj "/CN=Self Signed IP Access" \
     -reqexts SAN \
     -extensions SAN \
218
     -config <(cat {{ software_parameter_dict['openssl_cnf'] }} \
219 220 221
         <(printf "\n[SAN]\nsubjectAltName=IP:${:ipv6},IP:${:ipv4}")) \
     -out ${:certificate}'

222 223 224 225
[self-signed-fallback-access]
# Self Signed certificate for HTTPS access to the frontend with fallback certificate
recipe = plone.recipe.command
update-command = ${:command}
226
ipv6 = ${slap-configuration:ipv6-random}
227
ipv4 = {{instance_parameter_dict['ipv4-random']}}
228
certificate = ${frontend-directory:master-autocert-dir}/fallback-access.crt
229
{#- Can be stopped on error, as does not rely on self provided service #}
230 231 232 233 234
stop-on-error = True
command =
  [ -f ${:certificate} ] && exit 0
  rm -f ${:certificate}
  /bin/bash -c ' \
235
  {{ software_parameter_dict['openssl'] }} req \
236
     -new -newkey rsa -sha256 \
237 238
     -nodes -x509 -days 36500 \
     -keyout ${:certificate} \
239
     -subj "/CN=Fallback certificate/OU={{ instance_parameter_dict['configuration.frontend-name'] }}" \
240 241
     -out ${:certificate}'

242 243
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
244
output = ${buildout:directory}/${:filename}
245
extensions = jinja2.ext.do
246
extra-context =
247
slapparameter_dict = {{ dumps(slapparameter_dict) }}
248
slap_software_type = {{ dumps(instance_parameter_dict['slap-software-type']) }}
249 250
context =
    import json_module json
251 252 253
    raw profile_common {{ software_parameter_dict['profile_common'] }}
    raw profile_logrotate_base {{ software_parameter_dict['profile_logrotate_base'] }}
    raw profile_monitor {{ software_parameter_dict['profile_monitor'] }}
254 255 256 257 258 259
    key slap_software_type :slap_software_type
    key slapparameter_dict :slapparameter_dict
    section directory directory
    ${:extra-context}

[software-release-path]
260
template-empty = {{ software_parameter_dict['template_empty'] }}
261 262 263
template-frontend-haproxy-configuration = {{ software_parameter_dict['template_frontend_haproxy_configuration'] }}
template-frontend-haproxy-crt-list = {{ software_parameter_dict['template_frontend_haproxy_crt_list'] }}
template-frontend-haproxy-rsyslogd-conf = {{ software_parameter_dict['template_frontend_haproxy_rsyslogd_conf'] }}
264 265
template-backend-haproxy-configuration = {{ software_parameter_dict['template_backend_haproxy_configuration'] }}
template-backend-haproxy-rsyslogd-conf = {{ software_parameter_dict['template_backend_haproxy_rsyslogd_conf'] }}
266
template-expose-csr-nginx-conf = {{ software_parameter_dict['template_expose_csr_nginx_conf'] }}
267

268 269
[kedifa-login-config]
d = ${directory:ca-dir}
270
template-csr = ${:d}/kedifa-login-template-csr.pem
271 272 273 274 275 276 277 278 279
key = ${:d}/kedifa-login-certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/kedifa-caucase-ca.pem
cas-ca-certificate = ${:d}/kedifa-cas-caucase-ca.pem
crl = ${:d}/kedifa-login-crl.pem

[kedifa-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
280
organizational_unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
281 282
command =
{% if slapparameter_dict['kedifa-caucase-url'] %}
283
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
284
    {{ software_parameter_dict['openssl'] }} req -new -sha256 \
285
      -newkey rsa -nodes -keyout ${:key} \
286
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
287
      -out ${:template-csr}
288 289
  fi
{% endif %}
290
  test -f ${:key} && test -f ${:template-csr}
291
update-command = ${:command}
292
template-csr = ${kedifa-login-config:template-csr}
293
key = ${kedifa-login-config:key}
294
{#- Can be stopped on error, as does not rely on self provided service #}
295 296 297 298
stop-on-error = True

{{ caucase.updater(
     prefix='caucase-updater',
299
     buildout_bin_directory=software_parameter_dict['bin_directory'],
300 301 302 303 304 305 306
     updater_path='${directory:service}/kedifa-login-certificate-caucase-updater',
     url=slapparameter_dict['kedifa-caucase-url'],
     data_dir='${directory:srv}/caucase-updater',
     crt_path='${kedifa-login-config:certificate}',
     ca_path='${kedifa-login-config:ca-certificate}',
     crl_path='${kedifa-login-config:crl}',
     key_path='${kedifa-login-csr:key}',
307
     template_csr='${kedifa-login-csr:template-csr}'
308 309
)}}

310 311 312 313 314 315 316 317 318 319 320
[kedifa-configuration]
caucase-url = {{ slapparameter_dict['kedifa-caucase-url'] }}
ca-certificate = ${kedifa-login-config:ca-certificate}
certificate = ${kedifa-login-config:certificate}
cas-ca-certificate = ${kedifa-login-config:cas-ca-certificate}
csr = ${caucase-updater-csr:csr}
crl = ${kedifa-login-config:crl}
kedifa-updater-mapping-file = ${directory:etc}/kedifa_updater_mapping.txt
kedifa-updater-state-file = ${directory:srv}/kedifa_updater_state.json
slave_kedifa_information = {{ dumps(slapparameter_dict['slave-kedifa-information']) }}

321 322 323 324 325 326 327 328 329 330 331 332
[backend-client-login-config]
d = ${directory:backend-client-dir}
template-csr = ${:d}/csr.pem
key = ${:d}/certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/ca.pem
cas-ca-certificate = ${:d}/cas-ca.pem
crl = ${:d}/crl.pem

[backend-client-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
333
organizational_unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
334 335 336
command =
{% if slapparameter_dict['backend-client-caucase-url'] %}
  if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ]  ; then
337
    {{ software_parameter_dict['openssl'] }} req -new -sha256 \
338
      -newkey rsa -nodes -keyout ${:key} \
339 340 341 342 343 344 345 346
      -subj "/O=${:organization}/OU=${:organizational_unit}" \
      -out ${:template-csr}
  fi
{% endif %}
  test -f ${:key} && test -f ${:template-csr}
update-command = ${:command}
template-csr = ${backend-client-login-config:template-csr}
key = ${backend-client-login-config:key}
347
{#- Can be stopped on error, as does not rely on self provided service #}
348 349 350 351
stop-on-error = True

{{ caucase.updater(
     prefix='backend-client-caucase-updater',
352
     buildout_bin_directory=software_parameter_dict['bin_directory'],
353 354 355 356 357 358 359 360 361 362
     updater_path='${directory:service}/backend-client-login-certificate-caucase-updater',
     url=slapparameter_dict['backend-client-caucase-url'],
     data_dir='${directory:srv}/backend-client-caucase-updater',
     crt_path='${backend-client-login-config:certificate}',
     ca_path='${backend-client-login-config:ca-certificate}',
     crl_path='${backend-client-login-config:crl}',
     key_path='${backend-client-login-csr:key}',
     template_csr='${backend-client-login-csr:template-csr}'
)}}

363
[dynamic-custom-personal-profile-slave-list]
364
< = jinja2-template-base
365
depends = ${software-py:recipe}
366
url = {{ software_parameter_dict['profile_slave_list'] }}
367
filename = instance-slave-list.cfg
368
master_key_download_url = {{ dumps(slapparameter_dict['master-key-download-url']) }}
369
software_type = single-custom-personal
370
organization = {{ slapparameter_dict['cluster-identification'] }}
371
organizational-unit = {{ instance_parameter_dict['configuration.frontend-name'] }}
372
backend-client-caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
373
url-ready-file = ${directory:var}/url-ready.txt
374
http3-enable = {{ FRONTEND_HTTP3 }}
375
extra-context =
376
    key backend_client_caucase_url :backend-client-caucase-url
377
    import furl_module furl
378
    import urllib_module urllib
379
    import operator_module operator
380
    key master_key_download_url :master_key_download_url
381
    key url_ready_file :url-ready-file
382 383
    key expose_csr_organization :organization
    key expose_csr_organizational_unit :organizational-unit
384
    key global_ipv6 slap-configuration:ipv6-random
385
    key empty_template software-release-path:template-empty
386
    key template_expose_csr_nginx_conf software-release-path:template-expose-csr-nginx-conf
387
    key software_type :software_type
388
    key http3_enable :http3-enable
389
    key frontend_lazy_graceful_reload frontend-haproxy-lazy-graceful:output
390
    key monitor_base_url monitor-instance-parameter:monitor-base-url
391 392 393 394
    key node_id frontend-node-id:value
    key version_hash version-hash:value
    key software_release_url version-hash:software-release-url
    key node_information frontend-node-information:value
395
# BBB: SlapOS Master non-zero knowledge BEGIN
396
    key apache_certificate apache-certificate:output
397
# BBB: SlapOS Master non-zero knowledge END
398 399 400 401
    key custom_ssl_directory frontend-directory:custom-ssl-directory
## frontend haproxy
    key template_frontend_haproxy_configuration software-release-path:template-frontend-haproxy-configuration
    key template_frontend_haproxy_crt_list software-release-path:template-frontend-haproxy-crt-list
402 403
## backend haproxy
    key template_backend_haproxy_configuration software-release-path:template-backend-haproxy-configuration
404
## Configuration passed by section
405
    section frontend_directory frontend-directory
406
    section configuration configuration
407
    section frontend_haproxy_configuration frontend-haproxy-configuration
408
    section backend_haproxy_configuration backend-haproxy-configuration
409
    section instance_parameter_dict instance-parameter-section
410 411
    section frontend_configuration frontend-configuration
    section kedifa_configuration kedifa-configuration
412
    section software_parameter_dict software-parameter-section
413

414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
# Deploy frontend with Jinja power
[frontend-haproxy-rsyslogd-config]
log-socket = ${directory:run}/fhlog.sck
log-file = ${directory:log}/frontend-haproxy.log
pid-file = ${directory:run}/frontend-haproxy-rsyslogd.pid
spool-directory = ${directory:frontend-haproxy-rsyslogd-spool}
graceful-command = kill -HUP $(cat ${:pid-file})
slave-log-directory = ${frontend-directory:slave-log}

[frontend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
url = ${software-release-path:template-frontend-haproxy-rsyslogd-conf}
output = ${directory:etc}/frontend-haproxy-rsyslogd.conf
local_ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}

429 430
extra-context =
    key instance_home buildout:directory
431 432 433
    key master_certificate frontend-haproxy-configuration:master-certificate
    key access_log frontend-haproxy-configuration:access-log
    key slave_configuration_directory frontend-directory:slave-configuration
434 435 436
    section frontend_configuration frontend-configuration
    key http_port configuration:plain_http_port
    key https_port configuration:port
437
    key global_ipv6 slap-configuration:ipv6-random
438
    key local_ipv4 :local_ipv4
439
    key error_log frontend-haproxy-configuration:error-log
440 441
    key username monitor-instance-parameter:username
    key password monitor-htpasswd:passwd
442
# BBB: SlapOS Master non-zero knowledge BEGIN
443
    key apache_certificate apache-certificate:output
444
# BBB: SlapOS Master non-zero knowledge END
445
    section configuration frontend-haproxy-rsyslogd-config
446

447
[frontend-haproxy-rsyslogd]
448
recipe = slapos.cookbook:wrapper
449 450
command-line = {{ software_parameter_dict['rsyslogd_executable'] }} -i ${frontend-haproxy-rsyslogd-config:pid-file} -n -f ${frontend-haproxy-rsyslogd-configuration:output}
wrapper-path = ${directory:service}/frontend-haproxy-rsyslogd
451
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
452

453 454 455 456 457 458 459 460 461 462 463 464
[logrotate-entry-frontend-haproxy]
<= logrotate-entry-base
name = frontend-haproxy
log = ${frontend-haproxy-rsyslogd-config:log-file}
rotate-num = ${configuration:rotate-num}
# Note: Slaves do not define their own reload, as this would be repeated,
#       because sharedscripts work per entry, and each slave needs its own
#       olddir
#       Here we trust that there will be something to be rotated with error
#       or access log, and that this will trigger postrotate script.
post = ${frontend-haproxy-rsyslogd-lazy-graceful:output} &
delaycompress =
465

466 467 468 469
[frontend-haproxy-configuration]
file = ${directory:etc}/frontend-haproxy.cfg
crt-list = ${directory:etc}/frontend-haproxy-crt-list.txt
log-socket = ${frontend-haproxy-rsyslogd-config:log-socket}
470 471 472
access-log = ${directory:log}/frontend-access.log
error-log = ${directory:log}/frontend-error.log
pid-file = ${directory:run}/httpd.pid
473
frontend-graceful-command = ${frontend-haproxy-validate:output} && kill -USR2 $(cat ${:pid-file})
474
not-found-file = {{ software_parameter_dict['template_not_found_html'] }}
475 476 477 478
master-certificate = ${frontend-directory:master-autocert-dir}/master.pem
self-signed-fallback-certificate = ${self-signed-fallback-access:certificate}
http-port = ${configuration:plain_http_port}
https-port = ${configuration:port}
479 480
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}
481 482 483 484
# slave instrspection
slave-introspection-access-log = ${directory:log}/slave-introspection-access.log
slave-introspection-error-log = ${directory:log}/slave-introspection-error.log
slave-introspection-pid-file = ${directory:run}/slave-introspection.pid
485
slave-introspection-graceful-command = ${slave-introspection-validate:output} && kill -HUP $(cat ${:slave-introspection-pid-file})
486 487 488
local_ipv4 = {{ dumps(instance_parameter_dict['ipv4-random']) }}
version-hash = ${version-hash:value}
node-id = ${frontend-node-id:value}
489 490
http3-enable = {{ FRONTEND_HTTP3 }}
http3-port = {{ HTTP3_PORT }}
491

492
# BBB: SlapOS Master non-zero knowledge BEGIN
493
[get-self-signed-fallback-access]
494 495 496 497 498 499 500 501
recipe = slapos.recipe.build
certificate-file = ${self-signed-fallback-access:certificate}
init =
  import os
  options['certificate'] = ''
  if os.path.exists(options['certificate-file']):
    with open(options['certificate-file'], 'r') as fh:
      options['certificate'] = fh.read()
502

503
[apache-certificate]
504
recipe = slapos.recipe.template:jinja2
505
inline =
506
{% raw %}
507 508
  {{ certificate or fallback_certificate }}
  {{ key or '' }}
509 510 511 512
{% endraw %}
context =
  key certificate configuration:apache-certificate
  key key configuration:apache-key
513
  key fallback_certificate get-self-signed-fallback-access:certificate
514
output = ${directory:bbb-ssl-dir}/frontend.crt
515 516
# BBB: SlapOS Master non-zero knowledge END

517 518 519 520 521 522 523
[frontend-directory]
recipe = slapos.cookbook:mkdirectory
slave-configuration = ${directory:etc}/frontend-haproxy.d/
slave-log = ${directory:log}/httpd
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
custom-ssl-directory = ${:slave-configuration}/ssl
524 525 526 527 528 529 530 531

#################
# Trafficserver
#################
[trafficserver-directory]
recipe = slapos.cookbook:mkdirectory
configuration = ${directory:etc}/trafficserver
local-state = ${directory:var}/trafficserver
532
bin_path = {{ software_parameter_dict['trafficserver'] }}/bin
533 534
log = ${directory:log}/trafficserver
cache-path = ${directory:srv}/ats_cache
535
logrotate-backup = ${logrotate-directory:logrotate-backup}/trafficserver
536 537 538 539

[trafficserver-variable]
wrapper-path = ${directory:service}/trafficserver
reload-path = ${directory:etc-run}/trafficserver-reload
540
local-ip = {{ instance_parameter_dict['ipv4-random'] }}
541 542
input-port = 23432
hostname = ${configuration:frontend-name}
543 544
plugin-config =
ip-allow-config = src_ip=0.0.0.0-255.255.255.255 action=ip_allow
545 546 547
cache-path = ${trafficserver-directory:cache-path}
disk-cache-size = ${configuration:disk-cache-size}
ram-cache-size = ${configuration:ram-cache-size}
548
templates-dir = {{ software_parameter_dict['trafficserver'] }}/etc/trafficserver/body_factory
549
request-timeout = ${configuration:request-timeout}
550 551
version-hash = ${version-hash:value}
node-id = ${frontend-node-id:value}
552 553 554

[trafficserver-configuration-directory]
recipe = plone.recipe.command
555
command = cp -rn {{ software_parameter_dict['trafficserver'] }}/etc/trafficserver/* ${:target}
556 557 558 559
target = ${trafficserver-directory:configuration}

[trafficserver-launcher]
recipe = slapos.cookbook:wrapper
560
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_manager
561
wrapper-path = ${trafficserver-variable:wrapper-path}
562 563 564
environment =
  TS_ROOT=${buildout:directory}
  PROXY_CONFIG_CONFIG_DIR=${trafficserver-directory:configuration}
565
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
566 567 568

[trafficserver-reload]
recipe = slapos.cookbook:wrapper
569
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_ctl config reload
570 571 572 573 574 575
wrapper-path = ${trafficserver-variable:reload-path}
environment = TS_ROOT=${buildout:directory}

# XXX Dedicated Jinja Section without slapparameter
[trafficserver-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
576
output = ${trafficserver-directory:configuration}/${:filename}
577 578 579 580 581 582 583 584
extra-context =
context =
    section ats_directory trafficserver-directory
    section ats_configuration trafficserver-variable
    ${:extra-context}

[trafficserver-records-config]
< = trafficserver-jinja2-template-base
585
url = {{ software_parameter_dict['template_trafficserver_records_config'] }}
586 587 588 589 590 591
filename = records.config
extra-context =
    import os_module os

[trafficserver-storage-config]
< = trafficserver-jinja2-template-base
592
url = {{ software_parameter_dict['template_trafficserver_storage_config'] }}
593 594
filename = storage.config

595
[trafficserver-logging-yaml]
596
< = trafficserver-jinja2-template-base
597
url = {{ software_parameter_dict['template_trafficserver_logging_yaml'] }}
598
filename = logging.yaml
599

600
[trafficserver-remap-config]
601 602
<= trafficserver-jinja2-template-base
{%- raw %}
603
inline =
604
  map /HTTPS/ http://{{ ipv4 }}:{{ https_port }}
605
  map /HTTP/ http://{{ ipv4 }}:{{ http_port }}
606 607
{%- endraw %}
extra-context =
608
  raw ipv4 {{ instance_parameter_dict['ipv4-random'] }}
609 610 611
  key https_port backend-haproxy-configuration:https-port
  key http_port backend-haproxy-configuration:http-port

612 613 614 615
filename = remap.config

[trafficserver-plugin-config]
< = trafficserver-jinja2-template-base
616
url = {{ software_parameter_dict['template_empty'] }}
617 618 619 620
filename = plugin.config
context =
    key content trafficserver-variable:plugin-config

621 622
[trafficserver-ip-allow-config]
< = trafficserver-jinja2-template-base
623
url = {{ software_parameter_dict['template_empty'] }}
624 625 626 627
filename = ip_allow.config
context =
    key content trafficserver-variable:ip-allow-config

628
[trafficserver-promise-listen-port]
629
<= monitor-promise-base
630
promise = check_socket_listening
631
name = trafficserver-port-listening.py
632
config-host = ${trafficserver-variable:local-ip}
633
config-port = ${trafficserver-variable:input-port}
634

635
[trafficserver-ctl]
636
recipe = slapos.cookbook:wrapper
637
command-line = {{ software_parameter_dict['trafficserver'] }}/bin/traffic_ctl
638
wrapper-path = ${directory:bin}/traffic_ctl
639 640 641
environment = TS_ROOT=${buildout:directory}

[trafficserver-promise-cache-availability]
642
<= monitor-promise-base
643
promise = trafficserver_cache_availability
644
name = trafficserver-cache-availability.py
645
config-wrapper-path = ${trafficserver-ctl:wrapper-path}
646

647 648
[trafficserver-rotate-script]
< = jinja2-template-base
649 650
url = {{ software_parameter_dict['template_rotate_script'] }}
output = ${directory:bin}/trafficserver-rotate
651
xz_binary = {{ software_parameter_dict['xz_location'] ~ '/bin/xz' }}
652 653 654 655 656
pattern = *.old
# days to keep log files
keep_days = 365

extra-context =
657
  raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
658 659 660 661 662 663 664 665 666 667 668
  key log_dir trafficserver-directory:log
  key rotate_dir trafficserver-directory:logrotate-backup
  key xz_binary :xz_binary
  key keep_days :keep_days
  key pattern :pattern

[cron-entry-logrotate-trafficserver]
recipe = slapos.cookbook:cron.d
cron-entries = ${directory:etc}/cron.d
name = trafficserver-logrotate
frequency = 0 0 * * *
669
command = ${trafficserver-rotate-script:output}
670

671 672
### End of ATS sections

673 674
### Frontend Graceful and promises
[frontend-haproxy-configuration-state]
675
< = jinja2-template-base
676 677
url = {{ software_parameter_dict['template_configuration_state_script'] }}
output = ${directory:bin}/${:_buildout_section_name_}
678

679
path_list = ${frontend-haproxy-configuration:file} ${frontend-haproxy-configuration:crt-list} ${frontend-directory:master-autocert-dir}/*.key ${frontend-directory:master-autocert-dir}/*.crt ${frontend-directory:master-autocert-dir}/*.pem ${frontend-directory:autocert}/*.pem ${frontend-directory:custom-ssl-directory}/*.proxy_ca_crt ${directory:bbb-ssl-dir}/*.crt
680
sha256sum = {{ software_parameter_dict['sha256sum'] }}
681

682
extra-context =
683
    import os_module os
684
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
685 686 687
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file
688

689 690
[frontend-haproxy-configuration-state-graceful]
< = frontend-haproxy-configuration-state
691 692
signature_file = ${directory:run}/graceful_configuration_state_signature

693 694
[frontend-haproxy-configuration-state-validate]
< = frontend-haproxy-configuration-state
695 696
signature_file = ${directory:run}/validate_configuration_state_signature

697
[frontend-haproxy-graceful]
698
< = jinja2-template-base
699
url = {{ software_parameter_dict['template_graceful_script'] }}
700 701
output = ${directory:etc-run}/frontend-haproxy-safe-graceful
mode = 0700
702
extra-context =
703 704
    key graceful_reload_command frontend-haproxy-configuration:frontend-graceful-command
    key configuration_state frontend-haproxy-configuration-state-graceful:output
705

706
[frontend-haproxy-validate]
707
< = jinja2-template-base
708
url = {{ software_parameter_dict['template_validate_script'] }}
709 710 711
output = ${directory:bin}/frontend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/frontend_haproxy_configuration_last_state
712
validate_command = {{ FRONTEND_HAPROXY_EXECUTABLE }} -f ${frontend-haproxy-configuration:file} -c
713
extra-context =
714
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
715
    key validate_command :validate_command
716
    key configuration_state_command frontend-haproxy-configuration-state-validate:output
717
    key last_state_file :last_state_file
718

719 720 721 722 723 724
[backend-haproxy-validate]
<= jinja2-template-base
url = {{ software_parameter_dict['template_validate_script'] }}
output = ${directory:bin}/backend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
725
validate_command = {{ BACKEND_HAPROXY_EXECUTABLE }} -f ${backend-haproxy-configuration:file} -c
726 727 728 729 730 731 732
extra-context =
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
    key validate_command :validate_command
    key configuration_state_command backend-haproxy-configuration-state-validate:output
    key last_state_file :last_state_file

[frontend-haproxy-lazy-graceful]
733
< = jinja2-template-base
734
url = {{ software_parameter_dict['template_lazy_script_call'] }}
735 736
output = ${directory:bin}/frontend-haproxy-lazy-graceful
mode = 0700
737
pid-file = ${directory:run}/lazy-graceful.pid
738
wait_time = 60
739 740
extra-context =
    key pid_file :pid-file
741
    key wait_time :wait_time
742
    key lazy_command frontend-haproxy-configuration:frontend-graceful-command
743 744

# Promises checking configuration:
745 746
[promise-helper-last-configuration-state]
< = jinja2-template-base
747 748
url = {{ software_parameter_dict['template_empty'] }}
output = ${directory:bin}/frontend-read-last-configuration-state
749 750
content =
  #!/bin/sh
751
  exit `cat ${frontend-haproxy-validate:last_state_file}`
752 753 754
context =
    key content :content

755
[promise-frontend-frontend-haproxy-configuration]
756
<= monitor-promise-base
757
promise = validate_frontend_configuration
758
name = frontend-frontend-haproxy-configuration-promise.py
759
config-verification-script = ${promise-helper-last-configuration-state:output}
760

761
[promise-frontend-haproxy-v4-https]
762
<= monitor-promise-base
763
promise = check_socket_listening
764
name = frontend_haproxy_ipv4_https.py
765
config-host = {{ instance_parameter_dict['ipv4-random'] }}
766
config-port = ${configuration:port}
767

768
[promise-frontend-haproxy-v4-http]
769
<= monitor-promise-base
770
promise = check_socket_listening
771
name = frontend_haproxy_ipv4_http.py
772
config-host = {{ instance_parameter_dict['ipv4-random'] }}
773
config-port = ${configuration:plain_http_port}
774

775
[promise-frontend-haproxy-v6-https]
776
<= monitor-promise-base
777
promise = check_socket_listening
778
name = frontend_haproxy_ipv6_https.py
779
config-host = {{ instance_parameter_dict['ipv6-random'] }}
780
config-port = ${configuration:port}
781

782
[promise-frontend-haproxy-v6-http]
783
<= monitor-promise-base
784
promise = check_socket_listening
785
name = frontend_haproxy_ipv6_http.py
786
config-host = {{ instance_parameter_dict['ipv6-random'] }}
787
config-port = ${configuration:plain_http_port}
788

789
[promise-backend-haproxy-http]
790
<= monitor-promise-base
791
promise = check_socket_listening
792
name = backend_haproxy_http.py
793
config-host = {{ instance_parameter_dict['ipv4-random'] }}
794
config-port = ${backend-haproxy-configuration:http-port}
795

796
[promise-backend-haproxy-https]
797
<= monitor-promise-base
798
promise = check_socket_listening
799
name = backend_haproxy_https.py
800
config-host = {{ instance_parameter_dict['ipv4-random'] }}
801 802 803 804 805
config-port = ${backend-haproxy-configuration:https-port}

[backend-haproxy-configuration]
file = ${directory:etc}/backend-haproxy.cfg
pid-file = ${directory:run}/backend-haproxy.pid
806
log-socket = ${backend-haproxy-rsyslogd-config:log-socket}
807
graceful-command = ${backend-haproxy-validate:output} && kill -USR2 $(cat ${:pid-file})
808 809
http-port = ${configuration:backend-haproxy-http-port}
https-port = ${configuration:backend-haproxy-https-port}
810 811 812 813 814 815 816
# Caucase related configuration
caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
ca-certificate = ${backend-client-login-config:ca-certificate}
certificate = ${backend-client-login-config:certificate}
cas-ca-certificate = ${backend-client-login-config:cas-ca-certificate}
csr = ${backend-client-caucase-updater-csr:csr}
crl = ${backend-client-login-config:crl}
817 818 819 820 821
# the statistic page
statistic-certificate = ${self-signed-ip-access:certificate}
statistic-port = ${configuration:backend-haproxy-statistic-port}
statistic-username = ${monitor-instance-parameter:username}
statistic-password = ${monitor-htpasswd:passwd}
822
statistic-identification = {{ instance_parameter_dict['configuration.frontend-name'] + ' @ ' + slapparameter_dict['cluster-identification'] }}
823
statistic-frontend-secure_access = ${backend-haproxy-statistic-frontend:connection-secure_access}
824 825 826 827 828
version-hash = ${version-hash:value}
node-id = ${frontend-node-id:value}

[frontend-haproxy]
recipe = slapos.cookbook:wrapper
829
command-line = {{ FRONTEND_HAPROXY_EXECUTABLE }} -f ${frontend-haproxy-configuration:file}
830 831 832 833 834 835 836 837 838 839 840 841 842 843
wrapper-path = ${directory:service}/frontend-haproxy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

[frontend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
url = {{ software_parameter_dict['template_lazy_script_call'] }}
output = ${directory:bin}/frontend-haproxy-rsyslogd-lazy-graceful
mode = 0700
pid-file = ${directory:run}/frontend-haproxy-rsyslogd-lazy-graceful.pid
wait_time = 60
extra-context =
    key pid_file :pid-file
    key wait_time :wait_time
    key lazy_command frontend-haproxy-rsyslogd-config:graceful-command
844 845 846

[backend-haproxy]
recipe = slapos.cookbook:wrapper
847
command-line = {{ BACKEND_HAPROXY_EXECUTABLE }} -f ${backend-haproxy-configuration:file}
848 849 850
wrapper-path = ${directory:service}/backend-haproxy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

851 852
[backend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
853
url = {{ software_parameter_dict['template_lazy_script_call'] }}
854
output = ${directory:bin}/backend-haproxy-rsyslogd-lazy-graceful
855 856 857 858 859 860 861
pid-file = ${directory:run}/backend-haproxy-rsyslogd-lazy-graceful.pid
wait_time = 60
extra-context =
    key pid_file :pid-file
    key wait_time :wait_time
    key lazy_command backend-haproxy-rsyslogd-config:graceful-command

862 863 864
[logrotate-entry-backend-haproxy]
<= logrotate-entry-base
name = backend-haproxy
865
log = ${backend-haproxy-rsyslogd-config:log-file}
866
rotate-num = ${configuration:rotate-num}
867 868 869 870 871
# Note: Slaves do not define their own reload, as this would be repeated,
#       because sharedscripts work per entry, and each slave needs its own
#       olddir
#       Here we trust that there will be something to be rotated with error
#       or access log, and that this will trigger postrotate script.
872
post = ${backend-haproxy-rsyslogd-lazy-graceful:output} &
873
delaycompress =
874

875 876
[backend-haproxy-configuration-state]
<= jinja2-template-base
877 878
url = {{ software_parameter_dict['template_configuration_state_script'] }}
output = ${directory:bin}/${:_buildout_section_name_}
879

880
path_list = ${backend-haproxy-configuration:file} ${backend-client-login-config:certificate}
881
sha256sum = {{ software_parameter_dict['sha256sum'] }}
882 883

extra-context =
884
    import os_module os
885
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
886 887 888 889 890 891 892 893 894 895 896 897 898 899
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file

[backend-haproxy-configuration-state-graceful]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_graceful_configuration_state_signature

[backend-haproxy-configuration-state-validate]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_validate_configuration_state_signature

[backend-haproxy-graceful]
< = jinja2-template-base
900 901
url = {{ software_parameter_dict['template_graceful_script'] }}
output = ${directory:etc-run}/backend-haproxy-safe-graceful
902 903 904

extra-context =
    key graceful_reload_command backend-haproxy-configuration:graceful-command
905
    key configuration_state backend-haproxy-configuration-state-graceful:output
906 907 908

[backend-haproxy-validate]
<= jinja2-template-base
909 910
url = {{ software_parameter_dict['template_validate_script'] }}
output = ${directory:bin}/backend-haproxy-validate
911
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
912
validate_command = {{ BACKEND_HAPROXY_EXECUTABLE }} -f ${backend-haproxy-configuration:file} -c
913
extra-context =
914
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
915
    key validate_command :validate_command
916
    key configuration_state_command backend-haproxy-configuration-state-validate:output
917 918 919 920
    key last_state_file :last_state_file

[promise-backend-haproxy-configuration]
<= monitor-promise-base
921
promise = validate_frontend_configuration
922
name = backend-haproxy-configuration.py
923
config-verification-script = ${promise-backend-haproxy-configuration-helper:output}
924 925 926

[promise-backend-haproxy-configuration-helper]
< = jinja2-template-base
927 928
url = {{ software_parameter_dict['template_empty'] }}
output = ${directory:bin}/backend-haproxy-read-last-configuration-state
929 930 931 932 933
content =
  #!/bin/sh
  exit `cat ${backend-haproxy-validate:last_state_file}`
context =
    key content :content
934

935
[backend-haproxy-rsyslogd-config]
936 937 938
log-socket = ${directory:run}/bhlog.sck
log-file = ${directory:log}/backend-haproxy.log
pid-file = ${directory:run}/backend-haproxy-rsyslogd.pid
939 940
spool-directory = ${directory:backend-haproxy-rsyslogd-spool}
graceful-command = kill -HUP $(cat ${:pid-file})
941
log-directory = ${frontend-directory:slave-log}
942 943 944

[backend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
945 946
url = ${software-release-path:template-backend-haproxy-rsyslogd-conf}
output = ${directory:etc}/backend-haproxy-rsyslogd.conf
947
extra-context =
948
  section configuration backend-haproxy-rsyslogd-config
949 950 951

[backend-haproxy-rsyslogd]
recipe = slapos.cookbook:wrapper
952
command-line = {{ software_parameter_dict['rsyslogd_executable'] }} -i ${backend-haproxy-rsyslogd-config:pid-file} -n -f ${backend-haproxy-rsyslogd-configuration:output}
953 954 955
wrapper-path = ${directory:service}/backend-haproxy-rsyslogd
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg

956 957 958 959 960
#######
# Monitoring sections
#

[monitor-instance-parameter]
961 962 963
# Note: Workaround for monitor stack, which uses monitor-httpd-port parameter
#       directly, and in our case it can come from the network, thus resulting
#       with need to strip !py!'u'
964 965
monitor-httpd-port = {{ instance_parameter_dict['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter_dict['configuration.monitor-password'] | string }}
966 967

[monitor-conf-parameters]
968
private-path-list +=
969
  ${logrotate-directory:logrotate-backup}
970 971 972 973


[monitor-traffic-summary-last-stats-wrapper]
< = jinja2-template-base
974 975
url = {{ software_parameter_dict['template_wrapper'] }}
output = ${directory:bin}/traffic-summary-last-stats_every_1_hour
976
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ software_parameter_dict['trafficserver'] }}/bin/traffic_logstats -f ${trafficserver-directory:log}/squid.blog)</pre>"
977 978 979 980 981 982
extra-context =
  key content monitor-traffic-summary-last-stats-wrapper:command

# Produce ATS Cache stats
[monitor-ats-cache-stats-wrapper]
< = jinja2-template-base
983 984 985
url = {{ software_parameter_dict['template_wrapper'] }}
output = ${directory:bin}/ats-cache-stats_every_1_hour
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ software_parameter_dict['trafficserver'] }}/bin/traffic_shell ${monitor-ats-cache-stats-config:output})</pre>"
986 987 988 989 990
extra-context =
  key content monitor-ats-cache-stats-wrapper:command

[monitor-ats-cache-stats-config]
< = jinja2-template-base
991 992
url = {{ software_parameter_dict['template_empty'] }}
output = ${trafficserver-configuration-directory:target}/cache-config.stats
993 994 995 996
context =
    raw content show:cache-stats

[monitor-verify-re6st-connectivity]
997
<= monitor-promise-base
998
promise = check_url_available
999 1000
name = re6st-connectivity.py
config-url = ${configuration:re6st-verification-url}
1001

1002 1003 1004
[slave-introspection-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
1005
name = Slave Introspection Frontend {{ instance_parameter_dict['configuration.frontend-name'] }}
1006
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
1007
shared = true
1008
config-url = https://[${slap-configuration:ipv6-random}]:{{ instance_parameter_dict['configuration.slave-introspection-https-port'] }}/
1009
config-https-only = true
1010
return = secure_access
1011

1012 1013 1014
[backend-haproxy-statistic-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
1015
name = Backend Haproxy Statistic Frontend {{ instance_parameter_dict['configuration.frontend-name'] }}
1016
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
1017
shared = true
1018
config-url = https://[${slap-configuration:ipv6-random}]:{{ instance_parameter_dict['configuration.backend-haproxy-statistic-port'] }}/
1019 1020 1021
config-https-only = true
return = domain secure_access

1022 1023
[backend-haproxy-statistic-frontend-promise]
<= monitor-promise-base
1024
promise = check_url_available
1025 1026 1027 1028 1029
name = backend-haproxy-statistic-frontend.py
config-http-code = 401
config-url =
  ${backend-haproxy-statistic-frontend:connection-secure_access}

1030 1031
[slave-introspection-configuration-state]
<= jinja2-template-base
1032 1033
url = {{ software_parameter_dict['template_configuration_state_script'] }}
output = ${directory:bin}/${:_buildout_section_name_}
1034 1035

path_list = ${frontend-configuration:slave-introspection-configuration} ${frontend-configuration:ip-access-certificate}
1036
sha256sum = {{ software_parameter_dict['sha256sum'] }}
1037 1038

extra-context =
1039
    import os_module os
1040
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
    key path_list :path_list
    key sha256sum :sha256sum
    key signature_file :signature_file

[slave-introspection-configuration-state-graceful]
<= slave-introspection-configuration-state
signature_file = ${directory:run}/slave_introspection_graceful_configuration_state_signature

[slave-introspection-configuration-state-validate]
<= slave-introspection-configuration-state
signature_file = ${directory:run}/slave_introspection_validate_configuration_state_signature

[slave-introspection-graceful]
< = jinja2-template-base
1055 1056
url = {{ software_parameter_dict['template_graceful_script'] }}
output = ${directory:etc-run}/slave-introspection-safe-graceful
1057 1058

extra-context =
1059
    key graceful_reload_command frontend-haproxy-configuration:slave-introspection-graceful-command
1060
    key configuration_state slave-introspection-configuration-state-graceful:output
1061 1062 1063

[slave-introspection-validate]
<= jinja2-template-base
1064 1065
url = {{ software_parameter_dict['template_validate_script'] }}
output = ${directory:bin}/slave-introspection-validate
1066
last_state_file = ${directory:run}/slave_introspection_configuration_last_state
1067
validate_command = {{ software_parameter_dict['nginx'] }} -c ${frontend-configuration:slave-introspection-configuration} -t
1068
extra-context =
1069
    raw find_executable {{ software_parameter_dict['findutils'] }}/bin/find
1070
    key validate_command :validate_command
1071
    key configuration_state_command slave-introspection-configuration-state-validate:output
1072 1073 1074 1075
    key last_state_file :last_state_file

[promise-slave-introspection-configuration]
<= monitor-promise-base
1076
promise = validate_frontend_configuration
1077
name = slave-introspection-configuration.py
1078
config-verification-script = ${promise-slave-introspection-configuration-helper:output}
1079 1080 1081

[promise-slave-introspection-configuration-helper]
< = jinja2-template-base
1082 1083
url = {{ software_parameter_dict['template_empty'] }}
output = ${directory:bin}/slave-introspection-read-last-configuration-state
1084 1085 1086 1087 1088 1089 1090 1091
content =
  #!/bin/sh
  exit `cat ${slave-introspection-validate:last_state_file}`
context =
    key content :content

[promise-slave-introspection-https]
<= monitor-promise-base
1092
promise = check_socket_listening
1093
name = slave_introspection_https.py
1094
config-host = {{ instance_parameter_dict['ipv6-random'] }}
1095 1096 1097 1098 1099
config-port = ${frontend-configuration:slave-introspection-https-port}

[logrotate-entry-slave-introspection]
<= logrotate-entry-base
name = slave-introspection
1100
log = ${frontend-haproxy-configuration:slave-introspection-access-log} ${frontend-haproxy-configuration:slave-introspection-error-log}
1101
rotate-num = ${configuration:rotate-num}
1102
post = kill -USR2 $(cat ${frontend-haproxy-configuration:slave-introspection-pid-file})
1103
delaycompress =
1104

1105 1106 1107 1108 1109
[logrotate-setup-validate]
<= jinja2-template-base
url = {{ software_parameter_dict['template_wrapper'] }}
output = ${directory:scripts}/logrotate-setup-validate
command =
1110
  if ${logrotate:wrapper-path} -d > ${:state-file-tmp} 2>&1 ; then
1111
    cat /dev/null > ${:state-file}
1112 1113 1114
    rm -f ${:state-file-tmp}
  else
    mv ${:state-file-tmp} ${:state-file}
1115 1116 1117 1118
  fi
extra-context =
  key content :command
state-file = ${directory:run}/logrotate-setup.state
1119
state-file-tmp = ${:state-file}.tmp
1120

1121 1122
[promise-logrotate-setup]
<= monitor-promise-base
1123
promise = check_file_state
1124
name = ${:_buildout_section_name_}.py
1125 1126
config-filename = ${logrotate-setup-validate:state-file}
config-state = empty
1127

1128
[configuration]
1129
{%- for key, value in instance_parameter_dict.items() -%}
1130 1131 1132
{%-   if key.startswith('configuration.') %}
{{ key.replace('configuration.', '') }} = {{ dumps(value) }}
{%-   endif -%}
1133 1134
{%- endfor %}

1135
[instance-parameter-section]
1136 1137 1138
{#- There are dangerous keys like recipe, etc #}
{#- XXX: Some other approach would be useful #}
{%- set DROP_KEY_LIST = ['recipe', '__buildout_signature__', 'computer', 'partition', 'url', 'key', 'cert'] %}
1139
{%- for key, value in instance_parameter_dict.items() -%}
1140 1141 1142
{%-   if not key.startswith('configuration.') and key not in DROP_KEY_LIST %}
{{ key }} = {{ dumps(value) }}
{%-   endif -%}
1143 1144 1145
{%- endfor %}

[software-parameter-section]
1146
{%- for key, value in software_parameter_dict.items() %}
1147 1148
{{ key }} = {{ dumps(value) }}
{%- endfor %}