instance-runner.cfg 31.9 KB
Newer Older
1
[buildout]
2
common-runner-parts =
3 4 5 6
  nginx_conf
  nginx-launcher
  certificate-authority
  ca-nginx
7 8
  certificate-authority-service
  ca-nginx-service
9
  logrotate-entry-nginx
10 11
  gunicorn-launcher
  gunicorn-graceful
12
  publish-connection-information
13
  slaprunner-promise
14
  logrotate-entry-apache-httpd
15
  apache-httpd-promise
16
  slaprunner-supervisord-wrapper
17 18
  runner-sshd-add-authorized-key
  runner-sshd-promise
19
  runner-sshd-service
20
  runtestsuite
21
  symlinks
22
  shellinabox
23
  shellinabox-service
24
  slapos-cfg
25
  cron-entry-prepare-software
26
  deploy-instance-parameters
27
  instance-software
28
  instance-software-type
29
  minishell-cwd
30
  bash-profile
31
  supervisord-wrapper
32
  supervisord-promise
33
  logrotate-entry-supervisord
34
  logrotate-entry-slapgrid
35
  httpd-graceful-wrapper
36 37 38 39
{% if slapparameter_dict.get('no-ipv4-frontend', 'false') == 'false' %}
  slaprunner-frontend-promise
  httpd-frontend-promise
{% endif %}
40
{% if slapparameter_dict.get('custom-frontend-backend-url') and slapparameter_dict.get('check-custom-frontend-promise', 'false') == 'true' %}
41 42
  custom-frontend-promise
{% endif %}
43
## Monitoring part
44
  monitor-base
45
  monitor-check-webrunner-internal-instance
46 47
## Usability part
  template-slapuser-script
48

49
parts = $${:common-runner-parts}
50 51 52
extends =
  ${monitor2-template:rendered}
  ${template-logrotate-base:rendered}
53 54 55 56 57

eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true

58 59
{% if slapparameter_dict.get('custom-frontend-backend-url') -%}
[request-custom-frontend]
60
recipe = slapos.cookbook:requestoptional
61
software-url = {{ slapparameter_dict.get('custom-frontend-software-url', 'http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg') }}
62 63 64 65
software-type = {{ slapparameter_dict.get('custom-frontend-software-type', 'RootSoftwareInstance') }}
slave = true
name = Custom Web Frontend

66 67 68 69 70
server-url = $${slap-connection:server-url}
key-file = $${slap-connection:key-file}
cert-file = $${slap-connection:cert-file}
computer-id = $${slap-connection:computer-id}
partition-id = $${slap-connection:partition-id}
71

72
{% if slapparameter_dict.get('custom-frontend-instance-guid') -%}
73
sla-instance_guid = $${slap-parameter:frontend-instance-guid}
74 75
{% endif -%}

76 77
{% set custom_frontend_backend_type = slapparameter_dict.get('custom-frontend-backend-type') -%}
{% if custom_frontend_backend_type -%}
78 79
config-type = {{ custom_frontend_backend_type }}
{% endif -%}
80
config-url = {{ slapparameter_dict.get('custom-frontend-backend-url') }}
81
return = site_url domain
82 83

[custom-frontend-promise]
84 85 86 87
<= monitor-promise-base
module = check_url_available
name = custom_frontend_promise.py
config-url = https://$${request-custom-frontend:connection-domain}
88
{% if slapparameter_dict.get('custom-frontend-basic-auth') -%}
89
config-check-secure = 1
90
{% endif -%}
91

92
[custom-frontend-url-ready-promise-bin]
93 94
recipe = slapos.recipe.template:jinja2
url = https://$${request-custom-frontend:connection-domain}
95
rendered = $${directory:bin}/custom_frontend_ready_promise
96 97 98 99 100 101 102 103 104 105 106
template = inline:
  #!{{ dash_executable_location }}

  URL="$${:url}"
  CODE=$({{ curl_executable_location }} -g -k -sL $URL -w %{http_code} --max-time 5 -o /dev/null)

  if [ $? -eq 3 ]; then
    echo "Custom frontend URL malformed: $URL." >&2
    exit 1
  fi

107 108 109 110 111 112
[custom-frontend-url-ready-promise]
<= monitor-promise-base
module = check_command_execute
name = custom_frontend_ready_promise.py
config-command = $${custom-frontend-url-ready-promise-bin:rendered}

113
[publish-connection-information]
114
custom-frontend-url = $${custom-frontend-url-ready-promise-bin:url}
115
{% endif %}
116

117
# Create all needed directories
118
[directory]
119
recipe = slapos.cookbook:mkdirectory
120 121 122
home = $${buildout:directory}
etc = $${:home}/etc/
var = $${:home}/var/
123 124 125 126
# This srv path has an extra slash, which will cause runnerdirectory:home
# to be .../srv//runner/.. but for compatibility reasons we don't fix this,
# because this is the path that will be used as software URL installed by
# webrunner and would cause software release hash to become different.
127 128 129
srv = $${:home}/srv/
bin = $${:home}/bin/
tmp = $${:home}/tmp/
130

