[buildout] parts = directory configtest logrotate cron cron-entry-logrotate ca-frontend certificate-authority logrotate-entry-apache logrotate-entry-nginx apache-frontend switch-apache-softwaretype frontend-apache-graceful frontend-nginx-graceful dynamic-template-default-vh not-found-html promise-frontend-apache-configuration promise-apache-frontend-v4-https promise-apache-frontend-v4-http promise-apache-frontend-v6-https promise-apache-frontend-v6-http promise-apache-frontend-cached promise-apache-frontend-ssl-cached promise-nginx-frontend-v4-https promise-nginx-frontend-v4-http promise-nginx-frontend-v6-https promise-nginx-frontend-v6-http promise-nginx-configuration 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 apache monitor-base monitor-ats-cache-stats-wrapper monitor-verify-re6st-connectivity extends = ${monitor-template:output} eggs-directory = ${buildout:eggs-directory} develop-eggs-directory = ${buildout:develop-eggs-directory} offline = true # 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 [switch-apache-softwaretype] recipe = slapos.cookbook:softwaretype single-default = $${dynamic-custom-personal-template-slave-list:rendered} single-custom-personal = $${dynamic-custom-personal-template-slave-list:rendered} [instance-parameter] # Fetches parameters defined in SlapOS Master for this instance. # Always the same. 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} # Define default parameter(s) that will be used later, in case user didn't # specify it # All parameters are available through the configuration.XX syntax. # All possible parameters should have a default. configuration.domain = example.org configuration.public-ipv4 = configuration.port = 4443 configuration.plain_http_port = 8080 configuration.plain_nginx_port = 8081 configuration.nginx_port = 9443 configuration.server-admin = admin@example.com configuration.apache_custom_https = "" configuration.apache_custom_http = "" configuration.apache-key = configuration.apache-certificate = configuration.apache-ca-certificate = configuration.open-port = 80 443 configuration.extra_slave_instance_list = configuration.disk-cache-size = 8G configuration.ram-cache-size = 1G configuration.trafficserver-autoconf-port = 8083 configuration.trafficserver-mgmt-port = 8084 configuration.re6st-verification-url = http://[2001:67c:1254:4::1]/index.html [frontend-configuration] template-log-access = ${template-log-access:target} log-access-configuration = $${directory:etc}/apache-log-access.conf apache-directory = ${apache:location} apache-ipv6 = $${instance-parameter:ipv6-random} apache-https-port = $${instance-parameter:configuration.port} [jinja2-template-base] recipe = slapos.recipe.template:jinja2 rendered = $${buildout:directory}/$${:filename} extra-context = context = import json_module json key eggs_directory buildout:eggs-directory key develop_eggs_directory buildout:develop-eggs-directory key slap_software_type instance-parameter:slap-software-type key slapparameter_dict instance-parameter:configuration section directory directory $${:extra-context} [dynamic-template-default-vh] < = jinja2-template-base template = ${template-default-virtualhost:target} rendered = $${apache-directory:slave-configuration}/000.conf extensions = jinja2.ext.do extra-context = key http_port instance-parameter:configuration.plain_http_port key https_port instance-parameter:configuration.port [software-release-path] template-empty = ${template-empty:target} template-slave-configuration = ${template-slave-configuration:target} template-default-slave-virtualhost = ${template-default-slave-virtualhost:target} template-cached-slave-virtualhost = ${template-cached-slave-virtualhost:target} template-nginx-eventsource-slave-virtualhost = ${template-nginx-eventsource-slave-virtualhost:target} template-nginx-notebook-slave-virtualhost = ${template-nginx-notebook-slave-virtualhost:target} apache-location = ${apache:location} [dynamic-custom-personal-template-slave-list] < = jinja2-template-base template = ${template-slave-list:target} filename = custom-personal-instance-slave-list.cfg extensions = jinja2.ext.do extra-context = key apache_configuration_directory apache-directory:slave-configuration key nginx_configuration_directory apache-directory:nginx-slave-configuration key apache_cached_configuration_directory apache-directory:slave-with-cache-configuration key slave_with_cache_configuration_directory apache-directory:slave-with-cache-configuration key cached_port apache-configuration:cache-through-port key ssl_cached_port apache-configuration:ssl-cache-through-port key http_port instance-parameter:configuration.plain_http_port key https_port instance-parameter:configuration.port key nginx_http_port instance-parameter:configuration.plain_nginx_port key nginx_https_port instance-parameter:configuration.nginx_port key public_ipv4 instance-parameter:configuration.public-ipv4 key slave_instance_list instance-parameter:slave-instance-list key extra_slave_instance_list instance-parameter:configuration.extra_slave_instance_list key custom_ssl_directory apache-directory:vh-ssl key apache_log_directory apache-directory:slave-log key local_ipv4 instance-parameter:ipv4-random key global_ipv6 slap-network-information:global-ipv6 key cache_port apache-configuration:cache-port 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 raw software_type single-custom-personal section logrotate_dict logrotate section frontend_configuration frontend-configuration section apache_configuration apache-configuration section nginx_configuration nginx-configuration key monitor_base_url monitor-instance-parameter:monitor-base-url [dynamic-virtualhost-template-slave] <= jinja2-template-base template = ${template-slave-configuration:target} rendered = $${directory:template}/slave-virtualhost.conf.in extensions = jinja2.ext.do extra-context = key https_port instance-parameter:configuration.port key http_port instance-parameter:configuration.plain_http_port key apache_custom_https instance-parameter:configuration.apache_custom_https key apache_custom_http instance-parameter:configuration.apache_custom_http # Deploy Apache Frontend (new way, no recipe, jinja power) [dynamic-apache-frontend-template] < = jinja2-template-base template = ${template-apache-frontend-configuration:target} rendered = $${apache-configuration:frontend-configuration} extra-context = key httpd_home software-release-path:apache-location key httpd_mod_ssl_cache_directory apache-directory:mod-ssl key domain instance-parameter:configuration.domain key document_root apache-directory:document-root key instance_home buildout:directory key ipv4_addr instance-parameter:ipv4-random key ipv6_addr instance-parameter:ipv6-random key http_port instance-parameter:configuration.plain_http_port key https_port instance-parameter:configuration.port key server_admin instance-parameter:configuration.server-admin key protected_path apache-configuration:protected-path key access_control_string apache-configuration:access-control-string 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 apache-configuration:access-log key error_log apache-configuration:error-log key pid_file apache-configuration:pid-file key slave_configuration_directory apache-directory:slave-configuration key cached_port apache-configuration:cache-through-port key ssl_cached_port apache-configuration:ssl-cache-through-port key slave_with_cache_configuration_directory apache-directory:slave-with-cache-configuration section frontend_configuration frontend-configuration [apache-frontend] recipe = slapos.cookbook:wrapper command-line = ${apache:location}/bin/httpd -f $${dynamic-apache-frontend-template:rendered} -DFOREGROUND wrapper-path = $${directory:service}/frontend_apache wait-for-files = $${ca-frontend:cert-file} $${ca-frontend:key-file} [not-found-html] recipe = slapos.cookbook:symbolic.link target-directory = $${apache-directory:document-root} link-binary = ${template-not-found-html:target} [apache-directory] recipe = slapos.cookbook:mkdirectory document-root = $${directory:srv}/htdocs slave-configuration = $${directory:etc}/apache-slave-conf.d/ slave-with-cache-configuration = $${directory:etc}/apache-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/ [apache-configuration] frontend-configuration = $${directory:etc}/apache_frontend.conf access-log = $${directory:log}/frontend-apache-access.log error-log = $${directory:log}/frontend-apache-error.log pid-file = $${directory:run}/httpd.pid protected-path = / access-control-string = none frontend-configuration-verification = ${apache:location}/bin/httpd -Sf $${:frontend-configuration} > /dev/null frontend-graceful-command = $${:frontend-configuration-verification}; if [ $? -eq 0 ]; then kill -USR1 $(cat $${:pid-file}); fi # Comunication with ats cache-port = $${trafficserver-variable:input-port} cache-through-port = 26011 ssl-cache-through-port = 26012 # Create wrapper for "apachectl conftest" in bin [configtest] recipe = slapos.cookbook:wrapper command-line = ${apache:location}/bin/httpd -f $${directory:etc}/apache_frontend.conf -t wrapper-path = $${directory:bin}/apache-configtest [certificate-authority] recipe = slapos.cookbook:certificate_authority openssl-binary = ${openssl:location}/bin/openssl ca-dir = $${directory:ca-dir} requests-directory = $${cadirectory:requests} wrapper = $${directory:service}/certificate_authority 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-frontend] <= certificate-authority recipe = slapos.cookbook:certificate_authority.request key-file = $${cadirectory:certs}/apache_frontend.key cert-file = $${cadirectory:certs}/apache_frontend.crt executable = $${directory:service}/frontend_apache wrapper = $${directory:service}/frontend_apache key-content = $${instance-parameter:configuration.apache-key} cert-content = $${instance-parameter:configuration.apache-certificate} # Put domain name name = $${instance-parameter:configuration.domain} [ca-custom-frontend] < = jinja2-template-base template = ${template-empty:target} rendered = $${cadirectory:certs}/apache_frontend.ca.crt extra-context = key content instance-parameter:configuration.apache-ca-certificate [cron] recipe = slapos.cookbook:cron dcrond-binary = ${dcron:location}/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 = ${logrotate:location}/usr/sbin/logrotate gzip-binary = ${gzip:location}/bin/gzip gunzip-binary = ${gzip:location}/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-apache] <= logrotate recipe = slapos.cookbook:logrotate.d name = apache log = $${apache-configuration:error-log} $${apache-configuration:access-log} frequency = daily rotatep-num = 30 post = $${apache-configuration:frontend-graceful-command} sharedscripts = true notifempty = true create = true [logrotate-entry-nginx] <= logrotate recipe = slapos.cookbook:logrotate.d name = apache-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 = ${trafficserver:location}/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 = $${instance-parameter:configuration.frontend-name} remap = map /HTTPS/ http://$${instance-parameter:ipv4-random}:$${apache-configuration:ssl-cache-through-port} map / http://$${instance-parameter:ipv4-random}:$${apache-configuration:cache-through-port} plugin-config = ${trafficserver:location}/libexec/trafficserver/rfc5861.so cache-path = $${trafficserver-directory:cache-path} disk-cache-size = $${instance-parameter:configuration.disk-cache-size} autoconf-port = $${instance-parameter:configuration.trafficserver-autoconf-port} mgmt-port = $${instance-parameter:configuration.trafficserver-mgmt-port} ram-cache-size = $${instance-parameter:configuration.ram-cache-size} [trafficserver-configuration-directory] recipe = plone.recipe.command command = cp -rn ${trafficserver:location}/etc/trafficserver/* $${:target} target = $${trafficserver-directory:configuration} [trafficserver-launcher] recipe = slapos.cookbook:wrapper command-line = ${trafficserver:location}/bin/traffic_cop wrapper-path = $${trafficserver-variable:wrapper-path} environment = TS_ROOT=$${buildout:directory} [trafficserver-reload] recipe = slapos.cookbook:wrapper command-line = ${trafficserver:location}/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 = ${template-trafficserver-records-config:location}/${template-trafficserver-records-config:filename} filename = records.config extra-context = import os_module os [trafficserver-storage-config] < = trafficserver-jinja2-template-base template = ${template-trafficserver-storage-config:location}/${template-trafficserver-storage-config:filename} filename = storage.config [trafficserver-remap-config] < = trafficserver-jinja2-template-base template = ${template-empty:target} filename = remap.config context = key content trafficserver-variable:remap [trafficserver-plugin-config] < = trafficserver-jinja2-template-base template = ${template-empty:target} 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 = ${trafficserver:location}/bin/traffic_line wrapper-path = $${directory:bin}/traffic_line environment = TS_ROOT=$${buildout:directory} parameters-extra = true [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 ### Apaches Graceful and promises [frontend-apache-graceful] < = jinja2-template-base template = ${template-wrapper:output} rendered = $${directory:etc-run}/frontend-apache-safe-graceful mode = 0700 extra-context = key content apache-configuration:frontend-graceful-command # Promises checking configuration: [promise-frontend-apache-configuration] < = jinja2-template-base template = ${template-wrapper:output} rendered = $${directory:promise}/frontend-apache-configuration-promise mode = 0700 extra-context = key content apache-configuration:frontend-configuration-verification [promise-apache-frontend-v4-https] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_frontend_ipv4_https hostname = $${instance-parameter:ipv4-random} port = $${instance-parameter:configuration.port} [promise-apache-frontend-v4-http] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_frontend_ipv4_http hostname = $${instance-parameter:ipv4-random} port = $${instance-parameter:configuration.plain_http_port} [promise-apache-frontend-v6-https] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_frontend_ipv6_https hostname = $${instance-parameter:ipv6-random} port = $${instance-parameter:configuration.port} [promise-apache-frontend-v6-http] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_frontend_ipv6_http hostname = $${instance-parameter:ipv6-random} port = $${instance-parameter:configuration.plain_http_port} [promise-apache-frontend-cached] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_cached hostname = $${instance-parameter:ipv4-random} port = $${apache-configuration:cache-through-port} [promise-apache-frontend-ssl-cached] recipe = slapos.cookbook:check_port_listening path = $${directory:promise}/apache_ssl_cached hostname = $${instance-parameter:ipv4-random} port = $${apache-configuration:ssl-cache-through-port} [slap_connection] # Kept for backward compatiblity computer_id = $${slap-connection:computer-id} partition_id = $${slap-connection:partition-id} server_url = $${slap-connection:server-url} software_release_url = $${slap-connection:software-release-url} key_file = $${slap-connection:key-file} cert_file = $${slap-connection:cert-file} [slap-parameter] # Define default parameter(s) that will be used later, in case user didn't # specify it # All parameters are available through the configuration.XX syntax. # All possible parameters should have a default. domain = example.org public-ipv4 = port = 4443 plain_http_port = 8080 server-admin = admin@example.com apache_custom_https = "" apache_custom_http = "" apache-key = apache-certificate = open-port = 80 443 extra_slave_instance_list = frontend-name = monitor-cors-domains = monitor-httpd-port = 8072 monitor-username = $${monitor-htpasswd:username} monitor-password = $${monitor-htpasswd:passwd} ####### # Monitoring sections # [monitor-instance-parameter] monitor-httpd-port = $${slap-parameter:monitor-httpd-port} cors-domains = $${slap-parameter:monitor-cors-domains} username = $${slap-parameter:monitor-username} password = $${slap-parameter:monitor-password} [monitor-conf-parameters] private-path-list += $${directory:logrotate-backup} # Produce ATS Cache stats [monitor-ats-cache-stats-wrapper] < = jinja2-template-base template = ${template-wrapper:output} rendered = $${monitor-directory:reports}/ats-cache-stats mode = 0700 command = export TS_ROOT=$${buildout:directory} && echo "<pre>$(${trafficserver:location}/bin/traffic_shell $${monitor-ats-cache-stats-config:rendered})</pre>" extra-context = key content monitor-ats-cache-stats-wrapper:command [monitor-ats-cache-stats-config] < = jinja2-template-base template = ${template-empty:target} 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 = $${instance-parameter:configuration.re6st-verification-url} dash_path = ${dash:location}/bin/dash curl_path = ${curl:location}/bin/curl ####################### # Nginx # [nginx-frontend] recipe = slapos.cookbook:wrapper command-line = ${nginx-push-stream:location}/sbin/nginx -c $${nginx-configuration:output} wrapper-path = $${directory:service}/frontend_nginx [nginx-configuration] recipe = slapos.recipe.template url = ${template-nginx-configuration:output} output = $${directory:etc}/nginx.cfg mode = 0600 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 = $${instance-parameter:configuration.nginx_port} plain_port = $${instance-parameter:configuration.plain_nginx_port} worker_processes = 4 worker_connections = 1024 slave-configuration-directory = $${apache-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-push-stream:location}/sbin/nginx -t -c $${nginx-configuration:output} [frontend-nginx-graceful] < = jinja2-template-base template = ${template-wrapper:output} rendered = $${directory:etc-run}/frontend-nginx-safe-graceful mode = 0700 extra-context = key content nginx-configuration:nginx-graceful-command [promise-nginx-configuration] < = jinja2-template-base template = ${template-wrapper:output} 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 = $${instance-parameter: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 = $${instance-parameter: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 = $${instance-parameter: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 = $${instance-parameter:configuration.plain_nginx_port}