#!/bin/bash usage () { echo "Usage: launcher COMMAND [--skip-prereqs] [--docker-args STRING]" echo "Commands:" echo " start: Start/initialize a container" echo " stop: Stop a running container" echo " restart: Restart a container" echo " destroy: Stop and remove a container" echo " enter: Open a shell to run commands inside the container" echo " logs: View the Docker logs for a container" echo " bootstrap: Bootstrap a container for the config based on a template" echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)" echo echo "Options:" echo " --skip-prereqs Don't check launcher prerequisites" echo " --docker-args Extra arguments to pass when running docker" exit 1 } set -e set -o pipefail version=6.0.5 image=seafileorg/server:$version local_image=local_seafile/server:latest dockerdir=$(cd "$(dirname $0)"; pwd -P) sharedir=$dockerdir/shared installdir=/opt/seafile/seafile-server-$version bootstrap_conf=$dockerdir/bootstrap/bootstrap.conf cd $dockerdir dbg() { if [[ $debug == "true" ]]; then echo "dbg: $1" fi } show_progress() { if [[ -t 1 ]]; then >&2 printf "[$(date +'%Y-%m-%d %H:%M:%S')] \033[32m%s\033[m\n" "$1" else >&2 echo "[$(date +'%Y-%m-%d %H:%M:%S')] " "$1" fi } install_docker() { echo "---------------------------------------------------------------------------------" echo "Docker is not installed, you will need to install Docker in order to run Launcher" echo "See https://docs.docker.com/installation/" echo "---------------------------------------------------------------------------------" exit 1 } err_and_quit () { if [[ -t 1 ]]; then >&2 printf "\n\n\033[33mError: %s\033[m\n\n" "$1" else >&2 echo "$1" fi exit 1 } init_shared() { mkdir -p $sharedir/{seafile,db} mkdir -p $sharedir/logs/{seafile,var-log} mkdir -p $sharedir/logs/var-log/nginx touch $sharedir/logs/var-log/syslog local bash_history=$sharedir/.bash_history if [[ ! -e $bash_history ]]; then touch $bash_history fi } set_ports() { ports=$(docker run $user_args --rm -it \ -v ${dockerdir}/scripts:/scripts \ -v ${dockerdir}/bootstrap:/bootstrap:ro \ $image \ /scripts/bootstrap.py --parse-ports) } set_bootstrap_volumes() { local mounts init_shared mounts=( $sharedir:/shared $sharedir/logs/var-log:/var/log $sharedir/db:/var/lib/mysql $dockerdir/bootstrap:/bootstrap $dockerdir/scripts:/scripts:ro $dockerdir/templates:/templates:ro $dockerdir/scripts/tmp/check_init_admin.py:$installdir/check_init_admin.py:ro $sharedir/.bash_history:/root/.bash_history ) volumes="" local m for m in ${mounts[*]}; do volumes="$volumes -v $m" done } set_volumes() { local mounts init_shared mounts=( $sharedir:/shared $sharedir/logs/var-log:/var/log $sharedir/db:/var/lib/mysql $sharedir/.bash_history:/root/.bash_history ) volumes="" local m for m in ${mounts[*]}; do volumes="$volumes -v $m" done } set_existing_container() { existing=$(docker ps -a | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true) } bootstrap() { if [[ ! -e $bootstrap_conf ]]; then err_and_quit "The file $bootstrap_conf doesn't exist. Have you run seafile-server-setup?" fi docker history $image >/dev/null 2>&1 || { show_progress "Pulling Seafile server image $version, this may take a while." docker pull $image show_progress "Seafile server image $version pulled. Now bootstrapping the server ..." } # First initialize seafile server and letsencrypt set_bootstrap_volumes set_ports docker run $user_args --rm -it --name seafile-bootstrap -e SEAFILE_BOOTSRAP=1 $volumes $ports $image /sbin/my_init -- /scripts/bootstrap.py show_progress "Now building the local docker image." docker build -f bootstrap/generated/Dockerfile -t local_seafile/server:latest . >/dev/null show_progress "Image built." } start() { existing=$(docker ps | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true) if [[ $existing != "" ]]; then show_progress "Nothing to do, your container has already started!" exit 0 fi chmod 0700 $dockerdir/bootstrap $sharedir/seafile/conf set_existing_container if [[ $existing != "" ]]; then show_progress "starting up existing container" ( set -x docker start seafile ) exit 0 fi set_volumes set_ports local restart_policy attach_on_run if [[ "${SUPERVISED}" = "true" ]]; then restart_policy="--restart=no" attach_on_run="-a stdout -a stderr" else attach_on_run="-d" fi show_progress "Starting up new seafile server container" ( set -x docker run $user_args $attach_on_run $restart_policy --name seafile -h seafile $volumes $ports $local_image ) } ensure_container_running() { set_existing_container if [[ $existing == "" ]]; then err_and_quit "seafile was not started !" fi } stop() { ensure_container_running ( set -x docker stop -t 10 seafile ) } enter() { ensure_container_running ( set -x docker exec -it seafile /bin/bash ) } restart() { stop start } check_prereqs() { if [[ $SKIP_PREREQS == "true" ]]; then return 0 fi # check docker if ! which docker >/dev/null; then install_docker fi # TODO: check git version } logs() { ensure_container_running ( set -x docker logs --tail=20 -f seafile ) } destroy() { ( set -x docker stop -t 10 seafile || true docker rm seafile ) } rebuild() { if [[ "$(git symbolic-ref --short HEAD)" == "master" ]]; then show_progress "Ensuring launcher is up to date" git remote update LOCAL=$(git rev-parse @) REMOTE=$(git rev-parse "@{u}") BASE=$(git merge-base @ "@{u}") if [[ $LOCAL = "$REMOTE" ]]; then show_progress "Launcher is up-to-date" elif [[ $LOCAL = "$BASE" ]]; then show_progress "Updating Launcher" git pull || (echo 'failed to update' && exit 1) for (( i=${#BASH_ARGV[@]}-1,j=0; i>=0,j<${#BASH_ARGV[@]}; i--,j++ )) do args[$j]=${BASH_ARGV[$i]} done exec /bin/bash $0 "${args[@]}" # $@ is empty, because of shift at the beginning. Use BASH_ARGV instead. elif [[ $REMOTE = "$BASE" ]]; then show_progress "Your version of Launcher is ahead of origin" else show_progress "Launcher has diverged source, this is only expected in Dev mode" fi fi set_existing_container if [[ $existing != "" ]]; then show_progress "Stopping old container" ( set -x docker stop -t 10 seafile ) fi bootstrap show_progress "Rebuilt successfullly." if [[ $existing != "" ]]; then show_progress "Removing old container" ( set -x docker rm seafile ) fi start show_progress "Your seafile server is now running." exit 0 } main() { local action while [[ $# -gt 0 ]] do case "$1" in bootstrap|start|stop|restart|enter|destroy|logs|rebuild) action=$1 ; shift 1 ;; --debug) debug=true ; shift 1 ;; --skip-prereqs) SKIP_PREREQS=true ; shift 1 ;; --docker-args) user_args=$2 ; shift 2 ;; *) err_and_quit "Argument error. Please see help." ;; esac done "$action" } check_prereqs main "$@"