131 132 133 134 135 136 137 138
sshkeys = $${:srv}/sshkeys
services = $${:etc}/service/
scripts = $${:etc}/run/
ssh = $${:etc}/ssh/
log = $${:var}/log/
run = $${:var}/run/
backup = $${:srv}/backup/
test = $${:etc}/test/
139
nginx-data = $${:srv}/nginx
140
ca-dir = $${:srv}/ssl
141
project = $${:srv}/runner/project
142
cgi-bin = $${:srv}/cgi-bin
143 144 145

[runnerdirectory]
recipe = slapos.cookbook:mkdirectory
146 147
home = $${directory:srv}/runner/
test = $${directory:srv}/test/
148
project = $${:home}/project
149
public = $${:home}/public
150
software-root = {{ slapparameter_dict.get('software-root', '$${:home}/software') }}
151
instance-root = $${:home}/instance
152
shared-root = $${slap-parameter:buildout-shared-folder}
153 154 155
project-test = $${:test}/project
software-test = $${:test}/software
instance-test = $${:test}/instance
156
sessions = $${buildout:directory}/.sessions
157 158
private-project = $${:home}/.git-private
public-project = $${:home}/.git-public
159 160

[slaprunner]
161
slaprunner = ${buildout:directory}/bin/slaprunner
162
slapos = ${buildout:directory}/bin/slapos
163 164
slapproxy = ${buildout:directory}/bin/slapproxy
supervisor = ${buildout:directory}/bin/slapgrid-supervisorctl
165
git-binary = ${git:location}/bin/git
166
root_check = false
167
slapos.cfg = $${directory:etc}/slapos.cfg
168 169
working-directory = $${runnerdirectory:home}
project-directory = $${runnerdirectory:project}
170 171
instance_root = $${runnerdirectory:instance-root}
software_root = $${runnerdirectory:software-root}
172 173
shared_root = $${runnerdirectory:shared-root}
buildout-shared-part-list-dump = ${template-buildout-shared-part-list:output}
174 175
pidfile-software = $${directory:run}/slapgrid-cp.pid
pidfile-instance = $${directory:run}/slapgrid-sr.pid
176
public_key = $${runner-sshd-ssh-host-rsa-key:output}
177
instance-monitor-url = https://[$${:ipv6}]:$${slap-parameter:monitor-httpd-port}
178 179 180
etc_dir = $${directory:etc}
log_dir =  $${directory:log}
run_dir = $${directory:run}
181 182
ipv4 = $${slap-network-information:local-ipv4}
ipv6 = $${slap-network-information:global-ipv6}
183
instance_root = $${runnerdirectory:instance-root}
184 185
proxy_port = 50000
runner_port = 50005
186
partition-amount = $${slap-parameter:instance-amount}
187
wrapper = $${directory:services}/slaprunner
188
debug = $${slap-parameter:debug}
189
access-url = https://[$${:ipv6}]:$${:runner_port}
190
supervisord_config = $${directory:etc}/supervisord.conf
191
supervisord_server = http://$${supervisord:server}
192
proxy_database = $${slaprunner:working-directory}/proxy.db
193 194 195
console = False
verbose = False
debug = False
196 197 198
auto_deploy = $${slap-parameter:auto-deploy}
auto_deploy_instance = $${slap-parameter:auto-deploy-instance}
autorun = $${slap-parameter:autorun}
199
knowledge0_file = $${monitor-instance-parameter:configuration-file-path}
200
minishell_cwd_file = $${directory:etc}/.minishell-cwd
201
minishell_history_file = $${directory:etc}/.minishell_history
202 203
software_info_json = $${runnerdirectory:home}/software_info.json
instance_info_json = $${runnerdirectory:home}/instance_info.json
204
path = $${shell-environment:path}
205
instance_name = $${slap-parameter:instance-name}
206

207 208 209
default_repository = $${slap-parameter:slapos-repository}
default_repository_branch = $${slap-parameter:slapos-reference}

210 211 212 213 214 215 216

#---------------------------
#--
#-- supervisord managing slaprunner instance processes
[slaprunner-supervisord-wrapper]
recipe = slapos.cookbook:wrapper
# XXX hardcoded locations
217
command-line = $${directory:bin}/slapos node supervisord --cfg $${directory:etc}/slapos.cfg -n
218
wrapper-path = $${directory:services}/slaprunner-supervisord
219
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
220 221


222 223
[test-runner]
<= slaprunner
224
slapos.cfg = $${directory:etc}/slapos-test.cfg
225 226
working-directory = $${runnerdirectory:test}
project-directory = $${runnerdirectory:project-test}
227 228
software_root = $${runnerdirectory:software-test}
instance_root = $${runnerdirectory:instance-test}
229
proxy_port = 8602
230
etc_dir = $${directory:test}
231 232
autorun = False
auto_deploy = True
233

