#!/usr/bin/env bash set -euo pipefail # CISD init flow runner: # status -> preview -> create task -> execute -> query steps -> failed step log # # Usage: # chmod +x scripts/cisd_init_flow.sh # REQUEST_JSON=/tmp/cisd-init-standard-rabbit.json ./scripts/cisd_init_flow.sh # # Optional env: # BASE_URL=http://127.0.0.1:8080 # INTERNAL_TOKEN=change-me-internal-token # OUT_DIR=/tmp/cisd-init-run # FETCH_FAILED_STEP_LOG=true BASE_URL="${BASE_URL:-http://127.0.0.1:8080}" INTERNAL_TOKEN="${INTERNAL_TOKEN:-change-me-internal-token}" REQUEST_JSON="${REQUEST_JSON:-}" OUT_DIR="${OUT_DIR:-/tmp/cisd-init-run}" FETCH_FAILED_STEP_LOG="${FETCH_FAILED_STEP_LOG:-true}" TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-30}" TS="$(date +%Y%m%d%H%M%S)" RUN_DIR="${OUT_DIR}/run-${TS}" require_cmd() { local cmd="$1" if ! command -v "$cmd" >/dev/null 2>&1; then echo "[FATAL] command missing: ${cmd}" exit 1 fi } api_get() { local path="$1" curl -sS --max-time "${TIMEOUT_SECONDS}" \ -H "X-Internal-Token: ${INTERNAL_TOKEN}" \ "${BASE_URL}${path}" } api_post_json() { local path="$1" local body_file="$2" curl -sS --max-time "${TIMEOUT_SECONDS}" \ -H "X-Internal-Token: ${INTERNAL_TOKEN}" \ -H "Content-Type: application/json" \ -X POST "${BASE_URL}${path}" \ -d @"${body_file}" } api_post_empty() { local path="$1" curl -sS --max-time "${TIMEOUT_SECONDS}" \ -H "X-Internal-Token: ${INTERNAL_TOKEN}" \ -X POST "${BASE_URL}${path}" } expect_success() { local label="$1" local file="$2" if jq -e '.success == true and .code == 200' "${file}" >/dev/null 2>&1; then echo "[PASS] ${label}" else echo "[FAIL] ${label}" cat "${file}" exit 2 fi } main() { require_cmd curl require_cmd jq if [[ -z "${REQUEST_JSON}" ]]; then echo "[FATAL] REQUEST_JSON is required" echo "Example: REQUEST_JSON=/tmp/cisd-init-standard-rabbit.json ./scripts/cisd_init_flow.sh" exit 1 fi if [[ ! -f "${REQUEST_JSON}" ]]; then echo "[FATAL] request file not found: ${REQUEST_JSON}" exit 1 fi mkdir -p "${RUN_DIR}" echo "[INFO] run dir: ${RUN_DIR}" echo "[INFO] base url: ${BASE_URL}" echo "[STEP] device status" api_get "/api/v1/device/status" | tee "${RUN_DIR}/01-device-status.json" >/dev/null expect_success "device status" "${RUN_DIR}/01-device-status.json" jq '.data | {presetProductType,presetVersion,presetSource}' "${RUN_DIR}/01-device-status.json" || true echo "[STEP] init preview" api_post_json "/api/v1/init/preview" "${REQUEST_JSON}" | tee "${RUN_DIR}/02-preview.json" >/dev/null expect_success "init preview" "${RUN_DIR}/02-preview.json" jq '.data | {resolvedProductType,presetVersion,stepCount,summary}' "${RUN_DIR}/02-preview.json" || true echo "[STEP] create init task" api_post_json "/api/v1/init/tasks" "${REQUEST_JSON}" | tee "${RUN_DIR}/03-create-task.json" >/dev/null expect_success "create task" "${RUN_DIR}/03-create-task.json" TASK_ID="$(jq -r '.data.taskId // empty' "${RUN_DIR}/03-create-task.json")" if [[ -z "${TASK_ID}" ]]; then echo "[FATAL] taskId missing in create task response" cat "${RUN_DIR}/03-create-task.json" exit 2 fi echo "[INFO] task id: ${TASK_ID}" echo "[STEP] execute init task" api_post_empty "/api/v1/init/tasks/${TASK_ID}/execute" | tee "${RUN_DIR}/04-execute-task.json" >/dev/null expect_success "execute task api call" "${RUN_DIR}/04-execute-task.json" TASK_STATUS="$(jq -r '.data.status // empty' "${RUN_DIR}/04-execute-task.json")" echo "[INFO] task status: ${TASK_STATUS}" echo "[STEP] query task steps" api_get "/api/v1/init/tasks/${TASK_ID}/steps" | tee "${RUN_DIR}/05-task-steps.json" >/dev/null expect_success "query task steps" "${RUN_DIR}/05-task-steps.json" jq -r '.data[] | "\(.stepNo)\t\(.stepCode)\t\(.status)\t\(.message // "")"' "${RUN_DIR}/05-task-steps.json" || true if [[ "${FETCH_FAILED_STEP_LOG,,}" == "true" ]]; then FAILED_STEP_NO="$(jq -r '.data[] | select(.status=="FAILED") | .stepNo' "${RUN_DIR}/05-task-steps.json" | head -n1 || true)" if [[ -n "${FAILED_STEP_NO}" ]]; then echo "[STEP] fetch failed step log: stepNo=${FAILED_STEP_NO}" api_get "/api/v1/init/tasks/${TASK_ID}/steps/${FAILED_STEP_NO}/log" | tee "${RUN_DIR}/06-failed-step-log.json" >/dev/null || true if jq -e '.success == true and .code == 200' "${RUN_DIR}/06-failed-step-log.json" >/dev/null 2>&1; then jq -r '.data.content' "${RUN_DIR}/06-failed-step-log.json" > "${RUN_DIR}/06-failed-step.log.txt" || true echo "[INFO] failed step log saved: ${RUN_DIR}/06-failed-step.log.txt" else echo "[WARN] failed step log API did not return success" fi fi fi if [[ "${TASK_STATUS}" == "SUCCESS" ]]; then echo "[DONE] init flow completed successfully, taskId=${TASK_ID}" exit 0 fi echo "[DONE] init flow completed with non-success status=${TASK_STATUS}, taskId=${TASK_ID}" exit 3 } main "$@"