Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1931e07013 | |||
| c81aa882e9 | |||
| 142e6e990e | |||
| 9333b5cdd0 | |||
| b11739de3b | |||
| 269f084227 | |||
| 46b9e0b3b2 |
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
dist
|
dist
|
||||||
logs
|
logs
|
||||||
certs
|
certs
|
||||||
build
|
build
|
||||||
|
.venv
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
# Inventarsystem
|
# Inventarsystem
|
||||||
|
|
||||||
|
[](https://github.com/AIIrondev/legendary-octo-garbanzo/actions/workflows/release-docker.yml)
|
||||||
|
|
||||||
[](https://wakatime.com/badge/user/30b8509f-5e17-4d16-b6b8-3ca0f3f936d3/project/8a380b7f-389f-4a7e-8877-0fe9e1a4c243)
|
[](https://wakatime.com/badge/user/30b8509f-5e17-4d16-b6b8-3ca0f3f936d3/project/8a380b7f-389f-4a7e-8877-0fe9e1a4c243)
|
||||||
|
|
||||||
**Aktuelle Version: 3.2.1**
|
**Aktuelle Version: 3.2.1**
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css', v=APP_VERSION) }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/planned_appointments.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/planned_appointments.css', v=APP_VERSION) }}">
|
||||||
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
+83
@@ -36,6 +36,83 @@ need_cmd() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refresh_start_script_from_main() {
|
||||||
|
local start_url
|
||||||
|
start_url="https://raw.githubusercontent.com/$REPO_SLUG/main/start.sh"
|
||||||
|
|
||||||
|
if curl -fsSL "$start_url" -o "$TMP_DIR/start.sh"; then
|
||||||
|
sudo install -m 755 "$TMP_DIR/start.sh" "$PROJECT_DIR/start.sh"
|
||||||
|
else
|
||||||
|
echo "Warning: failed to refresh start.sh from main; using bundled start.sh"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_compose_app_image() {
|
||||||
|
local tag="$1"
|
||||||
|
local compose_file
|
||||||
|
compose_file="$PROJECT_DIR/docker-compose.yml"
|
||||||
|
|
||||||
|
if [ ! -f "$compose_file" ]; then
|
||||||
|
echo "Warning: $compose_file not found; cannot pin app image"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 - <<'PY' "$compose_file" "$tag"
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
compose_file, tag = sys.argv[1], sys.argv[2]
|
||||||
|
target_image = f"ghcr.io/aiirondev/legendary-octo-garbanzo:{tag}"
|
||||||
|
|
||||||
|
with open(compose_file, "r", encoding="utf-8") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
out = []
|
||||||
|
in_app = False
|
||||||
|
in_build = False
|
||||||
|
image_set = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.lstrip(" ")
|
||||||
|
indent = len(line) - len(stripped)
|
||||||
|
|
||||||
|
if not in_app and re.match(r"^\s{2}app:\s*$", line):
|
||||||
|
in_app = True
|
||||||
|
image_set = False
|
||||||
|
out.append(line)
|
||||||
|
out.append(f" image: {target_image}\n")
|
||||||
|
image_set = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if in_app:
|
||||||
|
if indent == 2 and re.match(r"^[A-Za-z0-9_-]+:\s*$", stripped):
|
||||||
|
in_app = False
|
||||||
|
in_build = False
|
||||||
|
|
||||||
|
if in_app:
|
||||||
|
if in_build:
|
||||||
|
if indent > 4:
|
||||||
|
continue
|
||||||
|
in_build = False
|
||||||
|
|
||||||
|
if re.match(r"^\s{4}build:\s*$", line):
|
||||||
|
in_build = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if re.match(r"^\s{4}image:\s*", line):
|
||||||
|
if image_set:
|
||||||
|
continue
|
||||||
|
out.append(f" image: {target_image}\n")
|
||||||
|
image_set = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
out.append(line)
|
||||||
|
|
||||||
|
with open(compose_file, "w", encoding="utf-8") as f:
|
||||||
|
f.writelines(out)
|
||||||
|
PY
|
||||||
|
}
|
||||||
|
|
||||||
install_docker_if_missing() {
|
install_docker_if_missing() {
|
||||||
if command -v docker >/dev/null 2>&1; then
|
if command -v docker >/dev/null 2>&1; then
|
||||||
return 0
|
return 0
|
||||||
@@ -292,6 +369,8 @@ main() {
|
|||||||
curl -fL "$bundle_url" -o "$TMP_DIR/$BUNDLE_ASSET"
|
curl -fL "$bundle_url" -o "$TMP_DIR/$BUNDLE_ASSET"
|
||||||
sudo tar -xzf "$TMP_DIR/$BUNDLE_ASSET" -C "$PROJECT_DIR"
|
sudo tar -xzf "$TMP_DIR/$BUNDLE_ASSET" -C "$PROJECT_DIR"
|
||||||
|
|
||||||
|
pin_compose_app_image "$tag"
|
||||||
|
|
||||||
if [ -z "$image_url" ]; then
|
if [ -z "$image_url" ]; then
|
||||||
echo "Error: release image asset is missing"
|
echo "Error: release image asset is missing"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -299,6 +378,8 @@ main() {
|
|||||||
|
|
||||||
curl -fL "$image_url" -o "$TMP_DIR/inventarsystem-image-$tag.tar.gz"
|
curl -fL "$image_url" -o "$TMP_DIR/inventarsystem-image-$tag.tar.gz"
|
||||||
sudo docker load -i "$TMP_DIR/inventarsystem-image-$tag.tar.gz" >/dev/null
|
sudo docker load -i "$TMP_DIR/inventarsystem-image-$tag.tar.gz" >/dev/null
|
||||||
|
# Compatibility alias: some legacy compose bundles may still reference :latest.
|
||||||
|
sudo docker tag "ghcr.io/aiirondev/legendary-octo-garbanzo:$tag" "ghcr.io/aiirondev/legendary-octo-garbanzo:latest" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
if [ ! -f "$PROJECT_DIR/start.sh" ]; then
|
if [ ! -f "$PROJECT_DIR/start.sh" ]; then
|
||||||
echo "Error: release bundle is missing start.sh"
|
echo "Error: release bundle is missing start.sh"
|
||||||
@@ -319,6 +400,8 @@ EOF
|
|||||||
sudo install -m 755 "$TMP_DIR/restart.sh" "$PROJECT_DIR/restart.sh"
|
sudo install -m 755 "$TMP_DIR/restart.sh" "$PROJECT_DIR/restart.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
refresh_start_script_from_main
|
||||||
|
|
||||||
if [ ! -f "$PROJECT_DIR/cleanup-old.sh" ] && [ -f "$INSTALLER_DIR/cleanup-old.sh" ]; then
|
if [ ! -f "$PROJECT_DIR/cleanup-old.sh" ] && [ -f "$INSTALLER_DIR/cleanup-old.sh" ]; then
|
||||||
sudo install -m 755 "$INSTALLER_DIR/cleanup-old.sh" "$PROJECT_DIR/cleanup-old.sh"
|
sudo install -m 755 "$INSTALLER_DIR/cleanup-old.sh" "$PROJECT_DIR/cleanup-old.sh"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
LOG_DIR="$PROJECT_DIR/logs"
|
LOG_DIR="$PROJECT_DIR/logs"
|
||||||
LOG_FILE="$LOG_DIR/update.log"
|
LOG_FILE="$LOG_DIR/update.log"
|
||||||
STATE_FILE="$PROJECT_DIR/.release-version"
|
STATE_FILE="$PROJECT_DIR/.release-version"
|
||||||
REPO_SLUG="AIIrondev/Inventarsystem"
|
REPO_SLUG="AIIrondev/legendary-octo-garbanzo"
|
||||||
API_URL="https://api.github.com/repos/$REPO_SLUG/releases/latest"
|
API_URL="https://api.github.com/repos/$REPO_SLUG/releases/latest"
|
||||||
BUNDLE_ASSET="inventarsystem-docker-bundle.tar.gz"
|
BUNDLE_ASSET="inventarsystem-docker-bundle.tar.gz"
|
||||||
APP_IMAGE_ASSET_PREFIX="inventarsystem-image-"
|
APP_IMAGE_ASSET_PREFIX="inventarsystem-image-"
|
||||||
ENV_FILE="$PROJECT_DIR/.docker-build.env"
|
ENV_FILE="$PROJECT_DIR/.docker-build.env"
|
||||||
APP_IMAGE_REPO="ghcr.io/aiirondev/inventarsystem"
|
APP_IMAGE_REPO="ghcr.io/aiirondev/legendary-octo-garbanzo"
|
||||||
DIST_DIR="$PROJECT_DIR/dist"
|
DIST_DIR="$PROJECT_DIR/dist"
|
||||||
|
|
||||||
mkdir -p "$LOG_DIR"
|
mkdir -p "$LOG_DIR"
|
||||||
@@ -234,10 +234,26 @@ load_release_image() {
|
|||||||
log_message "Loading app image from release asset $image_asset"
|
log_message "Loading app image from release asset $image_asset"
|
||||||
curl -fL "$image_url" -o "$archive"
|
curl -fL "$image_url" -o "$archive"
|
||||||
docker load -i "$archive" >> "$LOG_FILE" 2>&1
|
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
|
trap - RETURN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refresh_runtime_scripts_from_main() {
|
||||||
|
local start_url stop_url restart_url update_url
|
||||||
|
start_url="https://raw.githubusercontent.com/$REPO_SLUG/main/start.sh"
|
||||||
|
stop_url="https://raw.githubusercontent.com/$REPO_SLUG/main/stop.sh"
|
||||||
|
restart_url="https://raw.githubusercontent.com/$REPO_SLUG/main/restart.sh"
|
||||||
|
update_url="https://raw.githubusercontent.com/$REPO_SLUG/main/update.sh"
|
||||||
|
|
||||||
|
curl -fsSL "$start_url" -o "$PROJECT_DIR/start.sh" || log_message "WARNING: Could not refresh start.sh from main"
|
||||||
|
curl -fsSL "$stop_url" -o "$PROJECT_DIR/stop.sh" || log_message "WARNING: Could not refresh stop.sh 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() {
|
find_local_dist_image_archive() {
|
||||||
local tag="$1"
|
local tag="$1"
|
||||||
local archive
|
local archive
|
||||||
@@ -277,6 +293,7 @@ load_local_dist_image() {
|
|||||||
|
|
||||||
log_message "Loading app image from local dist artifact: $archive"
|
log_message "Loading app image from local dist artifact: $archive"
|
||||||
if docker load -i "$archive" >> "$LOG_FILE" 2>&1; then
|
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
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -342,6 +359,7 @@ EOF
|
|||||||
|
|
||||||
docker compose --env-file "$ENV_FILE" pull nginx mongodb >> "$LOG_FILE" 2>&1
|
docker compose --env-file "$ENV_FILE" pull nginx mongodb >> "$LOG_FILE" 2>&1
|
||||||
docker compose --env-file "$ENV_FILE" up -d --remove-orphans >> "$LOG_FILE" 2>&1
|
docker compose --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
|
||||||
}
|
}
|
||||||
|
|
||||||
verify_stack_health() {
|
verify_stack_health() {
|
||||||
@@ -460,6 +478,7 @@ main() {
|
|||||||
|
|
||||||
log_message "Updating from release $latest_tag"
|
log_message "Updating from release $latest_tag"
|
||||||
download_and_extract_bundle "$bundle_url" "$tmp_dir"
|
download_and_extract_bundle "$bundle_url" "$tmp_dir"
|
||||||
|
refresh_runtime_scripts_from_main
|
||||||
deploy "$latest_tag" "$meta_file"
|
deploy "$latest_tag" "$meta_file"
|
||||||
if ! verify_stack_health; then
|
if ! verify_stack_health; then
|
||||||
log_message "ERROR: Updated stack failed health check"
|
log_message "ERROR: Updated stack failed health check"
|
||||||
|
|||||||
Reference in New Issue
Block a user