234 235
[runtestsuite]
recipe = slapos.cookbook:wrapper
236 237
arguments = --server_url=$${slap-connection:server-url} --key_file=$${slap-connection:key-file} --cert_file=$${slap-connection:cert-file} --computer_id=$${slap-connection:computer-id} --partition_id=$${slap-connection:partition-id}
command-line = ${buildout:directory}/bin/slaprunnertest $${:arguments}
238
wrapper-path = $${directory:bin}/runTestSuite
239
environment = PATH=$${shell-environment:path}
240
  RUNNER_CONFIG=$${slapos-cfg:rendered}
241

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
# Deploy openssh-server
[runner-sshd-port]
recipe = slapos.cookbook:free_port
minimum = 22222
maximum = 22231
ip = $${slap-network-information:global-ipv6}

[runner-sshd-config]
recipe = slapos.recipe.template:jinja2
rendered = $${directory:etc}/runner-sshd.conf
path_pid = $${directory:run}/runner-sshd.pid
template = inline:
  PidFile $${:path_pid}
  Port $${runner-sshd-port:port}
  ListenAddress $${slap-network-information:global-ipv6}
  Protocol 2
  UsePrivilegeSeparation no
259 260
  HostKey $${runner-sshd-ssh-host-rsa-key:output}
  HostKey $${runner-sshd-ssh-host-ecdsa-key:output}
261 262 263
  PasswordAuthentication no
  PubkeyAuthentication yes
  AuthorizedKeysFile $${buildout:directory}/.ssh/authorized_keys
Jérome Perrin's avatar
Jérome Perrin committed
264
  ForceCommand cd $${directory:home}; if [ -z "$SSH_ORIGINAL_COMMAND" ]; then HOME=$${directory:home} $${shell-environment:shell} -l; else HOME=$${directory:home} SHELL=$${shell-environment:shell} PATH=$${shell-environment:path} eval "$SSH_ORIGINAL_COMMAND"; fi
265
  Subsystem sftp ${openssh:location}/libexec/sftp-server
266

267
[runner-sshd-service]
268 269
recipe = slapos.cookbook:wrapper
command-line = ${openssh:location}/sbin/sshd -D -e -f $${runner-sshd-config:rendered}
270
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
271
wrapper-path = $${directory:services}/runner-sshd
272

273
[runner-sshd-add-authorized-key]
274
recipe = slapos.cookbook:dropbear.add_authorized_key
275
home = $${buildout:directory}
276
key = $${slap-parameter:user-authorized-key}
277

278
[runner-sshd-ssh-keygen-base]
279
recipe = plone.recipe.command
280 281
output = $${directory:etc}/$${:_buildout_section_name_}
command = ${openssh-output:keygen} -f $${:output} -N '' $${:extra-args}
282

283 284 285 286 287 288 289 290
[runner-sshd-ssh-host-rsa-key]
<=runner-sshd-ssh-keygen-base
extra-args=-t rsa
[runner-sshd-ssh-host-ecdsa-key]
<=runner-sshd-ssh-keygen-base
extra-args=-t ecdsa -b 521

[runner-sshd-publickey-fingerprint-shelloutput]
291 292 293 294
recipe = collective.recipe.shelloutput
# XXX because collective.recipe.shelloutput ignore errors, we run the same
# command in a plone.recipe.command so that if fails if something goes wrong.
commands =
295
  fingerprint = bash -o pipefail -c "${openssh-output:keygen} -lf $${runner-sshd-ssh-host-ecdsa-key:output} | cut  -f 2 -d\ | sed 's/+/%2B/g' | sed 's/\//%2F/g' | sed 's/SHA256://'"
296

297
[runner-sshd-publickey-fingerprint]
298 299 300 301
# fingerprint for ssh url, see
# https://tools.ietf.org/id/draft-salowey-secsh-uri-00.html#connparam
# https://winscp.net/eng/docs/session_url#hostkey

302 303
_fingerprint = $${runner-sshd-publickey-fingerprint-shelloutput:fingerprint}

304 305 306
# format is host-key-alg-fingerprint, but we know that
# $${runner-sshkeys-sshd:public-key} is rsa so for host-key-alg
# we just use use rsa.
307 308 309 310 311 312 313 314 315 316 317 318
fingerprint = ssh-rsa-$${:_fingerprint}

# XXX because collective.recipe.shelloutput ignore errors and capture output
# "Error ...", we use a plone.recipe.command to check that this command did
# not fail.
# This command will always fail on first buildout run, because
# collective.recipe.shelloutput is evaluated at buildout recipes __init__ step,
# but the key file is created later at install step.
recipe = plone.recipe.command
stop-on-error = true
command = echo "$${:_fingerprint}" | ( grep ^Error || exit 0 && exit 1 )

319

320
#---------------------------
321
#--
322 323
#-- Set nginx frontend

324 325 326 327 328 329 330 331 332 333
[tempdirectory]
recipe = slapos.cookbook:mkdirectory
client_body_temp_path = $${directory:tmp}/client_body_temp_path
proxy_temp_path = $${directory:tmp}/proxy_temp_path
fastcgi_temp_path = $${directory:tmp}/fastcgi_temp_path
uwsgi_temp_path = $${directory:tmp}/uwsgi_temp_path
scgi_temp_path = $${directory:tmp}/scgi_temp_path

