eost_gissmo_tools/launch.sh

291 lines
9.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# CONFIG
## Default
PROGRAM=`basename $0`
docker_cmd=`which docker`
CURRENT_DIR=$(pwd)
GIT_URL="git@github.com:eost/gissmo.git"
GIT_BRANCH="dev" # Default Git Branch
GIT_DIR_NAME="gissmo"
DOCKERFILE_NAME="Dockerfile"
DB_DIR="/dbdata"
POSTGRES_VERSION="9.5"
GISSMO_DOCKER_NAME="gissmo"
## User
if ! test -f config; then
echo "'config' file not found. Copy config.example to config one and try again!"
exit 1
fi
. config || exit 1
## Composed
GISSMO_DIR="${PROJECT_DIR}/${GIT_DIR_NAME}"
DOCKERFILE="${GISSMO_DIR}/${DOCKERFILE_NAME}"
## Miscellaneous
COMMAND="$1"
shift 1; ARGS="$@"
red=`tput setaf 9`
green=`tput setaf 2`
yellow=`tput setaf 3`
blue=`tput setaf 4`
violet=`tput setaf 5`
cyan=`tput setaf 6`
white=`tput setaf 7`
reset=`tput sgr0` # No Color
# METHODS
error_and_continue() {
echo "${red}ERROR${reset}: $1"
}
error_and_quit() {
error_and_continue "$1"
exit 0
}
info() {
echo "${yellow}INFO${reset}: $1"
}
not_implemented() {
error_and_quit "Not implemented"
}
show_help() {
echo "$PROGRAM [COMMAND]"
echo -e " Where ${green}COMMAND${reset} is one of:"
echo -e " - create Create postgreSQL database volume and postgreSQL Docker container"
echo -e " - dev Mount git repository directory as volume for Gissmo Docker container and launch it in 'development' mode"
echo -e " - init Create project directory as python virtual environment, fetch git repository and install Python dependancies"
echo -e " - migrate Launch migration command: python manage.py migrate"
echo -e " - restore dump Restore the given dump"
echo -e " - start args Launch Gissmo Docker container (created by 'create' command) with a name given in GISSMO_DOCKER_NAME variable. args is optional."
echo -e " - stop Stop Gissmo Docker container which name is GISSMO_DOCKER_NAME variable content"
# TODO: Add clean() command to STOP and DELETE Gissmo Docker container
# TODO: Add clean_db() command to STOP and DELETE postgreSQL Docker container
# TODO: Add clean_all() command that makes clean() and clean_db()
}
check_command() {
# Allowed commands return 0 to continue. Otherwise show help and exit
if test $1 == "create"; then
return 0
elif test $1 == "dev"; then
return 0
elif test $1 == "init"; then
return 0
elif test $1 == "migrate"; then
return 0
elif test $1 == "restore"; then
return 0
elif test $1 == "start"; then
return 0
elif test $1 == "stop"; then
return 0
fi
error_and_continue "Unknown command."
show_help
exit 1
}
test_docker_cmd() {
if test -z "$docker_cmd"; then
error_and_quit "Docker command not found. Install docker or fill in the PATH."
fi
return 0
}
test_postgresql_exists() {
PSQL_RUNNING=$($docker_cmd inspect --format="{{ .State.Running }}" ${POSTGRES_DOCKER_NAME} 2> /dev/null)
if [ $? -eq 1 ]; then
error_and_quit "postgreSQL Docker container not found: ${POSTGRES_DOCKER_NAME}. Please launch '$PROGRAM create' first."
fi
}
test_postgresql_launched() {
PSQL_RUNNING=$($docker_cmd inspect --format="{{ .State.Running }}" ${POSTGRES_DOCKER_NAME} 2> /dev/null)
if test $PSQL_RUNNING == "false"; then
return 1
fi
return 0
}
test_create() {
test_docker_cmd
if test -z "$DB_DIR"; then
error_and_quit "No database directory given (DB_DIR in config file)."
fi
if test -z "$DB_VOLUME_NAME"; then
error_and_quit "No database volume name given (DB_VOLUME_NAME in config file)."
fi
if test -z "$POSTGRES_VERSION"; then
error_and_quit "No postgres version given (POSTGRES_VERSION in config file)."
fi
if test -z "$POSTGRES_DOCKER_NAME"; then
error_and_quit "You need a name for your Docker database container (POSTGRES_DOCKER_NAME in config file)."
fi
}
create() {
test_create
init
$docker_cmd create -v "${DB_DIR}:/var/lib/postgresql/data" --name "${DB_VOLUME_NAME}" "postgres:${POSTGRES_VERSION}" || error_and_quit "Initial database 'docker create' failed."
$docker_cmd run -d --volumes-from "${DB_VOLUME_NAME}" --name "${POSTGRES_DOCKER_NAME}" "postgres:${POSTGRES_VERSION}" || error_and_quit "Launching database docker container failed."
}
dev() {
initial_start
# Run existing Docker container, otherwise create a new one
GISSMO_RUNNING=$($docker_cmd inspect --format="{{ .State.Running }}" ${GISSMO_DOCKER_NAME} 2> /dev/null)
if [ $? -eq 1 ]; then
$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db -p ${GISSMO_DOCKER_PORT}:8000 -v ${GISSMO_DIR}:/opt/gissmo --name ${GISSMO_DOCKER_NAME} gissmo:${GISSMO_VERSION} development || error_and_quit "Failed to create and launch ${GISSMO_DOCKER_NAME} container."
else
error_and_quit "${GISSMO_DOCKER_NAME} is already launched!"
fi
}
init() {
# check directory existence
if ! test -d "$PROJECT_DIR"; then
mkdir -p "$PROJECT_DIR" || error_and_quit "Create ${PROJECT_DIR} failed."
info "$PROJECT_DIR created."
echo "${PROJECT_DIR} created."
virtualenv -p python3 $PROJECT_DIR || error_and_quit "Create ${PROJECT_DIR} python virtual environment failed."
info "Python virtual environment initialized."
fi
cd $PROJECT_DIR
sudo apt-get install -qq libpq-dev python3-dev python-virtualenv git-core python3-pip || error_and_quit "Dependancies installation failed."
info "Dependancies via apt-get checked/installed."
if ! test -d "$GISSMO_DIR/.git/"; then
git clone -q -b "$GIT_BRANCH" "$GIT_URL" "$GISSMO_DIR" || error_and_quit "Fetch Git repository failed."
else
GIT_WORK_TREE="${GISSMO_DIR}/" GIT_DIR="${GISSMO_DIR}/.git/" git pull -q origin master || error_and_quit "Pull command on Git repository failed."
fi
info "Git repository checked."
. bin/activate || error_and_quit "Failed entering python virtual environment"
cd $GISSMO_DIR
pip install -q -r requirements.txt || error_and_quit "Python dependancies installation failed."
info "Python dependancies checked."
deactivate || error_and_quit "Failed exiting python virtual environment."
}
test_migrate() {
test_start
}
migrate() {
test_migrate
$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db gissmo:${GISSMO_VERSION} python manage.py migrate || error_and_quit "Failed to launch Gissmo migration."
}
test_restore() {
if test -z $ARGS; then
error_and_quit "Missing database dump file"
fi
if ! test -f "$ARGS"; then
error_and_quit "File '${ARGS}' not found."
fi
DUMP_FILE=`basename $ARGS`
info "Dump file found: ${DUMP_FILE}"
DUMP_DIR="${ARGS%/*}"
}
restore() {
test_create
test_restore
$docker_cmd stop ${POSTGRES_DOCKER_NAME} && $docker_cmd rm ${POSTGRES_DOCKER_NAME} || error_and_quit "Failed to stop and delete postgreSQL Docker container: ${POSTGRES_DOCKER_NAME}"
sudo rm -rf ${DB_DIR} || error_and_quit "Failed to delete this directory: ${DB_DIR}"
$docker_cmd run -d --volumes-from "${DB_VOLUME_NAME}" --name "${POSTGRES_DOCKER_NAME}" "postgres:${POSTGRES_VERSION}" || error_and_quit "Launching database docker container failed."
sleep 6 # to wait about docker container runs totally
RESTORE_COMMAND="$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db -v ${DUMP_DIR}:/backup -e PGHOST=`$docker_cmd inspect -f \"{{ .NetworkSettings.IPAddress }}\" ${POSTGRES_DOCKER_NAME}` -e PGUSER=postgres postgres:${POSTGRES_VERSION} pg_restore -d postgres /backup/${DUMP_FILE}"
exec $RESTORE_COMMAND || error_and_quit "Failed to launch this command: ${CMD}"
}
test_initial_start() {
if test -z "$GISSMO_VERSION"; then
error_and_quit "No Gissmo version given (GISSMO_VERSION in config file)."
fi
if test -z "$GISSMO_DOCKER_PORT"; then
error_and_quit "No Gissmo Docker container port given (GISSMO_DOCKER_PORT in config file)."
fi
test_postgresql_exists
}
initial_start() {
test_initial_start
# Build Gissmo Docker images if missing
if [[ "$($docker_cmd images -q gissmo:${GISSMO_VERSION} 2> /dev/null)" == "" ]]; then
cd $GISSMO_DIR
$docker_cmd build -t gissmo:${GISSMO_VERSION} . || error_and_quit "Failed to build Gissmo Docker container."
cd $CURRENT_DIR
fi
# Check postgreSQL Docker container exists and is launched.
test_postgresql_launched
if [ $? -eq 1 ]; then
$docker_cmd start ${POSTGRES_DOCKER_NAME}
fi
}
start() {
initial_start
# Run existing Docker container, otherwise create a new one
GISSMO_RUNNING=$($docker_cmd inspect --format="{{ .State.Running }}" ${GISSMO_DOCKER_NAME} 2> /dev/null)
if [ $? -eq 1 ]; then
$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db -p ${GISSMO_DOCKER_PORT}:8000 -e SECRET_KEY="abcdefg" --name ${GISSMO_DOCKER_NAME} gissmo:${GISSMO_VERSION} $ARGS || error_and_quit "Failed to create and launch ${GISSMO_DOCKER_NAME} container."
else
error_and_quit "${GISSMO_DOCKER_NAME} is already launched!"
fi
}
test_stop(){
GISSMO_RUNNING=$($docker_cmd inspect --format="{{ .State.Running }}" ${GISSMO_DOCKER_NAME})
if [ $? -eq 1 ]; then
error_and_quit "Gissmo Docker container not found: ${GISSMO_DOCKER_NAME}. Please launch '$PROGRAM launch' first."
fi
}
stop() {
$docker_cmd stop $GISSMO_DOCKER_NAME || error_and_quit "Failed to stop $GISSMO_DOCKER_NAME Docker container."
info "${GISSMO_DOCKER_NAME} Docker container stopped successfully."
}
# CHECK CONFIG
if test -z $PROJECT_DIR; then
error_and_quit "No project directory given."
fi
if test -z $GIT_BRANCH; then
error_and_quit "No git branch given."
fi
# Don't check repository if INIT COMMAND is given
if ! test -d $GIT_REPOSITORY && ! test "$COMMAND" == "init"; then
error_and_quit "Repository don't exists: ${GIT_REPOSITORY}"
fi
if test -z $DOCKERFILE_NAME; then
error_and_quit "No docker filename given."
fi
if ! test -f $DOCKERFILE && ! test "$COMMAND" == "init"; then
error_and_quit "Docker file don't exists: ${DOCKERFILE}"
fi
if ! test -z $COMMAND; then
check_command "$COMMAND"
$COMMAND
else
show_help
fi
exit 1