194 lines
3.8 KiB
Bash
Executable File
194 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
CONFIG_FILE="/opt/appfactory/config/appfactory.env"
|
|
source "$CONFIG_FILE"
|
|
|
|
APP_ID="${1:-}"
|
|
|
|
if [ -z "$APP_ID" ]; then
|
|
echo "Usage: ./deploy-app.sh <app-id>"
|
|
exit 1
|
|
fi
|
|
|
|
export DOCKER_CONFIG="/tmp/.docker"
|
|
mkdir -p "$DOCKER_CONFIG"
|
|
|
|
DB_FILE="/opt/appfactory/data/appfactory/appfactory.db"
|
|
APP_SOURCE_DIR="$WORKSPACE_DIR/$APP_ID"
|
|
TOOLS_DIR="$WORKSPACE_DIR/appfactory-tools"
|
|
|
|
if [ ! -d "$APP_SOURCE_DIR" ]; then
|
|
echo "Missing app source: $APP_SOURCE_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$APP_SOURCE_DIR/Dockerfile" ]; then
|
|
echo "Missing Dockerfile in: $APP_SOURCE_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
DEPLOY_ID="$(python3 - "$DB_FILE" "$APP_ID" <<'PY'
|
|
import sqlite3
|
|
import sys
|
|
|
|
db_file = sys.argv[1]
|
|
app_id = sys.argv[2]
|
|
|
|
con = sqlite3.connect(db_file)
|
|
|
|
cur = con.execute(
|
|
"""
|
|
INSERT INTO deployments (
|
|
app_id,
|
|
kind,
|
|
status,
|
|
started_at
|
|
)
|
|
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
|
|
""",
|
|
(app_id, "app", "running"),
|
|
)
|
|
|
|
con.execute(
|
|
"""
|
|
UPDATE apps
|
|
SET status = 'deploying',
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = ?
|
|
""",
|
|
(app_id,),
|
|
)
|
|
|
|
con.commit()
|
|
print(cur.lastrowid)
|
|
con.close()
|
|
PY
|
|
)"
|
|
|
|
TMP_DIR="$(mktemp -d)"
|
|
STDOUT_FILE="$TMP_DIR/stdout.log"
|
|
STDERR_FILE="$TMP_DIR/stderr.log"
|
|
|
|
finish_deploy() {
|
|
local status="$1"
|
|
local returncode="$2"
|
|
|
|
python3 - "$DB_FILE" "$DEPLOY_ID" "$APP_ID" "$status" "$returncode" "$STDOUT_FILE" "$STDERR_FILE" <<'PY'
|
|
import sqlite3
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
db_file = sys.argv[1]
|
|
deploy_id = sys.argv[2]
|
|
app_id = sys.argv[3]
|
|
status = sys.argv[4]
|
|
returncode = int(sys.argv[5])
|
|
stdout_file = Path(sys.argv[6])
|
|
stderr_file = Path(sys.argv[7])
|
|
|
|
stdout = stdout_file.read_text(errors="replace") if stdout_file.exists() else ""
|
|
stderr = stderr_file.read_text(errors="replace") if stderr_file.exists() else ""
|
|
|
|
app_status = "deployed" if status == "success" else "failed"
|
|
|
|
con = sqlite3.connect(db_file)
|
|
|
|
con.execute(
|
|
"""
|
|
UPDATE deployments
|
|
SET status = ?,
|
|
finished_at = CURRENT_TIMESTAMP,
|
|
stdout = ?,
|
|
stderr = ?,
|
|
returncode = ?
|
|
WHERE id = ?
|
|
""",
|
|
(status, stdout, stderr, returncode, deploy_id),
|
|
)
|
|
|
|
con.execute(
|
|
"""
|
|
UPDATE apps
|
|
SET status = ?,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = ?
|
|
""",
|
|
(app_status, app_id),
|
|
)
|
|
|
|
con.commit()
|
|
con.close()
|
|
PY
|
|
|
|
rm -rf "$TMP_DIR"
|
|
}
|
|
|
|
run_step() {
|
|
local title="$1"
|
|
shift
|
|
|
|
{
|
|
echo ""
|
|
echo "=================================================="
|
|
echo "$title"
|
|
echo "=================================================="
|
|
"$@"
|
|
} >>"$STDOUT_FILE" 2>>"$STDERR_FILE"
|
|
}
|
|
|
|
set +e
|
|
|
|
run_step "Updating source code" bash -c "
|
|
cd '$APP_SOURCE_DIR'
|
|
if [ -d '.git' ]; then
|
|
git -c safe.directory='$APP_SOURCE_DIR' fetch origin main
|
|
git -c safe.directory='$APP_SOURCE_DIR' reset --hard origin/main
|
|
fi
|
|
"
|
|
|
|
RESULT=$?
|
|
|
|
if [ "$RESULT" -eq 0 ]; then
|
|
run_step "Building Docker image" docker build --pull --no-cache -t "$APP_ID:latest" "$APP_SOURCE_DIR"
|
|
RESULT=$?
|
|
fi
|
|
|
|
if [ "$RESULT" -eq 0 ]; then
|
|
run_step "Regenerating generated files" bash -c "
|
|
'$TOOLS_DIR/scripts/generate-catalog.sh'
|
|
'$TOOLS_DIR/scripts/generate-apps-compose.sh'
|
|
'$TOOLS_DIR/scripts/generate-caddyfile.sh'
|
|
'$TOOLS_DIR/scripts/generate-apps-page.sh'
|
|
"
|
|
RESULT=$?
|
|
fi
|
|
|
|
if [ "$RESULT" -eq 0 ]; then
|
|
run_step "Starting app container" bash -c "
|
|
cd '$APPFACTORY_DIR/deploy'
|
|
docker compose -f docker-compose.yml -f apps-compose.yml up -d --force-recreate '$APP_ID'
|
|
"
|
|
RESULT=$?
|
|
fi
|
|
|
|
set -e
|
|
|
|
if [ "$RESULT" -eq 0 ]; then
|
|
finish_deploy "success" 0
|
|
cat "$STDOUT_FILE"
|
|
cat "$STDERR_FILE" >&2
|
|
echo ""
|
|
echo "DONE"
|
|
echo "Open:"
|
|
echo "$APPFACTORY_PUBLIC_URL/apps/$APP_ID/docs"
|
|
else
|
|
finish_deploy "failed" "$RESULT"
|
|
cat "$STDOUT_FILE"
|
|
cat "$STDERR_FILE" >&2
|
|
echo ""
|
|
echo "FAILED"
|
|
echo "Deployment ID: $DEPLOY_ID"
|
|
exit "$RESULT"
|
|
fi
|