[nginx-frontend]
# Options
334
nb_workers = 5
335
# Network
336 337 338
local-ip = $${slap-network-information:local-ipv4}
global-ip = $${slap-network-information:global-ipv6}
global-port = $${slaprunner:runner_port}
339
# Backend
340 341
runner-ip = $${slaprunner:ipv4}
runner-port = $${slaprunner:runner_port}
342 343 344 345 346 347 348 349
# SSL
ssl-certificate = $${ca-nginx:cert-file}
ssl-key = $${ca-nginx:key-file}
# Log
path_pid = $${directory:run}/nginx.pid
path_log = $${directory:log}/nginx.log
path_access_log = $${directory:log}/nginx.access.log
path_error_log = $${directory:log}/nginx.error.log
350
path_tmp = $${directory:tmp}/
351
nginx_prefix = $${buildout:directory}
352 353 354
# Config files
path_nginx_conf = $${directory:etc}/nginx.conf
# Executables
355
bin_nginx = ${nginx-webdav:location}/sbin/nginx
356
bin_launcher = $${directory:bin}/launcher
357 358
# Utils
path_shell = ${dash:location}/bin/dash
359 360
# Misc.
etc_dir = $${directory:etc}
361
work_dir = $${slaprunner:working-directory}
362 363 364 365 366 367

[nginx_conf]
recipe = slapos.recipe.template:jinja2
template = ${template_nginx_conf:location}/${template_nginx_conf:filename}
rendered = $${nginx-frontend:path_nginx_conf}
context =
368
    key shellinabox_socket shellinabox:socket
369
    key socket gunicorn:socket
370 371 372 373 374 375 376 377 378 379 380
    section param_nginx_frontend nginx-frontend
    section param_tempdir tempdirectory

[nginx-launcher]
recipe = slapos.recipe.template:jinja2
template = ${template_launcher:location}/${template_launcher:filename}
rendered = $${nginx-frontend:bin_launcher}
mode = 700
context =
    section param_nginx_frontend nginx-frontend

381 382 383
[logrotate-entry-nginx]
<= logrotate-entry-base
name = nginx
Ivan Tyagov's avatar
Ivan Tyagov committed
384
log = $${directory:log}/nginx.access.log $${directory:log}/nginx.error.log
385
post = kill -USR1 $(cat $${buildout:directory}/var/run/nginx.pid)
386

387
[httpd-parameters]
388 389 390 391 392 393
path_pid = $${directory:run}/httpd.pid
path_error_log = $${directory:log}/httpd-error.log
path_access_log = $${directory:log}/httpd-access.log
# XXX Use ca-nginx, no need to regenerate certificate
cert_file = $${ca-nginx:cert-file}
key_file = $${ca-nginx:key-file}
394
global_ip = $${slap-network-information:global-ipv6}
395
global_port = $${slap-parameter:slaprunner-httpd-port}
396 397
working_directory = $${slaprunner:working-directory}
dav_lock = $${directory:var}/WebDavLock
398
htpasswd_file = $${directory:etc}/.htpasswd
399
etc_dir = $${directory:etc}
400 401
var_dir = $${directory:var}
project_folder = $${directory:project}
402
project_private_folder = $${runnerdirectory:private-project}
403
project_public_folder = $${runnerdirectory:public-project}
404
runner_home = $${runnerdirectory:home}
405
git_http_backend = ${git:location}/libexec/git-core/git-http-backend
406
cgid_sock = $${directory:run}/cgid.sock
407
httpd_cors_file = $${slaprunner-httpd-cors:location}
408 409 410 411

[httpd-conf]
recipe = slapos.recipe.template:jinja2
template = ${template_httpd_conf:location}/${template_httpd_conf:filename}
412
rendered = $${directory:etc}/httpd.conf
413
context =
414 415
    section parameters httpd-parameters

416 417 418 419 420 421 422 423 424
[apache-httpd]
recipe = slapos.cookbook:wrapper
apache-executable = ${apache:location}/bin/httpd
wrapper-path = $${directory:services}/slaprunner-httpd
command-line = $${:apache-executable} -f $${httpd-conf:rendered} -DFOREGROUND
access-url = https://[$${httpd-parameters:global_ip}]:$${httpd-parameters:global_port}
wait-for-files =
  $${ca-nginx:cert-file}
  $${ca-nginx:key-file}
425
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
426

427 428 429
[logrotate-entry-apache-httpd]
<= logrotate-entry-base
name = apache
Ivan Tyagov's avatar
Ivan Tyagov committed
430
log = $${directory:log}/httpd-access.log $${directory:log}/httpd-error.log
431 432
post = test ! -s $${buildout:directory}/var/run/httpd.pid || $${buildout:directory}/bin/slapos-kill --pidfile $${buildout:directory}/var/run/httpd.pid -s USR1

433 434 435 436 437 438 439 440 441
[httpd-graceful-wrapper]
recipe = collective.recipe.template
input = inline:
  #!/bin/sh
  exec kill -USR1 $(cat $${httpd-parameters:path_pid})
