106 lines
4.8 KiB
Bash
Executable File
106 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Van Emous CRM lokaal deployen vanaf een git-tag (zelfde werkwijze als straks op de server).
|
|
#
|
|
# ./deploy.sh nieuwste tag installeren en starten
|
|
# ./deploy.sh v0.0.1 een bepaalde versie (ook om terug te rollen)
|
|
# ./deploy.sh start de huidige versie starten zonder opnieuw te installeren
|
|
# ./deploy.sh list geïnstalleerde versies tonen
|
|
#
|
|
# Elke versie komt uit `git archive <tag>` (precies wat getagd is, niet de werkkopie) in
|
|
# $CRM_HOME/releases/<tag> met een eigen venv. `current` wijst naar de actieve versie.
|
|
# De data ($CRM_HOME/data) is gedeeld en blijft bestaan; vóór elke versiewissel gaat er
|
|
# een kopie van de database naar data/backups/, omdat migraties bij het starten draaien.
|
|
#
|
|
# De 3D-engine voor de viewer (gekozen model) zit niet in git: bij elke deploy komt die uit de
|
|
# configurator ($CONFIGURATOR, standaard ../configurator) in de actieve versie (tools/configurator-sync.sh).
|
|
#
|
|
# Instellingen via omgevingsvariabelen: CRM_HOME (standaard ~/.local/share/vanemous-crm),
|
|
# PORT (5050), HOST (127.0.0.1), WORKERS (2), CONFIGURATOR (../configurator).
|
|
set -euo pipefail
|
|
|
|
REPO="$(cd "$(dirname "$0")" && pwd)"
|
|
CRM_HOME="${CRM_HOME:-$HOME/.local/share/vanemous-crm}"
|
|
RELEASES="$CRM_HOME/releases"
|
|
DATA="$CRM_HOME/data"
|
|
PORT="${PORT:-5050}"
|
|
HOST="${HOST:-127.0.0.1}"
|
|
WORKERS="${WORKERS:-2}"
|
|
CONFIGURATOR="${CONFIGURATOR:-$REPO/../configurator}"
|
|
|
|
say() { printf '\033[38;2;185;89;19m▸\033[0m %s\n' "$*"; }
|
|
fail() { printf 'Fout: %s\n' "$*" >&2; exit 1; }
|
|
|
|
current_version() { [ -L "$CRM_HOME/current" ] && basename "$(readlink "$CRM_HOME/current")" || true; }
|
|
|
|
start() {
|
|
local dir="$CRM_HOME/current"
|
|
[ -d "$dir" ] || fail "nog geen versie geïnstalleerd; draai eerst ./deploy.sh"
|
|
say "Van Emous CRM $(current_version) op http://$HOST:$PORT (Ctrl+C om te stoppen)"
|
|
say "data: $DATA"
|
|
cd "$dir"
|
|
CRM_DATA="$DATA" exec "$dir/.venv/bin/gunicorn" --workers "$WORKERS" --bind "$HOST:$PORT" \
|
|
--access-logfile - --error-logfile - app:app
|
|
}
|
|
|
|
case "${1:-}" in
|
|
list)
|
|
active="$(current_version)"
|
|
for d in "$RELEASES"/*/; do
|
|
[ -d "$d" ] || { echo "Nog geen versies geïnstalleerd."; exit 0; }
|
|
v="$(basename "$d")"; [ "$v" = "$active" ] && echo "* $v (actief)" || echo " $v"
|
|
done
|
|
exit 0 ;;
|
|
start) start ;;
|
|
esac
|
|
|
|
# --- welke versie ---------------------------------------------------------------
|
|
git -C "$REPO" rev-parse --git-dir >/dev/null 2>&1 || fail "$REPO is geen git-repository"
|
|
TAG="${1:-$(git -C "$REPO" tag --list 'v*' --sort=-v:refname | head -n1)}"
|
|
[ -n "$TAG" ] || fail "geen versietags gevonden (verwacht bijv. v0.0.1)"
|
|
[[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "onbekende versie '$TAG' (verwacht vX.Y.Z)"
|
|
git -C "$REPO" rev-parse -q --verify "refs/tags/$TAG" >/dev/null || fail "tag $TAG bestaat niet"
|
|
|
|
# versie in de code moet bij de tag horen
|
|
code_version="$(git -C "$REPO" show "$TAG:app.py" | sed -nE "s/^__version__ = '([^']+)'.*/\1/p")"
|
|
[ "v$code_version" = "$TAG" ] || fail "tag $TAG bevat __version__ = '$code_version' in app.py; tag en code komen niet overeen"
|
|
|
|
if [ -n "$(git -C "$REPO" status --porcelain)" ]; then
|
|
say "let op: je werkkopie heeft niet-gecommitte wijzigingen; die zitten niet in $TAG"
|
|
fi
|
|
|
|
# --- installeren ----------------------------------------------------------------
|
|
target="$RELEASES/$TAG"
|
|
mkdir -p "$RELEASES" "$DATA/backups"
|
|
if [ -f "$target/.installed" ]; then
|
|
say "$TAG is al geïnstalleerd"
|
|
else
|
|
say "$TAG uitpakken naar $target"
|
|
rm -rf "$target"; mkdir -p "$target"
|
|
git -C "$REPO" archive "$TAG" | tar -x -C "$target"
|
|
say "venv en afhankelijkheden installeren"
|
|
python3 -m venv "$target/.venv"
|
|
"$target/.venv/bin/pip" install --quiet --upgrade pip
|
|
"$target/.venv/bin/pip" install --quiet -r "$target/requirements.txt" gunicorn
|
|
"$target/.venv/bin/python" -m py_compile "$target"/*.py
|
|
git -C "$REPO" rev-parse "$TAG^{commit}" > "$target/.installed"
|
|
fi
|
|
|
|
# --- wisselen ---------------------------------------------------------------------
|
|
previous="$(current_version)"
|
|
if [ -f "$DATA/crm.db" ] && [ "$previous" != "$TAG" ]; then
|
|
backup="$DATA/backups/crm-$(date +%Y%m%d-%H%M%S)-${previous:-onbekend}-naar-$TAG.db"
|
|
# sqlite3 .backup is veilig bij WAL; anders een gewone kopie
|
|
if command -v sqlite3 >/dev/null; then sqlite3 "$DATA/crm.db" ".backup '$backup'"; else cp "$DATA/crm.db" "$backup"; fi
|
|
say "database geback-upt: $backup"
|
|
fi
|
|
ln -sfn "$target" "$CRM_HOME/current"
|
|
say "actief: $TAG${previous:+ (was $previous)}"
|
|
|
|
# --- 3D-engine (configurator) ------------------------------------------------------
|
|
if [ -x "$target/tools/configurator-sync.sh" ]; then
|
|
"$target/tools/configurator-sync.sh" "$(cd "$CONFIGURATOR" 2>/dev/null && pwd || echo "$CONFIGURATOR")" "$target/static/configurator" \
|
|
|| say "let op: geen configurator in $CONFIGURATOR; de viewer van het gekozen model werkt dan niet"
|
|
fi
|
|
|
|
start
|