Browse Source

chg: dev: [www] merged with ``apache`` charm for docker.

postgres
Valentin Lab 9 years ago
parent
commit
a10662b40e
  1. 61
      www/actions/load
  2. 44
      www/actions/relations/publish-dir/load-files
  3. 27
      www/build/Dockerfile
  4. 21
      www/build/entrypoint.sh
  5. 1
      www/build/etc/apache2/site-enabled/monitor.formanoo.org.passwd
  6. 50
      www/hooks/init
  7. 49
      www/hooks/log_rotate-relation-joined
  8. 76
      www/hooks/publish_dir-relation-joined
  9. 55
      www/hooks/web_proxy-relation-joined
  10. 277
      www/lib/common
  11. 25
      www/metadata.yaml
  12. 1
      www/revision
  13. 3
      www/shorewall

61
www/actions/load

@ -0,0 +1,61 @@
#!/bin/bash
## deploy-files will deploy data files to $DOMAIN data from given FILE/DIRECTORY/URL
##
##
if [ -z "$SERVICE_DATASTORE" ]; then
echo "This script is meant to be run through 'compose' to work properly." >&2
exit 1
fi
usage="$exname [-h|--help] SOURCE DBNAME"
SRC=
DOMAIN=
while [ "$1" ]; do
case "$1" in
"--help"|"-h")
print_usage
exit 0
;;
*)
[ -z "$SRC" ] && { SRC=$1 ; shift ; continue ; }
[ -z "$DOMAIN" ] && { DOMAIN=$1 ; shift ; continue ; }
err "Unexpected argument '$1'."
exit 1
;;
esac
shift
done
if [ -z "$SRC" ]; then
err "You must provide a source file as first argument."
print_usage
exit 1
fi
if [ -z "$DOMAIN" ]; then
err "You must provide a destination domain as second argument."
exit 1
fi
. lib/common
set -e
DOCKER_SITE_PATH=/var/www/$DOMAIN
if [ "$RELATION_BASE_CHARM" ]; then ## In a relation, we should use it then
DST=$DATASTORE/$RELATION_BASE_CHARM$DOCKER_SITE_PATH
else
DST=${SERVICE_DATASTORE}$DOCKER_SITE_PATH
fi
echo rm -rf "$DST"
mkdir -p "$DST"
deploy_files "$SRC" "$DST"
info "Deployed files from '$SRC' to '$DST'."

44
www/actions/relations/publish-dir/load-files

@ -0,0 +1,44 @@
#!/bin/bash
## Load action gets a first argument a FILE/DIRECTORY/URL holding the necessary files.
##
##
if [ -z "$SERVICE_DATASTORE" ]; then
echo "This script is meant to be run through 'compose' to work properly." >&2
exit 1
fi
usage="$exname [-h|--help] SOURCE"
while [ "$1" ]; do
case "$1" in
"--help"|"-h")
print_usage
exit 0
;;
*)
[ -z "$SOURCE" ] && { SOURCE=$1 ; shift ; continue ; }
err "Unexpected argument '$1'."
exit 1
;;
esac
shift
done
if [ -z "$SOURCE" ]; then
err "You must provide a source file as first argument."
print_usage
exit 1
fi
include parse
include pretty
set -e
DOMAIN=$(relation-get domain)
run_service_action "$RELATION_TARGET_CHARM" load "$SOURCE" "$DOMAIN" "$@"
info "Correctly deployed '$SOURCE' towards domain '$DOMAIN'"

27
www/build/Dockerfile

@ -0,0 +1,27 @@
FROM docker.0k.io/apache:carif
## Limesurvey
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libpng12-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
docker-php-ext-install gd pdo_mysql mbstring
## Formanoo_nfo
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y libpq-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pgsql pdo_pgsql
RUN a2enmod headers proxy_http rewrite ssl
## Can remove this when SSL certificate are all valid ones
RUN apt-get update && apt-get install -y --force-yes ssl-cert
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

21
www/build/entrypoint.sh

@ -0,0 +1,21 @@
#!/bin/bash
. /etc/apache2/envvars
if [ "$SERVER_NAME" ]; then
FILE=/etc/apache2/apache2.conf
if grep -E "^ServerName\s+.*\$" "$FILE" > /dev/null 2>&1; then
echo "Updated IP."
sed -ri "s/^(ServerName)(\s+[^ ]*)\s*$/\1 $SERVER_NAME/g" "$FILE"
else
#echo "Added IP."
echo "ServerName $SERVER_NAME" >> "$FILE"
fi
fi
## Using exec replaces the current bash process with the given one.
## this is necessary if we want that apache2 receives signals correctly.
exec apache2-foreground "$@"

