#!/usr/bin/env bash set -euo pipefail python3_write_cancelled_state() { local state_file="$1" python3 - "$state_file" <<'PY' import json import sys from datetime import datetime, timezone from pathlib import Path state_path = Path(sys.argv[1]) state = {} if state_path.exists(): try: state = json.loads(state_path.read_text(encoding="utf-8")) except json.JSONDecodeError: state = {} now = datetime.now(timezone.utc).isoformat() state["last_state"] = "CANCELLED" state["last_seen_at"] = now state["closed_at"] = now notes = state.get("notes", []) if not isinstance(notes, list): notes = [str(notes)] if "Cancellation marker detected." not in notes: notes.append("Cancellation marker detected.") state["notes"] = notes state_path.write_text(json.dumps(state, indent=2, sort_keys=True), encoding="utf-8") PY } usage() { cat <<'EOF' Usage: cancel-atvm-run-watcher.sh --build-name [--state-root ] EOF } BUILD_NAME="" STATE_ROOT="/var/lib/atvm-run-watcher" while [[ $# -gt 0 ]]; do case "$1" in --build-name) BUILD_NAME="${2:-}"; shift 2 ;; --state-root) STATE_ROOT="${2:-}"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "Unknown argument: $1" >&2; usage >&2; exit 1 ;; esac done if [[ -z "$BUILD_NAME" ]]; then echo "--build-name is required" >&2 usage >&2 exit 1 fi RUN_DIR="${STATE_ROOT}/${BUILD_NAME}" mkdir -p "$RUN_DIR" touch "${RUN_DIR}/cancelled.marker" python3_write_cancelled_state "${RUN_DIR}/state.json" systemctl stop "atvm-run-watcher@${BUILD_NAME}.service" || true