From 7bd1b1b2a423218e90fffe37f687a325479d87fb Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 09:25:13 +0800 Subject: [PATCH] fix(runner): keep harbor waiting truth ahead of stale jobs --- docs/LOGBOOK.md | 14 ++++++++++++++ ops/runner/read-public-gitea-actions-queue.py | 10 ++++------ ops/runner/test_read_public_gitea_actions_queue.py | 13 +++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 79116899b..22baa5328 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,17 @@ +## 2026-07-01 — 09:24 Harbor repair waiting truth / public route blocker + +**照主線修正的問題**: +- 188 runner re-enable 後,live queue 已從 `awoooi-non110-*` no-matching 進展到 Harbor repair waiting;但 Gitea unauthenticated jobs API 仍回 `ai-code-review` 或 CD workflow jobs,造成 reader 將 visible waiting 誤升級為 `harbor_110_repair_jobs_stale_or_mismatched`。 +- `ops/runner/read-public-gitea-actions-queue.py` 調整 status 優先序:當 visible Harbor repair run 為 waiting 且 no-matching 為空時,主狀態維持 `harbor_110_repair_waiting_for_runner_or_queue` / `blocked_harbor_110_repair_workflow_waiting`;stale / cross-workflow jobs payload 仍保留在 readback / rollups 作為 evidence,不再覆蓋 visible queue truth。 +- 後續 live queue 已前進到 CD `#4211 Failure`,classifier=`harbor_registry_public_route_unavailable`、status code `502`;Harbor repair `#4212 Failure`、no-matching 空;public registry `/v2/` 仍 `502`。目前主線 blocker 已不是 runner label,而是 110 Harbor public route / repair failure。 + +**驗證**: +- `python3.11 -m pytest ops/runner/test_read_public_gitea_actions_queue.py -q` 通過(30 passed)。 +- `DATABASE_URL='postgresql+asyncpg://awoooi:awoooi_test_2026@127.0.0.1:5432/awoooi_test' python3.11 -m pytest apps/api/tests/test_harbor_registry_controlled_recovery_receipt.py ops/runner/test_verify_awoooi_non110_cd_closure.py -q` 通過(26 passed)。 +- `python3.11 -m py_compile ops/runner/read-public-gitea-actions-queue.py` 與 `git diff --check` 通過。 + +**邊界**:只改 public Gitea queue readback parser / tests / LOGBOOK;未讀 token / secret / `.env` / raw sessions / SQLite / auth;未使用 GitHub / `gh` / GitHub API;未 workflow_dispatch;未新增 host write、未重啟主機、未 restart Docker / Nginx / K3s / DB / firewall。 + ## 2026-07-01 — 09:18 non-110 runner runtime re-enable / queue no-matching cleared **照主線修正的問題**: diff --git a/ops/runner/read-public-gitea-actions-queue.py b/ops/runner/read-public-gitea-actions-queue.py index 8ffa567fa..df84339c9 100644 --- a/ops/runner/read-public-gitea-actions-queue.py +++ b/ops/runner/read-public-gitea-actions-queue.py @@ -677,13 +677,11 @@ def build_readback( build_log_classifier["harbor_public_route_blocked_or_retrying"] and harbor_110_repair_no_matching_runner_label ) - else "blocked_harbor_110_repair_jobs_stale_or_mismatched" + else "blocked_harbor_110_repair_workflow_waiting" if ( build_log_classifier["harbor_public_route_blocked_or_retrying"] - and harbor_110_repair_jobs_stale_or_mismatched + and harbor_110_repair_waiting_after_cd_harbor_blocker ) - else "blocked_harbor_110_repair_workflow_waiting" - if harbor_110_repair_waiting_after_cd_harbor_blocker else "blocked_harbor_public_route_unavailable" if build_log_classifier["harbor_public_route_blocked"] else "blocked_harbor_public_route_unavailable_pending_retry" @@ -694,14 +692,14 @@ def build_readback( if harbor_110_repair_no_matching_runner_label else "blocked_no_matching_online_runner" if workflow_no_matching - else "harbor_110_repair_jobs_stale_or_mismatched" - if harbor_110_repair_jobs_stale_or_mismatched else "harbor_110_repair_waiting_for_runner_or_queue" if harbor_110_repair_waiting else "harbor_110_repair_running" if harbor_110_repair_running else "blocked_harbor_110_repair_run" if harbor_110_repair_blocked + else "harbor_110_repair_jobs_stale_or_mismatched" + if harbor_110_repair_jobs_stale_or_mismatched else "cd_jobs_stale_or_mismatched" if cd_jobs_stale_or_mismatched else "no_matching_runner_not_visible" diff --git a/ops/runner/test_read_public_gitea_actions_queue.py b/ops/runner/test_read_public_gitea_actions_queue.py index 26723f9f3..02cd8abad 100644 --- a/ops/runner/test_read_public_gitea_actions_queue.py +++ b/ops/runner/test_read_public_gitea_actions_queue.py @@ -543,7 +543,7 @@ def test_build_readback_classifies_harbor_502_after_110_repair_jobs_success() -> assert payload["operation_boundaries"]["host_write_performed"] is False -def test_build_readback_rejects_stale_harbor_110_repair_jobs_payload() -> None: +def test_build_readback_rejects_stale_harbor_jobs_but_keeps_waiting_status() -> None: module = _load_module() payload = module.build_readback( actions_html=_actions_html_cd_running_harbor_repair_waiting(), @@ -557,7 +557,7 @@ def test_build_readback_rejects_stale_harbor_110_repair_jobs_payload() -> None: latest_cd_build_log_text=_harbor_blocked_log(), ) - assert payload["status"] == "blocked_harbor_110_repair_jobs_stale_or_mismatched" + assert payload["status"] == "blocked_harbor_110_repair_workflow_waiting" assert payload["readback"]["harbor_110_repair_jobs_all_success"] is False assert payload["readback"]["harbor_110_repair_jobs_stale_or_mismatched"] is True assert payload["readback"]["harbor_110_repair_jobs_unexpected_names"] == [ @@ -607,7 +607,7 @@ def test_build_readback_classifies_cross_workflow_harbor_jobs_payload() -> None: ) -def test_build_readback_prioritizes_harbor_repair_jobs_stale_status() -> None: +def test_build_readback_keeps_visible_harbor_waiting_before_stale_jobs_status() -> None: module = _load_module() payload = module.build_readback( actions_html=_actions_html_cd_running_harbor_repair_waiting(), @@ -619,8 +619,9 @@ def test_build_readback_prioritizes_harbor_repair_jobs_stale_status() -> None: harbor_110_repair_jobs_payload=_harbor_110_repair_stale_code_review_jobs(), ) - assert payload["status"] == "harbor_110_repair_jobs_stale_or_mismatched" + assert payload["status"] == "harbor_110_repair_waiting_for_runner_or_queue" assert payload["readback"]["harbor_110_repair_jobs_all_success"] is False + assert payload["readback"]["harbor_110_repair_jobs_stale_or_mismatched"] is True assert payload["readback"]["latest_visible_harbor_110_repair_waiting"] is True @@ -1051,11 +1052,15 @@ def test_harbor_repair_waiting_takes_actionable_precedence_after_harbor_blocker( actions_list_payload={"message": "token is required"}, cd_jobs_http_status=200, cd_jobs_payload={"jobs": [], "total_count": 0}, + harbor_110_repair_jobs_http_status=200, + harbor_110_repair_jobs_payload=_harbor_110_repair_cross_workflow_jobs(), latest_cd_build_log_http_status=200, latest_cd_build_log_text=_harbor_blocked_log(), ) assert payload["status"] == "blocked_harbor_110_repair_workflow_waiting" + assert payload["readback"]["harbor_110_repair_jobs_stale_or_mismatched"] is True + assert payload["readback"]["harbor_110_repair_jobs_cross_workflow_mismatch"] is True assert payload["readback"]["latest_visible_harbor_110_repair_waiting"] is True assert ( payload["readback"][