#!/bin/bash exname=$(basename $0) compose_core=$(which compose-core) || { echo "Requires compose-core executable to be in \$PATH." >&2 exit 1 } fetch-def() { local path="$1" fname="$2" ( . "$path" 1>&2 || { echo "Failed to load '$path'." >&2 exit 1 } declare -f "$fname" ) } prefix_cmd=" . /etc/shlib include common include parse . ../lib/common $(fetch-def "$compose_core" yaml_get_values) $(fetch-def "$compose_core" yaml_get_interpret) " || { echo "Couldn't build prefix cmd" >&2 exit 1 } ## ## Mocks ## relation-get() { local key="$1" echo "$CFG" | shyaml get-value "$key" 2>/dev/null } export -f relation-get export RELATION_DATA_FILE=x relation-set() { local key="$1" value="$2" echo "relation-set $key:" >&2 echo "$value" | prefix " | " >&2 } export -f relation-set cfg-get-value() { local key="$1" shyaml get-value "$key" 2>/dev/null } export -f cfg-get-value get_service_relations() { printf "%s\0" "${RELATIONS[@]}" } export -f get_service_relations file_put() { echo "file_put $1" cat - | prefix " | " } export -f file_put docker() { echo "docker" "$@" echo stdin: cat - | prefix " | " } export -f docker config-add() { echo "config-add" echo "$1" | prefix " | " } export -f config-add init-config-add() { echo "init-config-add" echo "$1" | prefix " | " } export -f init-config-add mkdir() { echo "called: $FUNCNAME $@" >&2 } export -f mkdir setfacl() { echo "called: $FUNCNAME $@" >&2 } export -f setfacl chgrp() { echo "called: $FUNCNAME $@" >&2 } export -f chgrp chmod() { echo "called: $FUNCNAME $@" >&2 } export -f chmod merge_yaml_str() { local arg_hash="$(H "$@" | cut -c -16)" local i echo "Calling: merge_yaml_str" >&2 ((i=0)) for arg in "$@"; do echo " arg$((i++)):" echo "$arg" | prefix " | " done >&2 echo " H> $arg_hash" >&2 while read-0 h res; do if [[ "$arg_hash" == "$h" ]]; then echo "Mock hash matched, returning:" >&2 echo "$res" | prefix " | " >&2 echo "$res" return 0 fi done < <(e "$MERGE_YAML_STR" | shyaml key-values-0) printf "<merge_yaml_str(" printf "'%s', " "$@" printf ")>" } export -f merge_yaml_str yaml_get_interpret() { shyaml get-value } export -f yaml_get_interpret yaml_key_val_str() { printf "%s: %s" "$1" "$2" } export -f yaml_key_val_str cached_cmd_on_base_image() { echo "called: $FUNCNAME $@" >&2 echo "stdout:" >&2 echo "<GID>" | prefix " | " >&2 echo "<GID>" } export -f cached_cmd_on_base_image export state_tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX) trap "rm -rf \"$state_tmpdir\"" EXIT ## ## apache_vhost_create ## try " export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' apache_vhost_create publish_dir ' domain: www.example.com '" is errlvl 0 is err part "\ relation-set url: | http://www.example.com" is out reg '^file_put \$SERVICE_CONFIGSTORE/.*/www.example.com.conf' try " export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' CFG=' domain: www.example.com ssl: true ' ADDITION=' apache-custom-rules: - | ## Auto-redirection from http to https RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]' MERGE_YAML_STR=\" 6b92a84e9d93e4a1: | \$(echo \"\$CFG\" | prefix ' ') \$(echo \"\$ADDITION\" | prefix ' ') \" apache_vhost_create publish_dir \"\$CFG\" " is errlvl 0 is err part "## Auto-redirection from http to https" is err part "\ relation-set url: | https://www.example.com" is out reg '^file_put \$SERVICE_CONFIGSTORE/.*/www.example.com.conf' try " export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' CFG=' domain: www.example.com ssl: key: | a b cert: c ' ADDITION=' apache-custom-rules: - | ## Auto-redirection from http to https RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]' MERGE_YAML_STR=\" 3b76349cfba9d3f2: | \$(echo \"\$CFG\" | prefix ' ') \$(echo \"\$ADDITION\" | prefix ' ') \" apache_vhost_create publish_dir \"\$CFG\" " is errlvl 0 is err part "## Auto-redirection from http to https" is err part "\ relation-set url: | https://www.example.com" is out part 'file_put $CONFIGSTORE/$BASE_SERVICE_NAME/etc/ssl/certs/www.example.com.pem | c' is out part 'file_put $CONFIGSTORE/$BASE_SERVICE_NAME/etc/ssl/private/www.example.com.key | a | b' is out reg 'init-config-add' is out reg ' - \$CONFIGSTORE/\$BASE_SERVICE_NAME/etc/ssl/certs/www.example.com.pem:/etc/ssl/certs/www.example.com.pem:ro' is out reg ' - \$CONFIGSTORE/\$BASE_SERVICE_NAME/etc/ssl/private/www.example.com.key:/etc/ssl/private/www.example.com.key:ro' try " export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' CFG=' domain: www.example.com creds: toto: xxx ' apache_vhost_create publish_dir \"\$CFG\" " is errlvl 0 is err part "\ relation-set url: | http://www.example.com" is out reg "htpasswd -bc '/etc/apache2/sites-enabled/www.example.com.passwd' 'toto' 'xxx'" is out reg 'docker run -i --entrypoint /bin/bash .* docker/apache' ## XXXvlab: we don't need this feature anymore it seems # try " # export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' # apache_vhost_create publish_dir '' ',http,' '000-default'" # is errlvl 0 # is err part "\ # relation-set url: # | http://" ## XXXvlab: this isn't right, is it ? # is out reg '^file_put \$SERVICE_CONFIGSTORE/.*/000-default.conf' ## ## apache_publish_dir ## try " export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_publish_dir ' creds: toto: xxx '" "missing domain" is errlvl 1 ## no domain try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_publish_dir ' domain: www.example.com creds: toto: xxx ' " is errlvl 0 is err reg 'setfacl -R -m g:<GID>:rx \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com' is err reg 'cached_cmd_on_base_image apache id -g www-data' try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_publish_dir ' domain: www.example.com creds: toto: xxx data-dirs: - a - b - c ' " is errlvl 0 is err reg 'setfacl -R -m g:<GID>:rwx \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/a \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/b \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/c' is err reg 'setfacl -R -d -m g:<GID>:rwx \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/a \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/b \$DATASTORE/\$BASE_SERVICE_NAME/var/www/www.example.com/c' try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export SERVICE_NAME='\$SERVICE_NAME' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_BASE_SERVICE_NAME='\$MASTER_BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_publish_dir ' domain: www.example.com location: /opt/apps/newlocation creds: toto: xxx data-dirs: - a - b - c ' " is errlvl 0 is err reg 'mkdir -p /opt/apps/newlocation' is err reg 'setfacl -R -m g:<GID>:rx /opt/apps/newlocation' is out part ' init-config-add | | $SERVICE_NAME: | volumes: | - /opt/apps/newlocation:/var/www/www.example.com' RTRIM try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_BASE_SERVICE_NAME='\$MASTER_BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_ssh_tunnel ' domain: www.example.com creds: toto: xxx ' " "ssh tunnel without ssl" is errlvl 1 is err 'Error: ssl must be valued in ssh-tunnel config. ' is out '' try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_BASE_SERVICE_NAME='\$MASTER_BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_ssh_tunnel ' ssl: true creds: toto: xxx ' " "ssh tunnel without domain" is errlvl 1 is err 'Error: domain must be valued in ssh-tunnel config. ' is out '' try " export DATASTORE='\$DATASTORE' export DOCKER_BASE_IMAGE=docker/apache export SERVICE_CONFIGSTORE='\$SERVICE_CONFIGSTORE' export CONFIGSTORE='\$CONFIGSTORE' export BASE_SERVICE_NAME='\$BASE_SERVICE_NAME' export MASTER_BASE_SERVICE_NAME='\$MASTER_BASE_SERVICE_NAME' export MASTER_TARGET_SERVICE_NAME='\$MASTER_TARGET_SERVICE_NAME' apache_ssh_tunnel ' domain: ssh.example.com ssl: key: a ca-cert: b creds: toto: xxx ' " "ssh tunnel" is errlvl 0 is err reg 'relation-set domain: | ssh.example.com' is out reg 'file_put \$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled/000-ssh.example.com.conf' is out reg 'file_put \$CONFIGSTORE/\$BASE_SERVICE_NAME/etc/ssl/private/ssh.example.com.key' is out reg 'file_put \$CONFIGSTORE/\$BASE_SERVICE_NAME/etc/ssl/certs/ssh.example.com-ca.pem' is out reg 'AuthUserFile /etc/apache2/sites-enabled/ssh.example.com.passwd' is out reg "htpasswd -bc '/etc/apache2/sites-enabled/000-ssh.example.com.passwd' 'toto' 'xxx'"