output = $${directory:scripts}/slaprunner-httpd-graceful
mode = 700

[apache-httpd-promise]
442 443 444
<= monitor-promise-base
module = check_url_available
name = $${:filename}.py
445
filename = apache-httpd-listening-on-tcp
446 447
config-url = $${apache-httpd:access-url}
config-check-secure = 1
448 449 450 451 452 453 454

[slaprunner-httpd-cors]
recipe = plone.recipe.command
command = if [ ! -f $${:location} ]; then touch $${:location}; fi
location = $${directory:etc}/$${:filename}
filename = slaprunner-httpd-cors.cfg
stop-on-error = true
455

456 457 458 459
#--------------------
#--
#-- WSGI

460
[gunicorn]
461 462 463 464 465 466 467 468
bin_gunicorn = $${directory:bin}/gunicorn
bin_launcher = $${directory:services}/gunicorn
path_shell = ${dash:location}/bin/dash
socket = $${directory:tmp}/flaskserver.sock
path_pid = $${directory:run}/gunicorn.pid

[gunicorn-launcher]
recipe = slapos.cookbook:wrapper
469
command-line = $${gunicorn:bin_gunicorn} slapos.runner.run:app -p $${gunicorn:path_pid} -b unix:$${gunicorn:socket} -e RUNNER_CONFIG=$${slaprunner:slapos.cfg} --error-logfile $${directory:log}/$${:error-log-file} --timeout 200 --threads 3 --log-level error --preload
470
error-log-file = gunicorn-error.log
471
wrapper-path = $${gunicorn:bin_launcher}
472
environment = PATH=$${shell-environment:path}
473
  RUNNER_CONFIG=$${slaprunner:slapos.cfg}
474
  LANG=en_GB.UTF-8
475
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
476 477 478

[gunicorn-graceful]
recipe = slapos.cookbook:wrapper
479
command-line = $${directory:bin}/killpidfromfile $${gunicorn:path_pid} SIGHUP
480 481
wrapper-path = $${directory:scripts}/gunicorn-graceful

482
#--------------------
483
#--
484
#-- ssl certificates
485 486 487 488 489 490

[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:ca-dir}
requests-directory = $${cadirectory:requests}
491
wrapper = $${directory:bin}/certificate_authority
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
ca-private = $${cadirectory:private}
ca-certs = $${cadirectory:certs}
ca-newcerts = $${cadirectory:newcerts}
ca-crl = $${cadirectory:crl}

[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-nginx]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = $${cadirectory:certs}/nginx_frontend.key
cert-file = $${cadirectory:certs}/nginx_frontend.crt
510
executable = $${nginx-launcher:rendered}
511
wrapper = $${directory:bin}/nginx-frontend
512 513 514
# Put domain name
name = example.com

515 516 517 518
[ca-nginx-service]
recipe = slapos.cookbook:wrapper
command-line = $${directory:bin}/nginx-frontend
wrapper-path = $${directory:services}/nginx-frontend
519
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
520 521 522 523 524

[certificate-authority-service]
recipe = slapos.cookbook:wrapper
command-line = $${directory:bin}/certificate_authority
wrapper-path = $${directory:services}/certificate_authority
525
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
526

527
#--------------------
528 529
#--
#-- Request frontend
530

531
{% if slapparameter_dict.get('no-ipv4-frontend', 'false') == 'false' -%}
532 533
[request-frontend]
<= slap-connection
534
recipe = slapos.cookbook:requestoptional
535
name = SlapRunner Frontend
536
# XXX We have hardcoded SR URL here.
537
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
538
slave = true
539
config-url = $${slaprunner:access-url}
540
config-domain = $${slap-parameter:frontend-domain}
541
return = site_url domain
542

543
[slaprunner-frontend-promise]
544 545 546 547 548
<= monitor-promise-base
module = check_url_available
name = slaprunner_frontend.py
config-url = https://$${request-frontend:connection-domain}/login
config-check-secure = 1
549

