2016-11-11 04:54:47 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2016-11-21 04:56:33 +00:00
|
|
|
usage () {
|
2016-11-21 05:07:09 +00:00
|
|
|
echo "Usage: launcher COMMAND [--skip-prereqs] [--docker-args STRING]"
|
2016-11-21 04:56:33 +00:00
|
|
|
echo "Commands:"
|
2016-11-29 06:44:26 +00:00
|
|
|
echo " start: Start/initialize the container"
|
2016-11-21 04:56:33 +00:00
|
|
|
echo " stop: Stop a running container"
|
2016-11-29 06:44:26 +00:00
|
|
|
echo " restart: Restart the container"
|
|
|
|
echo " destroy: Stop and remove the container"
|
2016-11-21 04:56:33 +00:00
|
|
|
echo " enter: Open a shell to run commands inside the container"
|
2016-11-29 06:44:26 +00:00
|
|
|
echo " logs: View the Docker container logs"
|
|
|
|
echo " bootstrap: Bootstrap the container based on a template"
|
|
|
|
echo " rebuild: Rebuild the container (destroy old, bootstrap, start new)"
|
2016-11-21 04:56:33 +00:00
|
|
|
echo
|
|
|
|
echo "Options:"
|
|
|
|
echo " --skip-prereqs Don't check launcher prerequisites"
|
|
|
|
echo " --docker-args Extra arguments to pass when running docker"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2016-11-11 04:54:47 +00:00
|
|
|
set -e
|
|
|
|
set -o pipefail
|
|
|
|
|
2016-11-29 06:44:26 +00:00
|
|
|
version=6.1.0
|
2016-11-11 04:54:47 +00:00
|
|
|
image=seafileorg/server:$version
|
2016-11-15 08:59:02 +00:00
|
|
|
local_image=local_seafile/server:latest
|
2016-11-12 07:15:26 +00:00
|
|
|
dockerdir=$(cd "$(dirname $0)"; pwd -P)
|
2016-11-12 03:28:49 +00:00
|
|
|
sharedir=$dockerdir/shared
|
|
|
|
installdir=/opt/seafile/seafile-server-$version
|
2016-11-16 01:46:08 +00:00
|
|
|
bootstrap_conf=$dockerdir/bootstrap/bootstrap.conf
|
2016-11-29 06:44:26 +00:00
|
|
|
version_stamp_file=$sharedir/seafile/seafile-data/current_version
|
2016-11-11 04:54:47 +00:00
|
|
|
|
2016-11-12 03:28:49 +00:00
|
|
|
cd $dockerdir
|
2016-11-11 04:54:47 +00:00
|
|
|
|
|
|
|
dbg() {
|
|
|
|
if [[ $debug == "true" ]]; then
|
|
|
|
echo "dbg: $1"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-11-25 06:14:30 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-11-21 04:56:33 +00:00
|
|
|
install_docker() {
|
2016-11-25 04:04:37 +00:00
|
|
|
echo "---------------------------------------------------------------------------------"
|
2016-11-21 04:56:33 +00:00
|
|
|
echo "Docker is not installed, you will need to install Docker in order to run Launcher"
|
|
|
|
echo "See https://docs.docker.com/installation/"
|
2016-11-25 04:04:37 +00:00
|
|
|
echo "---------------------------------------------------------------------------------"
|
2016-11-21 04:56:33 +00:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2016-11-11 04:54:47 +00:00
|
|
|
err_and_quit () {
|
2016-11-25 06:14:30 +00:00
|
|
|
if [[ -t 1 ]]; then
|
|
|
|
>&2 printf "\n\n\033[33mError: %s\033[m\n\n" "$1"
|
|
|
|
else
|
|
|
|
>&2 echo "$1"
|
|
|
|
fi
|
2016-11-11 04:54:47 +00:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2016-11-12 06:03:52 +00:00
|
|
|
init_shared() {
|
2016-11-14 06:47:40 +00:00
|
|
|
mkdir -p $sharedir/{seafile,db}
|
2016-11-12 06:03:52 +00:00
|
|
|
mkdir -p $sharedir/logs/{seafile,var-log}
|
2016-11-12 07:15:26 +00:00
|
|
|
|
|
|
|
mkdir -p $sharedir/logs/var-log/nginx
|
2016-11-12 06:03:52 +00:00
|
|
|
touch $sharedir/logs/var-log/syslog
|
2016-11-11 04:54:47 +00:00
|
|
|
|
|
|
|
local bash_history=$sharedir/.bash_history
|
|
|
|
if [[ ! -e $bash_history ]]; then
|
|
|
|
touch $bash_history
|
|
|
|
fi
|
2016-11-12 06:03:52 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 04:11:58 +00:00
|
|
|
set_ports() {
|
2016-11-21 05:07:09 +00:00
|
|
|
ports=$(docker run $user_args --rm -it \
|
2016-11-16 01:46:08 +00:00
|
|
|
-v ${dockerdir}/scripts:/scripts \
|
|
|
|
-v ${dockerdir}/bootstrap:/bootstrap:ro \
|
|
|
|
$image \
|
|
|
|
/scripts/bootstrap.py --parse-ports)
|
2016-11-15 04:11:58 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 08:59:02 +00:00
|
|
|
set_bootstrap_volumes() {
|
2016-11-12 06:03:52 +00:00
|
|
|
local mounts
|
|
|
|
init_shared
|
2016-11-11 04:54:47 +00:00
|
|
|
|
|
|
|
mounts=(
|
|
|
|
$sharedir:/shared
|
2016-11-12 05:27:24 +00:00
|
|
|
$sharedir/logs/var-log:/var/log
|
2016-11-14 06:47:40 +00:00
|
|
|
$sharedir/db:/var/lib/mysql
|
2016-11-15 08:59:02 +00:00
|
|
|
$dockerdir/bootstrap:/bootstrap
|
2016-11-12 03:28:49 +00:00
|
|
|
$dockerdir/scripts:/scripts:ro
|
2016-11-15 08:59:02 +00:00
|
|
|
$dockerdir/templates:/templates:ro
|
2016-11-12 03:28:49 +00:00
|
|
|
$dockerdir/scripts/tmp/check_init_admin.py:$installdir/check_init_admin.py:ro
|
2016-11-12 06:03:52 +00:00
|
|
|
$sharedir/.bash_history:/root/.bash_history
|
2016-11-11 04:54:47 +00:00
|
|
|
)
|
|
|
|
volumes=""
|
|
|
|
local m
|
|
|
|
for m in ${mounts[*]}; do
|
|
|
|
volumes="$volumes -v $m"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2016-11-15 08:59:02 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-11-21 04:56:33 +00:00
|
|
|
set_existing_container() {
|
|
|
|
existing=$(docker ps -a | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true)
|
|
|
|
}
|
|
|
|
|
2016-11-11 04:54:47 +00:00
|
|
|
bootstrap() {
|
2016-11-12 07:15:26 +00:00
|
|
|
if [[ ! -e $bootstrap_conf ]]; then
|
|
|
|
err_and_quit "The file $bootstrap_conf doesn't exist. Have you run seafile-server-setup?"
|
|
|
|
fi
|
2016-11-15 08:59:02 +00:00
|
|
|
|
2016-11-25 06:18:43 +00:00
|
|
|
docker history $image >/dev/null 2>&1 || {
|
|
|
|
show_progress "Pulling Seafile server image $version, this may take a while."
|
|
|
|
docker pull $image
|
2016-11-25 06:23:42 +00:00
|
|
|
show_progress "Seafile server image $version pulled. Now bootstrapping the server ..."
|
2016-11-25 06:18:43 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 08:59:02 +00:00
|
|
|
# First initialize seafile server and letsencrypt
|
|
|
|
set_bootstrap_volumes
|
2016-11-15 04:11:58 +00:00
|
|
|
set_ports
|
2016-11-15 08:59:02 +00:00
|
|
|
|
2016-11-21 05:07:09 +00:00
|
|
|
docker run $user_args --rm -it --name seafile-bootstrap -e SEAFILE_BOOTSRAP=1 $volumes $ports $image /sbin/my_init -- /scripts/bootstrap.py
|
2016-11-15 08:59:02 +00:00
|
|
|
|
2016-11-25 06:14:30 +00:00
|
|
|
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."
|
2016-11-11 04:54:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 08:59:02 +00:00
|
|
|
start() {
|
2016-11-21 04:56:33 +00:00
|
|
|
existing=$(docker ps | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true)
|
|
|
|
if [[ $existing != "" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Nothing to do, your container has already started!"
|
2016-11-21 04:56:33 +00:00
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2016-11-29 06:44:26 +00:00
|
|
|
check_version_match
|
|
|
|
|
2016-11-25 08:38:54 +00:00
|
|
|
chmod 0700 $dockerdir/bootstrap $sharedir/seafile/conf
|
|
|
|
|
2016-11-21 04:56:33 +00:00
|
|
|
set_existing_container
|
|
|
|
if [[ $existing != "" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "starting up existing container"
|
2016-11-21 04:56:33 +00:00
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker start seafile
|
|
|
|
)
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2016-11-15 08:59:02 +00:00
|
|
|
set_volumes
|
|
|
|
set_ports
|
2016-11-21 04:56:33 +00:00
|
|
|
|
2016-11-21 05:07:09 +00:00
|
|
|
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
|
|
|
|
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Starting up new seafile server container"
|
2016-11-21 04:56:33 +00:00
|
|
|
(
|
|
|
|
set -x
|
2016-11-21 05:34:46 +00:00
|
|
|
docker run $user_args $attach_on_run $restart_policy --name seafile -h seafile $volumes $ports $local_image
|
2016-11-21 04:56:33 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-11-25 07:28:20 +00:00
|
|
|
ensure_container_running() {
|
2016-11-21 04:56:33 +00:00
|
|
|
set_existing_container
|
2016-11-25 07:28:20 +00:00
|
|
|
if [[ $existing == "" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
err_and_quit "seafile was not started !"
|
2016-11-21 04:56:33 +00:00
|
|
|
fi
|
2016-11-11 04:54:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-25 07:28:20 +00:00
|
|
|
stop() {
|
|
|
|
ensure_container_running
|
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker stop -t 10 seafile
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-11-11 04:54:47 +00:00
|
|
|
enter() {
|
2016-11-25 07:28:20 +00:00
|
|
|
ensure_container_running
|
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker exec -it seafile /bin/bash
|
|
|
|
)
|
2016-11-21 04:56:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
restart() {
|
|
|
|
stop
|
|
|
|
start
|
|
|
|
}
|
|
|
|
|
|
|
|
check_prereqs() {
|
2016-11-21 05:26:41 +00:00
|
|
|
if [[ $SKIP_PREREQS == "true" ]]; then
|
2016-11-21 05:07:09 +00:00
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# check docker
|
2016-11-21 04:56:33 +00:00
|
|
|
if ! which docker >/dev/null; then
|
|
|
|
install_docker
|
|
|
|
fi
|
2016-11-21 05:07:09 +00:00
|
|
|
# TODO: check git version
|
|
|
|
}
|
|
|
|
|
|
|
|
logs() {
|
2016-11-25 07:28:20 +00:00
|
|
|
ensure_container_running
|
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker logs --tail=20 -f seafile
|
|
|
|
)
|
2016-11-21 05:07:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
2016-11-25 08:10:29 +00:00
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker stop -t 10 seafile || true
|
|
|
|
docker rm seafile
|
|
|
|
)
|
2016-11-21 05:07:09 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 06:44:26 +00:00
|
|
|
get_major_version() {
|
|
|
|
echo $1| awk -F . '{printf "%s.%s", $1, $2}'
|
|
|
|
}
|
|
|
|
|
|
|
|
check_version_match() {
|
|
|
|
local last_version last_major_version current_major_version
|
|
|
|
last_version=$(cat $version_stamp_file)
|
|
|
|
last_major_version=$(get_major_version $last_version)
|
|
|
|
current_major_version=$(get_major_version $version)
|
|
|
|
|
|
|
|
if [[ $last_major_version != "$current_major_version" ]]; then
|
|
|
|
show_progress "******* Major upgrade detected *******"
|
|
|
|
show_progress "You have $last_version, latest is $version"
|
|
|
|
show_progress "Please run './launcher rebuild' to upgrade"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
check_upgrade() {
|
|
|
|
show_progress "Checking if there is major version upgrade"
|
|
|
|
|
|
|
|
local last_version last_major_version current_major_version
|
|
|
|
last_version=$(cat $version_stamp_file)
|
|
|
|
last_major_version=$(get_major_version $last_version)
|
|
|
|
current_major_version=$(get_major_version $version)
|
|
|
|
|
|
|
|
if [[ $last_major_version == "$current_major_version" ]]; then
|
|
|
|
return
|
|
|
|
else
|
|
|
|
show_progress "********************************"
|
|
|
|
show_progress "Major upgrade detected: You have $last_version, latest is $version"
|
|
|
|
show_progress "********************************"
|
|
|
|
|
|
|
|
# use_manual_upgrade=true
|
|
|
|
if [[ $use_manual_upgrade == "true" ]]; then
|
|
|
|
show_progress "Now you can run './launcher manual-upgrade' to do manual upgrade."
|
|
|
|
exit 0
|
|
|
|
else
|
|
|
|
show_progress "Going to launch the docker container for manual upgrade"
|
|
|
|
_launch_for_upgrade --auto
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
_launch_for_upgrade() {
|
|
|
|
local cmd
|
|
|
|
if [[ $1 == "--auto" ]]; then
|
|
|
|
cmd="/scripts/upgrade.py"
|
|
|
|
else
|
|
|
|
cmd="/bin/bash"
|
|
|
|
fi
|
|
|
|
|
|
|
|
set_volumes
|
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker run $user_args \
|
|
|
|
-it --rm --name seafile-upgrade -h seafile \
|
|
|
|
$volumes $local_image \
|
|
|
|
/sbin/my_init -- $cmd
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2016-11-21 05:07:09 +00:00
|
|
|
rebuild() {
|
2016-11-25 04:33:10 +00:00
|
|
|
if [[ "$(git symbolic-ref --short HEAD)" == "master" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Ensuring launcher is up to date"
|
2016-11-25 04:33:10 +00:00
|
|
|
|
|
|
|
git remote update
|
|
|
|
|
|
|
|
LOCAL=$(git rev-parse @)
|
|
|
|
REMOTE=$(git rev-parse "@{u}")
|
|
|
|
BASE=$(git merge-base @ "@{u}")
|
|
|
|
|
|
|
|
if [[ $LOCAL = "$REMOTE" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Launcher is up-to-date"
|
2016-11-25 04:33:10 +00:00
|
|
|
|
|
|
|
elif [[ $LOCAL = "$BASE" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Updating Launcher"
|
2016-11-25 04:33:10 +00:00
|
|
|
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
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Your version of Launcher is ahead of origin"
|
2016-11-25 04:33:10 +00:00
|
|
|
else
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Launcher has diverged source, this is only expected in Dev mode"
|
2016-11-25 04:33:10 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
set_existing_container
|
|
|
|
|
|
|
|
if [[ $existing != "" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Stopping old container"
|
2016-11-25 04:33:10 +00:00
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker stop -t 10 seafile
|
|
|
|
)
|
|
|
|
fi
|
|
|
|
|
|
|
|
bootstrap
|
2016-11-28 09:07:13 +00:00
|
|
|
show_progress "Rebuilt successfully."
|
2016-11-25 04:33:10 +00:00
|
|
|
|
|
|
|
if [[ $existing != "" ]]; then
|
2016-11-25 06:14:30 +00:00
|
|
|
show_progress "Removing old container"
|
2016-11-25 04:33:10 +00:00
|
|
|
(
|
|
|
|
set -x
|
|
|
|
docker rm seafile
|
|
|
|
)
|
|
|
|
fi
|
|
|
|
|
2016-11-29 06:44:26 +00:00
|
|
|
check_upgrade
|
|
|
|
|
2016-11-25 04:33:10 +00:00
|
|
|
start
|
2016-11-25 06:14:30 +00:00
|
|
|
|
|
|
|
show_progress "Your seafile server is now running."
|
2016-11-25 04:33:10 +00:00
|
|
|
exit 0
|
2016-11-11 04:54:47 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 06:44:26 +00:00
|
|
|
manual_upgrade() {
|
|
|
|
_launch_for_upgrade
|
|
|
|
}
|
|
|
|
|
2016-11-15 04:11:58 +00:00
|
|
|
main() {
|
2016-11-11 04:54:47 +00:00
|
|
|
local action
|
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
do
|
|
|
|
case "$1" in
|
2016-11-29 06:44:26 +00:00
|
|
|
bootstrap|start|stop|restart|enter|destroy|logs|rebuild|manual-upgrade)
|
|
|
|
action=${1//-/_} ; shift 1 ;;
|
|
|
|
--skip-prereqs) SKIP_PREREQS=true ; shift 1 ;;
|
|
|
|
--docker-args) user_args=$2 ; shift 2 ;;
|
|
|
|
--manual-upgrade) use_manual_upgrade=true ; shift 1 ;;
|
2016-11-15 08:59:02 +00:00
|
|
|
*) err_and_quit "Argument error. Please see help." ;;
|
2016-11-11 04:54:47 +00:00
|
|
|
esac
|
|
|
|
done
|
2016-11-29 06:44:26 +00:00
|
|
|
|
2016-11-11 04:54:47 +00:00
|
|
|
"$action"
|
|
|
|
}
|
|
|
|
|
2016-11-21 04:56:33 +00:00
|
|
|
check_prereqs
|
2016-11-11 04:54:47 +00:00
|
|
|
main "$@"
|