Mercurial > sat_docs
view docker/libervia_cont.sh @ 134:4549cf265131
flatpak: install D-Bus .service on each frontend:
work around lack of dependency handling in Flatpak by installing D-Bus .service on each frontend.
This works because all backend is included in the runtime, but we have to add backend permissions to all frontend, and set --own-name=org.salutatoi.SAT.
Furthermore, if one frontend is removed, the symbolic link is removed and the backend will not be launched automatically anymore, even if other frontends are still there.
The benefict of this method is that backend has not to be installed manually to use a frontend.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 15 Jul 2018 16:56:55 +0200 |
parents | 37e100fd30ef |
children |
line wrap: on
line source
#!/bin/sh # Libervia container manager # Copyright (C) 2014-2016 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. VERSION="0.3.0" APP_NAME="Libervia" ACCOUNT="salutatoi" # environment variables that can be used for configuration: # SAT_CONT_TLS_DIR for TLS certificates directory # SAT_CONT_DOMAIN for the host name # SAT_CONT_BACKUP_DIR is the directory where tar.gz backup will be written # SAT_CONT_DK_EXTRA is used for extra options (used with all containers but sat_data) # SAT_CONT_PORT_<port> is used to specify port when -p is used, <port> must be an exposed port CONTAINERS="prosody sat_pubsub salut sat libervia" TEST_CONT="libervia" # container used to test status MAINT_CONT="debian:jessie" # container used for maintenance DK_DETACH="-d" DK_TERM="-ti" VOLUME_NAME="data" VOLUME_CONT="$ACCOUNT/$VOLUME_NAME" VOLUME_ALIAS="sat_data" DK_VOLUME="--volumes-from $VOLUME_ALIAS" PUBLIC=0 PROSODY_PORTS="5222 5269 5280 5281" PORT_5222_NAME="XMPP client to server" PORT_5269_NAME="XMPP server to server" PORT_5280_NAME="HTTP Upload" PORT_5281_NAME="HTTP Upload (HTTPS)" SAT_PORTS="10143 10125" PORT_10143_NAME="IMAP server" PORT_10125_NAME="SMTP server" LIBERVIA_PORTS="8080 8443" PORT_8080_NAME="HTTP" PORT_8443_NAME="HTTPS" NO_PORT="No public port" DOCKER_EXE="docker" USAGE="Usage: $0 [start|stop|restart|status|update|backup|restore|ports|config|stats] [ARGS...]" HELP_SITE="https://wiki.goffi.org/wiki/Docker/en" HELP_MUC="sat@chat.jabberfr.org" CONT_CERT_DIR="/usr/share/sat/certificates" DEFAULT_TMP_DIR="/tmp/tmp_sat_docker" eprintf() { >&2 printf "$@" } get_dyn_var() { # get dynamicly variable based on given name name=$1 var_type=$2 name_upp=$(echo "$name" | tr '[:lower:]' '[:upper:]') case $var_type in ports) eval echo "\$${name_upp}_PORTS";; port_name) eval echo "\$PORT_${name_upp}_NAME";; esac } list_ports() { # list used ports in currently running containers for cont in $CONTAINERS; do # we get variable name with uppercase container name # some magic to get the ports ports=$(get_dyn_var $cont ports) [ -n "$ports" ] && printf "== $cont ==\n\n" for port in $ports; do # some magic to get port human readable name port_name=$(get_dyn_var $port port_name) real_port=$(docker port $cont $port 2>&1) if [ $? -ne 0 ]; then real_port=$NO_PORT fi # we now show the ports with nice alignment desc="port $port ($port_name):" nb_tabs=$((5-${#desc}/8)) printf "$desc" for i in $(seq $nb_tabs); do printf "\t" done printf "$real_port\n" done [ -n "$ports" ] && printf '\n' done } public_ports_arg() { # create Docker arg to have public ports corresponding to container ports if [ $PUBLIC -ne 1 ]; then return fi cont=$1 ports=$(get_dyn_var $cont ports) ARG="" for port in $ports; do host_port=$(eval echo "\$SAT_CONT_PORT_${port}") if [ -z "$host_port" ]; then host_port=$port fi if [ "$host_port" != 0 ]; then ARG="$ARG -p $host_port:$port" fi done echo $ARG } download_missing() { # download images wich are not present locally for cont in $CONTAINERS $VOLUME_NAME; do image="$ACCOUNT/$cont" docker inspect $image:latest > /dev/null 2>&1 if [ $? -ne 0 ]; then printf "$image is not present locally, downloading it\n" docker pull $image:latest if [ $? -eq 0 ]; then printf "\nDownload of latest $image finished\n\n" else eprintf "\nError while downloading $image, please check your connection and logs\n" return 1 fi fi done } check_docker() { which $DOCKER_EXE > /dev/null 2>&1 if [ $? -ne 0 ]; then printf "Docker is not installed or not accessible, please install it.\nYou can check $HELP_SITE for instructions\n" return 1 fi } check_docker_version() { # check if current docker version is greater than or equal to the requested one wanted_major=$1 wanted_minor=$2 wanted_rev=$3 raw=$(docker --version | grep -o '\([0-9]\+\)\.[0-9]\+\.[0-9]\+') docker_major=$(echo "$raw" | cut -d . -f 1) docker_minor=$(echo "$raw" | cut -d . -f 2) docker_rev=$(echo "$raw" | cut -d . -f 3) for name in major minor rev; do docker_val=$(eval echo \$docker_$name) wanted_val=$(eval echo \$wanted_$name) if [ $docker_val -gt $wanted_val ]; then return 0 fi if [ $docker_val -lt $wanted_val ]; then return 1 fi done # wanted version and docker version are the same return 0 } parse_run_args() { # manage arguments for run command while [ $# -gt 0 ]; do case "$1" in -h|--help) cat << OPT_END options available for the run command: -h, --help display this help message -p, --public publish using true ports -d DOMAIN, --domain DOMAIN use DOMAIN as domain name OPT_END exit 0 ;; -d|--domain) shift if [ $# -eq 0 ]; then printf "no domain given, --domain must be followed by a domain\n" exit 1 fi SAT_CONT_DOMAIN="$1" shift ;; -p|--public) shift PUBLIC=1 ;; *) printf "Invalid argument, please check \"$0 run --help\"\n" exit 1 ;; esac done } check_docker || exit 1 if [ $# -ge 1 ];then case $1 in start) CMD=START;; stop) CMD=STOP;; restart) CMD=RESTART;; status) CMD=STATUS;; update) CMD=UPDATE;; backup) CMD=BACKUP;; restore) CMD=RESTORE;; ports) CMD=PORTS;; config) CMD=CONFIG;; stats) CMD=STATS;; -v|--version) printf "$VERSION\n"; exit 0;; -h|--help) printf "$USAGE\n\nYou can check $HELP_SITE for instructions, or go to $HELP_MUC XMPP MUC room for help\n"; exit 0;; *) echo $USAGE exit 1 esac shift else CMD=START fi case $CMD in START) parse_run_args "$@" download_missing || exit 1 printf "Running data container... " # we use -d even if data container doesn't stay in background to get id of the container docker_id=$(docker run -d --name $VOLUME_ALIAS $VOLUME_CONT 2>&1) if [ $? -eq 0 ]; then printf "OK ($docker_id)\n" else echo $docker_id | grep Conflict > /dev/null 2>&1 if [ $? -eq 0 ]; then printf "A data container already exists ($VOLUME_ALIAS), use \"docker ps -a\" to see it\n" else eprintf "Error, please check data volume\nerror message: $docker_id\n" exit 1 fi fi printf "\nRunning Libervia\n\n" # we first check if we need to mount TLS directory if [ -n "$SAT_CONT_TLS_DIR" ]; then printf "$SAT_CONT_TLS_DIR will be used for TLS certificate\n" DK_TLS="--volume=$SAT_CONT_TLS_DIR:$CONT_CERT_DIR" fi for CONT in $CONTAINERS; do case $CONT in prosody) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME $DK_TLS $(public_ports_arg $CONT) --name prosody" if [ -n "$SAT_CONT_DOMAIN" ]; then OPTS="-e DOMAIN=$SAT_CONT_DOMAIN $OPTS" fi ;; sat_pubsub) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --name sat_pubsub --link=prosody:prosody";; salut) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --name salut --link=prosody:prosody";; sat) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME -P $(public_ports_arg $CONT) --name sat --link=prosody:prosody";; libervia) OPTS="$DK_DETACH $DK_TERM $DK_VOLUME --volumes-from sat $DK_TLS -P $(public_ports_arg $CONT) --name libervia --link=sat:sat";; *) eprintf "Unkown container $CONT\n"; exit 1 esac printf "Launching $CONT... " docker_id=$(docker run $OPTS $SAT_CONT_DK_EXTRA $ACCOUNT/$CONT 2>&1) if [ $? -eq 0 ]; then printf "OK ($docker_id)\n" else eprintf "Error, please check container or ask help on XMPP MUC sat@chat.jabberfr.org\nerror message: $docker_id\n" eprintf "Abandon\n" exit 1 fi done printf '\nLibervia is launched and should be reachable in a couple of seconds.\nYou can check logs with "docker logs -f libervia" (or any other container name).\n' printf "An \"admin\" account has been created, you can check its password on $VOLUME_ALIAS container, in file /home/sat/ADMIN_PWD. Config can be tuned on this container.\n" printf 'Below are the ports used to connect, you can go with your browser to Libervia HTTP(S) port.\n\n' list_ports ;; STOP) printf "stopping Libervia\n" REVERSED="" for CONT in $CONTAINERS; do REVERSED="$CONT $REVERSED" done; for CONT in $REVERSED; do printf "\nStopping container $CONT" docker stop $CONT > /dev/null 2>&1 || eprintf "... Error while stopping $CONT\n" printf "\rDeleting container $CONT" docker rm -v $CONT > /dev/null 2>&1 || eprintf "... Error while removing $CONT\n" done printf "\n" ;; RESTART) printf "restarting containers...\n" "$0" stop && "$0" start "$@" ;; STATUS) docker inspect $TEST_CONT > /dev/null 2>&1 if [ $? -eq 0 ]; then printf "$APP_NAME is running" # we test the presence of "starting on xxxx" (where xxxx is one of the exposed ports) # this is not really reliable as ports can be changed in configuration # but in most case it should work OK PORTS_REGEX=$(get_dyn_var $TEST_CONT ports | sed 's/ /\\|/') docker logs $TEST_CONT | grep "starting on \($PORTS_REGEX\)" > /dev/null 2>&1 if [ $? -ne 0 ]; then printf " but no server is started\n" exit 2 fi printf "\n" exit 0 else printf "$APP_NAME is not running\n" exit 1 fi ;; UPDATE) printf "updating images...\n" errors=0 for CONT in $CONTAINERS data; do printf "\n*** updating $CONT ***\n" docker pull $ACCOUNT/$CONT:latest if [ $? -ne 0 ]; then eprintf "\nError while updating $ACCOUNT/$CONT\n" errors=1 fi done if [ $errors -eq 0 ]; then printf "\n\nImages are up-to-date\n" else eprintf "\n\nSome errors happened while updating images\n" exit 1 fi ;; BACKUP) case $# in 0) SAT_CONT_BACKUP_DIR="$(pwd)";; 1) SAT_CONT_BACKUP_DIR="$1";; *) printf "syntaxe is $0 backup [backup_dir_absolute_path]\n[backup_dir_absolute_path] default to current working dir\n" exit 1 ;; esac SAT_CONT_BACKUP_DIR=$(echo $SAT_CONT_BACKUP_DIR | sed 's%^\/*\|\/*$%\/%g') # we want to be sure that path starts and finishes with "/" filename="sat_data_backup_$(date '+%Y-%m-%d_%H:%M:%S').tar.gz" printf "backing up data container to ${SAT_CONT_BACKUP_DIR}${filename}\n\n" docker run --rm $DK_VOLUME -v "$SAT_CONT_BACKUP_DIR:/backup" $MAINT_CONT tar zcvf "/backup/$filename" -C / -h volumes if [ $? -eq 0 ]; then printf "\nBackup finished and available at ${SAT_CONT_BACKUP_DIR}${filename}\n" else eprintf "\nBackup Error !\n" exit 1 fi ;; RESTORE) if [ $# -ne 1 ]; then printf "syntaxe is $0 restore <backup_file.tar.gz>\n" exit 1 fi docker run --name $VOLUME_ALIAS $VOLUME_CONT > /dev/null 2>&1 if [ $? -ne 0 ]; then eprintf "Can't create $VOLUME_ALIAS container.\n\ If you have an existing one, please remove it with \"docker rm -v $VOLUME_ALIAS\" (/!\\ it will remove *ALL* your data)\n\n\ Hint: you can also rename your current data container with \"docker rename $VOLUME_ALIAS new_container_name\"\n" exit 1 fi printf "restoring $1 to $VOLUME_ALIAS container\n\n" HOST_BACKUP_DIR=$(dirname "$1") HOST_BACKUP_NAME=$(basename "$1") if [ $HOST_BACKUP_DIR = "." ]; then # workaround for a Docker bug (container crash if "." is used) HOST_BACKUP_DIR=$(pwd) fi docker run --rm $DK_VOLUME -v "$HOST_BACKUP_DIR:/backup" $MAINT_CONT tar zxvf "/backup/$HOST_BACKUP_NAME" -C / -h volumes if [ $? -eq 0 ]; then printf "\nRestore finished\n" else eprintf "\nRestore Error !\n" exit 1 fi ;; PORTS) list_ports ;; CONFIG) case $# in 0) CONF="libervia";; 1) CONF="$1";; *) CONF="";; esac case $CONF in libervia) CONT_CONF_FILE="/home/sat/.config/sat/sat.conf" ;; prosody) CONT_CONF_FILE="/etc/prosody/prosody_sat_cfg/prosody.cfg.lua" ;; *) printf "\nPlease enter type of configuration to edit (libervia, prosody)\n" exit 1 ;; esac HOST_CONF_FILE=$(basename $CONT_CONF_FILE) printf "\ngetting configuration for $CONF\n" # we copy config file to a temporary dit # then edit with $EDITOR and put it back TMP_DIR=$(mktemp -d 2>/dev/null) if [ $? -ne 0 ]; then TMP_DIR="$DEFAULT_TMP_DIR" mkdir -p "$TMP_DIR" fi docker cp "$VOLUME_ALIAS:$CONT_CONF_FILE" "$TMP_DIR/" "$EDITOR" "$TMP_DIR/$HOST_CONF_FILE" if [ $? -eq 0 -a -s "$TMP_DIR/$HOST_CONF_FILE" ]; then printf "updating configuration\n" check_docker_version 1 8 0 if [ $? -eq 0 ]; then docker cp "$TMP_DIR/$HOST_CONF_FILE" "$VOLUME_ALIAS:$CONT_CONF_FILE" else eprintf "Old Docker version detected, using workaround, please update!\n" docker run --rm $DK_VOLUME -v "$TMP_DIR:/tmp_config" $MAINT_CONT /bin/cp -f "/tmp_config/$HOST_CONF_FILE" "$CONT_CONF_FILE" fi # "docker cp" copy file on container as root, if an option is available later to change this behaviour, # the following operation could be removed printf "ownership fix..." docker run --rm $DK_VOLUME $MAINT_CONT /bin/chown 1000:1000 "$CONT_CONF_FILE" printf "done\n" fi rm -rf "$TMP_DIR" ;; STATS) if [ -n "$1" -a "$1" != "--no-stream" ]; then printf "usage: $0 stats [--no-stream]\n" exit 1 fi docker stats $1 $CONTAINERS ;; *) eprintf "Error: unknown command !" exit 2 esac