550 551 552
[request-httpd-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
553
# XXX - Unfortunately, we still call webrunner httpd frontend "Monitor Frontend" otherwise
554 555
# buildout will ignore previous frontend that was created and create a new one (in case of upgrade)
name = Monitor Frontend
556 557 558 559
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config-url = $${apache-httpd:access-url}
560
config-domain =
561 562 563
return = secure_access domain

[httpd-frontend-promise]
564 565 566 567 568
<= monitor-promise-base
module = check_url_available
name = slaprunner-apache-http-frontend.py
config-url = $${request-httpd-frontend:connection-secure_access}
config-check-secure = 1
569

570
{% endif %}
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589

[htpasswd]
recipe = slapos.cookbook:generate.password
storage-path = $${directory:etc}/.pwd
bytes = 8

[runner-htpasswd]
recipe = plone.recipe.command
stop-on-error = true
htpasswd-path = $${monitor-directory:etc}/.htpasswd
command = if [ ! -f "$${:htpasswd-path}" ]; then ${apache:location}//bin/htpasswd -cb $${:htpasswd-path} $${:user} $${:password}; fi
update-command = $${:command}
user = admin
{% if slapparameter_dict.get('monitor-password', '') -%}
password = {{ slapparameter_dict['monitor-password'] }}
{% else -%}
password = $${htpasswd:passwd}
{% endif -%}

590
#--------------------------------------
591
#--
592
#-- Send information to SlapOS Master
593

594 595 596
[user-info]
recipe = slapos.cookbook:userinfo

597
[publish-connection-information]
598
recipe = slapos.cookbook:publish
599 600 601
backend-url = $${slaprunner:access-url}
init-user = $${runner-htpasswd:user}
init-password = $${runner-htpasswd:password}
602
ssh-command = ssh $${user-info:pw-name}@$${slap-network-information:global-ipv6} -p $${runner-sshd-port:port}
603
ssh-url = ssh://$${user-info:pw-name};fingerprint=$${runner-sshd-publickey-fingerprint:fingerprint}@[$${slap-network-information:global-ipv6}]:$${runner-sshd-port:port}
604 605
git-public-url = https://[$${httpd-parameters:global_ip}]:$${httpd-parameters:global_port}/git-public/
git-private-url = https://[$${httpd-parameters:global_ip}]:$${httpd-parameters:global_port}/git/
606
monitor-base-url = $${monitor-publish-parameters:monitor-base-url}
607 608 609 610 611
{% if slapparameter_dict.get('no-ipv4-frontend', 'false') == 'false' -%}
url =  https://$${request-frontend:connection-domain}
webdav-url = $${request-httpd-frontend:connection-secure_access}/share/
public-url =  $${request-httpd-frontend:connection-secure_access}/public/
{% else %}
612
url =  $${slaprunner:access-url}
613 614 615 616
webdav-url = $${apache-httpd:access-url}/share/
public-url =  $${apache-httpd:access-url}/public/
{% endif %}

617 618
{% if slapparameter_dict.get('instance-type', '') != 'resilient' -%}
{% set monitor_interface_url = slapparameter_dict.get('monitor-interface-url', 'https://monitor.app.officejs.com') -%}
619
monitor-setup-url = {{ monitor_interface_url }}/#page=settings_configurator&url=$${monitor-publish-parameters:monitor-url}&username=$${monitor-publish-parameters:monitor-user}&password=$${monitor-publish-parameters:monitor-password}
620
{% else -%}
621 622 623
monitor-url = $${monitor-publish-parameters:monitor-url}
monitor-user = $${monitor-publish-parameters:monitor-user}
monitor-password = $${monitor-publish-parameters:monitor-password}
624
{% endif -%}
625 626 627
#---------------------------
#--
#-- Deploy promises scripts
Jean-Baptiste Petre's avatar
Jean-Baptiste Petre committed
628

629
[slaprunner-promise]
630 631 632 633 634
<= monitor-promise-base
module = check_port_listening
name = slaprunner.py
config-hostname = $${slaprunner:ipv6}
config-port = $${slaprunner:runner_port}
Jean-Baptiste Petre's avatar
Jean-Baptiste Petre committed
635

636
[runner-sshd-promise]
637 638 639 640 641
<= monitor-promise-base
module = check_port_listening
name = runner-sshd.py
config-hostname = $${slap-network-information:global-ipv6}
config-port = $${runner-sshd-port:port}
642

643 644
[symlinks]
recipe = cns.recipe.symlink
645
symlink_target = $${directory:bin}
646
symlink_base = ${buildout:directory}/bin
647 648 649

[slap-parameter]
# Default value if no ssh key is specified
650
user-authorized-key =
651
# Default value of instances number in slaprunner
652
instance-amount = 10
653 654
debug = false
frontend-domain =
655
slapos-repository = https://lab.nexedi.com/nexedi/slapos.git
656
slapos-software =
657
slapos-software-type =
658
slapos-reference = 1.0
659
auto-deploy = false
660
auto-deploy-instance = true
661
autorun = false
662
slaprunner-httpd-port = 9686
663
instance-name =
664 665
monitor-cors-domains =
monitor-interface-url =
666
monitor-httpd-port = 8386
667
buildout-shared-folder = $${runnerdirectory:home}/shared
668

669 670
[slapos-cfg]
recipe = slapos.recipe.template:jinja2
671
template = ${template-slapos-cfg:location}/${template-slapos-cfg:filename}
672 673 674
rendered = $${slaprunner:slapos.cfg}
mode = 700
context =
675
  section slaprunner slaprunner
676
  import codecs codecs
677
  raw buildout_shared_part_list_dump $${slaprunner:buildout-shared-part-list-dump}
678

679 680
[slapos-test-cfg]
recipe = slapos.recipe.template:jinja2
681
template = ${template-slapos-cfg:location}/${template-slapos-cfg:filename}
682 683 684 685 686
rendered = $${test-runner:slapos.cfg}
mode = 700
context =
  section slaprunner test-runner

687
[shellinabox]
688 689 690 691
recipe = slapos.recipe.template:jinja2
# We cannot use slapos.cookbook:wrapper here because this recipe escapes too much
socket = $${directory:run}/siab.sock
mode = 0700
692
rendered = $${directory:bin}/shellinaboxd
693 694 695 696
template = inline:
  #!/bin/sh
  exec ${shellinabox:location}/bin/shellinaboxd \
    --unixdomain-only=$${:socket}:$(id -u):$(id -g):0600 \
697
    --service "/:$(id -u):$(id -g):HOME:$${shell-environment:shell} -l"
698

699 700 701 702
[shellinabox-service]
recipe = slapos.cookbook:wrapper
command-line = $${directory:bin}/shellinaboxd
wrapper-path = $${directory:services}/shellinaboxd
703
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
704

705
[shell-environment]
706
shell = ${bash:location}/bin/bash
707
path = ${nano:location}/bin:${vim:location}/bin:${screen:location}/bin:${git:location}/bin:${curl:location}/bin:${python2.7:location}/bin:${tig:location}/bin:${zip:location}/bin:${mosh:location}/bin:${bash:location}/bin:$${buildout:directory}/bin/:/usr/bin:/bin/
708

709 710
[prepare-software]
recipe = slapos.cookbook:wrapper
711
command-line = ${curl:location}/bin/curl -g https://[$${slaprunner:ipv6}]:$${slaprunner:runner_port}/isSRReady --max-time 1 --insecure
712 713
wrapper-path = $${directory:scripts}/prepareSoftware

714 715 716 717 718 719 720
[cron-entry-prepare-software]
<= cron
recipe = slapos.cookbook:cron.d
name = prepare-software
frequency = */2 * * * *
command = $${prepare-software:wrapper-path}

721 722 723
[instance-parameters]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
724
template = ${template-parameters:location}/${template-parameters:filename}
725 726
rendered = $${directory:etc}/.parameter.xml.default
mode = 0644
727
context =
728 729 730 731 732 733 734 735
  key slapparameter_dict slap-configuration:configuration

[deploy-instance-parameters]
recipe = plone.recipe.command
stop-on-error = true
parameter-xml = $${directory:etc}/.parameter.xml
command = if [ ! -f $${:parameter-xml} ]; then cp $${instance-parameters:rendered} $${:parameter-xml}; fi

736 737 738 739 740 741 742
[instance-software-type]
recipe = plone.recipe.command
stop-on-error = true
# XXX It should not be named with .xml as it is not xml
software-type-path = $${directory:etc}/.software_type.xml
command = if [ ! -f $${:software-type-path} -a "$${slap-parameter:slapos-software-type}" != "" ]; then echo "$${slap-parameter:slapos-software-type}" > $${:software-type-path}; fi

743 744 745 746 747
[instance-software]
recipe = plone.recipe.command
stop-on-error = true
command = SR=$${slap-parameter:slapos-software} && if [ -n "$SR" ] && [ ! -f "$${directory:etc}/.project" ]; then echo workspace/slapos/$${slap-parameter:slapos-software}/ > $${directory:etc}/.project; fi

748 749 750 751 752 753 754 755
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}

