#!/usr/bin/env bash set -euo pipefail SERVICE_NAME="${SERVICE_NAME:-skd}" UPDATE_SERVICE_URL="${SKD_UPDATE_SERVICE_URL:-https://update.wlkns.org}" PROJECT_ID="${SKD_UPDATE_PROJECT_ID:-safe-kiddo-control}" UPDATE_TOKEN="${SKD_UPDATE_TOKEN:-}" STATUS_URL="${UPDATE_SERVICE_URL}/v1/projects/${PROJECT_ID}/status" INSTALL_DIR="${INSTALL_DIR:-/opt/sk}" STATUS_FILE="${SKD_UPDATE_STATUS_FILE:-/var/lib/skd/update_status.json}" LOG_FILE="${SKD_UPDATE_LOG_FILE:-/var/lib/skd/update_logs.jsonl}" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" } write_status() { local status="$1" local error="${2:-}" local version="$3" local timestamp timestamp="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" SKD_STATUS="${status}" SKD_ERROR="${error}" SKD_VERSION="${version}" \ SKD_STATUS_FILE="${STATUS_FILE}" SKD_LOG_FILE="${LOG_FILE}" python3 - <<'PY' import json import os from datetime import datetime, timezone from pathlib import Path status = os.environ["SKD_STATUS"] error = os.environ.get("SKD_ERROR", "") version = os.environ.get("SKD_VERSION", "unknown") status_file = Path(os.environ["SKD_STATUS_FILE"]) log_file = Path(os.environ["SKD_LOG_FILE"]) status_file.parent.mkdir(parents=True, exist_ok=True) log_file.parent.mkdir(parents=True, exist_ok=True) payload = { "device_id": os.uname().nodename, "version": version, "status": status, "error": error, "timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), } status_file.write_text(json.dumps(payload), encoding="utf-8") with log_file.open("a", encoding="utf-8") as handle: handle.write(json.dumps(payload) + "\n") PY local payload payload=$(cat </dev/null || true fi } LATEST_BACKUP="$(ls -dt /opt/sk_backup_* 2>/dev/null | head -1 || true)" if [[ -z "${LATEST_BACKUP}" ]]; then log "No backup found; rollback aborted." write_status "failed" "no backup found" "unknown" exit 1 fi VERSION="unknown" if [[ -f "${LATEST_BACKUP}/VERSION" ]]; then VERSION="$(cat "${LATEST_BACKUP}/VERSION" | tr -d '\n')" fi log "Stopping service ${SERVICE_NAME}..." sudo systemctl stop "${SERVICE_NAME}.service" FAILED_DIR="${INSTALL_DIR}_failed_$(date +%s)" log "Swapping ${INSTALL_DIR} -> ${FAILED_DIR}..." if [[ -d "${INSTALL_DIR}" ]]; then sudo mv "${INSTALL_DIR}" "${FAILED_DIR}" fi sudo mv "${LATEST_BACKUP}" "${INSTALL_DIR}" log "Starting service ${SERVICE_NAME}..." if sudo systemctl start "${SERVICE_NAME}.service"; then log "Rollback completed." write_status "success" "" "${VERSION}" else log "Rollback failed." write_status "failed" "service start failed" "${VERSION}" exit 1 fi