jean-cloud-services/provisioning/roles/deploy_all/files/bin/deployer.sh
Adrian Amaglio 48a27ddf71 update
2023-06-08 09:34:51 +02:00

206 lines
6.1 KiB
Bash
Executable File

#!/bin/bash
driglibash_run_retry=true
. driglibash-base
set -euo pipefail
###############################################################################
# Variables
###############################################################################
proxy_dir="/etc/nginx"
nginx_conf_path="$proxy_dir/sites-enabled"
new_nginx_conf_path="$proxy_dir/new-sites-enabled"
certs_path="/etc/letsencrypt/live"
dummy_cert_path="$certs_path/dummy"
###############################################################################
# Helpers
###############################################################################
# Returns the public IP4 address of a domain name
function ipof {
resolv.sh "$1"
}
function jcservice {
if [ "$#" -ne 2 ] ; then
echo "usage: $0 <action> <service>"
echo "action is start/stop/reload/restart"
echo "service is a jc service name"
exit 1
fi
action="$1"
service="$2"
if [ -f "/docker/$service/install.sh" ] ; then
section "Running install script"
. "/docker/$service/install.sh"
# Is $action a bash function?
if [ -n "$(LC_ALL=C type "$action" | head -n 1 | grep 'function')" ] ; then
"$action"
fi
unset -f start stop reload restart "$action"
fi
}
# Path to this directory
here="$(where 'follow_links')"
# Ip4 address
my_ip="$(ipof "$(cat /etc/hostname)")"
[ -z "$my_ip" ] && yell "Unable to find my IP" && exit 1
###############################################################################
# Nginx preparation
###############################################################################
driglibash_section_prefix="[Prepare nginx] "
section "Delete new conf directory (to recover)"
run rm -rf "$new_nginx_conf_path"
section "Create new conf file (for tests purposes)"
sed "s#$nginx_conf_path#$new_nginx_conf_path#" "/docker/_proxy/nginx.conf" > "$proxy_dir/new_nginx.conf"
section "Create proxy dir"
run mkdir -p "$proxy_dir" /docker /data
run chown root:root /docker
run chown root:root /data
run chmod 755 /docker
run chmod 755 /data
section "Check dummy cert exists "
#TODO check if expired
if [ ! -f "$dummy_cert_path/privkey.pem" ] ; then
echo "Dummy cert generation"
run mkdir -p "$dummy_cert_path"
run openssl req -x509 -newkey rsa:2048 -keyout /etc/letsencrypt/live/dummy/privkey.pem -out /etc/letsencrypt/live/dummy/fullchain.pem -days 365 -nodes -subj "/C=FR/ST=France/O=IT/CN=jean-cloud.net"
fi
section "Create new conf directory"
run mkdir -p "$new_nginx_conf_path"
###############################################################################
# Deploy services
###############################################################################
for dir in /docker/* ; do
service="$(basename "$dir")"
# Ignore _ prefixed directories
[ "${service::1}" == '_' ] && continue
[ ! -d "$dir" ] && continue
docker_service="$(echo "$service" | tr '.' '_')"
driglibash_section_prefix="[$service] "
export DATA_DIR="/data/$service"
export HTTP_DIR="/srv/http/$service"
export JC_SERVICE="$service"
line_in_file "HTTP_DIR='$HTTP_DIR'" "/docker/$service/.env"
line_in_file "DATA_DIR='$DATA_DIR'" "/docker/$service/.env"
line_in_file "JC_SERVICE='$JC_SERVICE'" "/docker/$service/.env"
cd "/docker/$service"
# Is service meant to be on this server?
ip="$(ipof "$service")"
[ -z "$ip" ] && echo "No ip found for $service"
if [[ "$ip" != *"$my_ip"* ]] ; then
if [ -n "$(docker ps | grep "$docker_service")" ] ; then
section "--------------------"
section "Removing service"
docker-compose down --rmi all --remove-orphans
[ -d "$HTTP_DIR" ] && rm -r "$HTTP_DIR"
fi
jcservice stop "$service"
# TODO check for leftover wg interfaces
continue
fi
mkdir -p "$DATA_DIR" "$HTTP_DIR"
# If there is a docker-compose file and it has services in it
if [ -f "/docker/$service/docker-compose.yml" ] && [ -n "$(grep '^[^#]*services' "/docker/$service/docker-compose.yml")" ] ; then
section "-------------------- $service"
section "Logging to registry"
# XXX Login to docker registry
section "Pulling images"
run docker-compose pull
section "Starting service"
run docker-compose up -d --remove-orphans
fi
jcservice start "$service"
# If there is a wireguard vpn script
for file in "/docker/$service/"wg-*.sh ; do
section "Starting wg interface"
if [ -x "$file" ] ; then
wgif="$(basename "$file")"
wgif="${wgif:3:-3}"
"$file" $wgif > "/etc/wireguard/$wgif.conf"
systemctl enable "wg-quick@$wgif"
startwg.sh $wgif
fi
done
# If there is a nginx conf file
if [ -f "/docker/$service/nginx_server.conf" ] ; then
section "Copy nginx conf"
run cp "/docker/$service/nginx_server.conf" "$new_nginx_conf_path/$service"
section "Template nginx conf with vars from '.env' file"
run template.sh "/docker/$service/.env" < "/docker/$service/nginx_server.conf" > "$new_nginx_conf_path/$service"
fi
# Do we need dummy cert?
if [ ! -e "$certs_path/$service/fullchain.pem" ] ; then
section "Create cert dir"
run mkdir -p "$certs_path/$service"
section "Link dummy to cert"
run ln -s "$dummy_cert_path/fullchain.pem" "$certs_path/$service"
run ln -s "$dummy_cert_path/privkey.pem" "$certs_path/$service"
fi
section "Testing nginx conf"
run nginx -t -c /etc/nginx/new_nginx.conf
done
###############################################################################
# Nginx restart
###############################################################################
driglibash_section_prefix="[Restart nginx] "
section "Test if nginx conf is ok"
run nginx -t -c "$proxy_dir/new_nginx.conf"
section "Update nginx conf"
run rm -rf "$nginx_conf_path"
run mv "$new_nginx_conf_path" "$nginx_conf_path"
run cp "/docker/_proxy/nginx.conf" "$proxy_dir/nginx.conf"
section "Test nginx conf to be sure"
run nginx -t
if [ -z "$(cat /var/run/nginx.pid)" ] ; then
section "Start nginx"
run nginx
else
section "Reload nginx"
run nginx -s reload
fi
clean