756

757 758 759 760 761 762
[minishell-cwd]
recipe = plone.recipe.command
command = if [ ! -f $${slaprunner:minishell_cwd_file} ]; then echo $${runnerdirectory:home} > $${slaprunner:minishell_cwd_file}; fi
location = $${slaprunner:minishell_cwd_file}
stop-on-error = true

763
[bash-profile]
764 765 766 767
recipe = slapos.recipe.template:jinja2
template = ${template-bash-profile:location}/${template-bash-profile:filename}
rendered = $${buildout:directory}/.bash_profile
context =
768
    raw path $${shell-environment:path}
769
    raw shell $${shell-environment:shell}
770
    key terminfo terminfo:location
771
    key instance_name slap-parameter:instance-name
772
    key workdir runnerdirectory:home
Jérome Perrin's avatar
Jérome Perrin committed
773
    key home directory:home
774

775 776 777
[terminfo]
location = ${ncurses:location}/share/terminfo/

778 779 780 781
#---------------------------
#--
#-- supervisord managing slaprunner automation features

782
[supervisord]
783
autorestart = false
784 785 786 787
autostart = false
directory = $${buildout:directory}
exitcodes = 0
logfile = $${directory:log}/supervisord.log
788
no_logfile = NONE
789
numprocs = 1
790
path = $${shell-environment:path}
791
pidfile = $${directory:run}/supervisord.pid
792 793
ip = $${slaprunner:ipv4}
server = $${:ip}:$${:port}
794
port = 39986
795
slapgrid-cp = slapgrid-cp
796
slapgrid-cp-command = $${slaprunner:slapos} node instance --cfg $${:slapos-cfg} --verbose --logfile $${:slapgrid-cp-log}
797
slapgrid-cp-log = $${runnerdirectory:home}/instance.log
798
slapgrid-cp-startretries = 0
799
slapgrid-sr = slapgrid-sr
800
slapgrid-sr-command = $${slaprunner:slapos} node software --all --cfg $${:slapos-cfg} --verbose --logfile $${:slapgrid-sr-log}
801
slapgrid-sr-log = $${runnerdirectory:home}/software.log
802
slapgrid-sr-startretries = 0
803 804 805
slapproxy = slapproxy
slapproxy-autorestart = true
slapproxy-autostart = true
806
slapproxy-startsecs = 1
807
slapproxy-command = $${slaprunner:slapos} proxy start --logfile $${:slapproxy-log} --cfg $${:slapos-cfg}
808
slapproxy-log = $${directory:log}/slapproxy.log
809 810
socket_name = unix://$${:socket_path}
socket_path = $${directory:tmp}/supervisord.sock
811
startsecs = 0
812 813 814
# This file logs errors from listeners. Supervisord has its own logfile.
# Processes should handle their logs by themselves
stderr_logfile = $${directory:log}/supervisord-errors.log
815
slapos-cfg = $${slaprunner:slapos.cfg}
816 817 818 819 820 821

