fix(reboot): surface vmx locator execution readiness
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m19s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-03 12:40:36 +08:00
parent 676042c188
commit d74516f2cd
5 changed files with 138 additions and 3 deletions

View File

@@ -3435,6 +3435,19 @@ def _enrich_from_current_readbacks(
state["windows99_vmx_source_locator_check_mode_ready"] = bool(
windows99_vmx_source_locator_readback.get("locator_check_mode_ready") is True
)
state["windows99_vmx_source_locator_effective_collect_ready"] = bool(
windows99_vmx_source_locator_readback.get("effective_locator_collect_ready")
is True
)
state["windows99_vmx_source_locator_collect_blocker"] = str(
windows99_vmx_source_locator_readback.get("locator_collect_blocker") or ""
)
state["windows99_vmx_source_locator_ssh_batch_ready"] = bool(
windows99_vmx_source_locator_readback.get("ssh_batch_ready") is True
)
state["windows99_vmx_source_locator_ssh_batch_status"] = str(
windows99_vmx_source_locator_readback.get("ssh_batch_status") or "unknown"
)
state["windows99_vmx_source_locator_target_aliases"] = _strings(
windows99_vmx_source_locator_readback.get("target_vm_aliases")
)
@@ -3822,6 +3835,18 @@ def _enrich_from_current_readbacks(
evidence["windows99_vmx_source_locator_check_mode_ready"] = state[
"windows99_vmx_source_locator_check_mode_ready"
]
evidence["windows99_vmx_source_locator_effective_collect_ready"] = state[
"windows99_vmx_source_locator_effective_collect_ready"
]
evidence["windows99_vmx_source_locator_collect_blocker"] = state[
"windows99_vmx_source_locator_collect_blocker"
]
evidence["windows99_vmx_source_locator_ssh_batch_ready"] = state[
"windows99_vmx_source_locator_ssh_batch_ready"
]
evidence["windows99_vmx_source_locator_ssh_batch_status"] = state[
"windows99_vmx_source_locator_ssh_batch_status"
]
evidence["windows99_vmx_source_locator_target_aliases"] = state[
"windows99_vmx_source_locator_target_aliases"
]
@@ -4584,6 +4609,18 @@ def _set_rollups_and_summary(
"windows99_vmx_source_locator_check_mode_ready": (
state.get("windows99_vmx_source_locator_check_mode_ready") is True
),
"windows99_vmx_source_locator_effective_collect_ready": (
state.get("windows99_vmx_source_locator_effective_collect_ready") is True
),
"windows99_vmx_source_locator_collect_blocker": str(
state.get("windows99_vmx_source_locator_collect_blocker") or ""
),
"windows99_vmx_source_locator_ssh_batch_ready": (
state.get("windows99_vmx_source_locator_ssh_batch_ready") is True
),
"windows99_vmx_source_locator_ssh_batch_status": str(
state.get("windows99_vmx_source_locator_ssh_batch_status") or "unknown"
),
"windows99_vmx_source_locator_target_aliases": _strings(
state.get("windows99_vmx_source_locator_target_aliases")
),
@@ -4876,6 +4913,18 @@ def _set_rollups_and_summary(
"windows99_vmx_source_locator_check_mode_ready": (
state.get("windows99_vmx_source_locator_check_mode_ready") is True
),
"windows99_vmx_source_locator_effective_collect_ready": (
state.get("windows99_vmx_source_locator_effective_collect_ready") is True
),
"windows99_vmx_source_locator_collect_blocker": str(
state.get("windows99_vmx_source_locator_collect_blocker") or ""
),
"windows99_vmx_source_locator_ssh_batch_ready": (
state.get("windows99_vmx_source_locator_ssh_batch_ready") is True
),
"windows99_vmx_source_locator_ssh_batch_status": str(
state.get("windows99_vmx_source_locator_ssh_batch_status") or "unknown"
),
"windows99_vmx_source_locator_target_aliases": _strings(
state.get("windows99_vmx_source_locator_target_aliases")
),

View File

@@ -75,6 +75,17 @@ def build_windows99_vmx_source_locator_readback(
and package.get("package_ready") is True
and package.get("check_mode_allowed_by_this_package") is True
)
management_channel_ready = package.get("management_channel_ready") is True
ssh_batch_ready = package.get("ssh_batch_ready") is True
ssh_batch_status = str(package.get("ssh_batch_status") or "unknown")
can_collect_vmware_verify_without_secret = (
package.get("can_collect_vmware_verify_without_secret") is True
)
local_console_channel_reachable = (
package.get("local_console_channel_reachable") is True
)
console_collection_channels = _strings(package.get("console_collection_channels"))
effective_locator_collect_ready = bool(locator_check_mode_ready and ssh_batch_ready)
if locator_check_mode_ready:
status = "check_mode_locator_ready_windows99_vmx_source_required"
next_step = "run_no_secret_windows99_vmx_source_locator_collect"
@@ -82,6 +93,12 @@ def build_windows99_vmx_source_locator_readback(
"bash scripts/reboot-recovery/locate-windows99-vmx-source.sh "
"--collect"
)
if not effective_locator_collect_ready:
next_step = "restore_windows99_ssh_publickey_channel_then_rerun_locator"
safe_next_step = (
"select_existing_authorized_public_key_user_or_set_WINDOWS99_SSH_USERS_"
"then_rerun_locator_no_password"
)
elif source_locator_required:
status = "blocked_locator_package_not_ready"
next_step = "repair_package_first"
@@ -112,6 +129,18 @@ def build_windows99_vmx_source_locator_readback(
"locator_schema_version": _LOCATOR_SCHEMA_VERSION,
"collector_readback_present": False,
"collector_collection_status": "not_collected_by_api_readback",
"management_channel_ready": management_channel_ready,
"can_collect_vmware_verify_without_secret": (
can_collect_vmware_verify_without_secret
),
"ssh_batch_ready": ssh_batch_ready,
"ssh_batch_status": ssh_batch_status,
"local_console_channel_reachable": local_console_channel_reachable,
"console_collection_channels": console_collection_channels,
"effective_locator_collect_ready": effective_locator_collect_ready,
"locator_collect_blocker": (
"" if effective_locator_collect_ready else f"ssh_batch_{ssh_batch_status}"
),
"remote_locator_mode": "in_memory_stdin_scriptblock",
"expected_vmx_path_count": expected_vmx_path_count,
"expected_vmx_path_present_count": None,
@@ -146,11 +175,14 @@ def build_windows99_vmx_source_locator_readback(
},
"check_mode": {
"allowed": locator_check_mode_ready,
"effective_collect_ready": effective_locator_collect_ready,
"path_existence_only": True,
"vmx_file_content_read": False,
"raw_path_output": False,
"path_fingerprint_only": True,
"collector_command": safe_next_step if locator_check_mode_ready else "",
"ssh_batch_ready": ssh_batch_ready,
"ssh_batch_status": ssh_batch_status,
},
"target_selector": {
"host_alias": "99",

View File

@@ -742,9 +742,17 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
)
assert state["windows99_vmx_source_locator_required"] is True
assert state["windows99_vmx_source_locator_check_mode_ready"] is True
assert state["windows99_vmx_source_locator_effective_collect_ready"] is False
assert state["windows99_vmx_source_locator_collect_blocker"] == (
"ssh_batch_permission_denied"
)
assert state["windows99_vmx_source_locator_ssh_batch_ready"] is False
assert state["windows99_vmx_source_locator_ssh_batch_status"] == (
"permission_denied"
)
assert state["windows99_vmx_source_locator_target_aliases"] == ["111"]
assert state["windows99_vmx_source_locator_next_executable_step"] == (
"run_no_secret_windows99_vmx_source_locator_collect"
"restore_windows99_ssh_publickey_channel_then_rerun_locator"
)
assert state["windows99_vmx_source_locator_expected_vmx_path_count"] == 1
assert state["windows99_vmx_source_locator_candidate_source_count_known"] is False

View File

@@ -26,7 +26,23 @@ def _scorecard() -> dict:
"readback": {
"windows99_no_secret_collector_status": (
"collected_windows99_vmware_verify_stdout"
)
),
"windows99_no_secret_collector_readback_present": True,
"windows99_no_secret_collector_ssh_batchmode_auth_ready": True,
"windows99_no_secret_collector_remote_verify_attempted": True,
},
"windows99_management_channel": {
"remote_execution_channel_ready": False,
"can_collect_vmware_verify_without_secret": False,
"winrm_http_open": False,
"winrm_https_open": False,
"local_console_channel_reachable": True,
"console_collection_channels": ["rdp_console", "hyperv_vmconnect"],
"ssh_batch": {
"checked": True,
"ready": False,
"status": "permission_denied",
},
},
}
@@ -52,8 +68,19 @@ def test_windows99_vmx_source_locator_builder_is_no_secret_check_mode() -> None:
assert payload["source_locator_required"] is True
assert payload["locator_check_mode_ready"] is True
assert payload["next_executable_step"] == (
"run_no_secret_windows99_vmx_source_locator_collect"
"restore_windows99_ssh_publickey_channel_then_rerun_locator"
)
assert payload["management_channel_ready"] is False
assert payload["can_collect_vmware_verify_without_secret"] is False
assert payload["ssh_batch_ready"] is False
assert payload["ssh_batch_status"] == "permission_denied"
assert payload["local_console_channel_reachable"] is True
assert payload["console_collection_channels"] == [
"rdp_console",
"hyperv_vmconnect",
]
assert payload["effective_locator_collect_ready"] is False
assert payload["locator_collect_blocker"] == "ssh_batch_permission_denied"
assert payload["expected_vmx_path_count"] == 1
assert payload["candidate_source_count_known"] is False
assert payload["collector_readback_present"] is False
@@ -64,6 +91,8 @@ def test_windows99_vmx_source_locator_builder_is_no_secret_check_mode() -> None:
"scripts/reboot-recovery/windows99-vmx-source-locator.ps1"
)
assert payload["check_mode"]["allowed"] is True
assert payload["check_mode"]["effective_collect_ready"] is False
assert payload["check_mode"]["ssh_batch_status"] == "permission_denied"
assert payload["check_mode"]["vmx_file_content_read"] is False
assert payload["raw_path_output"] is False
assert payload["path_fingerprint_only"] is True
@@ -102,6 +131,8 @@ def test_windows99_vmx_source_locator_endpoint_returns_public_safe_readback(
)
assert payload["target_vm_aliases"] == ["111"]
assert payload["locator_check_mode_ready"] is True
assert payload["effective_locator_collect_ready"] is False
assert payload["locator_collect_blocker"] == "ssh_batch_permission_denied"
assert payload["public_lan_topology_redacted"] is True
assert payload["raw_path_output"] is False
assert payload["file_content_read"] is False

View File

@@ -1,3 +1,18 @@
## 2026-07-03 — 12:36 Windows99 VMX locator effective collect readiness 防誤判
**完成內容**
- Production `/api/v1/agents/windows99-vmx-source-locator-readback` 已讀回 locator package`status=check_mode_locator_ready_windows99_vmx_source_required``target_vm_aliases=["111"]``next_executable_step=run_no_secret_windows99_vmx_source_locator_collect``raw_path_output=false``path_fingerprint_only=true``file_content_read=false``remote_write_performed=false``vm_power_change_performed=false`
- 實跑 no-secret locator check artifact`/tmp/awoooi-windows99-vmx-source-locator-20260703-123620`。結果:`port_22_open=1``port_3389_open=1``ssh_auth_probed_users=19``ssh_batchmode_auth_ready=0``locator_collection_status=blocked_ssh_publickey_auth_missing`
- `windows99-vmx-source-locator-readback` 補上 `management_channel_ready``ssh_batch_ready``ssh_batch_status``effective_locator_collect_ready``locator_collect_blocker``awoooi-priority-work-order-readback` 同步上卷,避免 operator 看到 `locator_check_mode_ready=true` 就誤判為可執行 collect。
**已跑驗證**
- `DATABASE_URL=postgresql+asyncpg://test:test@localhost/test PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_windows99_vmx_source_locator_readback_api.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py apps/api/tests/test_windows99_vmx_source_repair_package_api.py -q -p no:cacheprovider``23 passed`
- `python3.11 -m py_compile apps/api/src/services/windows99_vmx_source_locator_readback.py apps/api/src/services/awoooi_priority_work_order_readback.py apps/api/tests/test_windows99_vmx_source_locator_readback_api.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py`:通過。
- `git diff --check``python3.11 ops/runner/guard-gitea-runner-pressure.py --root .`:通過。
**仍維持**
- 未讀 secret / token / `.env` / raw sessions / SQLite / auth未使用 GitHub / gh未 workflow_dispatch未啟動或關閉 VM未重啟 host / service未 Docker / Nginx / K3s / DB / firewall restart未 DROP / TRUNCATE / restore / prune / delete / force push。
## 2026-07-03 — 11:58 Windows99 VMX package execution readiness 防誤判
**完成內容**