Changes from old deployment system to new dynamic one
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Release-only updater for Docker deployment.
|
||||
# Updates are pulled exclusively from Gitea Releases assets.
|
||||
# Updates pull the deployment bundle from Gitea and the Docker Image via 'docker pull'.
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOG_DIR="$PROJECT_DIR/logs"
|
||||
@@ -11,13 +11,10 @@ STATE_FILE="$PROJECT_DIR/.release-version"
|
||||
REPO_SLUG="Invario/Inventarsystem"
|
||||
API_URL="https://git.invario-software.eu/api/v1/repos/$REPO_SLUG/releases/latest"
|
||||
BUNDLE_ASSET="inventarsystem-docker-bundle.tar.gz"
|
||||
APP_IMAGE_ASSET_PREFIX="inventarsystem-image-"
|
||||
ENV_FILE="$PROJECT_DIR/.docker-build.env"
|
||||
APP_IMAGE_REPO="git.invario-software.eu/invario/inventarsystem"
|
||||
DIST_DIR="$PROJECT_DIR/dist"
|
||||
COMPOSE_FILE="docker-compose-multitenant.yml"
|
||||
MIN_ROOT_FREE_MB="${INVENTAR_MIN_ROOT_FREE_MB:-2048}"
|
||||
DIST_KEEP_COUNT="${INVENTAR_DIST_KEEP_COUNT:-2}"
|
||||
MODE="release"
|
||||
|
||||
mkdir -p "$LOG_DIR"
|
||||
@@ -109,36 +106,6 @@ ensure_min_root_disk_space() {
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_old_dist_artifacts() {
|
||||
local keep_count
|
||||
keep_count="$DIST_KEEP_COUNT"
|
||||
|
||||
if [ ! -d "$DIST_DIR" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! [[ "$keep_count" =~ ^[0-9]+$ ]]; then
|
||||
keep_count=2
|
||||
fi
|
||||
|
||||
mapfile -t archives < <(find "$DIST_DIR" -maxdepth 1 -type f \( -name 'inventarsystem-image-*.tar.gz' -o -name 'inventarsystem-image-*.tar' \) -printf '%T@ %p\n' | sort -nr | awk '{print $2}')
|
||||
if [ "${#archives[@]}" -le "$keep_count" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local index old_archive deleted=0
|
||||
for (( index=keep_count; index<${#archives[@]}; index++ )); do
|
||||
old_archive="${archives[$index]}"
|
||||
if rm -f "$old_archive"; then
|
||||
deleted=$((deleted + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$deleted" -gt 0 ]; then
|
||||
log_message "Cleaned up $deleted old dist image archive(s)"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_docker_dangling_images() {
|
||||
if docker image prune -f >> "$LOG_FILE" 2>&1; then
|
||||
log_message "Cleaned up dangling Docker images"
|
||||
@@ -153,7 +120,6 @@ Usage: $0 [options]
|
||||
|
||||
Options:
|
||||
--multitenant Use docker-compose-multitenant.yml (default)
|
||||
development Install development build from Gitea Registry or local dist
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
}
|
||||
@@ -165,10 +131,6 @@ parse_args() {
|
||||
COMPOSE_FILE="docker-compose-multitenant.yml"
|
||||
shift
|
||||
;;
|
||||
development|dev)
|
||||
MODE="development"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
@@ -216,14 +178,12 @@ create_backup() {
|
||||
}
|
||||
|
||||
fetch_release_metadata() {
|
||||
local meta_file
|
||||
meta_file="$1"
|
||||
local meta_file="$1"
|
||||
curl -fsSL "$API_URL" -o "$meta_file"
|
||||
}
|
||||
|
||||
parse_latest_tag() {
|
||||
local meta_file
|
||||
meta_file="$1"
|
||||
local meta_file="$1"
|
||||
python3 - <<'PY' "$meta_file"
|
||||
import json, sys
|
||||
with open(sys.argv[1], 'r', encoding='utf-8') as f:
|
||||
@@ -233,9 +193,8 @@ PY
|
||||
}
|
||||
|
||||
parse_asset_url() {
|
||||
local meta_file asset_name
|
||||
meta_file="$1"
|
||||
asset_name="$2"
|
||||
local meta_file="$1"
|
||||
local asset_name="$2"
|
||||
python3 - <<'PY' "$meta_file" "$asset_name"
|
||||
import json, sys
|
||||
meta_file, asset_name = sys.argv[1], sys.argv[2]
|
||||
@@ -248,31 +207,6 @@ for asset in data.get('assets', []):
|
||||
PY
|
||||
}
|
||||
|
||||
load_release_image() {
|
||||
local meta_file tag image_asset image_url tmp_dir archive
|
||||
|
||||
meta_file="$1"
|
||||
tag="$2"
|
||||
image_asset="${APP_IMAGE_ASSET_PREFIX}${tag}.tar.gz"
|
||||
image_url="$(parse_asset_url "$meta_file" "$image_asset")"
|
||||
|
||||
if [ -z "$image_url" ]; then
|
||||
log_message "ERROR: Release image asset not found: $image_asset"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
archive="$tmp_dir/$image_asset"
|
||||
trap 'rm -rf "${tmp_dir:-}"' RETURN
|
||||
|
||||
log_message "Loading app image from release asset $image_asset"
|
||||
curl -fL "$image_url" -o "$archive"
|
||||
docker load -i "$archive" >> "$LOG_FILE" 2>&1
|
||||
docker tag "$APP_IMAGE_REPO:$tag" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
|
||||
|
||||
trap - RETURN
|
||||
}
|
||||
|
||||
refresh_runtime_scripts_from_main() {
|
||||
local start_url stop_url restart_url update_url
|
||||
start_url="https://git.invario-software.eu/$REPO_SLUG/raw/branch/main/start.sh"
|
||||
@@ -285,61 +219,13 @@ refresh_runtime_scripts_from_main() {
|
||||
curl -fsSL "$restart_url" -o "$PROJECT_DIR/restart.sh" || log_message "WARNING: Could not refresh restart.sh from main"
|
||||
curl -fsSL "$update_url" -o "$PROJECT_DIR/update.sh" || log_message "WARNING: Could not refresh update.sh from main"
|
||||
|
||||
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh"
|
||||
}
|
||||
|
||||
find_local_dist_image_archive() {
|
||||
local tag="$1"
|
||||
local archive
|
||||
|
||||
if [ ! -d "$DIST_DIR" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for archive in \
|
||||
"$DIST_DIR/inventarsystem-image-$tag.tar.gz" \
|
||||
"$DIST_DIR/inventarsystem-image-$tag.tar" \
|
||||
"$DIST_DIR/inventarsystem-image.tar.gz" \
|
||||
"$DIST_DIR/inventarsystem-image.tar"; do
|
||||
if [ -f "$archive" ]; then
|
||||
echo "$archive"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
archive="$(find "$DIST_DIR" -maxdepth 1 -type f \( -name 'inventarsystem-image-*.tar.gz' -o -name 'inventarsystem-image-*.tar' \) | sort | tail -n1)"
|
||||
if [ -n "$archive" ]; then
|
||||
echo "$archive"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
load_local_dist_image() {
|
||||
local tag="$1"
|
||||
local archive
|
||||
|
||||
archive="$(find_local_dist_image_archive "$tag" || true)"
|
||||
if [ -z "$archive" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_message "Loading app image from local dist artifact: $archive"
|
||||
if docker load -i "$archive" >> "$LOG_FILE" 2>&1; then
|
||||
docker tag "$APP_IMAGE_REPO:$tag" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_message "WARNING: Failed to load local dist artifact: $archive"
|
||||
return 1
|
||||
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" 2>/dev/null || true
|
||||
}
|
||||
|
||||
download_and_extract_bundle() {
|
||||
local url tmp_dir archive
|
||||
url="$1"
|
||||
tmp_dir="$2"
|
||||
archive="$tmp_dir/$BUNDLE_ASSET"
|
||||
local url="$1"
|
||||
local tmp_dir="$2"
|
||||
local archive="$tmp_dir/$BUNDLE_ASSET"
|
||||
|
||||
curl -fL "$url" -o "$archive"
|
||||
tar -xzf "$archive" -C "$tmp_dir"
|
||||
@@ -375,19 +261,15 @@ download_and_extract_bundle() {
|
||||
|
||||
# Ensure executable permissions on all copied scripts
|
||||
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" "$PROJECT_DIR/backup.sh" "$PROJECT_DIR/manage-tenant.sh" "$PROJECT_DIR/run-tenant-cmd.sh" 2>/dev/null || true
|
||||
chmod +x "$PROJECT_DIR"/manage-tenant.sh "$PROJECT_DIR"/run-tenant-cmd.sh 2>/dev/null || true
|
||||
|
||||
if [ ! -f "$PROJECT_DIR/config.json" ] && [ -f "$tmp_dir/config.json" ]; then
|
||||
cp -f "$tmp_dir/config.json" "$PROJECT_DIR/config.json"
|
||||
log_message "Installed default config.json from release bundle"
|
||||
fi
|
||||
|
||||
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" "$PROJECT_DIR/backup.sh" "$PROJECT_DIR/manage-tenant.sh" "$PROJECT_DIR/run-tenant-cmd.sh" 2>/dev/null || true
|
||||
}
|
||||
|
||||
deploy() {
|
||||
local tag="$1"
|
||||
local meta_file="$2"
|
||||
local app_image="${APP_IMAGE_REPO}:${tag}"
|
||||
local compose_path
|
||||
|
||||
@@ -410,17 +292,14 @@ EOF
|
||||
printf '\nINVENTAR_APP_IMAGE=%s\n' "$app_image" >> "$ENV_FILE"
|
||||
fi
|
||||
|
||||
if ! load_local_dist_image "$tag"; then
|
||||
if ! load_release_image "$meta_file" "$tag"; then
|
||||
log_message "Falling back to tagged Gitea Registry image $app_image"
|
||||
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
|
||||
log_message "Falling back to local Docker build for $app_image"
|
||||
docker build -t "$app_image" "$PROJECT_DIR" >> "$LOG_FILE" 2>&1
|
||||
fi
|
||||
fi
|
||||
log_message "Pulling Gitea Registry image $app_image"
|
||||
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
|
||||
log_message "Falling back to local Docker build for $app_image"
|
||||
docker build -t "$app_image" "$PROJECT_DIR" >> "$LOG_FILE" 2>&1
|
||||
fi
|
||||
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull app mongodb >> "$LOG_FILE" 2>&1
|
||||
# Image wurde oben gepullt, Stack hochfahren
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull mongodb redis >> "$LOG_FILE" 2>&1 || true
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" up -d --remove-orphans >> "$LOG_FILE" 2>&1
|
||||
docker tag "$app_image" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
|
||||
}
|
||||
@@ -460,9 +339,12 @@ cleanup_server_space() {
|
||||
else
|
||||
log_message "WARNING: Docker system prune failed"
|
||||
fi
|
||||
# Clean up old dist artifacts
|
||||
cleanup_old_dist_artifacts
|
||||
# Clean up log files older than 7 days
|
||||
# Delete legacy dist folder if it exists
|
||||
if [ -d "$PROJECT_DIR/dist" ]; then
|
||||
rm -rf "$PROJECT_DIR/dist" || true
|
||||
log_message "Legacy dist folder removed"
|
||||
fi
|
||||
# Clean up old log files older than 7 days
|
||||
if find "$LOG_DIR" -type f -name '*.log' -mtime +7 -exec rm -f {} +; then
|
||||
log_message "Old log files (older than 7 days) cleaned up"
|
||||
else
|
||||
@@ -511,17 +393,14 @@ EOF
|
||||
printf '\nINVENTAR_APP_IMAGE=%s\n' "$app_image" >> "$ENV_FILE"
|
||||
fi
|
||||
|
||||
# Try local dist first, then pull from Gitea Registry
|
||||
if ! load_local_dist_image "$tag"; then
|
||||
log_message "Attempting to pull development image $app_image"
|
||||
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
|
||||
log_message "ERROR: Could not obtain development image $app_image"
|
||||
exit 1
|
||||
fi
|
||||
log_message "Attempting to pull development image $app_image"
|
||||
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
|
||||
log_message "ERROR: Could not obtain development image $app_image"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Bring up stack
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull app mongodb >> "$LOG_FILE" 2>&1 || true
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull mongodb redis >> "$LOG_FILE" 2>&1 || true
|
||||
docker compose -f "$compose_path" --env-file "$ENV_FILE" up -d --remove-orphans >> "$LOG_FILE" 2>&1
|
||||
|
||||
if ! verify_stack_health; then
|
||||
@@ -581,7 +460,7 @@ EOF
|
||||
|
||||
if [ "$current_tag" = "$latest_tag" ]; then
|
||||
log_message "Already on latest release ($latest_tag). Refreshing containers from prebuilt image."
|
||||
deploy "$latest_tag" "$meta_file"
|
||||
deploy "$latest_tag"
|
||||
if verify_stack_health; then
|
||||
log_message "Container refresh completed"
|
||||
else
|
||||
@@ -611,18 +490,19 @@ EOF
|
||||
log_message "Updating from release $latest_tag"
|
||||
download_and_extract_bundle "$bundle_url" "$tmp_dir"
|
||||
refresh_runtime_scripts_from_main
|
||||
deploy "$latest_tag" "$meta_file"
|
||||
deploy "$latest_tag"
|
||||
if ! verify_stack_health; then
|
||||
log_message "ERROR: Updated stack failed health check"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$latest_tag" > "$STATE_FILE"
|
||||
cleanup_old_dist_artifacts
|
||||
cleanup_docker_dangling_images
|
||||
log_message "Update completed successfully to release $latest_tag"
|
||||
|
||||
sudo ./opt/Inventarsystem/restart.sh
|
||||
if [ -x "./opt/Inventarsystem/restart.sh" ]; then
|
||||
sudo ./opt/Inventarsystem/restart.sh
|
||||
fi
|
||||
echo "Restart of the Server Completed"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user