feat: add control board replacement workflow
This commit is contained in:
1 parent
62c91a2c3e
commit
bcf1b4e3cf
16 files changed
+2122
-279
No files matched your search
@@ -62,8 +62,52 @@ fi
|
||||
echo "Validating Compose configuration..."
|
||||
MINEROPS_DEV_PORT="${dev_port}" "${compose[@]}" config --quiet
|
||||
|
||||
echo "Building and starting disposable development stack..."
|
||||
MINEROPS_DEV_PORT="${dev_port}" "${compose[@]}" up --detach --build
|
||||
echo "Starting disposable data services..."
|
||||
MINEROPS_DEV_PORT="${dev_port}" "${compose[@]}" up --detach postgres redis
|
||||
|
||||
echo "Waiting for PostgreSQL initialization and Redis..."
|
||||
for attempt in $(seq 1 180); do
|
||||
postgres_ready=false
|
||||
redis_ready=false
|
||||
if "${compose[@]}" exec -T postgres sh -ec \
|
||||
'test "$(cat /proc/1/comm)" = "postgres"; psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Atqc "SELECT 1"' \
|
||||
2>/dev/null | grep -qx '1'; then
|
||||
postgres_ready=true
|
||||
fi
|
||||
if "${compose[@]}" exec -T redis redis-cli ping 2>/dev/null | grep -qx 'PONG'; then
|
||||
redis_ready=true
|
||||
fi
|
||||
if [[ "${postgres_ready}" == "true" && "${redis_ready}" == "true" ]]; then
|
||||
break
|
||||
fi
|
||||
if (( attempt == 180 )); then
|
||||
echo "Disposable data services did not become ready within 180 seconds." >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Building and starting the disposable backend..."
|
||||
MINEROPS_DEV_PORT="${dev_port}" "${compose[@]}" up --detach --build --no-deps backend
|
||||
backend_container="$("${compose[@]}" ps -q backend)"
|
||||
for attempt in $(seq 1 180); do
|
||||
backend_health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "${backend_container}")"
|
||||
if [[ "${backend_health}" == "healthy" ]]; then
|
||||
break
|
||||
fi
|
||||
if [[ "${backend_health}" == "exited" || "${backend_health}" == "dead" ]]; then
|
||||
echo "Disposable backend exited before becoming healthy." >&2
|
||||
exit 1
|
||||
fi
|
||||
if (( attempt == 180 )); then
|
||||
echo "Disposable backend did not become healthy within 180 seconds." >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Starting the disposable gateway..."
|
||||
MINEROPS_DEV_PORT="${dev_port}" "${compose[@]}" up --detach --no-deps gateway
|
||||
|
||||
echo "Waiting for the gateway health endpoint..."
|
||||
health_file="${tmp_prefix}-health.json"
|
||||
@@ -88,7 +132,7 @@ health_json="$(cat "${health_file}")"
|
||||
|
||||
echo "Checking migrations and required schema..."
|
||||
current_revision="$("${compose[@]}" exec -T backend alembic current 2>/dev/null)"
|
||||
[[ "${current_revision}" == *"0012_return_to_service"* ]]
|
||||
[[ "${current_revision}" == *"0013_control_board_replacement"* ]]
|
||||
|
||||
missing_tables="$(
|
||||
"${compose[@]}" exec -T postgres sh -c \
|
||||
@@ -168,6 +212,8 @@ echo "Checking Begin Repair permission and workflow..."
|
||||
INSERT INTO miners (
|
||||
id,
|
||||
asset_tag,
|
||||
current_mac,
|
||||
control_board_sn,
|
||||
status,
|
||||
lifecycle_status,
|
||||
first_seen_at,
|
||||
@@ -176,6 +222,8 @@ INSERT INTO miners (
|
||||
VALUES (
|
||||
'00000000-0000-0000-0000-000000000981',
|
||||
'SMOKE-REPAIR-001',
|
||||
'02:AA:BB:CC:EE:01',
|
||||
'SMOKE-CB-OLD',
|
||||
'unknown',
|
||||
'active',
|
||||
NULL,
|
||||
@@ -202,19 +250,31 @@ smoke_repair_id="$(
|
||||
| python3 -c 'import json, sys; print(json.load(sys.stdin)["data"]["repair_id"])'
|
||||
)"
|
||||
[[ -n "${smoke_repair_id}" ]]
|
||||
[[ "$(
|
||||
status_for "${readonly_cookie}" POST /api/miners/00000000-0000-0000-0000-000000000981/replace-control-board \
|
||||
'{"new_mac_address":"02:AA:BB:CC:EE:02","new_control_board_serial":"SMOKE-CB-NEW","removed_board_disposition":"sent_for_repair","replacement_reason":"failed"}'
|
||||
)" == "403" ]]
|
||||
board_response="$(curl --fail --silent -b "${technician_cookie}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"new_mac_address":"02:AA:BB:CC:EE:02","new_control_board_serial":"SMOKE-CB-NEW","removed_board_disposition":"sent_for_repair","replacement_reason":"failed","notes":"Smoke replacement."}' \
|
||||
"${base_url}/api/miners/00000000-0000-0000-0000-000000000981/replace-control-board")"
|
||||
[[ "${board_response}" == *'"current_mac":"02:AA:BB:CC:EE:02"'* ]]
|
||||
[[ "${board_response}" == *'"event_sequence":3'* ]]
|
||||
readonly_repair_detail="$(
|
||||
curl --fail --silent -b "${readonly_cookie}" \
|
||||
"${base_url}/api/repairs/${smoke_repair_id}"
|
||||
)"
|
||||
[[ "${readonly_repair_detail}" == *'"miner_asset_id":"SMOKE-REPAIR-001"'* ]]
|
||||
[[ "${readonly_repair_detail}" == *'"miner_lifecycle":"in_repair"'* ]]
|
||||
[[ "${readonly_repair_detail}" == *'"latest_event_sequence":2'* ]]
|
||||
[[ "${readonly_repair_detail}" == *'"latest_event_sequence":3'* ]]
|
||||
readonly_repair_events="$(
|
||||
curl --fail --silent -b "${readonly_cookie}" \
|
||||
"${base_url}/api/repairs/${smoke_repair_id}/events"
|
||||
)"
|
||||
[[ "${readonly_repair_events}" == *'"sequence":1'* ]]
|
||||
[[ "${readonly_repair_events}" == *'"sequence":2'* ]]
|
||||
[[ "${readonly_repair_events}" == *'"sequence":3'* ]]
|
||||
[[ "${readonly_repair_events}" == *'"event_type":"CONTROL_BOARD_REPLACED"'* ]]
|
||||
[[ "${readonly_repair_events}" == *'"event_type":"REPAIR_STARTED"'* ]]
|
||||
[[ "${readonly_repair_events}" == *'"event_type":"INITIAL_NOTE"'* ]]
|
||||
[[ "$(status_for "${technician_cookie}" GET /api/repairs/queue)" == "200" ]]
|
||||
|
||||
Reference in new issue
Block a user