1
www/build/etc/apache2/site-enabled/monitor.formanoo.org.passwd

@ -0,0 +1 @@
admin:$apr1$DxN/jqDN$0hboJaVxmG5ETv8vNdDAN0

50
www/hooks/init

@ -0,0 +1,50 @@
#!/bin/bash
## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.
## Accessible variables are:
## - SERVICE_NAME Name of current service
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
APACHE_LOG_DIR=/var/log/apache2
set -u
cat <<EOF | file_put "$SERVICE_DATASTORE/var/www/html/.htaccess"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
EOF
cat <<EOF | file_put "$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled/000-default.conf"
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF

49
www/hooks/log_rotate-relation-joined

@ -0,0 +1,49 @@
#!/bin/bash
## Should be executable N time in a row with same result.
. lib/common
set -e
LOGS=/var/log/apache2
## XXXvlab: hum it seems apache logging is run as root, so well...
# logs_creds=$(cached_cmd_on_base_image apache "stat -c '%u %g' '$LOGS'") || {
# debug "Failed to query for www-data gid in ${DARKYELLOW}apache${NORMAL} base image."
# return 1
# }
## XXXvlab: a lot of this intelligence should be moved away into ``logrotate`` charm
DST="$CONFIGSTORE/$TARGET_SERVICE_NAME/etc/logrotate.d/$SERVICE_NAME"
file_put "$DST" <<EOF
/var/log/docker/$SERVICE_NAME/*error.log
/var/log/docker/$SERVICE_NAME/*access.log
{
weekly
missingok
dateext
dateyesterday
dateformat _%Y-%m-%d
extension .log
rotate 52
compress
delaycompress
notifempty
create 640 root root
sharedscripts
postrotate
docker-send-signal \$${MASTER_BASE_CHARM_NAME^^}_NAME SIGUSR1;
endscript
}
EOF
config-add "\
$MASTER_TARGET_CHARM_NAME:
volumes:
- $DST:/etc/logrotate.d/docker-${SERVICE_NAME}:ro
- $SERVICE_DATASTORE$LOGS:/var/log/docker/$SERVICE_NAME:rw
$MASTER_BASE_CHARM_NAME:
volumes:
- $SERVICE_DATASTORE$LOGS:$LOGS:rw
"

76
www/hooks/publish_dir-relation-joined

@ -0,0 +1,76 @@
#!/bin/bash
## Should be executable N time in a row with same result.
. lib/common
set -e
DOMAIN=$(relation-get domain)
DATA_DIRS=$(relation-get data_dirs 2>/dev/null | shyaml get-values 2>/dev/null) || true
LOCATION=$(relation-get location 2>/dev/null) || true
CREDS=$(relation-get creds 2>/dev/null) || true
SERVER_ALIAS=$(relation-get server-alias 2>/dev/null) || true
export SERVER_ALIAS
if SSL_CERT_LOCATION=$(relation-get ssl-cert-file 2>/dev/null); then
SSL_CERT=/etc/ssl/certs/${DOMAIN}.pem
config-add "\
$MASTER_BASE_CHARM_NAME:
volumes:
- ${SSL_CERT_LOCATION}:${SSL_CERT}
"
fi
if SSL_KEY_LOCATION=$(relation-get ssl-key-file 2>/dev/null); then
SSL_KEY=/etc/ssl/private/${DOMAIN}.key
config-add "\
$MASTER_BASE_CHARM_NAME:
volumes:
- ${SSL_KEY_LOCATION}:${SSL_KEY}
"
fi
if SSL_CA_CERT_LOCATION=$(relation-get ssl-ca-cert-file 2>/dev/null); then
SSL_CA_CERT=/etc/ssl/cert/${DOMAIN}-ca.pem
config-add "\
$MASTER_BASE_CHARM_NAME:
volumes:
- ${SSL_CA_CERT_LOCATION}:${SSL_CA_CERT}
"
fi
export CREDS
apache_ssl_add "$DOMAIN"
if [ "$LOCATION" ]; then
if [ -d "$LOCATION" -a ! -d "$LOCATION/.git" ]; then
err "Hum, location '$LOCATION' does not seem to be a git directory."
exit 1
fi
if ! [ -d "$LOCATION/.git" ]; then
BRANCH=$(relation-get branch)
BRANCH=${BRANCH:-master}
SOURCE=$(relation-get source)
parent="$(dirname "$LOCATION")"
(
mkdir -p "$parent" && cd "$parent"
git clone -b "$BRANCH" "$SOURCE" "$(basename "$LOCATION")"
)
fi
apache_code_dir "$DOMAIN" "$LOCATION"
else
mkdir -p "$SERVICE_DATASTORE/var/www/${DOMAIN}" || return 1
config-add "
$MASTER_BASE_CHARM_NAME:
volumes:
- $DATASTORE/$BASE_CHARM_NAME/var/www/${DOMAIN}:/var/www/${DOMAIN}
"
fi
if [ "$DATA_DIRS" ]; then
apache_data_dir "$DOMAIN" "$DATA_DIRS"
fi

55
www/hooks/web_proxy-relation-joined

@ -0,0 +1,55 @@
#!/bin/bash
## Should be executable N time in a row with same result.
. lib/common
set -e
DOMAIN=$(relation-get domain)
TARGET=$(relation-get target)
APACHE_CUSTOM_RULES=$(relation-get apache-custom-rules 2>/dev/null) || true
CREDS=$(relation-get creds 2>/dev/null) || true
SERVER_ALIAS=$(relation-get server-alias 2>/dev/null) || true
export SERVER_ALIAS
if SSL_CERT_LOCATION=$(relation-get ssl-cert-file 2>/dev/null); then
SSL_CERT=/etc/ssl/certs/${DOMAIN}.pem
config-add "\
$MASTER_TARGET_CHARM_NAME:
volumes:
- ${SSL_CERT_LOCATION}:${SSL_CERT}
"
fi
if SSL_KEY_LOCATION=$(relation-get ssl-key-file 2>/dev/null); then
SSL_KEY=/etc/ssl/private/${DOMAIN}.key
config-add "\
$MASTER_TARGET_CHARM_NAME:
volumes:
- ${SSL_KEY_LOCATION}:${SSL_KEY}
"
fi
if SSL_CA_CERT_LOCATION=$(relation-get ssl-ca-cert-file 2>/dev/null); then
SSL_CA_CERT=/etc/ssl/cert/${DOMAIN}-ca.pem
config-add "\
$MASTER_TARGET_CHARM_NAME:
volumes:
- ${SSL_CA_CERT_LOCATION}:${SSL_CA_CERT}
"
fi
control=$(echo "$DOMAIN%$TARGET%$APACHE_CUSTOM_RULES%$CREDS%$SSL_CERT%$SSL_CA_CERT%$SSL_KEY" | md5_compat)
[ "$control" == "$(relation-get control 2>/dev/null)" ] && exit 0
## XXXvlab: could probably figure target ourselves
apache_ssl_proxy_add "$DOMAIN" "$TARGET" "$APACHE_CUSTOM_RULES" "$CREDS"
relation-set control "$control"
info "Configured $DARKYELLOW$BASE_CHARM_NAME$NORMAL for proxy access."

277
www/lib/common

@ -0,0 +1,277 @@
# -*- mode: shell-script -*-
export APACHE_CONFIG_LOCATION="$SERVICE_CONFIGSTORE/etc/apache2/sites-enabled"
## XXXvlab: berk, sending conf via environment and args.
apache_ssl_proxy_config () {
local DOMAIN="$1" TARGET="$2" CUSTOM_RULES="$3" CREDS="$4"
## target is meant to be a charm name
PASSWORD_FILE=/etc/apache2/sites-enabled/${DOMAIN}.passwd
CRED_PART=
if [ "$CREDS" ]; then
CRED_PART="
AuthType basic
AuthName "private"
AuthUserFile ${PASSWORD_FILE}
Require valid-user
"
rm -f "$SERVICE_CONFIGSTORE$PASSWORD_FILE"
include parse
first=c
while read-0 login password; do
debug "htpasswd -b$first ${PASSWORD_FILE} '$login' '$password'"
echo "htpasswd -b$first ${PASSWORD_FILE} '$login' '$password'"
[ "$first" ] && first=
done < <(echo "$CREDS" | shyaml key-values-0 2>/dev/null) |
docker run -i --entrypoint "/bin/bash" \
-v "$APACHE_CONFIG_LOCATION:/etc/apache2/sites-enabled" \
"$DOCKER_BASE_IMAGE" || return 1
fi
if [ -z "$SSL_CERT" ]; then
SSL_CERT=/etc/ssl/certs/ssl-cert-snakeoil.pem
fi
if [ -z "$SSL_KEY" ]; then
SSL_KEY=/etc/ssl/private/ssl-cert-snakeoil.key
fi
cat <<EOF
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin ${ADMIN_MAIL:-contact@$DOMAIN}
ServerName ${DOMAIN}
$(
while read-0 alias; do
echo " ServerAlias $alias"
done < <(echo "$SERVER_ALIAS" | shyaml get-values-0 2>/dev/null)
)
ServerSignature Off
CustomLog /var/log/apache2/s-${DOMAIN}_access.log combined
ErrorLog /var/log/apache2/s-${DOMAIN}_error.log
ErrorLog syslog:local2
<IfModule mod_proxy.c>
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyVia On
ProxyPass / http://$TARGET/ retry=0
<Location / >
${CRED_PART}
ProxyPassReverse /
</Location>
</IfModule>
## Forbid any cache, this is only usefull on dev server.
#Header set Cache-Control "no-cache"
#Header set Access-Control-Allow-Origin "*"
#Header set Access-Control-Allow-Methods "POST, GET, OPTIONS"
#Header set Access-Control-Allow-Headers "origin, content-type, accept"
RequestHeader set "X-Forwarded-Proto" "https"
## Fix IE problem (httpapache proxy dav error 408/409)
SetEnv proxy-nokeepalive 1
#ServerSignature On
SSLProxyEngine On
SSLEngine On
## Full stance
SSLCertificateFile $SSL_CERT
SSLCertificateKeyFile $SSL_KEY
$([ "$SSL_CA_CERT" ] && echo "SSLCACertificateFile $SSL_CA_CERT")
SSLVerifyClient None
$CUSTOM_RULES
</VirtualHost>
</IfModule>
EOF
}
export -f apache_ssl_proxy_config
apache_ssl_config() {
local DOMAIN=$1
if [ -z "$SSL_CERT" ]; then
SSL_CERT=/etc/ssl/certs/ssl-cert-snakeoil.pem
fi
if [ -z "$SSL_KEY" ]; then
SSL_KEY=/etc/ssl/private/ssl-cert-snakeoil.key
fi
PASSWORD_FILE=/etc/apache2/sites-enabled/${DOMAIN}.passwd
CRED_PART=
if [ "$CREDS" ]; then
CRED_PART="
AuthType basic
AuthName \"private\"
AuthUserFile ${PASSWORD_FILE}
Require valid-user
"
include parse || true
first=
if ! [ -e "$CONFIGSTORE/$MASTER_TARGET_CHARM_NAME$PASSWORD_FILE" ]; then
debug "No file $CONFIGSTORE/$MASTER_TARGET_CHARM_NAME$PASSWORD_FILE, creating password file." || true
first=c
fi
while read-0 login password; do
debug "htpasswd -b$first ${PASSWORD_FILE} '$login' '$password'" || true
echo "htpasswd -b$first ${PASSWORD_FILE} '$login' '$password'"
if [ "$first" ]; then
first=
fi
done < <(echo "$CREDS" | shyaml key-values-0 2>/dev/null) |
docker run -i --entrypoint "/bin/bash" \
-v "$APACHE_CONFIG_LOCATION:/etc/apache2/sites-enabled" \
"$DOCKER_BASE_IMAGE" || return 1
else
CRED_PART="allow from all"
fi
cat <<EOF
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin ${ADMIN_MAIL:-contact@$DOMAIN}
ServerName ${DOMAIN}
$(
while read-0 alias; do
echo " ServerAlias $alias"
done < <(echo "$SERVER_ALIAS" | shyaml get-values-0 2>/dev/null)
)
ServerSignature Off
CustomLog /var/log/apache2/s-${DOMAIN}_access.log combined
ErrorLog /var/log/apache2/s-${DOMAIN}_error.log
ErrorLog syslog:local2
DocumentRoot /var/www/${DOMAIN}
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/${DOMAIN}>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
${CRED_PART}
</Directory>
SSLEngine On
## Full stance
SSLCertificateFile $SSL_CERT
SSLCertificateKeyFile $SSL_KEY
$([ "$SSL_CA_CERT" ] && echo "SSLCACertificateFile $SSL_CA_CERT")
SSLVerifyClient None
</VirtualHost>
</IfModule>
EOF
}
export -f apache_ssl_config
apache_ssl_add () {
local DOMAIN="$1"
DOCKER_SITE_PATH=/var/www/$DOMAIN
BASE=$DATASTORE/$BASE_CHARM_NAME
DST=$BASE$DOCKER_SITE_PATH
# [ -e "$APACHE_CONFIG_LOCATION/$DOMAIN.conf" ] && return 0
mkdir -p "$APACHE_CONFIG_LOCATION" || return 1
apache_ssl_config "$DOMAIN" > "$APACHE_CONFIG_LOCATION/$DOMAIN.conf"
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."
return 1
}
mkdir -p "$DST"
setfacl -R -m g:"$www_data_gid":rx "$DST"
info "Added $DOMAIN apache config."
}
export -f apache_ssl_add
apache_ssl_proxy_add () {
local DOMAIN="$1" TARGET="$2" CUSTOM_RULES="$3" CREDS="$4"
mkdir -p "$APACHE_CONFIG_LOCATION" || return 1
apache_ssl_proxy_config "$DOMAIN" "$TARGET" "$CUSTOM_RULES" "$CREDS" > "$APACHE_CONFIG_LOCATION/$DOMAIN.conf" || return 1
info "Added $DOMAIN as a proxy to $TARGET."
}
export -f apache_ssl_proxy_add
apache_code_dir() {
local domain="$1" location="$2"
config-add "
$MASTER_BASE_CHARM_NAME:
volumes:
- $location:/var/www/$domain
"
}
apache_data_dir() {
local DOMAIN=$1 DATA_COMMA_SEPARATED=$2
DOCKER_SITE_PATH=/var/www/$DOMAIN
BASE=$DATASTORE/$BASE_CHARM_NAME
DST=$BASE$DOCKER_SITE_PATH
DATA=()
while IFS="," read -ra ADDR; do
for dir in "${ADDR[@]}"; do
mkdir -p "$DST/$dir"
DATA+=($dir)
done
done <<< "$DATA_COMMA_SEPARATED"
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."
return 1
}
info "www-data gid from ${DARKYELLOW}apache${NORMAL} is '$www_data_gid'"
dirs=()
for d in "${DATA[@]}"; do
dirs+=("$DST/$d")
done
chgrp "$www_data_gid" "${dirs[@]}" -R && chmod 775 "${dirs[@]}" -R
config-add "
$MASTER_BASE_CHARM_NAME:
volumes:
$(
for d in "${DATA[@]}"; do
echo " - $DST/$d:$DOCKER_SITE_PATH/$d"
done
)"
}
deploy_files() {
local src="$1" dst="$2"
if ! [ -d "$dst" ]; then
err "Destination '$dst' does not exist or is not a directory"
return 1
fi
(
cd "$dst" && info "In $dst:" &&
get_file "$src" | tar xv
)
}
export -f deploy_files

25
www/metadata.yaml

@ -1,13 +1,20 @@
name: www
summary: "Apache"
description: "Apache Web Server"
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" maintainer: "Valentin Lab <valentin.lab@kalysto.org>"
## XXXvlab: currently only used when building LXC along with hooks/install
## XXXvlab: docker uses the 'build' directory or the 'image:' option here.
inherit: base-0k inherit: base-0k
compatiblity:
compatiblity: ## 'hooks/install' script was run on a these images without issues
- ubuntu/15.10 - ubuntu/15.10
description: |
Installs a HTTP Apache server.
config-resources:
- /etc/apache2
- /etc/postfix
docker-compose:
## XXXvlab: should move to global lxc/docker compatible option
ports:
- "0.0.0.0:80:80"
- "0.0.0.0:443:443"
data-resources: data-resources:
- /var/www
- /var/www/html
- /var/log/apache2
config-resources:
- /etc/apache2/sites-enabled
provides:
web-proxy:
tech-dep: "reversed"

1
www/revision

@ -1 +0,0 @@
0

3
www/shorewall

@ -1,3 +1,6 @@
## XXXvlab: these should be set in metadata with a common option for
## docker and LXC/shorewall
DNAT net lan:%%NAME%%:80 tcp 80 DNAT net lan:%%NAME%%:80 tcp 80
DNAT net lan:%%NAME%%:443 tcp 443 DNAT net lan:%%NAME%%:443 tcp 443

Loading…
Cancel
Save