fix(reboot): add windows99 vmx source locate check
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m17s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m17s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -54260,3 +54260,24 @@ production browser smoke:
|
||||
|
||||
**下一步**:
|
||||
- commit / push 到 Gitea main;等待 CD deploy marker 後讀回 production `/api/v1/agents/windows99-vmx-source-repair-package`、`/api/v1/agents/awoooi-priority-work-order-readback` 與 `/zh-TW/awooop/work-items`,確認 executor / verifier / learning refs 在 API 與 UI 均可見。
|
||||
|
||||
## 2026-07-03 — P0-006 Windows99 VMX source locate check-mode
|
||||
|
||||
**完成內容**:
|
||||
- 新增 `scripts/reboot-recovery/windows99-vmx-source-locate-check.ps1` 與 `collect-windows99-vmx-source-locate-check.sh`,把 111 VMX source 定位從一次性手動查找提升為 no-write / no-secret / no-power-change check-mode collector。
|
||||
- collector 只使用 BatchMode public-key SSH,可經 `--via-host wooo@192.168.0.110` 進入 Windows99,並以 stdin PowerShell bootstrap 執行 bounded path / VMX identity scan;不讀密碼、不寫遠端檔、不啟動或關閉 VM、不重啟 Windows service / host、不套 registry。
|
||||
- 2026-07-03 12:00 live production readback:SLO scorecard `active_blocker_count=8`、readiness `60%`、primary `fresh_all_host_reboot_event_missing`;priority readback 顯示 Windows99 VMX repair stage `source_repair_check_mode_ready`、next executable step `locate_or_relink_missing_vmx_source_check_mode`。
|
||||
- live locator 結果:expected 111 VMX path `exists=0`、`candidate_vmx_count=6`、`alias_hint_candidate_count=0`、`identity_target_hint_count=0`、`identity_unassigned_ubuntu_candidate_count=1`、`locate_status=single_identity_unassigned_ubuntu_candidate_requires_confirmation`。唯一 generic Ubuntu candidate 尚不能安全 relink;需要 external verified backup artifact 或更強 identity evidence 後才可產生 scoped relink / restore dry-run 與 post-verifier。
|
||||
- `FULL-STACK-COLD-START-SOP`、`REBOOT-RECOVERY-SOP` 與統帥插入需求台帳已更新,將 stale 10-blocker 狀態覆蓋為目前 8-blocker truth,並把下一步固定為 111 VMX source verified artifact / identity evidence。
|
||||
|
||||
**本地驗證結果**:
|
||||
- `bash -n scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh`:通過。
|
||||
- `python3.11 -m pytest scripts/reboot-recovery/tests/test_windows99_vmx_source_locate_check.py -q -p no:cacheprovider`:通過。
|
||||
|
||||
**仍維持**:
|
||||
- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth。
|
||||
- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。
|
||||
- 沒有重啟主機,沒有 Docker / Nginx / K3s / DB / firewall restart,沒有 workflow_dispatch,沒有 DROP / TRUNCATE / restore / prune,沒有啟動或關閉 VM。
|
||||
|
||||
**下一步**:
|
||||
- 跑 full focused verifier / runner pressure guard / `git diff --check` 後 commit / push 到 Gitea main;等待 CD deploy marker 後讀回 production priority / SLO,並接續取得 111 VMX source external verified backup artifact 或更強 identity evidence,再做 scoped relink / restore dry-run。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AWOOOI 全棧冷啟動與主機重啟 SOP
|
||||
|
||||
> Version: v1.114
|
||||
> Version: v1.115
|
||||
> Last updated: 2026-07-03 Asia/Taipei
|
||||
> Scope: 99 / 110 / 111 / 112 / 120 / 121 / 188 全棧重啟恢復。112 仍是 Kali / VM guest 訊號,但 2026-06-30 全主機重啟後已納入 10 分鐘 SLO 的必要 boot / power signal;此納入不代表授權任何破壞性 runtime apply。
|
||||
|
||||
@@ -60,6 +60,8 @@ v1.113 Windows99 VMX source repair package API rule:production `/api/v1/agents
|
||||
|
||||
v1.114 Windows99 VMX package public redaction boundary rule:public `/api/v1/agents/reboot-auto-recovery-slo-scorecard` 與 `/api/v1/agents/windows99-vmx-source-repair-package` 會先套用 LAN topology redaction,因此 VMX path 內的 `192.168.0.111` 可能在 public JSON 變成 `host:dev-a` 類 display alias。public response 必須同步輸出 `public_lan_topology_redacted=true`、`redacted_public_display_only=true`、`check_mode_probe_commands_executable=false` 與 `internal_console_package_required_for_execution=true`;所有 `vm_rows[]` 也必須帶相同 executable=false 邊界。任何 `host:...` VMX path 只能供瀏覽器 / Telegram / UI 顯示,不得作為 Windows console 可執行命令。要跑 `Test-Path` 時只能使用授權內部 console / no-secret package 保留的原始 Windows path;仍不得讀密碼、啟動 VM、重啟 service / host 或套用 registry。
|
||||
|
||||
v1.115 Windows99 VMX source locate check-mode rule:2026-07-03 12:00 production readback 已更新為 `status=blocked_reboot_auto_recovery_slo_not_ready`、`active_blocker_count=8`、`readiness_percent=60`、`primary_blocker=fresh_all_host_reboot_event_missing`、`can_claim_all_services_recovered_within_target=false`,priority readback 同步顯示 `windows99_vmx_source_repair_action_stage=source_repair_check_mode_ready` 與 `windows99_vmx_source_repair_next_executable_step=locate_or_relink_missing_vmx_source_check_mode`。定位 111 VMX source 時固定使用 `scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh --via-host wooo@192.168.0.110 --include-identity-metadata`;此 collector 只用 BatchMode public-key SSH、stdin PowerShell bootstrap 與 bounded VMX identity keys,不讀 secret、不寫遠端檔、不啟動 / 關閉 VM、不重啟 Windows service / host、不套 registry。live 結果:expected 111 VMX path `exists=0`、`candidate_vmx_count=6`、`alias_hint_candidate_count=0`、`identity_target_hint_count=0`、`identity_unassigned_ubuntu_candidate_count=1`、`locate_status=single_identity_unassigned_ubuntu_candidate_requires_confirmation`。該 generic Ubuntu candidate 不能直接 relink;先前 MAC / neighbor evidence 未證明它是 111,且 99 local named backup roots 與 110 bounded backup roots 未找到 111 VMX artifact。下一步只能是取得外部 verified backup artifact 或更強身份證據後建立 scoped relink / restore dry-run,再跑 post-verifier;不得用猜測候選直接 relink、power on 或宣稱 SLA 完成。
|
||||
|
||||
2026-07-02 110 control-path / Harbor recovery receipt rule:若 Gitea Harbor repair queue 仍保留 `harbor_110_remote_ssh_publickey_auth_stalled`、remote-control unavailable、jobs stale 或 historical failure,但同一輪本地證據同時證明 `wooo` command path ready、110 local Harbor `/v2/` ready、public/internal registry `/v2/` 回 `401`,則該 Gitea Harbor repair 失敗只能列為 historical queue metadata,不得再當成 current SSH blocker。必須用 `/api/v1/agents/harbor-registry-controlled-recovery-receipt` 或同等 validator 合併 `diagnose-110-ssh-publickey-auth.sh`、`recover-110-control-path-and-harbor-local.sh --check`、public Gitea queue readback 與 registry `/v2/` verifier,並把機器可讀結果寫入 `docs/operations/harbor-110-control-path-recovery-readback-2026-07-02.snapshot.json` 類型的 snapshot。2026-07-02 live receipt 顯示:public/internal registry `/v2/` 均為 `401`、latest visible CD `#4335` 為 `Success`、Gitea Harbor repair failure 已是 `historical_after_latest_cd_success=true`;active blockers 收斂為 110 controlled CD lane config / binary / registration / service guardrail、active action container pressure,以及 Gitea CD jobs head-SHA / stale readback mismatch。若 local-console output 只有 `AWOOOI_110_CONTROLLED_CD_LANE_READY` marker,non110 runner parser 不得從 110 `BLOCKER` 行推導 non110 blocker;non110 只有看到 `AWOOOI_NON110_RUNNER_READY` marker 才能列入 active blocker。
|
||||
|
||||
2026-07-02 110 controlled CD lane fail-closed enforcer staging rule:110 runner 壓力事故後,legacy / generic runner 仍必須 fail-closed;但 `awoooi-cd-lane-drain.service` 的非 secret staging artifact 不得再被 enforcer 無差別封回 stub。`scripts/reboot-recovery/enforce-110-runner-failclosed.sh` 只有在 `config.yaml` 符合 `capacity <= 1`、只含 `awoooi-host:host` 與 `awoooi-ubuntu:docker://192.168.0.110:5000/awoooi/ci-runner:act-22.04`、binary 是 executable ELF、systemd unit 具備 `ConditionPathExists=/home/wooo/awoooi-cd-lane-drain/data/.runner`、`CPUAccounting` / `MemoryAccounting` / `TasksAccounting` / `NoNewPrivileges` 等 guardrail,且 service `inactive`、`MainPID=0`、未 enabled / 未 masked 時,才可保留 drain config / binary / unit,並輸出 `CONTROLLED_DRAIN_STAGING_ALLOWED=1` 與 textfile metric。此 staging 規則不得讀 token、不得讀 `.runner` 內容、不得註冊 runner、不得啟動 service;若 registration 缺失,readiness verifier 仍必須只留下 `controlled_cd_lane_registration_missing` / `controlled_cd_lane_service_not_active` 類 blocker。若 `CONTROLLED_DRAIN_STAGING_ALLOWED=0` 且 config / binary 又被搬走,優先修 source enforcer / unit guardrail,不要手工反覆補同一組 artifact。
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# AWOOOI 重開機恢復 SOP
|
||||
|
||||
> **版本**: v5.7
|
||||
> **版本**: v5.8
|
||||
> **最後更新**: 2026-07-03 (台北時間)
|
||||
> **更新者**: Codex
|
||||
> **觸發事件**: 2026-07-03 11:35 production SLO scorecard:Windows99 VMX source repair public endpoint 已補 redaction execution boundary,10 分鐘 SLO 仍 blocked
|
||||
> **觸發事件**: 2026-07-03 12:00 production SLO scorecard + Windows99 VMX source locate check-mode:111 VMX source 尚未找到,10 分鐘 SLO 仍 blocked
|
||||
|
||||
---
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
## 架構概覽與依賴圖
|
||||
|
||||
### 2026-07-03 10:50 P0 現況覆蓋
|
||||
### 2026-07-03 12:00 P0 現況覆蓋
|
||||
|
||||
目前不得宣稱「全主機重啟後 10 分鐘內全部恢復」。production SLO scorecard 仍為 `blocked_reboot_auto_recovery_slo_not_ready`,`active_blocker_count=10`、`readiness_percent=60`、primary blocker `reboot_event_required_host_unreachable`,`can_claim_all_services_recovered_within_target=false`。10 個 active blockers 固定為:
|
||||
目前不得宣稱「全主機重啟後 10 分鐘內全部恢復」。production SLO scorecard 仍為 `blocked_reboot_auto_recovery_slo_not_ready`,`active_blocker_count=8`、`readiness_percent=60`、primary blocker `fresh_all_host_reboot_event_missing`,`can_claim_all_services_recovered_within_target=false`。8 個 active blockers 固定為:
|
||||
|
||||
- `all_required_hosts_not_in_10_minute_reboot_window`
|
||||
- `fresh_all_host_reboot_event_missing`
|
||||
@@ -33,18 +33,18 @@
|
||||
- `reboot_event_required_host_unreachable`
|
||||
- `windows99_vmware_guest_power_not_ready`
|
||||
- `windows99_vmware_vmx_missing`
|
||||
- `windows99_vmware_autostart_config_not_ready`
|
||||
- `windows99_update_no_auto_reboot_policy_not_ready`
|
||||
|
||||
最新 no-write artifact 仍以 `/tmp/awoooi-reboot-verify-only-20260703-082310` 與後續 Windows99 management / collector readback 為來源:
|
||||
最新 no-write artifact 以 production API readback、110 上最新 Windows99 collector readback 與本輪 VMX locate collector 為來源:
|
||||
|
||||
- 99 可 ping / RDP / Hyper-V VMConnect,但 uptime unknown;SSH BatchMode 與 WinRM 仍不可用。
|
||||
- 111 仍 unreachable。
|
||||
- 99 no-secret VMware verify stdout 已能透過 110 / public-key SSH 收集;`VMAuthdService`、`VMnetDHCP`、`AWOOOI-Start-VMware-VMs` 與 Windows Update no-auto-reboot policy 讀回為 ok。
|
||||
- 111 VMX expected path 不存在;`windows99_vmware_vmx_missing` 仍是 Windows99 主要 source blocker。
|
||||
- 111 / 188 / 120 / 121 / 112 VM power readback 仍為 not running;`windows99_vmware_guest_power_not_ready` 仍 blocked,且此 SOP 不授權直接 power change。
|
||||
- 111 host 仍 unreachable。
|
||||
- 112 / 120 / 121 可達,但 uptime 已超過 10 分鐘目標窗口。
|
||||
- 188 可達,但 `systemd_state=degraded` 且 `awoooi-startup.service failed`。
|
||||
- `reboot_detected=false`、`fresh_boot_hosts=[]`,因此 10 分鐘 SLO 尚未證明。
|
||||
- `fresh_all_host_reboot_event_missing` 仍為 primary blocker,因此 10 分鐘 SLO 尚未證明。
|
||||
|
||||
固定下一步:`restore_windows99_missing_vmx_source_for_aliases_then_rerun_no_secret_collector_and_scorecard_no_vm_power_change`。先讀 production scorecard 的 `windows99_vmx_source_repair_package`,確認 111 expected VMX path 與 `Test-Path -LiteralPath ...` check-mode probe;再恢復 111 VMX source 與 99 no-secret management / console Verify stdout,使 `windows99-vmware-autostart.ps1 -Mode Verify` 產生 normalized artifact;同時補 111 reachability,再重跑 host probe、reboot-event detector、SLO scorecard。若 public API response 顯示 `public_lan_topology_redacted=true` 或 `check_mode_probe_commands_executable=false`,其中 `host:...` VMX path 只能當 public display evidence,不得直接貼到 Windows console 執行;要執行 probe 時必須使用授權內部 console / no-secret package 保留的原始 Windows path。禁止讀 Windows 密碼、啟動 / 關閉 VM、host reboot、service restart、Docker / Nginx / K3s / DB / firewall restart、restore、prune、delete。
|
||||
固定下一步:`locate_or_relink_missing_vmx_source_check_mode`。執行 `scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh --via-host wooo@192.168.0.110 --include-identity-metadata`;本輪 live 結果為 expected 111 VMX path `exists=0`、`candidate_vmx_count=6`、`alias_hint_candidate_count=0`、`identity_target_hint_count=0`、`identity_unassigned_ubuntu_candidate_count=1`、`locate_status=single_identity_unassigned_ubuntu_candidate_requires_confirmation`。唯一 generic Ubuntu candidate 還不能安全 relink,因為 display name / alias 沒有 111 identity hint,先前 MAC / neighbor evidence 也未證明它是 111,且 99 local named backup roots 與 110 bounded backup roots 尚未找到 111 VMX artifact。下一步只能取得外部 verified backup artifact 或更強 identity evidence,再產生 scoped relink / restore dry-run 與 post-verifier。若 public API response 顯示 `public_lan_topology_redacted=true` 或 `check_mode_probe_commands_executable=false`,其中 `host:...` VMX path 只能當 public display evidence,不得直接貼到 Windows console 執行;要執行 probe 時必須使用授權內部 console / no-secret package 保留的原始 Windows path。禁止讀 Windows 密碼、啟動 / 關閉 VM、host reboot、service restart、Docker / Nginx / K3s / DB / firewall restart、restore、prune、delete。
|
||||
|
||||
### 五主機全貌
|
||||
|
||||
|
||||
@@ -57,14 +57,14 @@
|
||||
|
||||
| 順序 | ID | 優先序 | 使用者插入要求 | 正規化工作項 | 目前狀態 | 下一個可驗證動作 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 1 | CIR-P0-RBT-001 | P0 | 「主機重啟後 10 分鐘內全部恢復,且要自動判斷所有主機被重啟」 | 建立 99/110/111/112/120/121/188 reboot event detector + 10 分鐘 SLO scorecard + fixed triage order | 2026-07-03 10:50 production scorecard:readiness `60%`、active blockers `10`、`can_claim_all_services_recovered_within_target=false`;blockers 已含 reboot event / host unreachable / uptime unknown / Windows99 VMX / guest power / VMware config / Windows Update policy;artifact `/tmp/awoooi-reboot-continue-20260703-085205`:111 不可達、99 uptime unknown、188 startup failed/degraded;09:22 已把 unreliable console artifact 投影成 machine-readable blocker | 優先收斂 111 VMX source、99 local console Verify output / no-secret management channel 與 111 reachability;不可宣稱 10 分鐘 SLA 已證明,不得用 RDP clipboard 片段當完成證據 |
|
||||
| 1 | CIR-P0-RBT-001 | P0 | 「主機重啟後 10 分鐘內全部恢復,且要自動判斷所有主機被重啟」 | 建立 99/110/111/112/120/121/188 reboot event detector + 10 分鐘 SLO scorecard + fixed triage order | 2026-07-03 12:00 production scorecard:readiness `60%`、active blockers `8`、primary `fresh_all_host_reboot_event_missing`、`can_claim_all_services_recovered_within_target=false`;Windows99 no-secret collector 已收 verify stdout,Windows Update / VMware services / scheduled task 讀回 ok,但 111 VMX source missing 與 guest power not ready 仍 blocked | 優先收斂 111 VMX source locate / verified backup artifact、111 reachability 與 fresh all-host reboot event;不可宣稱 10 分鐘 SLA 已證明,不得用 RDP clipboard 片段或 generic VMX guess 當完成證據 |
|
||||
| 2 | CIR-P0-RBT-002 | P0 | 「沒有偵測到主機重啟」 | 修正 host reboot/shutdown/up detection:boot_id / uptime / node exporter / Windows exporter / VMware VM power state 都要進同一事件 | Scorecard 已接 collection packet + management probe;08:23 host probe 有 7 列但 99 只有 ping/RDP reachable、uptime unknown,111 unreachable,112/120/121/188 uptime 都已超過 10 分鐘窗口 | 讓 99 verifier / Windows exporter 或等效 no-secret readback 進入 host boot event,並補 111 reachability 證據 |
|
||||
| 3 | CIR-P0-RBT-003 | P0 | 「192.168.0.99 VMWare 要自動啟動,裡面 111/188/120/121/112 也自動啟動」 | Windows 99 VMware host autostart + guest VM autostart contract;VM host 111/188/120/121/112 開機順序與 readback | Source verifier / parser / API readback / collection packet 已完成;10:58 API scorecard 已接入 `windows99_vmx_source_repair_package`,會把 111 VMX missing 轉成 expected path / `Test-Path` check-mode probe;11:35 public API 已補 `public_lan_topology_redacted=true` / `check_mode_probe_commands_executable=false`,避免把 public display alias 誤當 Windows console 可執行命令;10:15 source/API patch 已把 nested `service_blockers=["VMAuthdService","VMnetDHCP"]` 與 VMX / power evidence 提升到 active blocker matrix;09:53 management probe 讀回 99 host reachable、RDP / Hyper-V VMConnect reachable,但 SSH BatchMode `permission_denied`、WinRM timeout,`console_artifact_status=blocked_clipboard_unreliable` | 先用授權內部 console / no-secret package 保留的原始 Windows path 修 111 VMX source,再處理 VMware service / autostart task check-mode package,重跑 no-secret collector 與 scorecard;不得從 public redacted path 或 scorecard 直接啟動 / 關閉 VM、重啟 Windows service、讀密碼或 host reboot |
|
||||
| 3 | CIR-P0-RBT-003 | P0 | 「192.168.0.99 VMWare 要自動啟動,裡面 111/188/120/121/112 也自動啟動」 | Windows 99 VMware host autostart + guest VM autostart contract;VM host 111/188/120/121/112 開機順序與 readback | Source verifier / parser / API readback / collection packet 已完成;12:00 API / priority readback 顯示 `source_repair_check_mode_ready`、下一步 `locate_or_relink_missing_vmx_source_check_mode`;本輪 no-write locator 確認 expected 111 VMX path `exists=0`、`candidate_vmx_count=6`、`alias_hint_candidate_count=0`、`identity_target_hint_count=0`、`identity_unassigned_ubuntu_candidate_count=1`、`locate_status=single_identity_unassigned_ubuntu_candidate_requires_confirmation`;VMware services / scheduled task / Windows Update policy 已 ok,但 guest power 仍 not ready | 不得直接 relink generic Ubuntu candidate;先取得 external verified backup artifact 或更強 identity evidence,再做 scoped relink / restore dry-run 與 post-verifier;不得從 public redacted path 或 scorecard 直接啟動 / 關閉 VM、重啟 Windows service、讀密碼或 host reboot |
|
||||
| 4 | CIR-P0-RBT-004 | P0 | 「192.168.0.99 不可因 Windows Update 無預警重開」 | Windows Update reboot policy:active hours / no auto-restart / maintenance window / update notification audit | 10:15 source/API patch:若 nested verifier 回 `policy_blockers=["windows_update_policy_readback_missing"]`,API 必須 fail-closed 重新提升 `windows99_update_no_auto_reboot_policy_not_ready`;不得只信舊 Prometheus `windows99_update_no_auto_reboot_ready=true` | 補 no-secret policy readback / drift alert;若 policy 不綠,另走 controlled apply package + rollback + post-verifier,禁止要求或記錄 Windows 密碼,禁止由 scorecard 直接 apply registry |
|
||||
| 5 | CIR-P0-RBT-005 | P0 | 「網站重啟後 502 嚴重影響體驗,要維護頁,外部雲端或專業做法」 | Public maintenance fallback:Nginx / edge / external static maintenance page / status page / fail-open UX,避免 502 直出 | Source + runtime verifier 已實作;Gitea CD `#4459` Success、deploy marker `8d7a6faaf`,production API scorecard 已讀回 `public_maintenance_fallback.ready=true`、raw 5xx=`0`、unreachable without L1=`0`,P0 blockers `11`、readiness `47`;仍不可宣稱整體 10 分鐘 SLO 完成 | 若未來 public route 出現 raw 5xx,先走 L0 Nginx intercept / header verifier;若 edge unreachable,才產生 L1 external static origin / CDN decision record + rollback |
|
||||
| 6 | CIR-P0-RBT-006 | P0 | 「所有主機關機立刻 Telegram 告警,重啟後也要告警,其他告警一併完整思考」 | Down / shutdown suspected / reboot detected / reboot recovered / SLO missed / backup failed / freshness stale / CPU pressure / Gitea queue 告警矩陣 | HostDown / HostRebootEventDetected / RebootAutoRecoverySLOMissed 已存在;per-blocker reboot alerts 與 backup receipt rules 已 deploy/readback。Backup receipt 缺段已從 100 條 stage 噪音收斂為 110 / 188 兩條 host-level pending;仍需完整 shutdown/up E2E receipt | 補 Prometheus / Alertmanager active/resolved 與 outbound receipt;backup alert 先補 `/backup/alert-receipts/*.last_success` 脫敏 marker,不送測試 secret、不重啟主機 |
|
||||
| 7 | CIR-P0-RBT-007 | P0 | 「所有備份包含主機、DB、網站、服務、套件、工具、日誌都沒有監控告警」 | Backup observability coverage:backup job inventory、last success、freshness、offsite、restore drill、Telegram/AwoooP receipt | 已有 backup health exporter / alert rules / Gitea bundle restore dry-run;2026-07-03 runtime 讀回 110 有 88 個 receipt stage requirement、188 有 12 個,`BackupAlertReceiptMetricMissing*` inactive,`BackupAlertReceiptStageMissing` 聚合 pending 110 / 188 各一條 | 補 `/backup/alert-receipts/*.last_success`;再補 Gitea full dump / DB / settings / issues / packages / LFS 與所有工具/log 全量備份監控 |
|
||||
| 8 | CIR-P0-RBT-008 | P0 | 「每次重啟排查都不一樣,也不知道多久恢復,不符合 SLA」 | 固定化 reboot runbook:fixed triage order、ETA、active blocker、remaining seconds、owner lane、next command | Production scorecard readback 已固定 `status=blocked_reboot_auto_recovery_slo_not_ready`、readiness `60%`、active blockers `10`、primary `reboot_event_required_host_unreachable`;10:50 next action 固定為 `restore_windows99_missing_vmx_source_for_aliases_then_rerun_no_secret_collector_and_scorecard_no_vm_power_change` | 優先收斂 111 VMX source、99 no-secret Verify / 111 reachability / 188 startup failed/degraded;不得用不同排查路徑繞過 scorecard |
|
||||
| 8 | CIR-P0-RBT-008 | P0 | 「每次重啟排查都不一樣,也不知道多久恢復,不符合 SLA」 | 固定化 reboot runbook:fixed triage order、ETA、active blocker、remaining seconds、owner lane、next command | Production scorecard readback 已固定 `status=blocked_reboot_auto_recovery_slo_not_ready`、readiness `60%`、active blockers `8`、primary `fresh_all_host_reboot_event_missing`;12:00 next executable step 固定為 `locate_or_relink_missing_vmx_source_check_mode`,且 locator 結果要求先補 identity / backup evidence | 優先收斂 111 VMX source verified artifact、111 reachability / fresh all-host reboot event、188 startup failed/degraded;不得用不同排查路徑繞過 scorecard |
|
||||
| 9 | CIR-P0-RBT-009 | P0 | 「所有產品、網站都要是最新版本;版本和數據是否最新要驗證」 | Product freshness/version matrix:source commit、deploy marker、runtime image、public health、data freshness、latest source availability | AWOOOI Gitea `main=bc8d3af3f chore(cd): deploy dacdd90 [skip ci]`;CD `#4558` log 顯示 API/Web build/push wrapper 全部 `rc=0`、deploy marker `dacdd90`、production deploy readback matched。Production SLO route 已讀回最新 API 行為:`active_blocker_count=10`、`runtime_metric_runtime_readback_added_blockers=["windows99_vmware_autostart_config_not_ready","windows99_update_no_auto_reboot_policy_not_ready"]`、`windows99_update_no_auto_reboot_ready=false`。StockPlatform public freshness / ingestion 仍為 `ok`,latest trading date `2026-07-02`。 | 版本層已補到 AWOOOI production;下一步仍要建立全產品 readback 表,且收斂 Windows99 VMX / service / policy / power 與 host reboot-event blockers |
|
||||
| 10 | CIR-P0-GIT-001 | P0 | 「Gitea 儲存庫都不見了?Gitea 沒完整備份嗎?」 | Gitea repository identity + backup proof + restore drill:不能只看 UI visible,要比對 SSH heads、repo path、bundle backup、restore sample | 2026-07-02 production `/api/v1/agents/gitea-repo-bundle-backup-readback` 已 ready:9 expected repos present/ok、missing=0、failed=0、checksum_missing=0、bundle_fresh=true、all_expected_ok=true、sample_restore_dry_run_ok=true;repo bundle / restore dry-run 層已關閉,不是 repo missing。 | 維持每日 bundle backup + restore dry-run monitoring;另補 Gitea full dump / DB / settings / issues / packages / LFS 備份 readback。禁止刪 repo / 改 visibility / 讀 token / restore 到 production |
|
||||
| 11 | CIR-P0-CPU-001 | P0 | 「110 / 188 CPU 負載持續過高,為什麼沒監控告警、沒主動修復」 | Sustained CPU pressure automation:Alertmanager → controller → evidence → service playbook → verifier → KM writeback | 110 已有 `Host110SustainedModeratePressure`、Gitea playbook、Stock/Postgres evidence;188 仍需同級 controller/alerts readback | 下一步接 `postgres_hot_query_or_backup_export_playbook`;並補 188 equivalent readback,不以單次下降結案 |
|
||||
@@ -134,10 +134,10 @@
|
||||
| KM / PlayBook / RAG / MCP 整合 | 已被列為 P1,不再遺漏 | 建立 work item schema 與 trust writeback 欄位 |
|
||||
| OpenClaw / Gather-style 持續動畫工作室 | route 已存在,已列為 P1 工作項 | 補 production desktop/mobile smoke、AwoooP 導流與截圖證據 |
|
||||
| AI 專業 UI / 非文字牆 cockpit | 已列為 P2 UX 驗收 | 將長文字區塊收斂成 first-viewport cockpit、cards、flow rows 與 expandable details |
|
||||
| 10 分鐘 reboot auto-recovery SLA | 2026-07-03 10:50 production scorecard 固定 `10` blockers / readiness `60%`,但 `can_claim_all_services_recovered_within_target=false`;artifact `/tmp/awoooi-reboot-verify-only-20260703-082310` 保留 host probe / reboot detector / scorecard,production readback 已把 Windows99 config / policy blockers 上卷 | 收斂 111 VMX source、99 no-secret Verify、111 reachability、188 startup failed/degraded,再 rerun host probe + reboot-event detector |
|
||||
| 10 分鐘 reboot auto-recovery SLA | 2026-07-03 12:00 production scorecard 固定 `8` blockers / readiness `60%`,但 `can_claim_all_services_recovered_within_target=false`;primary `fresh_all_host_reboot_event_missing`,Windows99 verify stdout 已收,111 VMX source / guest power 仍 blocked | 收斂 111 VMX source verified artifact、111 reachability、188 startup failed/degraded,再 rerun host probe + reboot-event detector |
|
||||
| AWOOOI latest source production deploy readback | Gitea `main=bc8d3af3f`,deploy marker `dacdd90`;public CD `#4558` log job succeeded / production deploy readback matched;production scorecard 已讀回 latest API 行為並把 Windows99 config / policy blockers 上卷 | 下一步轉回 Windows99 VMX / service / policy / power 與 host reboot-event blockers;不得因 deploy/readback 成功宣稱 10 分鐘 SLO 完成 |
|
||||
| 99 Windows / VMware autostart | Source verifier / parser / API readback / collection packet 已完成;10:58 API scorecard 已接入 `windows99_vmx_source_repair_package`,111 VMX missing 會輸出 expected path 與 check-mode probe;live 99 Verify output 尚未收集;08:23 management probe 顯示 RDP / Hyper-V VMConnect reachable,但 SSH BatchMode / WinRM blocked,collector `blocked_ssh_publickey_auth_missing` | 依 API package 修 111 VMX source,收集 99 no-secret Verify output,確認 VM 111/188/120/121/112 running、scheduled task / services / Windows Update policy 全綠 |
|
||||
| Reboot SLO blocker 收斂 | production scorecard 已固定 `10` blockers / readiness `60%`,source / runtime 已補 per-blocker metric/alert;剩餘主 blocker 是 host boot detection + Windows99 VMware VMX / guest power / autostart config / Windows Update policy | 依具名 blocker 收斂 99/111/188;不得用 route green 或 RDP 可見宣稱 SLA 完成 |
|
||||
| 99 Windows / VMware autostart | Source verifier / parser / API readback / collection packet 已完成;live 99 Verify output 已透過 no-secret collector 收集,VMware services / scheduled task / Windows Update policy ok;VMX locate check 顯示 expected 111 path missing、無 alias / identity target hint、只有一個 generic Ubuntu candidate 需再確認 | 取得 external verified backup artifact 或更強 identity evidence,產生 scoped relink / restore dry-run,重跑 no-secret collector,確認 VM 111/188/120/121/112 running |
|
||||
| Reboot SLO blocker 收斂 | production scorecard 已固定 `8` blockers / readiness `60%`,source / runtime 已補 per-blocker metric/alert;剩餘主 blocker 是 fresh all-host reboot event + Windows99 111 VMX source / guest power + 111 reachability / 188 degraded | 依具名 blocker 收斂 99/111/188;不得用 route green 或 RDP 可見宣稱 SLA 完成 |
|
||||
| 全備份監控告警 coverage | exporter/rule 已有 host/DB/site/service/package/tool/log coverage 與 backup alert receipt requirement;runtime rules 已部署,缺段 alert 聚合成 110 / 188 host-level pending;production receipt markers / full Gitea dump / DB/settings/issues/packages/LFS 尚未全綠 | 補 `/backup/alert-receipts/*.last_success`、Gitea full dump 與 restore drill verifier |
|
||||
| Stock/Postgres hot pressure | 110 live 已導向 Stock/Postgres playbook;尚未完成 hot query / backup export playbook closure | 下一步執行 read-only Stock/Postgres evidence 與 source freshness / query attribution |
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
## 下一輪固定執行順序
|
||||
|
||||
1. 先確認 Gitea `main` / CD / production readback 是否仍與最新 truth 一致。
|
||||
2. 接續目前 active reboot P0:用 10:50 production scorecard 的固定順序收斂 111 VMX source、99 no-secret Verify、111 reachability、188 startup failed/degraded,再 rerun host probe / reboot-event detector / scorecard。
|
||||
2. 接續目前 active reboot P0:用 12:00 production scorecard 的固定順序收斂 111 VMX source verified artifact、111 reachability、188 startup failed/degraded,再 rerun host probe / reboot-event detector / scorecard。
|
||||
3. 補全 reboot auto-recovery P0:99/110/111/112/120/121/188 reboot detection、10 分鐘 SLO scorecard、Telegram down/up/recovered/SLO missed / active-blocker receipts。
|
||||
4. 補 99 Windows / VMware autostart P0:99 host 自動啟動 VMware,VM 111/188/120/121/112 自動啟動;同時補 Windows Update no-auto-restart verifier。
|
||||
5. 補 111 reachability / host boot readback,讓 `host_unreachable_after_reboot` 與 `reboot_event_required_host_unreachable` 有單一固定處理路徑。
|
||||
|
||||
152
scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh
Executable file
152
scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TARGET_HOST="${WINDOWS99_HOST:-192.168.0.99}"
|
||||
TARGET_USER="${WINDOWS99_USER:-wooo}"
|
||||
TARGET_PORT="${WINDOWS99_PORT:-22}"
|
||||
VIA_HOST="${WINDOWS99_VIA_HOST:-}"
|
||||
CONNECT_TIMEOUT="${WINDOWS99_CONNECT_TIMEOUT:-8}"
|
||||
KNOWN_HOSTS_FILE="${WINDOWS99_KNOWN_HOSTS_FILE:-/tmp/awoooi-windows99-vmx-locate-known_hosts}"
|
||||
LOCAL_LOCATE_SCRIPT="${WINDOWS99_VMX_LOCATE_SCRIPT:-${SCRIPT_DIR}/windows99-vmx-source-locate-check.ps1}"
|
||||
INCLUDE_IDENTITY_METADATA=0
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
usage: collect-windows99-vmx-source-locate-check.sh [options]
|
||||
|
||||
Runs the Windows99 VMX source locate check through public-key SSH only. This is
|
||||
check-mode evidence: it does not read secrets, write files, start VMs, restart
|
||||
services, apply registry changes, or reboot hosts.
|
||||
|
||||
Options:
|
||||
--host HOST Windows99 host. Default: 192.168.0.99
|
||||
--user USER Windows99 SSH user. Default: wooo
|
||||
--port PORT Windows99 SSH port. Default: 22
|
||||
--via-host USER@HOST Optional SSH jump host, e.g. wooo@192.168.0.110
|
||||
--timeout SECONDS SSH connect timeout. Default: 8
|
||||
--include-identity-metadata Read bounded VMX identity keys after path-only scan
|
||||
-h, --help Show this help
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--host)
|
||||
shift
|
||||
TARGET_HOST="${1:?--host requires a value}"
|
||||
;;
|
||||
--user)
|
||||
shift
|
||||
TARGET_USER="${1:?--user requires a value}"
|
||||
;;
|
||||
--port)
|
||||
shift
|
||||
TARGET_PORT="${1:?--port requires a value}"
|
||||
;;
|
||||
--via-host)
|
||||
shift
|
||||
VIA_HOST="${1:?--via-host requires a value}"
|
||||
;;
|
||||
--timeout)
|
||||
shift
|
||||
CONNECT_TIMEOUT="${1:?--timeout requires a value}"
|
||||
;;
|
||||
--include-identity-metadata)
|
||||
INCLUDE_IDENTITY_METADATA=1
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'error=unknown_argument:%s\n' "$1" >&2
|
||||
usage >&2
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ ! -f "$LOCAL_LOCATE_SCRIPT" ]]; then
|
||||
printf 'schema_version=windows99_vmx_source_locate_collector_v1\n'
|
||||
printf 'status=blocked_local_locate_script_missing\n'
|
||||
printf 'local_locate_script=%s\n' "$LOCAL_LOCATE_SCRIPT"
|
||||
printf 'secret_value_read=false\n'
|
||||
printf 'remote_write_performed=false\n'
|
||||
printf 'vm_power_change_performed=false\n'
|
||||
exit 75
|
||||
fi
|
||||
|
||||
payload_file="$(mktemp "${TMPDIR:-/tmp}/awoooi-windows99-vmx-locate.XXXXXX")"
|
||||
trap 'rm -f "$payload_file"' EXIT
|
||||
|
||||
python3 - "$LOCAL_LOCATE_SCRIPT" "$INCLUDE_IDENTITY_METADATA" "$payload_file" <<'PY'
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
include_identity = sys.argv[2] == "1"
|
||||
output = pathlib.Path(sys.argv[3])
|
||||
script = path.read_text(encoding="utf-8")
|
||||
if include_identity:
|
||||
script = script.replace(
|
||||
" [switch]$IncludeIdentityMetadata\n)",
|
||||
" [switch]$IncludeIdentityMetadata = $true\n)",
|
||||
)
|
||||
output.write_text(script, encoding="utf-8")
|
||||
PY
|
||||
|
||||
SSH_OPTS=(
|
||||
-o BatchMode=yes
|
||||
-o PreferredAuthentications=publickey
|
||||
-o PubkeyAuthentication=yes
|
||||
-o PasswordAuthentication=no
|
||||
-o KbdInteractiveAuthentication=no
|
||||
-o NumberOfPasswordPrompts=0
|
||||
-o ConnectTimeout="${CONNECT_TIMEOUT}"
|
||||
-o ConnectionAttempts=1
|
||||
-o StrictHostKeyChecking=no
|
||||
-o UserKnownHostsFile="${KNOWN_HOSTS_FILE}"
|
||||
)
|
||||
|
||||
bootstrap_command="$(
|
||||
python3 - <<'PY'
|
||||
import base64
|
||||
|
||||
bootstrap = "& ([scriptblock]::Create([Console]::In.ReadToEnd()))"
|
||||
print(base64.b64encode(bootstrap.encode("utf-16le")).decode("ascii"))
|
||||
PY
|
||||
)"
|
||||
|
||||
REMOTE_PS=(
|
||||
powershell
|
||||
-NoProfile
|
||||
-ExecutionPolicy
|
||||
Bypass
|
||||
-EncodedCommand
|
||||
"$bootstrap_command"
|
||||
)
|
||||
|
||||
quote_words() {
|
||||
printf '%q ' "$@"
|
||||
}
|
||||
|
||||
printf 'schema_version=windows99_vmx_source_locate_collector_v1\n'
|
||||
printf 'target_host=%s\n' "$TARGET_HOST"
|
||||
printf 'target_user=%s\n' "$TARGET_USER"
|
||||
printf 'via_host=%s\n' "${VIA_HOST:-none}"
|
||||
printf 'include_identity_metadata=%s\n' "$INCLUDE_IDENTITY_METADATA"
|
||||
printf 'secret_value_read=false\n'
|
||||
printf 'remote_write_performed=false\n'
|
||||
printf 'vm_power_change_performed=false\n'
|
||||
printf 'windows_service_restart_performed=false\n'
|
||||
printf 'windows_registry_apply_performed=false\n'
|
||||
|
||||
if [[ -n "$VIA_HOST" ]]; then
|
||||
inner_ssh=(ssh "${SSH_OPTS[@]}" -p "$TARGET_PORT" "${TARGET_USER}@${TARGET_HOST}" "${REMOTE_PS[@]}")
|
||||
inner_command="$(quote_words "${inner_ssh[@]}")"
|
||||
ssh "${SSH_OPTS[@]}" "$VIA_HOST" "bash -lc $(printf '%q' "$inner_command")" <"$payload_file"
|
||||
else
|
||||
ssh "${SSH_OPTS[@]}" -p "$TARGET_PORT" "${TARGET_USER}@${TARGET_HOST}" "${REMOTE_PS[@]}" <"$payload_file"
|
||||
fi
|
||||
@@ -0,0 +1,52 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
PS1 = ROOT / "scripts/reboot-recovery/windows99-vmx-source-locate-check.ps1"
|
||||
COLLECTOR = (
|
||||
ROOT / "scripts/reboot-recovery/collect-windows99-vmx-source-locate-check.sh"
|
||||
)
|
||||
|
||||
|
||||
def test_windows99_vmx_source_locate_check_is_no_write_check_mode() -> None:
|
||||
text = PS1.read_text(encoding="utf-8")
|
||||
|
||||
assert "AWOOOI_WINDOWS99_VMX_LOCATE_CHECK=1" in text
|
||||
assert 'ProgressPreference = "SilentlyContinue"' in text
|
||||
assert "secret_value_read=false" in text
|
||||
assert "remote_write_performed=false" in text
|
||||
assert "vm_power_change_performed=false" in text
|
||||
assert "expected_vmx_exists" in text
|
||||
assert "candidate_vmx_count" in text
|
||||
assert "VMX_IDENTITY_SUMMARY" in text
|
||||
assert "identity_unassigned_ubuntu_candidate_count" in text
|
||||
assert "single_identity_unassigned_ubuntu_candidate_requires_confirmation" in text
|
||||
assert "locate_status=" in text
|
||||
assert "Start-VM" not in text
|
||||
assert "vmrun" not in text
|
||||
assert "Set-Content" not in text
|
||||
assert "New-Item" not in text
|
||||
assert "Register-ScheduledTask" not in text
|
||||
assert "Set-ItemProperty" not in text
|
||||
|
||||
|
||||
def test_windows99_vmx_source_locate_collector_uses_publickey_only() -> None:
|
||||
text = COLLECTOR.read_text(encoding="utf-8")
|
||||
|
||||
assert "windows99_vmx_source_locate_collector_v1" in text
|
||||
assert "BatchMode=yes" in text
|
||||
assert "PasswordAuthentication=no" in text
|
||||
assert "KbdInteractiveAuthentication=no" in text
|
||||
assert "NumberOfPasswordPrompts=0" in text
|
||||
assert "--via-host" in text
|
||||
assert "--include-identity-metadata" in text
|
||||
assert "[Console]::In.ReadToEnd()" in text
|
||||
assert "bootstrap_command" in text
|
||||
assert "payload_file" in text
|
||||
assert "secret_value_read=false" in text
|
||||
assert "remote_write_performed=false" in text
|
||||
assert "vm_power_change_performed=false" in text
|
||||
assert "scp " not in text
|
||||
assert "sudo " not in text
|
||||
122
scripts/reboot-recovery/windows99-vmx-source-locate-check.ps1
Normal file
122
scripts/reboot-recovery/windows99-vmx-source-locate-check.ps1
Normal file
@@ -0,0 +1,122 @@
|
||||
param(
|
||||
[string]$Alias = "111",
|
||||
[string]$ExpectedVmxPath = "D:\Documents\Virtual Machines\192.168.0.111_Ubuntu_64-bit\192.168.0.111_Ubuntu_64-bit.vmx",
|
||||
[string[]]$DiscoveryRoot = @(
|
||||
"D:\Documents\Virtual Machines",
|
||||
"D:\Downloads",
|
||||
"D:\VMs",
|
||||
"E:\VMs",
|
||||
"C:\VMs",
|
||||
"C:\Users\Public\Documents\Virtual Machines"
|
||||
),
|
||||
[int]$MaxResults = 120,
|
||||
[switch]$IncludeIdentityMetadata
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$identityPatterns = "^(displayName|guestOS|ethernet0\.addressType|ethernet0\.generatedAddress|uuid\.bios|uuid\.location|scsi0:0\.fileName|ide1:0\.fileName)\s*="
|
||||
|
||||
Write-Output "AWOOOI_WINDOWS99_VMX_LOCATE_CHECK=1"
|
||||
Write-Output "target_alias=$Alias"
|
||||
Write-Output "secret_value_read=false"
|
||||
Write-Output "remote_write_performed=false"
|
||||
Write-Output "vm_power_change_performed=false"
|
||||
Write-Output "windows_service_restart_performed=false"
|
||||
Write-Output "windows_registry_apply_performed=false"
|
||||
Write-Output "identity_metadata_read=$([int][bool]$IncludeIdentityMetadata)"
|
||||
Write-Output "expected_vmx_path=$ExpectedVmxPath"
|
||||
Write-Output "expected_vmx_exists=$([int](Test-Path -LiteralPath $ExpectedVmxPath))"
|
||||
|
||||
$candidateCount = 0
|
||||
$aliasHintCount = 0
|
||||
$unassignedUbuntuCandidateCount = 0
|
||||
$identityTargetHintCount = 0
|
||||
$identityUnassignedUbuntuCandidateCount = 0
|
||||
|
||||
foreach ($root in $DiscoveryRoot) {
|
||||
$rootExists = Test-Path -LiteralPath $root
|
||||
Write-Output "ROOT path=$root exists=$([int]$rootExists)"
|
||||
if (-not $rootExists) {
|
||||
continue
|
||||
}
|
||||
|
||||
$files = @(
|
||||
Get-ChildItem -LiteralPath $root -Recurse -Filter "*.vmx" -File -ErrorAction SilentlyContinue |
|
||||
Select-Object -First $MaxResults
|
||||
)
|
||||
|
||||
foreach ($file in $files) {
|
||||
$candidateCount += 1
|
||||
$aliasHint = [int]($file.FullName -match [regex]::Escape($Alias))
|
||||
$ubuntuHint = [int]($file.FullName -match "Ubuntu|ubuntu")
|
||||
if ($aliasHint -eq 1) {
|
||||
$aliasHintCount += 1
|
||||
}
|
||||
if ($aliasHint -eq 0 -and $ubuntuHint -eq 1) {
|
||||
$unassignedUbuntuCandidateCount += 1
|
||||
}
|
||||
Write-Output "VMX_FILE path=$($file.FullName) alias_hint=$aliasHint ubuntu_hint=$ubuntuHint size=$($file.Length)"
|
||||
|
||||
if ($IncludeIdentityMetadata) {
|
||||
$identityLines = @(
|
||||
Select-String -LiteralPath $file.FullName -Pattern $identityPatterns -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 20
|
||||
)
|
||||
$displayName = ""
|
||||
foreach ($match in $identityLines) {
|
||||
$line = $match.Line -replace "`r", ""
|
||||
if ($line -match "^displayName\s*=\s*`"(.+)`"") {
|
||||
$displayName = $Matches[1]
|
||||
}
|
||||
Write-Output "VMX_IDENTITY_FIELD path=$($file.FullName) $line"
|
||||
}
|
||||
$knownNonTargetAlias = [int]($displayName -match "192\.168\.0\.(110|112|120|121|188)")
|
||||
$targetAliasIdentityHint = [int]($displayName -match "192\.168\.0\.$Alias")
|
||||
$genericUnassignedIdentityHint = [int](
|
||||
$ubuntuHint -eq 1 -and
|
||||
$knownNonTargetAlias -eq 0 -and
|
||||
$targetAliasIdentityHint -eq 0
|
||||
)
|
||||
if ($targetAliasIdentityHint -eq 1) {
|
||||
$identityTargetHintCount += 1
|
||||
}
|
||||
if ($genericUnassignedIdentityHint -eq 1) {
|
||||
$identityUnassignedUbuntuCandidateCount += 1
|
||||
}
|
||||
Write-Output "VMX_IDENTITY_SUMMARY path=$($file.FullName) display_name=$displayName known_non_target_alias=$knownNonTargetAlias target_alias_identity_hint=$targetAliasIdentityHint generic_unassigned_identity_hint=$genericUnassignedIdentityHint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output "candidate_vmx_count=$candidateCount"
|
||||
Write-Output "alias_hint_candidate_count=$aliasHintCount"
|
||||
Write-Output "unassigned_ubuntu_candidate_count=$unassignedUbuntuCandidateCount"
|
||||
Write-Output "identity_target_hint_count=$identityTargetHintCount"
|
||||
Write-Output "identity_unassigned_ubuntu_candidate_count=$identityUnassignedUbuntuCandidateCount"
|
||||
if ((Test-Path -LiteralPath $ExpectedVmxPath)) {
|
||||
Write-Output "locate_status=expected_vmx_path_present"
|
||||
Write-Output "safe_next_step=rerun_windows99_vmware_verify_collector_no_secret"
|
||||
} elseif ($aliasHintCount -gt 0) {
|
||||
Write-Output "locate_status=alias_hint_candidate_found"
|
||||
Write-Output "safe_next_step=build_scoped_relink_dry_run_for_alias_hint_candidate_then_post_verify"
|
||||
} elseif ($IncludeIdentityMetadata -and $identityTargetHintCount -gt 0) {
|
||||
Write-Output "locate_status=identity_target_hint_candidate_found"
|
||||
Write-Output "safe_next_step=build_scoped_relink_dry_run_for_identity_hint_candidate_then_post_verify"
|
||||
} elseif ($IncludeIdentityMetadata -and $identityUnassignedUbuntuCandidateCount -eq 1) {
|
||||
Write-Output "locate_status=single_identity_unassigned_ubuntu_candidate_requires_confirmation"
|
||||
Write-Output "safe_next_step=confirm_single_unassigned_ubuntu_candidate_is_target_alias_before_scoped_relink_dry_run"
|
||||
} elseif ($IncludeIdentityMetadata -and $identityUnassignedUbuntuCandidateCount -gt 1) {
|
||||
Write-Output "locate_status=multiple_identity_unassigned_ubuntu_candidates_requires_confirmation"
|
||||
Write-Output "safe_next_step=confirm_candidate_identity_before_any_relink_or_restore"
|
||||
} elseif ($unassignedUbuntuCandidateCount -eq 1) {
|
||||
Write-Output "locate_status=single_unassigned_ubuntu_candidate_requires_identity_confirmation"
|
||||
Write-Output "safe_next_step=confirm_unassigned_ubuntu_candidate_identity_before_scoped_relink_dry_run"
|
||||
} elseif ($unassignedUbuntuCandidateCount -gt 1) {
|
||||
Write-Output "locate_status=multiple_unassigned_ubuntu_candidates_requires_identity_confirmation"
|
||||
Write-Output "safe_next_step=confirm_candidate_identity_before_any_relink_or_restore"
|
||||
} else {
|
||||
Write-Output "locate_status=no_candidate_found"
|
||||
Write-Output "safe_next_step=restore_vmx_source_from_verified_backup_artifact_then_post_verify_no_vm_power_change"
|
||||
}
|
||||
Reference in New Issue
Block a user