2024-09-02 22:51:10 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
## CONSTANTS ##
|
|
|
|
readonly CODEBASE_DIR="/opt/etebase"
|
|
|
|
readonly DATA_DIR="/opt/etebase-data"
|
|
|
|
|
|
|
|
|
|
|
|
## HANDLE EXIT SIGNALS ##
|
|
|
|
trap trap_exit EXIT SIGINT SIGTERM
|
|
|
|
trap_exit(){
|
|
|
|
if [[ "${pid:+x}" ]]; then
|
|
|
|
kill -- $pid 2> /dev/null || true
|
|
|
|
q=0
|
|
|
|
while proc_running $pid; do
|
|
|
|
q=$(( q + 1 ))
|
|
|
|
snore 1
|
|
|
|
if [[ "$q" -ge 15 ]]; then
|
|
|
|
log_warn "Sending kill to Etebase"
|
|
|
|
kill -s KILL -- $pid 2> /dev/null || true
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# LIB: Efficient sleep (does not create a new process).
|
|
|
|
#
|
|
|
|
snore(){
|
|
|
|
local IFS
|
|
|
|
[[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:)
|
|
|
|
read ${1:+-t "$1"} -u $_snore_fd || true
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# HELPER: Check whether given pid is running.
|
|
|
|
#
|
|
|
|
# @param $1 Process ID.
|
|
|
|
#
|
|
|
|
# @exit 0: Process is running
|
|
|
|
# 1: Process is not running.
|
|
|
|
#
|
|
|
|
proc_running(){
|
|
|
|
# try reading state
|
|
|
|
local state_path="/proc/$1/stat"
|
|
|
|
[[ ! -f "$state_path" ]] && return 1
|
|
|
|
local state
|
|
|
|
state=$(cat "$state_path" 2> /dev/null | cut -d ' ' -f3) || return 1
|
|
|
|
|
|
|
|
# parse state
|
|
|
|
case "$state" in
|
|
|
|
R|S|D|Z|W|W|P|I) return 0;;
|
|
|
|
*) return 1;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# HELPER: Initialize etebase config files.
|
|
|
|
#
|
|
|
|
etebase_config_init(){
|
|
|
|
## MAYBE CREATE SYMLINK ##
|
|
|
|
if [[ ! -h "${CODEBASE_DIR}/etebase-server.ini" ]]; then
|
|
|
|
ln -s "${DATA_DIR}/server.ini" "${CODEBASE_DIR}/etebase-server.ini"
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
## MAYBE WRITE DEFAULT FILE ##
|
|
|
|
if [[ ! -f "${DATA_DIR}/server.ini" ]]; then
|
|
|
|
echo "[global]
|
|
|
|
debug = false
|
|
|
|
secret_file = ${DATA_DIR}/secret.txt
|
|
|
|
static_root = ${CODEBASE_DIR}/static
|
|
|
|
media_root = ${DATA_DIR}/media
|
|
|
|
;language_code = en-us
|
|
|
|
;time_zone = UTC
|
|
|
|
|
|
|
|
[allowed_hosts]
|
|
|
|
allowed_host1 = *
|
|
|
|
|
|
|
|
[database]
|
|
|
|
engine = django.db.backends.sqlite3
|
2024-09-02 23:07:32 +02:00
|
|
|
name = ${DATA_DIR}/db.sqlite3" > "${DATA_DIR}/server.ini"
|
2024-09-02 22:51:10 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# HELPER: Initialize django app.
|
|
|
|
#
|
|
|
|
etebase_app_init(){
|
|
|
|
## RUN MIGRATIONS ##
|
|
|
|
.venv/bin/python3 ./manage.py migrate
|
|
|
|
|
|
|
|
|
|
|
|
## MAYBE COPY STATIC FILES ##
|
|
|
|
if [[ ! -d "${CODEBASE_DIR}/static" ]]; then
|
|
|
|
.venv/bin/python3 ./manage.py collectstatic
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
## OVERWRITE INDEX PAGE ##
|
|
|
|
cat /index.html > "${CODEBASE_DIR}/etebase_server/templates/success.html"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## SET UP DATA DIRECTORIES ##
|
|
|
|
mkdir -p "$DATA_DIR"
|
|
|
|
mkdir -p "${DATA_DIR}/media"
|
|
|
|
|
|
|
|
|
|
|
|
## INITIALIZE CONFIG ##
|
|
|
|
etebase_config_init
|
|
|
|
|
|
|
|
|
|
|
|
## INITIALIZE DJANGO APP ##
|
|
|
|
etebase_app_init
|
|
|
|
|
|
|
|
|
|
|
|
## RUN SERVER ##
|
|
|
|
.venv/bin/uvicorn etebase_server.asgi:application --host 0.0.0.0 --port 80 & pid=$!
|
|
|
|
wait $pid
|