1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
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
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
{%- if slap_software_type == software_type -%}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
[buildout]
extends =
{{ parameter_dict['common_profile'] }}
{{ parameter_dict['monitor_template'] }}
parts =
directory
configtest
logrotate
cron
cron-entry-logrotate
ca-frontend
ca-frontend-service
certificate-authority
certificate-authority-service
logrotate-entry-caddy
logrotate-entry-nginx
caddy-frontend
switch-caddy-softwaretype
frontend-caddy-graceful
frontend-nginx-graceful
not-found-html
port-redirection
promise-frontend-caddy-configuration
promise-caddy-frontend-v4-https
promise-caddy-frontend-v4-http
promise-caddy-frontend-v6-https
promise-caddy-frontend-v6-http
promise-caddy-frontend-cached
promise-caddy-frontend-ssl-cached
promise-caddy-is-process-older-than-dependency-set
promise-nginx-frontend-v4-https
promise-nginx-frontend-v4-http
promise-nginx-frontend-v6-https
promise-nginx-frontend-v6-http
promise-nginx-configuration
promise-nginx-is-process-older-than-dependency-set
trafficserver-launcher
trafficserver-reload
trafficserver-configuration-directory
trafficserver-records-config
trafficserver-remap-config
trafficserver-plugin-config
trafficserver-storage-config
trafficserver-promise-listen-port
trafficserver-promise-cache-availability
## Nginx
nginx-frontend
## Monitor for Caddy
monitor-base
monitor-ats-cache-stats-wrapper
monitor-traffic-summary-last-stats-wrapper
monitor-caddy-server-status-wrapper
monitor-verify-re6st-connectivity
# 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/
template = ${buildout:directory}/template/
backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
service = ${:etc}/service
etc-run = ${:etc}/run
promise = ${:etc}/promise
logrotate-backup = ${:backup}/logrotate
logrotate-entries = ${:etc}/logrotate.d
cron-entries = ${:etc}/cron.d
crontabs = ${:etc}/crontabs
cronstamps = ${:etc}/cronstamps
ca-dir = ${:srv}/ssl
varnginx = ${:var}/nginx
frontend_cluster = ${:var}/frontend_cluster
nginx_cluster = ${:var}/nginx_cluster
[switch-caddy-softwaretype]
recipe = slapos.cookbook:softwaretype
single-default = ${dynamic-custom-personal-template-slave-list:rendered}
single-custom-personal = ${dynamic-custom-personal-template-slave-list:rendered}
[frontend-configuration]
template-log-access = {{ parameter_dict['template_log_access'] }}
log-access-configuration = ${directory:etc}/log-access.conf
caddy-directory = {{ parameter_dict['caddy_location'] }}
caddy-ipv6 = {{ instance_parameter['ipv6-random'] }}
caddy-https-port = ${configuration:port}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
slapparameter_dict = {{ dumps(instance_parameter['configuration']) }}
slap_software_type = {{ dumps(instance_parameter['slap-software-type']) }}
context =
import json_module json
raw common_profile {{ parameter_dict['common_profile'] }}
key slap_software_type :slap_software_type
key slapparameter_dict :slapparameter_dict
section directory directory
${:extra-context}
[software-release-path]
template-empty = {{ parameter_dict['template_empty'] }}
template-slave-configuration = {{ parameter_dict['template_slave_configuration'] }}
template-default-slave-virtualhost = {{ parameter_dict['template_default_slave_virtualhost'] }}
template-cached-slave-virtualhost = {{ parameter_dict['template_cached_slave_virtualhost'] }}
caddy-location = {{ parameter_dict['caddy_location'] }}
template-nginx-eventsource-slave-virtualhost = {{ parameter_dict['template_nginx_eventsource_slave_virtualhost'] }}
template-nginx-notebook-slave-virtualhost = {{ parameter_dict['template_nginx_notebook_slave_virtualhost'] }}
[dynamic-custom-personal-template-slave-list]
< = jinja2-template-base
template = {{ parameter_dict['template_slave_list'] }}
filename = custom-personal-instance-slave-list.cfg
extensions = jinja2.ext.do
slave_instance_list = {{ dumps(instance_parameter['slave-instance-list']) }}
extra_slave_instance_list = {{ dumps(instance_parameter.get('configuration.extra_slave_instance_list')) }}
local_ipv4 = {{ dumps(instance_parameter['ipv4-random']) }}
local_ipv6 = {{ dumps(instance_parameter['ipv6-random']) }}
software_type = single-custom-personal
bin_directory = {{ parameter_dict['bin_directory'] }}
sixtunnel_executable = {{ parameter_dict['sixtunnel'] }}/bin/6tunnel
service_directory = ${directory:service}
extra-context =
key caddy_configuration_directory caddy-directory:slave-configuration
key nginx_configuration_directory caddy-directory:nginx-slave-configuration
key caddy_cached_configuration_directory caddy-directory:slave-with-cache-configuration
key slave_with_cache_configuration_directory caddy-directory:slave-with-cache-configuration
key http_port configuration:plain_http_port
key https_port configuration:port
key nginx_http_port configuration:plain_nginx_port
key nginx_https_port configuration:nginx_port
key public_ipv4 configuration:public-ipv4
key slave_instance_list :slave_instance_list
key extra_slave_instance_list :extra_slave_instance_list
key custom_ssl_directory caddy-directory:vh-ssl
key caddy_log_directory caddy-directory:slave-log
key local_ipv4 :local_ipv4
key local_ipv6 :local_ipv6
key global_ipv6 slap-network-information:global-ipv6
key varnginx directory:varnginx
key empty_template software-release-path:template-empty
key template_custom_slave_configuration software-release-path:template-slave-configuration
key template_default_slave_configuration software-release-path:template-default-slave-virtualhost
key template_cached_slave_configuration software-release-path:template-cached-slave-virtualhost
key template_eventsource_slave_configuration software-release-path:template-nginx-eventsource-slave-virtualhost
key template_notebook_slave_configuration software-release-path:template-nginx-notebook-slave-virtualhost
key software_type :software_type
key frontend_lazy_graceful_reload frontend-caddy-lazy-graceful:rendered
section logrotate_dict logrotate
section frontend_configuration frontend-configuration
section caddy_configuration caddy-configuration
section nginx_configuration nginx-configuration
key monitor_base_url monitor-instance-parameter:monitor-base-url
key promise_directory monitor-directory:promises
key report_directory monitor-directory:reports
key bin_directory :bin_directory
key login_certificate ca-frontend:cert-file
key login_key ca-frontend:key-file
key login_ca_crt ca-custom-frontend:rendered
key enable_http2_by_default configuration:enable-http2-by-default
key access_log caddy-configuration:access-log
key error_log caddy-configuration:error-log
key sixtunnel_executable :sixtunnel_executable
key service_directory directory:service
key not_found_file caddy-configuration:not-found-file
[dynamic-virtualhost-template-slave]
<= jinja2-template-base
template = {{ parameter_dict['template_slave_configuration'] }}
rendered = ${directory:template}/slave-virtualhost.conf.in
extensions = jinja2.ext.do
# BBB: apache_custom_https and apache_custom_http
extra-context =
key https_port configuration:port
key http_port configuration:plain_http_port
key apache_custom_https configuration:apache_custom_https
key apache_custom_http configuration:apache_custom_http
key caddy_custom_https configuration:caddy_custom_https
key caddy_custom_http configuration:caddy_custom_http
# Deploy Caddy Frontend with Jinja power
[dynamic-caddy-frontend-template]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_frontend_configuration'] }}
rendered = ${caddy-configuration:frontend-configuration}
local_ipv4 = {{ dumps(instance_parameter['ipv4-random']) }}
extra-context =
key httpd_home software-release-path:caddy-location
key httpd_mod_ssl_cache_directory caddy-directory:mod-ssl
key instance_home buildout:directory
key login_certificate ca-frontend:cert-file
key login_key ca-frontend:key-file
key login_ca_crt ca-custom-frontend:rendered
key ca_dir certificate-authority:ca-dir
key ca_crl certificate-authority:ca-crl
key access_log caddy-configuration:access-log
key slave_configuration_directory caddy-directory:slave-configuration
key cached_port caddy-configuration:cache-through-port
key ssl_cached_port caddy-configuration:ssl-cache-through-port
key slave_with_cache_configuration_directory caddy-directory:slave-with-cache-configuration
section frontend_configuration frontend-configuration
key http_port configuration:plain_http_port
key https_port configuration:port
key local_ipv4 :local_ipv4
key global_ipv6 slap-network-information:global-ipv6
key error_log caddy-configuration:error-log
key not_found_file caddy-configuration:not-found-file
key username monitor-instance-parameter:username
key password monitor-htpasswd:passwd
[caddy-wrapper]
recipe = slapos.cookbook:wrapper
environment =
CADDYPATH=${directory:frontend_cluster}
command-line = {{ parameter_dict['caddy'] }}
-conf ${dynamic-caddy-frontend-template:rendered}
-log stdout
-http2=true
{% if instance_parameter['configuration.enable-quic'].lower() in TRUE_VALUES %}
-quic
{% endif %}
-grace {{ instance_parameter['configuration.mpm-graceful-shutdown-timeout'] }}s
-disable-http-challenge
-disable-tls-sni-challenge
wrapper-path = ${directory:bin}/caddy-wrapper
[caddy-frontend]
recipe = slapos.cookbook:wrapper
command-line = ${caddy-wrapper:wrapper-path} -pidfile ${caddy-configuration:pid-file}
wrapper-path = ${directory:service}/frontend_caddy
wait-for-files =
${ca-frontend:cert-file}
${ca-frontend:key-file}
hash-files = ${buildout:directory}/software_release/buildout.cfg
[not-found-html]
recipe = slapos.cookbook:symbolic.link
target-directory = ${caddy-directory:document-root}
link-binary =
{{ parameter_dict['template_not_found_html'] }}
[caddy-directory]
recipe = slapos.cookbook:mkdirectory
document-root = ${directory:srv}/htdocs
slave-configuration = ${directory:etc}/caddy-slave-conf.d/
slave-with-cache-configuration = ${directory:etc}/caddy-slave-with-cache-conf.d/
cache = ${directory:var}/cache
mod-ssl = ${:cache}/httpd_mod_ssl
vh-ssl = ${:slave-configuration}/ssl
slave-log = ${directory:log}/httpd
nginx-slave-configuration = ${directory:etc}/nginx-slave-conf.d/
[caddy-configuration]
frontend-configuration = ${directory:etc}/Caddyfile
access-log = ${directory:log}/frontend-access.log
error-log = ${directory:log}/frontend-error.log
pid-file = ${directory:run}/httpd.pid
frontend-configuration-verification = ${caddy-wrapper:wrapper-path} -validate > /dev/null
frontend-graceful-command = ${:frontend-configuration-verification}; if [ $? -eq 0 ]; then kill -USR1 $(cat ${:pid-file}); fi
not-found-file = ${caddy-directory:document-root}/notfound.html
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}
cache-through-port = 26011
ssl-cache-through-port = 26012
[configtest]
recipe = slapos.cookbook:wrapper
command-line = ${caddy-wrapper:wrapper-path} -validate
wrapper-path = ${directory:bin}/caddy-configtest
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ parameter_dict['openssl'] }}/bin/openssl
ca-dir = ${directory:ca-dir}
requests-directory = ${cadirectory:requests}
wrapper = ${directory:bin}/certificate_authority
ca-private = ${cadirectory:private}
ca-certs = ${cadirectory:certs}
ca-newcerts = ${cadirectory:newcerts}
ca-crl = ${cadirectory:crl}
[certificate-authority-service]
recipe = slapos.cookbook:wrapper
command-line = ${certificate-authority:wrapper}
wrapper-path = ${directory:service}/certificate_authority
hash-files = ${buildout:directory}/software_release/buildout.cfg
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = ${directory:ca-dir}/requests/
private = ${directory:ca-dir}/private/
certs = ${directory:ca-dir}/certs/
newcerts = ${directory:ca-dir}/newcerts/
crl = ${directory:ca-dir}/crl/
[ca-frontend]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = ${cadirectory:certs}/frontend.key
cert-file = ${cadirectory:certs}/frontend.crt
executable = ${directory:service}/frontend_caddy
wrapper = ${directory:bin}/frontend_caddy
key-content = ${configuration:apache-key}
cert-content = ${configuration:apache-certificate}
# Put domain name
name = ${configuration:domain}
[ca-frontend-service]
recipe = slapos.cookbook:wrapper
command-line = ${ca-frontend:wrapper}
wrapper-path = ${directory:service}/frontend_caddy
hash-files = ${buildout:directory}/software_release/buildout.cfg
[ca-custom-frontend]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${cadirectory:certs}/frontend.ca.crt
apache-ca-certificate = ${configuration:apache-ca-certificate}
extra-context =
key content :apache-ca-certificate
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = {{ parameter_dict['dcron'] }}/sbin/crond
cron-entries = ${directory:cron-entries}
crontabs = ${directory:crontabs}
cronstamps = ${directory:cronstamps}
catcher = ${cron-simplelogger:wrapper}
binary = ${directory:service}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = ${directory:bin}/cron_simplelogger
log = ${directory:log}/cron.log
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = ${logrotate:wrapper}
# Deploy Logrotate
[logrotate]
recipe = slapos.cookbook:logrotate
# Binaries
logrotate-binary = {{ parameter_dict['logrotate'] }}/sbin/logrotate
gzip-binary = {{ parameter_dict['gzip'] }}/bin/gzip
gunzip-binary = {{ parameter_dict['gzip'] }}/bin/gunzip
# Directories
wrapper = ${directory:bin}/logrotate
conf = ${directory:etc}/logrotate.conf
logrotate-entries = ${directory:logrotate-entries}
backup = ${directory:logrotate-backup}
state-file = ${directory:srv}/logrotate.status
[logrotate-entry-caddy]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = caddy
log = ${caddy-configuration:error-log} ${caddy-configuration:access-log}
frequency = daily
rotatep-num = 30
post = ${frontend-caddy-lazy-graceful:rendered} &
sharedscripts = true
notifempty = true
create = true
[logrotate-entry-nginx]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = caddy-nginx
log = ${nginx-configuration:error_log} ${nginx-configuration:access_log}
frequency = daily
rotatep-num = 30
post = ${nginx-configuration:nginx-graceful-command}
sharedscripts = true
notifempty = true
create = true
#################
# Trafficserver
#################
[trafficserver-directory]
recipe = slapos.cookbook:mkdirectory
configuration = ${directory:etc}/trafficserver
local-state = ${directory:var}/trafficserver
bin_path = {{ parameter_dict['trafficserver'] }}/bin
log = ${directory:log}/trafficserver
cache-path = ${directory:srv}/ats_cache
[trafficserver-variable]
wrapper-path = ${directory:service}/trafficserver
reload-path = ${directory:etc-run}/trafficserver-reload
local-ip = {{ instance_parameter['ipv4-random'] }}
input-port = 23432
hostname = ${configuration:frontend-name}
remap = map /HTTPS/ http://{{ instance_parameter['ipv4-random'] }}:${caddy-configuration:ssl-cache-through-port}
map / http://{{ instance_parameter['ipv4-random'] }}:${caddy-configuration:cache-through-port}
plugin-config = {{ parameter_dict['trafficserver'] }}/libexec/trafficserver/rfc5861.so
cache-path = ${trafficserver-directory:cache-path}
disk-cache-size = ${configuration:disk-cache-size}
autoconf-port = ${configuration:trafficserver-autoconf-port}
mgmt-port = ${configuration:trafficserver-mgmt-port}
ram-cache-size = ${configuration:ram-cache-size}
[trafficserver-configuration-directory]
recipe = plone.recipe.command
command = cp -rn {{ parameter_dict['trafficserver'] }}/etc/trafficserver/* ${:target}
target = ${trafficserver-directory:configuration}
[trafficserver-launcher]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_cop
wrapper-path = ${trafficserver-variable:wrapper-path}
environment = TS_ROOT=${buildout:directory}
hash-files = ${buildout:directory}/software_release/buildout.cfg
[trafficserver-reload]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_line -x
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
rendered = ${trafficserver-directory:configuration}/${:filename}
extra-context =
mode = 600
context =
section ats_directory trafficserver-directory
section ats_configuration trafficserver-variable
${:extra-context}
[trafficserver-records-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_records_config_location'] }}/{{ parameter_dict['template_trafficserver_records_config_filename'] }}
filename = records.config
extra-context =
import os_module os
[trafficserver-storage-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_storage_config_location'] }}/{{ parameter_dict['template_trafficserver_storage_config_filename'] }}
filename = storage.config
[trafficserver-remap-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = remap.config
context =
key content trafficserver-variable:remap
[trafficserver-plugin-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = plugin.config
context =
key content trafficserver-variable:plugin-config
[trafficserver-promise-listen-port]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/trafficserver-port-listening
hostname = ${trafficserver-variable:local-ip}
port = ${trafficserver-variable:input-port}
[trafficserver-line]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_line
wrapper-path = ${directory:bin}/traffic_line
environment = TS_ROOT=${buildout:directory}
[trafficserver-promise-cache-availability]
recipe = collective.recipe.template
input =
inline:#!${buildout:executable}
import subprocess
import sys
traffic_line = "${trafficserver-line:wrapper-path}"
result = float(subprocess.check_output([traffic_line, '-r', 'proxy.node.cache.percent_free' ]))
if result != 0: sys.exit(0)
sys.stderr.write("Cache not available, availability: %s" % result)
sys.exit(127)
output = ${directory:promise}/trafficserver-cache-availability
mode = 700
### End of ATS sections
### Caddy Graceful and promises
[frontend-caddy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_graceful_script'] }}
rendered = ${directory:etc-run}/frontend-caddy-safe-graceful
mode = 0700
extra-context =
key directory_run directory:run
key directory_etc directory:etc
key directory_bin directory:bin
key caddy_graceful_reload_command caddy-configuration:frontend-graceful-command
[frontend-nginx-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_nginx_graceful_script'] }}
rendered = ${directory:etc-run}/frontend-nginx-safe-graceful
mode = 0700
extra-context =
key directory_run directory:run
key directory_etc directory:etc
key directory_bin directory:bin
key nginx_graceful_reload_command nginx-configuration:nginx-graceful-command
[frontend-caddy-lazy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/frontend-caddy-lazy-graceful
mode = 0700
pid-file = ${directory:run}/lazy-graceful.pid
wait_time = 60
extra-context =
key pid_file :pid-file
key wait_time :wait_time
key lazy_command caddy-configuration:frontend-graceful-command
# Promises checking configuration:
[promise-frontend-caddy-configuration]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:promise}/frontend-caddy-configuration-promise
mode = 0700
extra-context =
key content caddy-configuration:frontend-configuration-verification
[promise-caddy-frontend-v4-https]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_frontend_ipv4_https
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${configuration:port}
[promise-caddy-frontend-v4-http]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_frontend_ipv4_http
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${configuration:plain_http_port}
[promise-caddy-frontend-v6-https]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_frontend_ipv6_https
hostname = {{ instance_parameter['ipv6-random'] }}
port = ${configuration:port}
[promise-caddy-frontend-v6-http]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_frontend_ipv6_http
hostname = {{ instance_parameter['ipv6-random'] }}
port = ${configuration:plain_http_port}
[promise-caddy-frontend-cached]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_cached
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${caddy-configuration:cache-through-port}
[promise-caddy-frontend-ssl-cached]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/caddy_ssl_cached
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${caddy-configuration:ssl-cache-through-port}
[promise-caddy-is-process-older-than-dependency-set]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['bin_directory'] }}/is-process-older-than-dependency-set ${caddy-configuration:pid-file}
wrapper-path = ${directory:promise}/caddy-frontend-is-running-actual-software-release
#######
# Monitoring sections
#
[monitor-instance-parameter]
# 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'
{% set monitor_httpd_port = instance_parameter.get('configuration.monitor-httpd-port') %}
{% if monitor_httpd_port %}
monitor-httpd-port = {{ monitor_httpd_port | int }}
{% endif -%}
[monitor-conf-parameters]
private-path-list +=
${directory:logrotate-backup}
[monitor-traffic-summary-last-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${monitor-directory:reports}/traffic-summary-last-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ parameter_dict['trafficserver'] }}/bin/traffic_logstats -f ${trafficserver-directory:log}/squid.blog)</pre>"
extra-context =
key content monitor-traffic-summary-last-stats-wrapper:command
# Produce ATS Cache stats
[monitor-ats-cache-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${monitor-directory:reports}/ats-cache-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "<pre>$({{ parameter_dict['trafficserver'] }}/bin/traffic_shell ${monitor-ats-cache-stats-config:rendered})</pre>"
extra-context =
key content monitor-ats-cache-stats-wrapper:command
[monitor-caddy-server-status-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${monitor-directory:reports}/monitor-caddy-server-status-wrapper
mode = 0700
command = {{ parameter_dict['curl'] }}/bin/curl -s http://{{ instance_parameter['ipv4-random'] }}:${configuration:plain_http_port}/server-status -u ${monitor-instance-parameter:username}:${monitor-htpasswd:passwd} 2>&1
extra-context =
key content monitor-caddy-server-status-wrapper:command
[monitor-ats-cache-stats-config]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${trafficserver-configuration-directory:target}/cache-config.stats
mode = 644
context =
raw content show:cache-stats
[monitor-verify-re6st-connectivity]
recipe = slapos.cookbook:check_url_available
path = ${directory:promise}/re6st-connectivity
url = ${configuration:re6st-verification-url}
dash_path = {{ parameter_dict['dash'] }}/bin/dash
curl_path = {{ parameter_dict['curl'] }}/bin/curl
#######################
# Nginx
#
[nginx-wrapper]
recipe = slapos.cookbook:wrapper
environment =
CADDYPATH=${directory:nginx_cluster}
command-line = {{ parameter_dict['caddy'] }}
-conf ${dynamic-nginx-frontend-template:rendered}
-log stdout
-http2=true
-grace {{ instance_parameter['configuration.mpm-graceful-shutdown-timeout'] }}s
-disable-http-challenge
-disable-tls-sni-challenge
wrapper-path = ${directory:bin}/nginx-wrapper
[nginx-frontend]
recipe = slapos.cookbook:wrapper
command-line = ${nginx-wrapper:wrapper-path} -pidfile ${nginx-configuration:pid-file}
wrapper-path = ${directory:service}/frontend_nginx
hash-files = ${buildout:directory}/software_release/buildout.cfg
[dynamic-nginx-frontend-template]
< = jinja2-template-base
template = {{ parameter_dict['template_nging_configuration'] }}
rendered = ${directory:etc}/nginx.cfg
mode = 0600
extra-context =
key port nginx-configuration:port
key ssl_certificate nginx-configuration:ssl_certificate
key ssl_key nginx-configuration:ssl_key
key local_ip nginx-configuration:local_ip
key plain_port nginx-configuration:plain_port
key slave_configuration_directory nginx-configuration:slave-configuration-directory
key error_log nginx-configuration:error_log
key access_log nginx-configuration:access_log
key not_found_file caddy-configuration:not-found-file
[nginx-configuration]
access_log = ${directory:log}/nginx-access.log
error_log = ${directory:log}/nginx-error.log
ip = ${slap-network-information:global-ipv6}
local_ip = ${slap-network-information:local-ipv4}
port = ${configuration:nginx_port}
plain_port = ${configuration:plain_nginx_port}
worker_processes = 4
worker_connections = 1024
slave-configuration-directory = ${caddy-directory:nginx-slave-configuration}
pid-file = ${directory:run}/nginx.pid
nginx-graceful-command = ${:nginx-configuration-verification}; if [ $? -eq 0 ]; then kill -HUP $(cat ${:pid-file}); fi
nginx-configuration-verification = ${nginx-wrapper:wrapper-path} -validate
ssl_certificate = ${ca-frontend:cert-file}
ssl_key = ${ca-frontend:key-file}
[promise-nginx-configuration]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:promise}/nginx-configuration-promise
mode = 0700
extra-context =
key content nginx-configuration:nginx-configuration-verification
[promise-nginx-frontend-v4-https]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/nginx_frontend_ipv4_https
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${configuration:nginx_port}
[promise-nginx-frontend-v4-http]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/nginx_frontend_ipv4_http
hostname = {{ instance_parameter['ipv4-random'] }}
port = ${configuration:plain_nginx_port}
[promise-nginx-frontend-v6-https]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/nginx_frontend_ipv6_https
hostname = {{ instance_parameter['ipv6-random'] }}
port = ${configuration:nginx_port}
[promise-nginx-frontend-v6-http]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/nginx_frontend_ipv6_http
hostname = {{ instance_parameter['ipv6-random'] }}
port = ${configuration:plain_nginx_port}
[promise-nginx-is-process-older-than-dependency-set]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['bin_directory'] }}/is-process-older-than-dependency-set ${nginx-configuration:pid-file}
wrapper-path = ${directory:promise}/promise-nginx-is-process-older-than-dependency-set
[port-redirection]
<= jinja2-template-base
template = inline:
[{"srcPort": 80, "destPort": {{ '{{' }} http_port {{ '}}' }}}, {"srcPort": 443, "destPort": {{ '{{' }} https_port {{ '}}' }}}]
rendered = ${buildout:directory}/.slapos-port-redirect
mode = 0644
extra-context =
key http_port configuration:plain_http_port
key https_port configuration:port
[configuration]
{%- for key, value in instance_parameter.iteritems() -%}
{%- if key.startswith('configuration.') %}
{{ key.replace('configuration.', '') }} = {{ dumps(value) }}
{%- endif -%}
{%- endfor -%}
{%- endif -%} {# if slap_software_type == software_type #}