Files
git.stella-ops.org/scripts/mirror/export-center-wire.sh
StellaOps Bot bc0762e97d up
2025-12-09 00:20:52 +02:00

123 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Prepare Export Center handoff metadata for mirror thin bundles and optionally schedule a run.
# Usage (handoff only):
# scripts/mirror/export-center-wire.sh
# Usage (handoff + schedule when secrets exist):
# EXPORT_CENTER_BASE_URL=https://export.example.com \
# EXPORT_CENTER_TOKEN=token123 \
# EXPORT_CENTER_TENANT=tenant-a \
# EXPORT_CENTER_AUTO_SCHEDULE=1 \
# scripts/mirror/export-center-wire.sh
# Inputs:
# - MILESTONE_PATH: path to milestone.json (default: out/mirror/thin/milestone.json)
# - EXPORT_CENTER_OUT_DIR: output directory for handoff files (default: out/mirror/thin/export-center)
# - EXPORT_CENTER_PROFILE_ID: profile identifier for the Export Center run (default: mirror:thin)
# - EXPORT_CENTER_TARGETS_JSON: override targets array sent to Export Center (JSON array string)
# - EXPORT_CENTER_FORMATS_JSON: override formats array (JSON array string; default: ["tar.gz","json","dsse"])
# - EXPORT_CENTER_AUTO_SCHEDULE: when "1", schedule a run using schedule-export-center-run.sh
# - EXPORT_CENTER_BASE_URL / EXPORT_CENTER_TENANT / EXPORT_CENTER_PROJECT / EXPORT_CENTER_TOKEN: forwarded to scheduler
# - EXPORT_CENTER_AUDIT_LOG: optional override for scheduler audit log path
MILESTONE_PATH="${MILESTONE_PATH:-out/mirror/thin/milestone.json}"
OUT_DIR="${EXPORT_CENTER_OUT_DIR:-out/mirror/thin/export-center}"
PROFILE_ID="${EXPORT_CENTER_PROFILE_ID:-mirror:thin}"
FORMATS_JSON="${EXPORT_CENTER_FORMATS_JSON:-[\"tar.gz\",\"json\",\"dsse\"]}"
AUTO_SCHEDULE="${EXPORT_CENTER_AUTO_SCHEDULE:-0}"
HANDOFF_PATH="${OUT_DIR}/export-center-handoff.json"
TARGETS_PATH="${OUT_DIR}/export-center-targets.json"
RESPONSE_PATH="${OUT_DIR}/schedule-response.json"
export HANDOFF_PATH TARGETS_PATH RESPONSE_PATH PROFILE_ID MILESTONE_PATH
mkdir -p "${OUT_DIR}"
PROFILE_ID="${PROFILE_ID}" MILESTONE_PATH="${MILESTONE_PATH}" HANDOFF_PATH="${HANDOFF_PATH}" TARGETS_PATH="${TARGETS_PATH}" python3 - <<'PY'
import datetime
import json
import os
import sys
from typing import Dict, Any
milestone_path = os.environ["MILESTONE_PATH"]
handoff_path = os.environ["HANDOFF_PATH"]
targets_path = os.environ["TARGETS_PATH"]
profile = os.environ.get("PROFILE_ID", "mirror:thin")
try:
with open(milestone_path, encoding="utf-8") as f:
milestone = json.load(f)
except FileNotFoundError:
print(f"milestone file not found: {milestone_path}", file=sys.stderr)
sys.exit(1)
artifacts = []
def add_artifact(name: str, entry: Dict[str, Any] | None) -> None:
if not isinstance(entry, dict):
return
path = entry.get("path")
sha = entry.get("sha256")
if path and sha:
artifacts.append({"name": name, "path": path, "sha256": sha})
add_artifact("manifest", milestone.get("manifest"))
add_artifact("manifest_dsse", milestone.get("dsse"))
add_artifact("bundle", milestone.get("tarball"))
add_artifact("bundle_meta", milestone.get("bundle"))
add_artifact("bundle_meta_dsse", milestone.get("bundle_dsse"))
add_artifact("time_anchor", milestone.get("time_anchor"))
for name, entry in sorted((milestone.get("policies") or {}).items()):
add_artifact(f"policy_{name}", entry)
handoff = {
"profileId": profile,
"generatedAt": datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
"sourceMilestone": os.path.abspath(milestone_path),
"artifacts": artifacts,
}
with open(handoff_path, "w", encoding="utf-8") as f:
json.dump(handoff, f, indent=2)
with open(targets_path, "w", encoding="utf-8") as f:
json.dump([a["name"] for a in artifacts], f)
PY
ARTIFACTS_JSON=$(python3 - <<'PY'
import json
import os
with open(os.environ["HANDOFF_PATH"], encoding="utf-8") as f:
data = json.load(f)
print(json.dumps(data.get("artifacts", [])))
PY
)
ARTIFACTS_JSON="${ARTIFACTS_JSON//$'\n'/}"
TARGETS_JSON_DEFAULT=$(tr -d '\r\n' < "${TARGETS_PATH}")
TARGETS_JSON="${EXPORT_CENTER_TARGETS_JSON:-$TARGETS_JSON_DEFAULT}"
echo "[info] Export Center handoff written to ${HANDOFF_PATH}"
echo "[info] Recommended targets: ${TARGETS_JSON}"
schedule_note="AUTO_SCHEDULE=0"
if [[ "${AUTO_SCHEDULE}" == "1" ]]; then
schedule_note="missing EXPORT_CENTER_BASE_URL"
if [[ -n "${EXPORT_CENTER_BASE_URL:-}" ]]; then
export EXPORT_CENTER_ARTIFACTS_JSON="${ARTIFACTS_JSON}"
schedule_note="scheduled"
bash src/Mirror/StellaOps.Mirror.Creator/schedule-export-center-run.sh "${PROFILE_ID}" "${TARGETS_JSON}" "${FORMATS_JSON}" | tee "${RESPONSE_PATH}"
fi
fi
if [[ ! -f "${RESPONSE_PATH}" ]]; then
cat > "${RESPONSE_PATH}" <<JSON
{"scheduled": false, "reason": "${schedule_note}"}
JSON
fi
echo "[info] Scheduler response captured at ${RESPONSE_PATH}"