[supervisord-conf]
recipe = slapos.recipe.template:jinja2
template = ${template-supervisord:location}/${template-supervisord:filename}
rendered = $${directory:etc}/supervisord.conf
context =
822 823
    import multiprocessing multiprocessing
    import builtin __builtin__
824
    section supervisord supervisord
825
    key slapparameter_dict slap-configuration:configuration
826 827 828 829 830 831 832 833 834 835
    key listener_slapgrid listener-slapgrid-bin:rendered

[listener-slapgrid-bin]
recipe = slapos.recipe.template:jinja2
template = ${template-listener-slapgrid:location}/${template-listener-slapgrid:filename}
rendered = $${directory:bin}/listener_slapgrid.py
mode = 0744
context =
    section supervisord supervisord
    section slaprunner slaprunner
836
    raw python_executable ${buildout:directory}/bin/${extra-eggs:interpreter}
837 838 839 840 841

[supervisord-wrapper]
recipe = slapos.cookbook:wrapper
command-line = $${buildout:directory}/bin/supervisord -c $${supervisord-conf:rendered} --nodaemon
wrapper-path = $${directory:services}/supervisord
842
hash-existing-files = $${buildout:directory}/software_release/buildout.cfg
843

844 845 846
[logrotate-entry-supervisord]
<= logrotate-entry-base
name = supervisord
Ivan Tyagov's avatar
Ivan Tyagov committed
847
log = $${directory:log}/slapproxy.log $${directory:log}/supervisord.log $${directory:log}/supervisord-errors.log
848
post = kill -USR2 $(cat $${buildout:directory}/var/run/supervisord.pid)
849

850 851 852
[logrotate-entry-slapgrid]
<= logrotate-entry-base
name = slapgrid
Ivan Tyagov's avatar
Ivan Tyagov committed
853
log = $${runnerdirectory:home}/instance/*/.slapgrid/log/instance.log $${runnerdirectory:home}/instance/*/.slapgrid/promise/log/*.log
854

855
[supervisord-promise]
856 857 858 859 860
<= monitor-promise-base
module = check_port_listening
name = supervisord.py
config-hostname = $${slaprunner:ipv4}
config-port = $${supervisord:port}
861

862
# XXX Monitor
863
[monitor-instance-parameter]
864
monitor-httpd-port = $${slap-parameter:monitor-httpd-port}
865 866 867
{% if slapparameter_dict.get('name', '') -%}
monitor-title = {{ slapparameter_dict['name'] }}
{% endif -%}
868
cors-domains = {{ slapparameter_dict.get('monitor-cors-domains', 'monitor.app.officejs.com') }}
869 870 871
{% if slapparameter_dict.get('monitor-username', '') -%}
username = {{ slapparameter_dict['monitor-username'] }}
{% endif -%}
872
password = $${runner-htpasswd:password}
873
{% if slapparameter_dict.get('monitor-url-list', '') -%}
874
monitor-url-list = {{ slapparameter_dict['monitor-url-list'] }}
875 876
{% endif -%}
instance-configuration =
877
  httpdcors cors-domain $${slaprunner-httpd-cors:location} $${httpd-graceful-wrapper:output}
878
configuration-file-path = $${buildout:directory}/knowledge0.cfg
879

880 881 882 883
[monitor-conf-parameters]
private-path-list +=
  $${logrotate-directory:logrotate-backup}

884 885 886
[monitor-check-webrunner-internal-instance]
recipe = slapos.recipe.template:jinja2
template = ${monitor-check-webrunner-internal-instance:location}/${monitor-check-webrunner-internal-instance:filename}
887
rendered = $${monitor-directory:bin}/$${:filename}
888 889 890
filename = monitor-check-webrunner-internal-instance
mode = 0744

891 892 893
## Slapuser slapos command script
[template-slapuser-script]
recipe = slapos.recipe.template:jinja2
894
template = ${template-slapuser-script:location}/${template-slapuser-script:filename}
895 896 897 898 899
rendered = $${buildout:bin-directory}/slapos
mode = 0744
context =
  raw config_location $${slapos-cfg:rendered}
  raw slapos_python_file_location ${buildout:bin-directory}/slapos