|
@ -1,10 +1,10 @@ |
|
|
# -*- mode: shell-script -*- |
|
|
# -*- mode: shell-script -*- |
|
|
|
|
|
|
|
|
config_hash= |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_domain() { |
|
|
|
|
|
local cfg="$1" |
|
|
|
|
|
|
|
|
get_domain () { |
|
|
|
|
|
relation-get domain 2>/dev/null && return 0 |
|
|
|
|
|
|
|
|
e "$cfg" | cfg-get-value domain 2>/dev/null && return 0 |
|
|
|
|
|
|
|
|
## is service name a regex ? |
|
|
## is service name a regex ? |
|
|
if [[ "$BASE_SERVICE_NAME" =~ ^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$ ]]; then |
|
|
if [[ "$BASE_SERVICE_NAME" =~ ^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$ ]]; then |
|
@ -12,64 +12,71 @@ get_domain () { |
|
|
return 0 |
|
|
return 0 |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
err "You must specify a ${WHITE}domain$NORMAL option in relation." |
|
|
|
|
|
|
|
|
err "You must specify a ${WHITE}domain$NORMAL option in relation. (${FUNCNAME[@]})" |
|
|
return 1 |
|
|
return 1 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
apache_proxy_dir () { |
|
|
|
|
|
DOMAIN=$(get_domain) || return 1 |
|
|
|
|
|
relation-set domain "$DOMAIN" |
|
|
|
|
|
proxy=yes apache_vhost_create || return 1 |
|
|
|
|
|
info "Added $DOMAIN as a proxy to $TARGET." |
|
|
|
|
|
} |
|
|
|
|
|
export -f apache_proxy_dir |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## |
|
|
|
|
|
## Master entrypoints |
|
|
|
|
|
## |
|
|
|
|
|
|
|
|
apache_publish_dir () { |
|
|
|
|
|
DOMAIN=$(get_domain) || return 1 |
|
|
|
|
|
relation-set domain "$DOMAIN" |
|
|
|
|
|
DOCKER_SITE_PATH="/var/www/${DOMAIN}" |
|
|
|
|
|
LOCATION=$(relation-get location 2>/dev/null) || |
|
|
|
|
|
LOCATION="$DATASTORE/$BASE_SERVICE_NAME$DOCKER_SITE_PATH" |
|
|
|
|
|
|
|
|
apache_proxy_dir() { |
|
|
|
|
|
local cfg="$1" domain |
|
|
|
|
|
apache_vhost_create web_proxy "$cfg" || return 1 |
|
|
|
|
|
} |
|
|
|
|
|
export -f apache_proxy_dir |
|
|
|
|
|
|
|
|
apache_vhost_create || return 1 |
|
|
|
|
|
info "Added $DOMAIN apache config." |
|
|
|
|
|
apache_code_dir || return 1 |
|
|
|
|
|
apache_data_dirs |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apache_publish_dir() { |
|
|
|
|
|
local cfg="$1" domain |
|
|
|
|
|
apache_vhost_create publish_dir "$cfg" || return 1 |
|
|
|
|
|
apache_code_dir "$cfg" || return 1 |
|
|
|
|
|
apache_data_dirs "$cfg" |
|
|
} |
|
|
} |
|
|
export -f apache_publish_dir |
|
|
export -f apache_publish_dir |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apache_vhost_create () { |
|
|
|
|
|
local custom_rules |
|
|
|
|
|
export APACHE_CONFIG_LOCATION="$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled" vhost_statement |
|
|
|
|
|
|
|
|
|
|
|
SERVER_ALIAS=$(relation-get server-aliases 2>/dev/null) || true |
|
|
|
|
|
PROTOCOLS=$(__vhost_cfg_normalize_protocol) || return 1 |
|
|
|
|
|
|
|
|
## |
|
|
|
|
|
## Simple functions |
|
|
|
|
|
## |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export SERVER_ALIAS PROTOCOLS SSL_PLUGIN_FUN SSL_CFG_{VALUE,OPTION} |
|
|
|
|
|
|
|
|
apache_vhost_create() { |
|
|
|
|
|
local type="$1" cfg="$2" custom_rules vhost_statement creds |
|
|
|
|
|
|
|
|
if is_protocol_enabled https; then |
|
|
|
|
|
read-0 SSL_PLUGIN_FUN SSL_CFG_VALUE SSL_CFG_OPTIONS < <(ssl_get_plugin_fun) || return 1 |
|
|
|
|
|
"$SSL_PLUGIN_FUN"_vars "$SSL_CFG_OPTIONS" "$SSL_CFG_VALUE" || return 1 |
|
|
|
|
|
redirect=$(relation-get 'redirect-to-ssl' 2>/dev/null) || true |
|
|
|
|
|
if is_protocol_enabled http; then |
|
|
|
|
|
|
|
|
export APACHE_CONFIG_LOCATION="$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled" |
|
|
|
|
|
|
|
|
|
|
|
protocols=$(__vhost_cfg_normalize_protocol "$cfg") || return 1 |
|
|
|
|
|
|
|
|
|
|
|
if is_protocol_enabled https "$protocols"; then |
|
|
|
|
|
read-0 ssl_plugin_fun ssl_cfg_value ssl_cfg_options < <(ssl_get_plugin_fun "$cfg") || return 1 |
|
|
|
|
|
"$ssl_plugin_fun"_vars "$cfg" "$ssl_cfg_options" "$ssl_cfg_value" || return 1 |
|
|
|
|
|
redirect=$(e "$cfg" | cfg-get-value 'redirect-to-ssl' 2>/dev/null) || true |
|
|
|
|
|
if is_protocol_enabled http "$protocols"; then |
|
|
redirect=${redirect:-true} |
|
|
redirect=${redirect:-true} |
|
|
else |
|
|
else |
|
|
redirect=false |
|
|
redirect=false |
|
|
fi |
|
|
fi |
|
|
if [ "$redirect" == "true" ]; then |
|
|
if [ "$redirect" == "true" ]; then |
|
|
custom_rules=$(_get_custom_rules) || return 1 |
|
|
|
|
|
|
|
|
custom_rules=$(_get_custom_rules "$cfg") || return 1 |
|
|
if [[ "$custom_rules" != *"## Auto-redirection from http to https"* ]]; then |
|
|
if [[ "$custom_rules" != *"## Auto-redirection from http to https"* ]]; then |
|
|
relation-set apache-custom-rules "- | |
|
|
|
|
|
|
|
|
redirect_rule="- | |
|
|
## Auto-redirection from http to https |
|
|
## Auto-redirection from http to https |
|
|
RewriteEngine On |
|
|
RewriteEngine On |
|
|
RewriteCond %{HTTPS} off |
|
|
RewriteCond %{HTTPS} off |
|
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA] |
|
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA] |
|
|
|
|
|
" |
|
|
|
|
|
relation-set apache-custom-rules "$redirect_rule |
|
|
$(if [ "$custom_rules" ]; then |
|
|
$(if [ "$custom_rules" ]; then |
|
|
echo "- |"$'\n'"$(echo "$custom_rules" | prefix " ")" |
|
|
echo "- |"$'\n'"$(echo "$custom_rules" | prefix " ")" |
|
|
fi)" |
|
|
fi)" |
|
|
|
|
|
cfg=$(merge_yaml_str "$cfg" "$(yaml_key_val_str "apache-custom-rules" "$redirect_rule |
|
|
|
|
|
$(if [ "$custom_rules" ]; then |
|
|
|
|
|
echo "- |"$'\n'"$(echo "$custom_rules" | prefix " ")" |
|
|
|
|
|
fi)")") |
|
|
fi |
|
|
fi |
|
|
relation-set protocol https |
|
|
relation-set protocol https |
|
|
else |
|
|
else |
|
@ -80,30 +87,36 @@ $(if [ "$custom_rules" ]; then |
|
|
else |
|
|
else |
|
|
relation-set protocol http |
|
|
relation-set protocol http |
|
|
fi |
|
|
fi |
|
|
vhost_statement=$(apache_vhost_statement "$PROTOCOLS") || return 1 |
|
|
|
|
|
echo "$vhost_statement"| file_put "$APACHE_CONFIG_LOCATION/$prefix$DOMAIN.conf" || return 1 |
|
|
|
|
|
|
|
|
vhost_statement=$(apache_vhost_statement "$type" "$protocols" "$cfg") || { |
|
|
|
|
|
err "Failed to get vhost statement for type $type on ${protocols:1:-1}" |
|
|
|
|
|
return 1 |
|
|
|
|
|
} |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
relation-set domain "$domain" |
|
|
|
|
|
|
|
|
__vhost_cfg_creds_enabled=$(relation-get creds 2>/dev/null) || true |
|
|
|
|
|
if [ "$__vhost_cfg_creds_enabled" ]; then |
|
|
|
|
|
apache_passwd_file || return 1 |
|
|
|
|
|
|
|
|
echo "$vhost_statement"| file_put "$APACHE_CONFIG_LOCATION/$prefix$domain.conf" || return 1 |
|
|
|
|
|
|
|
|
|
|
|
creds=$(e "$cfg" | cfg-get-value creds 2>/dev/null) || true |
|
|
|
|
|
if [ "$creds" ]; then |
|
|
|
|
|
apache_passwd_file "$cfg" || return 1 |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
if is_protocol_enabled https; then |
|
|
|
|
|
"$SSL_PLUGIN_FUN"_prepare "$SSL_CFG_OPTIONS" "$SSL_CFG_VALUE" || return 1 |
|
|
|
|
|
|
|
|
if is_protocol_enabled https "$protocols"; then |
|
|
|
|
|
"$ssl_plugin_fun"_prepare "$cfg" "$ssl_cfg_options" "$ssl_cfg_value" || return 1 |
|
|
fi |
|
|
fi |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
is_protocol_enabled() { |
|
|
is_protocol_enabled() { |
|
|
local protocol=$1 |
|
|
|
|
|
[[ "$PROTOCOLS" == *",$protocol,"* ]] |
|
|
|
|
|
|
|
|
local protocol="$1" protocols="$2" |
|
|
|
|
|
[[ "$protocols" == *",$protocol,"* ]] |
|
|
} |
|
|
} |
|
|
export -f is_protocol_enabled |
|
|
export -f is_protocol_enabled |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_get_ssl_option_value() { |
|
|
_get_ssl_option_value() { |
|
|
local target_relation rn ts rc td |
|
|
|
|
|
relation-get ssl 2>/dev/null && return 0 |
|
|
|
|
|
|
|
|
local cfg="$1" target_relation rn ts rc td |
|
|
|
|
|
e "$cfg" | cfg-get-value ssl 2>/dev/null && return 0 |
|
|
|
|
|
|
|
|
target_relation="cert-provider" |
|
|
target_relation="cert-provider" |
|
|
while read-0 rn ts rc td; do |
|
|
while read-0 rn ts rc td; do |
|
@ -118,19 +131,29 @@ _get_ssl_option_value() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__vhost_cfg_normalize_protocol() { |
|
|
__vhost_cfg_normalize_protocol() { |
|
|
local protocol |
|
|
|
|
|
|
|
|
|
|
|
if ! protocol=$(relation-get protocol 2>/dev/null); then |
|
|
|
|
|
protocol=auto |
|
|
|
|
|
else |
|
|
|
|
|
|
|
|
local cfg="$1" protocol |
|
|
|
|
|
## XXXvlab: can't cache if libcharm is not able to give me some checksums |
|
|
|
|
|
## indeed, ``_get_ssl_option_value`` depends on relations calculations... |
|
|
|
|
|
|
|
|
|
|
|
# local cfg="$1" cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" | md5_compat)" \ |
|
|
|
|
|
# protocol |
|
|
|
|
|
# if [ -e "$cache_file" ]; then |
|
|
|
|
|
# #debug "$FUNCNAME: STATIC cache hit $1" |
|
|
|
|
|
# cat "$cache_file" && |
|
|
|
|
|
# touch "$cache_file" || return 1 |
|
|
|
|
|
# return 0 |
|
|
|
|
|
# fi |
|
|
|
|
|
|
|
|
|
|
|
if protocol=$(e "$cfg" | cfg-get-value protocol 2>/dev/null); then |
|
|
protocol=${protocol:-auto} |
|
|
protocol=${protocol:-auto} |
|
|
|
|
|
else |
|
|
|
|
|
protocol=auto |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
case "$protocol" in |
|
|
case "$protocol" in |
|
|
auto) |
|
|
auto) |
|
|
if __vhost_cfg_ssl="$(_get_ssl_option_value)"; then |
|
|
|
|
|
|
|
|
if _get_ssl_option_value "$cfg" >/dev/null 2>&1; then |
|
|
protocol="http,https" |
|
|
protocol="http,https" |
|
|
export __vhost_cfg_ssl |
|
|
|
|
|
else |
|
|
else |
|
|
protocol="http" |
|
|
protocol="http" |
|
|
fi |
|
|
fi |
|
@ -149,24 +172,22 @@ __vhost_cfg_normalize_protocol() { |
|
|
return 1 |
|
|
return 1 |
|
|
esac |
|
|
esac |
|
|
echo ",$protocol," |
|
|
echo ",$protocol," |
|
|
|
|
|
#| tee "$cache_file" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## ssl_plugin_* and ssl_fallback should : |
|
|
## ssl_plugin_* and ssl_fallback should : |
|
|
## - do anything to ensure that |
|
|
|
|
|
|
|
|
## - do anything to ensure that |
|
|
## - issue config-add to add volumes if necessary |
|
|
## - issue config-add to add volumes if necessary |
|
|
## - output 3 vars of where to find the 3 files from within the docker apache |
|
|
## - output 3 vars of where to find the 3 files from within the docker apache |
|
|
|
|
|
|
|
|
ssl_get_plugin_fun() { |
|
|
ssl_get_plugin_fun() { |
|
|
# from ssl conf, return the function that should manage SSL code creation |
|
|
# from ssl conf, return the function that should manage SSL code creation |
|
|
local cfg type keys |
|
|
|
|
|
cfg=$(_get_ssl_option_value) |
|
|
|
|
|
if [ -z "$cfg" ]; then |
|
|
|
|
|
return 0 |
|
|
|
|
|
else |
|
|
|
|
|
type="$(echo "$cfg" | shyaml -y get-type 2>/dev/null)" || return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
local master_cfg="$1" cfg type keys |
|
|
|
|
|
cfg=$(_get_ssl_option_value "$master_cfg") |
|
|
|
|
|
[ "$cfg" ] || return 0 |
|
|
|
|
|
|
|
|
|
|
|
type="$(echo "$cfg" | shyaml -y get-type 2>/dev/null)" || return 1 |
|
|
if [[ "$type" == "bool" ]]; then |
|
|
if [[ "$type" == "bool" ]]; then |
|
|
printf "%s\0" "ssl_fallback" "" "$cfg" |
|
|
printf "%s\0" "ssl_fallback" "" "$cfg" |
|
|
echo ssl_fallback |
|
|
echo ssl_fallback |
|
@ -216,18 +237,19 @@ ssl_get_plugin_fun() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ssl_fallback_vars() { |
|
|
ssl_fallback_vars() { |
|
|
local cfg="$1" cert key ca_cert |
|
|
|
|
|
|
|
|
local cfg="$1" ssl_cfg="$2" cert key ca_cert domain |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_cert=$(echo "$cfg" | shyaml get-value cert 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}.pem |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_cert=$(echo "$ssl_cfg" | shyaml get-value cert 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_CERT_LOCATION=/etc/ssl/certs/${domain}.pem |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_key=$(echo "$cfg" | shyaml get-value key 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_KEY_LOCATION=/etc/ssl/private/${DOMAIN}.key |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_key=$(echo "$ssl_cfg" | shyaml get-value key 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_KEY_LOCATION=/etc/ssl/private/${domain}.key |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_ca_cert=$(echo "$cfg" | shyaml get-value ca-cert 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_CA_CERT_LOCATION=/etc/ssl/certs/${DOMAIN}-ca.pem |
|
|
|
|
|
|
|
|
if __vhost_cfg_ssl_ca_cert=$(echo "$ssl_cfg" | shyaml get-value ca-cert 2>/dev/null); then |
|
|
|
|
|
__vhost_cfg_SSL_CA_CERT_LOCATION=/etc/ssl/certs/${domain}-ca.pem |
|
|
fi |
|
|
fi |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -259,19 +281,30 @@ $volumes |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ssl_plugin_cert-provider_vars() { |
|
|
ssl_plugin_cert-provider_vars() { |
|
|
|
|
|
local cfg="$1" ssl_cfg="$2" |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
|
|
|
__vhost_cfg_SSL_CERT_LOCATION=/etc/letsencrypt/live/${DOMAIN}/cert.pem |
|
|
|
|
|
__vhost_cfg_SSL_KEY_LOCATION=/etc/letsencrypt/live/${DOMAIN}/privkey.pem |
|
|
|
|
|
__vhost_cfg_SSL_CHAIN=/etc/letsencrypt/live/${DOMAIN}/chain.pem |
|
|
|
|
|
|
|
|
__vhost_cfg_SSL_CERT_LOCATION=/etc/letsencrypt/live/${domain}/cert.pem |
|
|
|
|
|
__vhost_cfg_SSL_KEY_LOCATION=/etc/letsencrypt/live/${domain}/privkey.pem |
|
|
|
|
|
__vhost_cfg_SSL_CHAIN=/etc/letsencrypt/live/${domain}/chain.pem |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ssl_plugin_cert-provider_prepare() { |
|
|
ssl_plugin_cert-provider_prepare() { |
|
|
local cfg="$1" service="$2" options |
|
|
|
|
|
|
|
|
local cfg="$1" ssl_cfg="$2" service="$3" options domain server_aliases |
|
|
|
|
|
|
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
|
|
|
options=$(yaml_key_val_str "options" "$cfg") || return 1 |
|
|
|
|
|
|
|
|
options=$(yaml_key_val_str "options" "$ssl_cfg") || return 1 |
|
|
service_config=$(yaml_key_val_str "$service" "$options") |
|
|
service_config=$(yaml_key_val_str "$service" "$options") |
|
|
|
|
|
server_aliases=$(e "$cfg" | cfg-get-value server-aliases 2>/dev/null) || true |
|
|
|
|
|
[ "$server_aliases" == None ] && server_aliases="" |
|
|
|
|
|
if [ "$server_aliases" ]; then |
|
|
|
|
|
server_aliases=($(echo "$server_aliases" | shyaml get-values)) || return 1 |
|
|
|
|
|
else |
|
|
|
|
|
server_aliases=() |
|
|
|
|
|
fi |
|
|
compose --debug --add-compose-content "$service_config" run --rm --service-ports "$service" \ |
|
|
compose --debug --add-compose-content "$service_config" run --rm --service-ports "$service" \ |
|
|
crt create "$DOMAIN" $(echo "$SERVER_ALIAS" | shyaml get-values 2>/dev/null) || { |
|
|
|
|
|
|
|
|
crt create "$domain" "${server_aliases[@]}" || { |
|
|
err "Failed to launch letsencrypt for certificate creation." |
|
|
err "Failed to launch letsencrypt for certificate creation." |
|
|
return 1 |
|
|
return 1 |
|
|
} |
|
|
} |
|
@ -286,22 +319,24 @@ services: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apache_passwd_file() { |
|
|
apache_passwd_file() { |
|
|
|
|
|
local cfg="$1" creds |
|
|
include parse || true |
|
|
include parse || true |
|
|
|
|
|
|
|
|
## XXXvlab: called twice... no better way to do this ? |
|
|
## XXXvlab: called twice... no better way to do this ? |
|
|
__vhost_creds_statement >/dev/null |
|
|
|
|
|
|
|
|
creds=$(e "$cfg" | cfg-get-value creds 2>/dev/null) || true |
|
|
|
|
|
password_path=$(password-path-get "$cfg") |
|
|
first= |
|
|
first= |
|
|
if ! [ -e "$CONFIGSTORE/$MASTER_TARGET_SERVICE_NAME$password_file" ]; then |
|
|
|
|
|
debug "No file $CONFIGSTORE/$MASTER_TARGET_SERVICE_NAME$password_file, creating password file." || true |
|
|
|
|
|
|
|
|
if ! [ -e "$CONFIGSTORE/$MASTER_TARGET_SERVICE_NAME$password_path" ]; then |
|
|
|
|
|
debug "No file $CONFIGSTORE/$MASTER_TARGET_SERVICE_NAME$password_path, creating password file." || true |
|
|
first=c |
|
|
first=c |
|
|
fi |
|
|
fi |
|
|
while read-0 login password; do |
|
|
while read-0 login password; do |
|
|
debug "htpasswd -b$first '${password_file}' '$login' '$password'" |
|
|
|
|
|
echo "htpasswd -b$first '${password_file}' '$login' '$password'" |
|
|
|
|
|
|
|
|
debug "htpasswd -b$first '${password_path}' '$login' '$password'" |
|
|
|
|
|
echo "htpasswd -b$first '${password_path}' '$login' '$password'" |
|
|
if [ "$first" ]; then |
|
|
if [ "$first" ]; then |
|
|
first= |
|
|
first= |
|
|
fi |
|
|
fi |
|
|
done < <(echo "$__vhost_cfg_creds_enabled" | shyaml key-values-0 2>/dev/null) | |
|
|
|
|
|
|
|
|
done < <(e "$creds" | shyaml key-values-0 2>/dev/null) | |
|
|
docker run -i --entrypoint "/bin/bash" \ |
|
|
docker run -i --entrypoint "/bin/bash" \ |
|
|
-v "$APACHE_CONFIG_LOCATION:/etc/apache2/sites-enabled" \ |
|
|
-v "$APACHE_CONFIG_LOCATION:/etc/apache2/sites-enabled" \ |
|
|
"$DOCKER_BASE_IMAGE" || return 1 |
|
|
"$DOCKER_BASE_IMAGE" || return 1 |
|
@ -309,16 +344,16 @@ apache_passwd_file() { |
|
|
|
|
|
|
|
|
## Produce the full statements depending on relation-get informations |
|
|
## Produce the full statements depending on relation-get informations |
|
|
apache_vhost_statement() { |
|
|
apache_vhost_statement() { |
|
|
local vhost_statement |
|
|
|
|
|
export SERVER_ALIAS=$(relation-get server-aliases 2>/dev/null) || true |
|
|
|
|
|
export PROTOCOLS="$1" |
|
|
|
|
|
|
|
|
local type="$1" protocols="$2" cfg="$3" \ |
|
|
|
|
|
vhost_statement |
|
|
|
|
|
|
|
|
if is_protocol_enabled http; then |
|
|
|
|
|
__vhost_full_vhost_statement http || return 1 |
|
|
|
|
|
|
|
|
if is_protocol_enabled http "$protocols"; then |
|
|
|
|
|
__vhost_full_vhost_statement "$type" http "$cfg" || return 1 |
|
|
fi |
|
|
fi |
|
|
if is_protocol_enabled https; then |
|
|
|
|
|
"$SSL_PLUGIN_FUN"_vars "$(_get_ssl_option_value 2>/dev/null)" || return 1 |
|
|
|
|
|
vhost_statement=$(__vhost_full_vhost_statement https) || return 1 |
|
|
|
|
|
|
|
|
if is_protocol_enabled https "$protocols"; then |
|
|
|
|
|
read-0 ssl_plugin_fun ssl_cfg_value ssl_cfg_options < <(ssl_get_plugin_fun "$cfg") || return 1 |
|
|
|
|
|
"$ssl_plugin_fun"_vars "$cfg" "$ssl_cfg_options" "$ssl_cfg_value" || return 1 |
|
|
|
|
|
vhost_statement=$(__vhost_full_vhost_statement "$type" https "$cfg") || return 1 |
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
|
|
|
|
|
|
<IfModule mod_ssl.c> |
|
|
<IfModule mod_ssl.c> |
|
@ -331,37 +366,42 @@ export -f apache_vhost_statement |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apache_code_dir() { |
|
|
apache_code_dir() { |
|
|
local www_data_gid |
|
|
|
|
|
|
|
|
local cfg="$1" www_data_gid local_path |
|
|
www_data_gid=$(cached_cmd_on_base_image apache 'id -g www-data') || { |
|
|
www_data_gid=$(cached_cmd_on_base_image apache 'id -g www-data') || { |
|
|
debug "Failed to query for www-data gid in ${DARKYELLOW}apache${NORMAL} base image." |
|
|
debug "Failed to query for www-data gid in ${DARKYELLOW}apache${NORMAL} base image." |
|
|
return 1 |
|
|
return 1 |
|
|
} |
|
|
} |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
local_path="/var/www/${domain}" |
|
|
|
|
|
host_path=$(e "$cfg" | cfg-get-value location 2>/dev/null) || |
|
|
|
|
|
host_path="$DATASTORE/$BASE_SERVICE_NAME${local_path}" |
|
|
|
|
|
|
|
|
mkdir -p "$LOCATION" || return 1 |
|
|
|
|
|
setfacl -R -m g:"$www_data_gid":rx "$LOCATION" |
|
|
|
|
|
info "Set permission for read and traversal on '$LOCATION'." |
|
|
|
|
|
|
|
|
mkdir -p "$host_path" || return 1 |
|
|
|
|
|
setfacl -R -m g:"$www_data_gid":rx "$host_path" |
|
|
|
|
|
info "Set permission for read and traversal on '$host_path'." |
|
|
|
|
|
|
|
|
config-add " |
|
|
config-add " |
|
|
$MASTER_BASE_SERVICE_NAME: |
|
|
$MASTER_BASE_SERVICE_NAME: |
|
|
volumes: |
|
|
volumes: |
|
|
- $LOCATION:$DOCKER_SITE_PATH |
|
|
|
|
|
|
|
|
- $host_path:$local_path |
|
|
" |
|
|
" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
apache_data_dirs() { |
|
|
apache_data_dirs() { |
|
|
|
|
|
|
|
|
DATA_DIRS=$(relation-get data-dirs 2>/dev/null | shyaml get-values 2>/dev/null) || true |
|
|
|
|
|
if [ -z "$DATA_DIRS" ]; then |
|
|
|
|
|
|
|
|
local cfg="$1" data_dirs dst data dirs |
|
|
|
|
|
data_dirs=$(e "$cfg" | cfg-get-value data-dirs 2>/dev/null | shyaml get-values 2>/dev/null) || true |
|
|
|
|
|
if [ -z "$data_dirs" ]; then |
|
|
return 0 |
|
|
return 0 |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
DST=$DATASTORE/$BASE_SERVICE_NAME$DOCKER_SITE_PATH |
|
|
|
|
|
DATA=() |
|
|
|
|
|
while IFS="," read -ra ADDR; do |
|
|
|
|
|
for dir in "${ADDR[@]}"; do |
|
|
|
|
|
DATA+=($dir) |
|
|
|
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
local_path="/var/www/${domain}" |
|
|
|
|
|
dst=$DATASTORE/$BASE_SERVICE_NAME$local_path |
|
|
|
|
|
data=() |
|
|
|
|
|
while IFS="," read -ra addr; do |
|
|
|
|
|
for dir in "${addr[@]}"; do |
|
|
|
|
|
data+=($dir) |
|
|
done |
|
|
done |
|
|
done <<< "$DATA_DIRS" |
|
|
|
|
|
|
|
|
done <<< "$data_dirs" |
|
|
|
|
|
|
|
|
www_data_gid=$(cached_cmd_on_base_image apache 'id -g www-data') || { |
|
|
www_data_gid=$(cached_cmd_on_base_image apache 'id -g www-data') || { |
|
|
debug "Failed to query for www-data gid in ${DARKYELLOW}apache${NORMAL} base image." |
|
|
debug "Failed to query for www-data gid in ${DARKYELLOW}apache${NORMAL} base image." |
|
@ -370,8 +410,8 @@ apache_data_dirs() { |
|
|
info "www-data gid from ${DARKYELLOW}apache${NORMAL} is '$www_data_gid'" |
|
|
info "www-data gid from ${DARKYELLOW}apache${NORMAL} is '$www_data_gid'" |
|
|
|
|
|
|
|
|
dirs=() |
|
|
dirs=() |
|
|
for d in "${DATA[@]}"; do |
|
|
|
|
|
dirs+=("$DST/$d") |
|
|
|
|
|
|
|
|
for d in "${data[@]}"; do |
|
|
|
|
|
dirs+=("$dst/$d") |
|
|
done |
|
|
done |
|
|
|
|
|
|
|
|
mkdir -p "${dirs[@]}" |
|
|
mkdir -p "${dirs[@]}" |
|
@ -382,8 +422,8 @@ apache_data_dirs() { |
|
|
$MASTER_BASE_SERVICE_NAME: |
|
|
$MASTER_BASE_SERVICE_NAME: |
|
|
volumes: |
|
|
volumes: |
|
|
$( |
|
|
$( |
|
|
for d in "${DATA[@]}"; do |
|
|
|
|
|
echo " - $DST/$d:$DOCKER_SITE_PATH/$d" |
|
|
|
|
|
|
|
|
for d in "${data[@]}"; do |
|
|
|
|
|
echo " - $dst/$d:$local_path/$d" |
|
|
done |
|
|
done |
|
|
)" |
|
|
)" |
|
|
|
|
|
|
|
@ -443,18 +483,24 @@ EOF |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
password-path-get() { |
|
|
|
|
|
local cfg="$1" domain |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
echo /etc/apache2/sites-enabled/${domain}.passwd |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
__vhost_creds_statement() { |
|
|
__vhost_creds_statement() { |
|
|
if ! __vhost_cfg_creds_enabled=$(relation-get creds 2>/dev/null); then |
|
|
|
|
|
|
|
|
local cfg="$1" password_path |
|
|
|
|
|
password_path=$(password-path-get "$cfg") || return 1 |
|
|
|
|
|
if ! e "$cfg" | cfg-get-value creds >/dev/null 2>&1; then |
|
|
echo "Allow from all" |
|
|
echo "Allow from all" |
|
|
return 0 |
|
|
return 0 |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
password_file=/etc/apache2/sites-enabled/${DOMAIN}.passwd |
|
|
|
|
|
|
|
|
|
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
AuthType basic |
|
|
AuthType basic |
|
|
AuthName "private" |
|
|
AuthName "private" |
|
|
AuthUserFile ${password_file} |
|
|
|
|
|
|
|
|
AuthUserFile ${password_path} |
|
|
Require valid-user |
|
|
Require valid-user |
|
|
EOF |
|
|
EOF |
|
|
|
|
|
|
|
@ -462,7 +508,20 @@ EOF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__vhost_head_statement() { |
|
|
__vhost_head_statement() { |
|
|
local protocol="$1" |
|
|
|
|
|
|
|
|
local cfg="$1" protocol="$2" server_aliases admin_mail |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
admin_mail=$(e "$1" | cfg-get-value "admin-mail" 2>/dev/null) || true |
|
|
|
|
|
server_aliases=$(e "$cfg" | cfg-get-value server-aliases 2>/dev/null) || true |
|
|
|
|
|
[ "$server_aliases" == None ] && server_aliases="" |
|
|
|
|
|
if [ "$server_aliases" ]; then |
|
|
|
|
|
server_aliases=($(e "$server_aliases" | shyaml get-values)) || return 1 |
|
|
|
|
|
if [ -z "$domain" ]; then |
|
|
|
|
|
err "You can't specify server aliases if you don't have a domain." |
|
|
|
|
|
return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
|
|
|
server_aliases=() |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
if [ "$protocol" == "https" ]; then |
|
|
if [ "$protocol" == "https" ]; then |
|
|
prefix="s-" |
|
|
prefix="s-" |
|
@ -471,16 +530,17 @@ __vhost_head_statement() { |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
ServerAdmin ${ADMIN_MAIL:-contact@$DOMAIN} |
|
|
|
|
|
ServerName ${DOMAIN} |
|
|
|
|
|
|
|
|
ServerAdmin ${admin_mail:-contact@$domain} |
|
|
|
|
|
ServerName ${domain} |
|
|
$( |
|
|
$( |
|
|
while read-0 alias; do |
|
|
|
|
|
|
|
|
for alias in "${server_aliases[@]}"; do |
|
|
|
|
|
[ "$alias" ] || continue |
|
|
echo "ServerAlias $alias" |
|
|
echo "ServerAlias $alias" |
|
|
done < <(echo "$SERVER_ALIAS" | shyaml get-values-0 2>/dev/null) |
|
|
|
|
|
|
|
|
done |
|
|
) |
|
|
) |
|
|
ServerSignature Off |
|
|
ServerSignature Off |
|
|
CustomLog /var/log/apache2/${prefix}${DOMAIN}_access.log combined |
|
|
|
|
|
ErrorLog /var/log/apache2/${prefix}${DOMAIN}_error.log |
|
|
|
|
|
|
|
|
CustomLog /var/log/apache2/${prefix}${domain}_access.log combined |
|
|
|
|
|
ErrorLog /var/log/apache2/${prefix}${domain}_error.log |
|
|
ErrorLog syslog:local2 |
|
|
ErrorLog syslog:local2 |
|
|
EOF |
|
|
EOF |
|
|
|
|
|
|
|
@ -488,8 +548,8 @@ EOF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_get_custom_rules() { |
|
|
_get_custom_rules() { |
|
|
local custom_rules type elt value first |
|
|
|
|
|
custom_rules=$(relation-get apache-custom-rules 2>/dev/null) || true |
|
|
|
|
|
|
|
|
local cfg="$1" custom_rules type elt value first |
|
|
|
|
|
custom_rules=$(e "$cfg" | cfg-get-value apache-custom-rules 2>/dev/null) || true |
|
|
if [ -z "$custom_rules" ]; then |
|
|
if [ -z "$custom_rules" ]; then |
|
|
return 0 |
|
|
return 0 |
|
|
fi |
|
|
fi |
|
@ -527,8 +587,8 @@ _get_custom_rules() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__vhost_custom_rules() { |
|
|
__vhost_custom_rules() { |
|
|
local custom_rules |
|
|
|
|
|
custom_rules=$(_get_custom_rules) || return 1 |
|
|
|
|
|
|
|
|
local cfg="$1" custom_rules |
|
|
|
|
|
custom_rules=$(_get_custom_rules "$cfg") || return 1 |
|
|
if [ "$custom_rules" ]; then |
|
|
if [ "$custom_rules" ]; then |
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
|
|
|
|
|
@ -545,19 +605,23 @@ EOF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__vhost_content_statement() { |
|
|
__vhost_content_statement() { |
|
|
if [ "$proxy" ]; then |
|
|
|
|
|
__vhost_proxy_statement "$@" || return 1 |
|
|
|
|
|
else |
|
|
|
|
|
__vhost_publish_dir_statement "$@" || return 1 |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
local type="$1" |
|
|
|
|
|
shift |
|
|
|
|
|
case "$type" in |
|
|
|
|
|
"web_proxy") |
|
|
|
|
|
__vhost_proxy_statement "$@" || return 1 |
|
|
|
|
|
;; |
|
|
|
|
|
"publish_dir") |
|
|
|
|
|
__vhost_publish_dir_statement "$@" || return 1 |
|
|
|
|
|
;; |
|
|
|
|
|
esac |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__vhost_proxy_statement() { |
|
|
|
|
|
local protocol="$1" |
|
|
|
|
|
|
|
|
|
|
|
TARGET=$(relation-get target 2>/dev/null) || true |
|
|
|
|
|
if [ -z "$TARGET" ]; then |
|
|
|
|
|
|
|
|
target-get() { |
|
|
|
|
|
local cfg="$1" target first_exposed_port base_image |
|
|
|
|
|
target=$(e "$cfg" | cfg-get-value target 2>/dev/null) || true |
|
|
|
|
|
if [ -z "$target" ]; then |
|
|
## First exposed port: |
|
|
## First exposed port: |
|
|
base_image=$(service_base_docker_image "$BASE_SERVICE_NAME") || return 1 |
|
|
base_image=$(service_base_docker_image "$BASE_SERVICE_NAME") || return 1 |
|
|
if ! docker_has_image "$base_image"; then |
|
|
if ! docker_has_image "$base_image"; then |
|
@ -568,15 +632,22 @@ __vhost_proxy_statement() { |
|
|
err "Failed to get first exposed port of image '$base_image'." |
|
|
err "Failed to get first exposed port of image '$base_image'." |
|
|
return 1 |
|
|
return 1 |
|
|
fi |
|
|
fi |
|
|
TARGET=$MASTER_BASE_SERVICE_NAME:$first_exposed_port |
|
|
|
|
|
info "No target was specified, introspection found: $TARGET" |
|
|
|
|
|
|
|
|
target=$MASTER_BASE_SERVICE_NAME:$first_exposed_port |
|
|
|
|
|
info "No target was specified, introspection found: $target" |
|
|
fi |
|
|
fi |
|
|
|
|
|
echo "$target" |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
__vhost_proxy_statement() { |
|
|
|
|
|
local protocol="$1" cfg="$2" |
|
|
|
|
|
|
|
|
|
|
|
target=$(target-get "$cfg") || return 1 |
|
|
|
|
|
|
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## |
|
|
## |
|
|
## Proxy declaration towards $TARGET |
|
|
|
|
|
|
|
|
## Proxy declaration towards $target |
|
|
## |
|
|
## |
|
|
|
|
|
|
|
|
<IfModule mod_proxy.c> |
|
|
<IfModule mod_proxy.c> |
|
@ -586,9 +657,9 @@ __vhost_proxy_statement() { |
|
|
Allow from all |
|
|
Allow from all |
|
|
</Proxy> |
|
|
</Proxy> |
|
|
ProxyVia On |
|
|
ProxyVia On |
|
|
ProxyPass / http://$TARGET/ retry=0 |
|
|
|
|
|
|
|
|
ProxyPass / http://$target/ retry=0 |
|
|
<Location / > |
|
|
<Location / > |
|
|
$(__vhost_creds_statement | prefix " ") |
|
|
|
|
|
|
|
|
$(__vhost_creds_statement "$cfg" | prefix " ") |
|
|
ProxyPassReverse / |
|
|
ProxyPassReverse / |
|
|
</Location> |
|
|
</Location> |
|
|
$([ "$protocol" == "https" ] && echo " SSLProxyEngine On") |
|
|
$([ "$protocol" == "https" ] && echo " SSLProxyEngine On") |
|
@ -603,11 +674,11 @@ EOF |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__vhost_full_vhost_statement() { |
|
|
__vhost_full_vhost_statement() { |
|
|
local protocol="$1" head_statement custom_rules content_statement |
|
|
|
|
|
|
|
|
local type="$1" protocol="$2" cfg="$3" head_statement custom_rules content_statement |
|
|
|
|
|
|
|
|
head_statement=$(__vhost_head_statement "$protocol") || return 1 |
|
|
|
|
|
custom_rules=$(__vhost_custom_rules) || return 1 |
|
|
|
|
|
content_statement=$(__vhost_content_statement "$protocol") || return 1 |
|
|
|
|
|
|
|
|
head_statement=$(__vhost_head_statement "$cfg" "$protocol") || return 1 |
|
|
|
|
|
custom_rules=$(__vhost_custom_rules "$cfg") || return 1 |
|
|
|
|
|
content_statement=$(__vhost_content_statement "$type" "$protocol" "$cfg") || return 1 |
|
|
|
|
|
|
|
|
case "$protocol" in |
|
|
case "$protocol" in |
|
|
https) |
|
|
https) |
|
@ -637,22 +708,26 @@ EOF |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
__vhost_publish_dir_statement() { |
|
|
__vhost_publish_dir_statement() { |
|
|
|
|
|
local protocol="$1" cfg="$2" |
|
|
|
|
|
domain=$(get_domain "$cfg") || return 1 |
|
|
|
|
|
local_path="/var/www/${domain}" |
|
|
|
|
|
|
|
|
cat <<EOF |
|
|
cat <<EOF |
|
|
## |
|
|
## |
|
|
## Publish directory $DOCKER_SITE_PATH |
|
|
|
|
|
|
|
|
## Publish directory $local_path |
|
|
## |
|
|
## |
|
|
|
|
|
|
|
|
DocumentRoot $DOCKER_SITE_PATH |
|
|
|
|
|
|
|
|
DocumentRoot $local_path |
|
|
|
|
|
|
|
|
<Directory /> |
|
|
<Directory /> |
|
|
Options FollowSymLinks |
|
|
Options FollowSymLinks |
|
|
AllowOverride None |
|
|
AllowOverride None |
|
|
</Directory> |
|
|
</Directory> |
|
|
|
|
|
|
|
|
<Directory $DOCKER_SITE_PATH> |
|
|
|
|
|
|
|
|
<Directory $local_path> |
|
|
Options Indexes FollowSymLinks MultiViews |
|
|
Options Indexes FollowSymLinks MultiViews |
|
|
AllowOverride all |
|
|
AllowOverride all |
|
|
$(__vhost_creds_statement | prefix " ") |
|
|
|
|
|
|
|
|
$(__vhost_creds_statement "$cfg" | prefix " ") |
|
|
</Directory> |
|
|
</Directory> |
|
|
|
|
|
|
|
|
EOF |
|
|
EOF |
|
|