372 lines
13 KiB
Bash
Executable File
372 lines
13 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"
|
|
POSTGRES_VERSION="9.5"
|
|
GISSMO_DOCKER_NAME="gissmo"
|
|
|
|
## User
|
|
if test -z "$GISSMO_CFG"; then
|
|
# No Gissmo Launcher configuration file given. Search one.
|
|
CONFIG_FILENAME="config"
|
|
# first in XDG directory, otherwise ~/.config one.
|
|
if test -z $XDG_CONFIG_HOME; then
|
|
CONFIG_DEFAULT_DIR="${HOME}/.config/gissmo"
|
|
else
|
|
CONFIG_DEFAULT_DIR="${XDG_CONFIG_HOME}"
|
|
fi
|
|
CONFIG_FILE="${CONFIG_DEFAULT_DIR}/${CONFIG_FILENAME}"
|
|
if ! test -f ${CONFIG_FILE}; then
|
|
CONFIG_FILE="${PWD}/${CONFIG_FILENAME}"
|
|
if ! test -f ${CONFIG_FILE}; then
|
|
echo "'config' file not found. Use 'config.example' file and copy it
|
|
to 'config' one either in ${CONFIG_DEFAULT_DIR}/ or ${PWD}/ directory. Then try again!"
|
|
exit 1
|
|
fi
|
|
fi
|
|
else
|
|
# Gissmo Launcher configuration file is given! Check it.
|
|
CONFIG_FILE=$GISSMO_CFG
|
|
if ! test -f $CONFIG_FILE; then
|
|
echo "Configuration file not found: ${CONFIG_FILE}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
. ${CONFIG_FILE} || 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 1
|
|
}
|
|
|
|
info() {
|
|
echo "${yellow}INFO${reset}: $1"
|
|
}
|
|
|
|
not_implemented() {
|
|
error_and_quit "Not implemented"
|
|
}
|
|
|
|
show_help() {
|
|
echo "$PROGRAM COMMAND [arg ...]"
|
|
echo -e " Where ${green}COMMAND${reset} is one of:"
|
|
echo -e " - backup Create a compressed postgreSQL database dump
|
|
in current directory"
|
|
echo -e " - create Create postgreSQL database volume and
|
|
postgreSQL Docker container"
|
|
echo -e " - dev [arg ...] 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:
|
|
python3 manage.py migrate"
|
|
echo -e " - psql Enter PSQL database via psql command"
|
|
echo -e " - restore dump Restore the given dump"
|
|
echo -e " - start [arg ...] 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"
|
|
echo ""
|
|
echo "Use README.md file for more explanations."
|
|
# TODO: Add clean() command with args to: STOP and DELETE Gissmo container,
|
|
# STOP and DELETE postgreSQL container, DELETE dbdata OR do all these
|
|
# things into one.
|
|
}
|
|
|
|
check_command() {
|
|
# Allowed commands return 0 to continue. Otherwise show help and exit
|
|
if test $1 == "backup"; then
|
|
return 0
|
|
elif test $1 == "create"; then
|
|
return 0
|
|
elif test $1 == "dev"; then
|
|
return 0
|
|
elif test $1 == "init"; then
|
|
return 0
|
|
elif test $1 == "psql"; 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 -P --volumes-from "${DB_VOLUME_NAME}" --name "${POSTGRES_DOCKER_NAME}" "postgres:${POSTGRES_VERSION}" || error_and_quit "Launching database docker container failed."
|
|
}
|
|
|
|
dev() {
|
|
initial_start
|
|
PORT_PARAM=" -p ${GISSMO_DOCKER_PORT}:8000 "
|
|
GISSMO_DEV_RUNNING_PORT=$(nc -z 127.0.0.1 ${GISSMO_DOCKER_PORT} &> /dev/null; echo $?)
|
|
if [ $GISSMO_DEV_RUNNING_PORT -eq 0 ]; then
|
|
PORT_PARAM=" -P "
|
|
fi
|
|
$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db ${PORT_PARAM} -v ${GISSMO_DIR}:/opt/gissmo -v ${UPLOAD_DIR}:/data gissmo:${GISSMO_VERSION} ${ARGS:='development'} || error_and_quit "Failed to create and launch ${GISSMO_DOCKER_NAME} container."
|
|
}
|
|
|
|
test_backup() {
|
|
# Check postgreSQL Docker container exists and is launched.
|
|
test_postgresql_launched
|
|
if [ $? -eq 1 ]; then
|
|
$docker_cmd start ${POSTGRES_DOCKER_NAME}
|
|
fi
|
|
}
|
|
|
|
backup() {
|
|
# Check all variables are availables
|
|
test_create
|
|
# Then check some specific things for dump method
|
|
test_backup
|
|
$docker_cmd run -it --rm --volume $PWD/:/tmp/ --link ${POSTGRES_DOCKER_NAME}:db postgres:${POSTGRES_VERSION} bash -c 'exec pg_dump -F c -h "$DB_PORT_5432_TCP_ADDR" -p "$DB_PORT_5432_TCP_PORT" -U postgres postgres > /tmp/gissmo-`date +"%Y.%m.%d.%H%M"`-'${GISSMO_VERSION}'.dump' || error_and_quit "Failed to backup Gissmo database."
|
|
}
|
|
|
|
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"
|
|
# On Fedora 23: gcc postgresql-devel python3-devel python-virtualenv git-core python3-pip redhat-rpm-config gmp-devel
|
|
# On ArchLinux: base-devel postgresql-libs python python-virtualenv git python-pip
|
|
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 ${GIT_BRANCH} || error_and_quit "Pull command on Git repository failed."
|
|
fi
|
|
info "Git repository state checked."
|
|
# install pre-commit hook that check code validity and more
|
|
if ! test -f "${GISSMO_DIR}/.git/hooks/pre-commit"; then
|
|
cp "${GISSMO_DIR}/scripts/git_hooks/pre-commit" "${GISSMO_DIR}/.git/hooks/pre-commit" || error_and_quit "Failed to install pre-commit hook."
|
|
info "Git repository pre-commit hook installed."
|
|
fi
|
|
source 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_initial_start
|
|
}
|
|
|
|
migrate() {
|
|
test_migrate
|
|
$docker_cmd run -it --rm --link ${POSTGRES_DOCKER_NAME}:db gissmo:${GISSMO_VERSION} python3 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%/*}"
|
|
}
|
|
|
|
psql() {
|
|
test_postgresql_launched
|
|
if [ $? -eq 1 ]; then
|
|
$docker_cmd start ${POSTGRES_DOCKER_NAME}
|
|
sleep 4 # wait postgreSQL database to be fully launched
|
|
fi
|
|
$docker_cmd run -it --link ${POSTGRES_DOCKER_NAME}:db --rm "postgres:${POSTGRES_VERSION}" sh -c 'exec psql -h "$DB_PORT_5432_TCP_ADDR" -p "$DB_PORT_5432_TCP_PORT" -U postgres' || error_and_quit "Failed to connect to postgreSQL Docker container."
|
|
}
|
|
|
|
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 -P --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 -f "$DOCKERFILE"; then
|
|
error_and_quit "Docker file don't exists: ${DOCKERFILE}"
|
|
fi
|
|
if test -z "$UPLOAD_DIR"; then
|
|
error_and_quit "No Gissmo upload directory given (UPLOAD_DIR in config file)."
|
|
fi
|
|
# Build Gissmo Docker images if missing
|
|
if [[ "$($docker_cmd images -q gissmo:${GISSMO_VERSION} 2> /dev/null)" == "" ]]; then
|
|
cd "$GISSMO_DIR"
|
|
info "Building Docker images…"
|
|
$docker_cmd build -t gissmo:${GISSMO_VERSION} -f ${DOCKERFILE} . || error_and_quit "Failed to build Gissmo Docker container."
|
|
info "…done."
|
|
cd "$CURRENT_DIR"
|
|
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
|
|
# 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} -v ${UPLOAD_DIR}:/data 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! If you need
|
|
another name please set GISSMO_DOCKER_NAME in configuration file."
|
|
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 -z $COMMAND; then
|
|
check_command "$COMMAND"
|
|
$COMMAND
|
|
else
|
|
show_help
|
|
fi
|
|
|
|
exit 0
|