diff --git a/apps/api/src/services/reboot_auto_recovery_slo_scorecard.py b/apps/api/src/services/reboot_auto_recovery_slo_scorecard.py index 65ee6ded8..821b869fe 100644 --- a/apps/api/src/services/reboot_auto_recovery_slo_scorecard.py +++ b/apps/api/src/services/reboot_auto_recovery_slo_scorecard.py @@ -112,8 +112,11 @@ _WINDOWS99_POWERED_OFF_NEXT_SAFE_ACTION = ( "build_windows99_vmware_autostart_check_mode_package_for_powered_off_aliases_" "then_rerun_no_secret_collector_no_vm_power_change" ) -_WINDOWS99_REQUIRED_VM_ALIASES = ["111", "188", "120", "121", "112"] +_WINDOWS99_REQUIRED_VM_ALIASES = ["110", "188", "120", "121", "112"] _WINDOWS99_EXPECTED_VMX_CANDIDATES = { + "110": [ + r"D:\Documents\Virtual Machines\Ubuntu 64-bit (3)\Ubuntu 64-bit (3).vmx", + ], "111": [ r"D:\Documents\Virtual Machines\192.168.0.111_Ubuntu_64-bit\192.168.0.111_Ubuntu_64-bit.vmx", ], @@ -1602,6 +1605,8 @@ def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]: scorecard.get("public_maintenance_fallback") ) windows99 = _dict(scorecard.get("windows99_vmware_autostart")) + if windows99.get("readback_present") is not True: + windows99["required_vm_aliases"] = _WINDOWS99_REQUIRED_VM_ALIASES windows99_management = _dict(scorecard.get("windows99_management_channel")) windows99_ssh_batch = _dict(windows99_management.get("ssh_batch")) windows99_collector = _dict(scorecard.get("windows99_vmware_verify_collector")) @@ -2377,7 +2382,7 @@ def _build_windows99_verify_collection_packet( ), "no_secret_collector": windows99_collector, "required_vm_aliases": _strings(windows99.get("required_vm_aliases")) - or ["111", "112", "120", "121", "188"], + or _WINDOWS99_REQUIRED_VM_ALIASES, "expected_no_secret_output_fields": [ "VMRUN_PRESENT", "VMX alias= present=<0|1>", @@ -2588,6 +2593,9 @@ def _build_windows99_vmx_source_repair_package( _strings(windows99.get("required_vm_aliases")) or _WINDOWS99_REQUIRED_VM_ALIASES ) + row_aliases = _unique_strings( + [*required_aliases, *missing_vmx_aliases, *powered_off_aliases] + ) package_ready = bool(missing_vmx_aliases or powered_off_aliases) if missing_vmx_aliases: status = "check_mode_package_ready_windows99_vmx_source_repair_required" @@ -2600,7 +2608,7 @@ def _build_windows99_vmx_source_repair_package( safe_next_step = "rerun_no_secret_collector_and_reboot_slo_scorecard_verify_only" rows: list[dict[str, Any]] = [] - for alias in required_aliases: + for alias in row_aliases: candidates = _WINDOWS99_EXPECTED_VMX_CANDIDATES.get(alias, []) rows.append( { diff --git a/apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py b/apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py index ecf019b5f..24aa49c28 100644 --- a/apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py +++ b/apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py @@ -1385,7 +1385,7 @@ def _assert_reboot_slo_payload(payload: dict): assert "manual_db_update" in service_data_backup["forbidden_actions"] windows99 = payload["windows99_vmware_autostart"] assert windows99["readback_present"] is False - assert windows99["required_vm_aliases"] == ["111", "112", "120", "121", "188"] + assert windows99["required_vm_aliases"] == ["110", "188", "120", "121", "112"] assert windows99["blockers"] == ["windows99_vmware_autostart_readback_missing"] collection = payload["windows99_verify_collection"] assert collection["schema_version"] == ( diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index c450f6528..4c7bce633 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,22 @@ +## 2026-07-03 — 13:40 Windows99 VM target source-of-truth 校正 + +**完成內容**: +- 讀回 Gitea CD `#4585`:commit `232d68096` 已部署,deploy marker `59e8e4b32 chore(cd): deploy 232d680 [skip ci]`,production deploy readback matched=true、job_succeeded=true。 +- Production readback 確認目前服務 / 資料 / 備份 / StockPlatform / Gitea bundle 為綠,但 `reboot-auto-recovery-slo-scorecard` 仍是 `blocked_reboot_auto_recovery_slo_not_ready`、`active_blocker_count=10`、`readiness_percent=60`、`can_claim_all_services_recovered_within_target=false`。 +- 沿 P0-006 追到 source-of-truth 分叉:2026-07-01 runtime apply evidence 已證明 99 實際 VMware layout 是 `110 -> 188 -> 120 -> 121 -> 112`,且標記 `host111_vmware_target=missing_no_vmx_found_on_99_ping_only`;但 repo/API/CLI default 仍把 `111` 當 Windows99 required VM,造成 scorecard 持續要求無證據的 111 VMX source。 +- `scripts/reboot-recovery/windows99-vmware-autostart.ps1` default target 改回 `110 / 188 / 120 / 121 / 112`;若未來提供 explicit `Host111Vmx`,會自動將 `111` 納入 VM order。 +- `reboot-auto-recovery-slo-scorecard` API / CLI fallback 同步改為 `110 / 188 / 120 / 121 / 112`;CLI parser 若 verifier stdout 已列出 `VMX alias=...` / `VM_POWER alias=...`,改以實際 verifier aliases 為準,保留 explicit `111` artifact / future override 的 repair lane。 +- `windows99_vmx_source_repair_package.vm_rows` 改為 default required aliases 與 runtime missing / powered-off aliases 的 union,避免 Prometheus runtime 明確送進來的 alias 被 package row 漏掉。 +- `FULL-STACK-COLD-START-SOP` 升到 v1.118,`REBOOT-RECOVERY-SOP` 升到 v5.10,固定記錄 Windows99 default VM target 與 111 required host 的分層。 + +**已跑驗證**: +- `python3.11 -m py_compile apps/api/src/services/reboot_auto_recovery_slo_scorecard.py scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py`:通過。 +- `DATABASE_URL=postgresql+asyncpg://test:test@localhost/test PYTHONPATH=apps/api python3.11 -m pytest scripts/reboot-recovery/tests/test_reboot_auto_recovery_slo_scorecard.py scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py scripts/reboot-recovery/tests/test_windows99_vmx_source_repair_package.py apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py apps/api/tests/test_windows99_vmx_source_repair_package_api.py apps/api/tests/test_windows99_vmx_source_locator_readback_api.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py -q -p no:cacheprovider`:`71 passed`。 + +**仍維持**: +- 此輪只修 source/readback truth,不執行 Windows task apply、不 relink、不 restore、不啟動 VM、不重啟 host / service、不碰 Docker / Nginx / K3s / DB / firewall;未讀 secret / token / `.env` / raw sessions / SQLite / auth,未使用 GitHub / gh,未 workflow_dispatch。 +- P0-006 尚未完成:要重新部署後讀回 production,並重跑 no-secret verifier / scorecard,確認 Windows99 VM target truth 不再把 111 VMX 當預設 blocker;111 仍需作為 required host 可達性與服務 freshness 處理。 + ## 2026-07-03 — 13:12 Windows99 VMX relink dry-run / identity gate 上卷 **完成內容**: diff --git a/docs/runbooks/FULL-STACK-COLD-START-SOP.md b/docs/runbooks/FULL-STACK-COLD-START-SOP.md index fb5aa6ab4..5d4f22d66 100644 --- a/docs/runbooks/FULL-STACK-COLD-START-SOP.md +++ b/docs/runbooks/FULL-STACK-COLD-START-SOP.md @@ -1,6 +1,6 @@ # AWOOOI 全棧冷啟動與主機重啟 SOP -> Version: v1.116 +> Version: v1.118 > 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。 @@ -20,7 +20,7 @@ v1.80 / v1.81 credential escrow intake scorecard rule:同一輪 owner response v1.93 reboot SLA readback fixed fields rule:`scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py`、`docs/operations/awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json` 與 `/api/v1/agents/reboot-auto-recovery-slo-scorecard` 必須固定輸出 `current_phase`、`eta_or_wait_reason`、`primary_blocker`、`active_blockers`、`next_safe_action` 與 `reboot_sop_progress.fixed_triage_order`。回報時先讀這些欄位,不得重新臨場發明排查順序;若 `current_phase=host_boot_detection_blocked` 且 `eta_or_wait_reason=target_window_elapsed_eta_unavailable_until_fresh_all_host_reboot_event_and_probe`,只能宣稱「10 分鐘 SLO 尚未證明」,下一步固定補 fresh all-host reboot event / probe 與 99 VMware/Windows readback,不得把部分 Linux host green 當全主機 green。 -v1.94 Windows 99 / VMware verifier rule:99 主機與 guest VM 自動啟動不得再只靠「ping 到 99」或「VMX source 存在」宣稱。`scripts/reboot-recovery/windows99-vmware-autostart.ps1 -Mode Verify` 必須輸出 no-secret 固定欄位:`VMRUN_PRESENT`、`VMX alias=... present=...`、`VMWARE_SERVICE ... ok=...`、`VMWARE_AUTOSTART_TASK ... ok=...`、`WINDOWS_UPDATE_POLICY ... ok=...`、`VM_POWER alias=... running=...`、`VMWARE_AUTOSTART_CONFIG_READY`、`VMWARE_AUTOSTART_POWER_READY`、`WINDOWS_UPDATE_NO_AUTO_REBOOT_READY`、`VMWARE_AUTOSTART_VERIFY_READY`。`reboot-auto-recovery-slo-scorecard.py --windows99-vmware-file ` 必須解析這些欄位;缺 readback 時 active blocker 固定為 `windows99_vmware_autostart_readback_missing`,next action 固定為 `collect_windows99_vmware_autostart_verify_readback_then_rerun_all_host_reboot_scorecard_no_secret_no_reboot`。預設 required guest VM alias 為 `111 / 188 / 120 / 121 / 112`;`110` 不再被 99 VMware autostart 預設清單替代。此 verifier 不讀 Windows 密碼、不讀 secret、不啟動 VM、不重啟 host;`Apply` 仍需獨立 controlled apply 與 post-verifier。 +v1.94 Windows 99 / VMware verifier rule:99 主機與 guest VM 自動啟動不得再只靠「ping 到 99」或「VMX source 存在」宣稱。`scripts/reboot-recovery/windows99-vmware-autostart.ps1 -Mode Verify` 必須輸出 no-secret 固定欄位:`VMRUN_PRESENT`、`VMX alias=... present=...`、`VMWARE_SERVICE ... ok=...`、`VMWARE_AUTOSTART_TASK ... ok=...`、`WINDOWS_UPDATE_POLICY ... ok=...`、`VM_POWER alias=... running=...`、`VMWARE_AUTOSTART_CONFIG_READY`、`VMWARE_AUTOSTART_POWER_READY`、`WINDOWS_UPDATE_NO_AUTO_REBOOT_READY`、`VMWARE_AUTOSTART_VERIFY_READY`。`reboot-auto-recovery-slo-scorecard.py --windows99-vmware-file ` 必須解析這些欄位;缺 readback 時 active blocker 固定為 `windows99_vmware_autostart_readback_missing`,next action 固定為 `collect_windows99_vmware_autostart_verify_readback_then_rerun_all_host_reboot_scorecard_no_secret_no_reboot`。預設 required guest VM alias 以 99 runtime apply truth 為準:`110 / 188 / 120 / 121 / 112`;`111` 保留為 required host / service reachability 與 explicit `Host111Vmx` override,不得在缺少 verified VMX source 時被當成 99 VMware 預設 VM。此 verifier 不讀 Windows 密碼、不讀 secret、不啟動 VM、不重啟 host;`Apply` 仍需獨立 controlled apply 與 post-verifier。 v1.95 Windows 99 management-channel readback rule:若 99 可 ping / RDP / TCP,但 `windows99-vmware-autostart.ps1 -Mode Verify` 尚未收回,不得只寫成「等 verifier」。必須先跑 `scripts/reboot-recovery/windows99-management-channel-probe.py --output `,並把結果用 `reboot-auto-recovery-slo-scorecard.py --windows99-management-file ` 接入同一份 SLO scorecard。此 probe 只做 no-secret readback:TCP `22 / 135 / 445 / 2179 / 3389 / 5985 / 5986`、SSH BatchMode publickey、WinRM port、RDP console reachability 與 VMConnect / local console reachability;不得讀 Windows 密碼、不得啟動 VM、不得重啟、不得改 Windows Update。2026-07-02 18:28 live readback:`host_reachable=true`、`rdp_console_reachable=true`、`hyperv_vmconnect_open=true`、`local_console_channel_reachable=true`、`console_collection_channels=["rdp_console","hyperv_vmconnect"]`、`ssh_batch.status=permission_denied`、`winrm_http_open=false`、`winrm_https_open=false`、`remote_execution_channel_ready=false`;因此 active blockers 必須包含 `windows99_remote_execution_channel_unavailable` 與 `windows99_vmware_autostart_readback_missing`,next action 固定為 `restore_windows99_no_secret_management_channel_or_collect_local_console_verify_readback_then_rerun_reboot_scorecard_no_reboot`。 @@ -66,6 +66,8 @@ v1.116 Windows99 VMX locator via-host execution rule:若目前工作站直連 v1.117 Windows99 VMX candidate confirmation gate rule:locator receipt 顯示 `single_identity_unassigned_ubuntu_candidate_requires_confirmation` 時,不能把「唯一 generic Ubuntu candidate」直接升級成 111 VMX source。`/api/v1/agents/windows99-vmx-source-locator-readback` 必須輸出 `candidate_confirmation_gate`,並同步到 priority readback / Work Items;目前 gate 固定 `candidate_identity_evidence_sufficient=false`、`candidate_relink_dry_run_ready=false`、`apply_allowed_by_candidate_confirmation_gate=false`,missing evidence 至少包含 `target_alias_identity_hint`、`verified_backup_or_authorized_console_candidate_identity`、`pre_apply_backup_plan`、`scoped_relink_dry_run`。只有取得 target alias / MAC / UUID / display-name 或 verified backup path 證據,且產生 rollback + post-verifier 的 scoped relink dry-run 後,才可進下一階段;scorecard / locator / work item 均不得授權 VM power change、Windows write、service restart、host reboot、secret/password 讀取或 production restore。 +v1.118 Windows99 VM target source-of-truth reconciliation rule:99 VMware autostart 的預設 target 不得與 2026-07-01 runtime apply truth 分叉。repo source、API scorecard fallback、CLI scorecard fallback 必須一致使用 `110 / 188 / 120 / 121 / 112`;`111` 仍是全主機 reboot SLO 的 required host,但不是 99 VMware 預設 VMX source。若 verifier stdout 已列出 `VMX alias=...` / `VM_POWER alias=...`,scorecard 必須以 verifier 實際 alias 集合為準,讓舊的 explicit `111` artifact 或未來 `Host111Vmx` override 仍可走 `111` repair lane。`windows99_vmx_source_repair_package.vm_rows` 必須是 default required aliases 與 runtime missing / powered-off aliases 的 union,避免 runtime 明確送進來的 alias 被 UI/API row 漏掉。此規則只修 source-of-truth / readback;不授權改 Windows task、relink、restore、啟動 VM 或重啟 host。 + 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。 diff --git a/docs/runbooks/REBOOT-RECOVERY-SOP.md b/docs/runbooks/REBOOT-RECOVERY-SOP.md index a5d29d1c5..fea2b7c20 100644 --- a/docs/runbooks/REBOOT-RECOVERY-SOP.md +++ b/docs/runbooks/REBOOT-RECOVERY-SOP.md @@ -1,9 +1,9 @@ # AWOOOI 重開機恢復 SOP -> **版本**: v5.9 +> **版本**: v5.10 > **最後更新**: 2026-07-03 (台北時間) > **更新者**: Codex -> **觸發事件**: 2026-07-03 13:10 deploy 後 production SLO scorecard + Windows99 VMX source locator confirmation gate:111 VMX candidate 尚未取得足夠 identity evidence,10 分鐘 SLO 仍 blocked +> **觸發事件**: 2026-07-03 13:40 deploy 後 source-of-truth reconciliation:99 VMware default VM target 回到 runtime apply truth `110 / 188 / 120 / 121 / 112`;111 維持 required host / explicit VMX override,不再無證據當作 99 預設 VMX blocker --- @@ -50,6 +50,8 @@ 2026-07-03 13:10 最新 overlay:Gitea CD `#4582` 已推 deploy marker `558b9e9`,source `ba0849f70`,production deploy readback matched=true 且 job_succeeded=true;Gitea UI 若仍顯示 Running,只能視為 run-level lag。production `/api/v1/agents/windows99-vmx-source-locator-readback` 已上卷 redacted locator receipt:`candidate_source_count=6`、`alias_hint_candidate_count=0`、`unassigned_ubuntu_candidate_count=5`、`identity_unassigned_ubuntu_candidate_count=1`、`candidate_confirmation_required=true`,狀態為 `collector_readback_single_identity_candidate_confirmation_required`。新的 `candidate_confirmation_gate` 固定輸出 `candidate_identity_evidence_sufficient=false`、`candidate_relink_dry_run_ready=false`、`apply_allowed_by_candidate_confirmation_gate=false`;缺少 evidence 為 `target_alias_identity_hint`、`verified_backup_or_authorized_console_candidate_identity`、`pre_apply_backup_plan`、`scoped_relink_dry_run`。因此下一步已從「重跑 locator」收斂為:取得授權 console candidate identity evidence 或 verified backup path,重跑 confirmation gate,再產生 scoped relink dry-run + rollback + post-verifier;仍不得猜測 generic Ubuntu candidate、不得 relink、不得 restore、不得 power on VM。 +2026-07-03 13:40 source-of-truth overlay:7/1 runtime apply evidence 顯示 99 實際 VMware layout 是 `110 -> 188 -> 120 -> 121 -> 112`,且當時已標記 `host111_vmware_target=missing_no_vmx_found_on_99_ping_only`。因此 repo source、API scorecard fallback、CLI scorecard fallback 必須使用 `110 / 188 / 120 / 121 / 112` 作為 Windows99 default VM target;`111` 仍是 reboot SLO required host,但不是 99 VMware 預設 VM。若未來取得 verified `Host111Vmx` 或 verifier stdout 明確列出 `VMX alias=111` / `VM_POWER alias=111`,scorecard 仍會用 verifier 實際 alias 集合把 `111` 納入 repair package。禁止用 generic Ubuntu candidate 推測成 111、禁止為了清 blocker 修改 Windows task、relink、restore、啟動 VM 或重啟 host。 + ### 五主機全貌 ``` diff --git a/scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py b/scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py index cbdf738db..6a22d10b8 100755 --- a/scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py +++ b/scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py @@ -16,7 +16,7 @@ from typing import Any ROOT = Path(__file__).resolve().parents[2] SCHEMA_VERSION = "awoooi_reboot_auto_recovery_slo_scorecard_v1" REQUIRED_HOSTS = {"99", "110", "111", "112", "120", "121", "188"} -WINDOWS99_REQUIRED_VM_ALIASES = {"111", "112", "120", "121", "188"} +WINDOWS99_REQUIRED_VM_ALIASES = {"110", "112", "120", "121", "188"} def parse_args() -> argparse.Namespace: @@ -208,6 +208,10 @@ def parse_windows99_vmware_readback(text: str) -> dict[str, Any]: "ok": match.group(4) == "1", } + observed_aliases = sorted(set(vmx_present) | set(vm_power)) + if observed_aliases: + required_aliases = observed_aliases + missing_from_vmx = [alias for alias in required_aliases if not vmx_present.get(alias)] missing_from_power = [ alias diff --git a/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py b/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py index f46dda528..71d0d1516 100644 --- a/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py +++ b/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py @@ -87,7 +87,8 @@ def test_reboot_p0_contract_covers_all_required_hosts_and_vmware_autostart() -> assert "Host112Vmx" in windows99 assert "D:\\Documents\\Virtual Machines" in windows99 assert "D:\\Downloads" in windows99 - assert '[string[]]$RequiredVmAliases = @("111", "188", "120", "121", "112")' in windows99 + assert '[string[]]$RequiredVmAliases = @("110", "188", "120", "121", "112")' in windows99 + assert 'if ($Host111Vmx -and -not ($VmOrder -contains "111"))' in windows99 assert "HOST111_VMWARE_TARGET=explicit_or_required" in windows99 assert "VMWARE_AUTOSTART_VERIFY_READY" in windows99 assert "WINDOWS_UPDATE_POLICY" in windows99 diff --git a/scripts/reboot-recovery/windows99-vmware-autostart.ps1 b/scripts/reboot-recovery/windows99-vmware-autostart.ps1 index 7f3a807af..996929cc1 100644 --- a/scripts/reboot-recovery/windows99-vmware-autostart.ps1 +++ b/scripts/reboot-recovery/windows99-vmware-autostart.ps1 @@ -8,7 +8,7 @@ param( [string]$Host120Vmx = "", [string]$Host121Vmx = "", [string]$Host112Vmx = "", - [string[]]$RequiredVmAliases = @("111", "188", "120", "121", "112"), + [string[]]$RequiredVmAliases = @("110", "188", "120", "121", "112"), [string[]]$DiscoveryRoot = @( "D:\Documents\Virtual Machines", "D:\Downloads", @@ -24,7 +24,10 @@ $ErrorActionPreference = "Stop" $TaskName = "AWOOOI-Start-VMware-VMs" $ProgramDataDir = "C:\ProgramData\AWOOOI" $StartScript = Join-Path $ProgramDataDir "Start-AWOOOI-VMs.ps1" -$VmOrder = $RequiredVmAliases +$VmOrder = @($RequiredVmAliases) +if ($Host111Vmx -and -not ($VmOrder -contains "111")) { + $VmOrder = @("111") + $VmOrder +} $SuppliedVmx = @{ "110" = $Host110Vmx "111" = $Host111Vmx