diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 87912ea1..b6c8fedb 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,24 @@ +## 2026-07-01 — 13:11 P0-7 Windows 99 VMware autostart controlled apply + +**照主線修正的問題**: +- 99 runtime readback 已從 RDP console 補齊:`wooo-super\administrator`、`vmrun_present=True`、`vmrun_path=C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe`。 +- 99 Apply 前實際 `vmrun list` 為 5 台 VM:`192.168.0.110_Ubuntu_64-bit_DevOps`、`192.168.0.188_Ubuntu_64-bit_AI`、`192.168.0.120_Ubuntu_64-bit_K3s`、`192.168.0.121_Ubuntu_64-bit_K3s`、`192.168.0.112_KALI-Linux`;`192.168.0.111` ping 可達,但 99 上沒有任何 `111` VMX,故標記為 `host111_vmware_target=missing_no_vmx_found_on_99_ping_only`,不能假裝 111 由 99 VMware 管理。 +- 已在 99 controlled apply 建立 / 覆蓋 `AWOOOI-Start-VMware-VMs` SYSTEM startup task:`task_state=Ready`、`task_action_execute=powershell.exe`、`args=-NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\AWOOOI\Start-AWOOOI-VMs.ps1"`、`task_principal=SYSTEM runlevel=Highest`。 +- 已寫入 `C:\ProgramData\AWOOOI\Start-AWOOOI-VMs.ps1`,並以正式 repo source 重套一次;順序為 `110 -> 188 -> 120 -> 121 -> 112`;startup script 會先啟動 VMware auth / DHCP service,若 VM 已在 `vmrun list` 內則輸出 `VM_ALREADY_RUNNING` 並跳過,避免重複 start。 +- 已套用 Windows Update no-auto-reboot policy:`NoAutoRebootWithLoggedOnUsers=1`、`AlwaysAutoRebootAtScheduledTime=0`、`AUOptions=3`、`ScheduledInstallDay=0`、`ScheduledInstallTime=3`、`AUPowerManagement=0`。 +- repo source `scripts/reboot-recovery/windows99-vmware-autostart.ps1` 已同步 99 真實 layout:新增 `Host110Vmx`、`RequiredVmAliases`、`D:\Documents\Virtual Machines` / `D:\Downloads` discovery roots、known VMX candidates、displayName matching 與 `VM_ALREADY_RUNNING` skip 行為。 + +**runtime verifier**: +- `task_present=1`、`task_state=Ready`、`start_script_present=1`、`start_script_bytes=1441`、`wu_policy_present=1`、`vmrun_present=1`。 +- `vmrun_list=Total running VMs: 5`,且 `ping_192.168.0.110=True`、`ping_192.168.0.111=True`、`ping_192.168.0.112=True`、`ping_192.168.0.120=True`、`ping_192.168.0.121=True`、`ping_192.168.0.188=True`。 +- Windows Security 右下角曾提示 `Controlled Folder Access` 對 `vmrun.exe` 的封鎖提醒;本輪未點擊、未放寬 Defender/Controlled Folder Access,需在下一次真實 99 reboot 或 approved reboot drill 觀察 startup task 是否被攔截。 + +**仍維持**: +- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth;沒有使用 GitHub / `gh` / GitHub API;沒有重啟主機,沒有 Docker / Nginx / K3s / DB restart,沒有 firewall / Defender policy 放寬。 + +**下一步**: +- 回到 ordered P0:重跑 all-host cold-start / SLO scorecard;110 仍是 `harbor_110_remote_ssh_publickey_auth_stalled` + Harbor / registry `502` 主 blocker,若 110 SSH/control path 恢復,第一動作仍是套用新版 systemd exporter 或暫停舊 exporter,再回讀 systemd/logind、Gitea CPU 與 load5/core。 + ## 2026-07-01 — 13:05 AI Loop current blocker 對齊 publickey offer timeout / load-not-high **照主線修正的問題**: 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 f70d895e..7f0638ee 100644 --- a/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py +++ b/scripts/reboot-recovery/tests/test_reboot_p0_operational_contract.py @@ -18,11 +18,16 @@ def test_reboot_p0_contract_covers_all_required_hosts_and_vmware_autostart() -> assert host in host_probe assert "AWOOOI-Start-VMware-VMs" in windows99 assert "NoAutoRebootWithLoggedOnUsers" in windows99 + assert "Host110Vmx" in windows99 assert "Host111Vmx" in windows99 assert "Host188Vmx" in windows99 assert "Host120Vmx" in windows99 assert "Host121Vmx" in windows99 assert "Host112Vmx" in windows99 + assert "D:\\Documents\\Virtual Machines" in windows99 + assert "D:\\Downloads" in windows99 + assert "HOST111_VMWARE_TARGET=not_required_by_default_missing_no_vmx_found_on_99" in windows99 + assert "VM_ALREADY_RUNNING" in windows99 def test_reboot_p0_contract_has_maintenance_and_telegram_alerts() -> None: diff --git a/scripts/reboot-recovery/windows99-vmware-autostart.ps1 b/scripts/reboot-recovery/windows99-vmware-autostart.ps1 index 63d5b94a..afd02d11 100644 --- a/scripts/reboot-recovery/windows99-vmware-autostart.ps1 +++ b/scripts/reboot-recovery/windows99-vmware-autostart.ps1 @@ -2,12 +2,21 @@ param( [ValidateSet("Verify", "DryRun", "Apply")] [string]$Mode = "Verify", [string]$VmrunPath = "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe", + [string]$Host110Vmx = "", [string]$Host111Vmx = "", [string]$Host188Vmx = "", [string]$Host120Vmx = "", [string]$Host121Vmx = "", [string]$Host112Vmx = "", - [string[]]$DiscoveryRoot = @("D:\VMs", "E:\VMs", "C:\VMs", "C:\Users\Public\Documents\Virtual Machines") + [string[]]$RequiredVmAliases = @("110", "188", "120", "121", "112"), + [string[]]$DiscoveryRoot = @( + "D:\Documents\Virtual Machines", + "D:\Downloads", + "D:\VMs", + "E:\VMs", + "C:\VMs", + "C:\Users\Public\Documents\Virtual Machines" + ) ) $ErrorActionPreference = "Stop" @@ -15,14 +24,22 @@ $ErrorActionPreference = "Stop" $TaskName = "AWOOOI-Start-VMware-VMs" $ProgramDataDir = "C:\ProgramData\AWOOOI" $StartScript = Join-Path $ProgramDataDir "Start-AWOOOI-VMs.ps1" -$VmOrder = @("111", "188", "120", "121", "112") +$VmOrder = $RequiredVmAliases $SuppliedVmx = @{ + "110" = $Host110Vmx "111" = $Host111Vmx "188" = $Host188Vmx "120" = $Host120Vmx "121" = $Host121Vmx "112" = $Host112Vmx } +$KnownVmxCandidates = @{ + "110" = @("D:\Documents\Virtual Machines\Ubuntu 64-bit (3)\Ubuntu 64-bit (3).vmx") + "188" = @("D:\Documents\Virtual Machines\Ollama_Ubuntu_64-bit\Ollama_Ubuntu_64-bit.vmx") + "120" = @("D:\Documents\Virtual Machines\192.168.0.120_Ubuntu_64-bit\192.168.0.120_Ubuntu_64-bit.vmx") + "121" = @("D:\Documents\Virtual Machines\192.168.0.121_Ubuntu_64-bit\192.168.0.121_Ubuntu_64-bit.vmx") + "112" = @("D:\Downloads\kali-linux-2025.4-vmware-amd64\kali-linux-2025.4-vmware-amd64.vmwarevm\kali-linux-2025.4-vmware-amd64.vmx") +} function Resolve-VmxPath { param([string]$HostAlias) @@ -32,12 +49,28 @@ function Resolve-VmxPath { return (Resolve-Path -LiteralPath $supplied).Path } + foreach ($candidate in @($KnownVmxCandidates[$HostAlias])) { + if ($candidate -and (Test-Path -LiteralPath $candidate)) { + return (Resolve-Path -LiteralPath $candidate).Path + } + } + foreach ($root in $DiscoveryRoot) { if (-not (Test-Path -LiteralPath $root)) { continue } $match = Get-ChildItem -LiteralPath $root -Recurse -Filter "*.vmx" -ErrorAction SilentlyContinue | - Where-Object { $_.FullName -match "(^|[\\_\-\s])$HostAlias([\\_\-\s]|$)" } | + Where-Object { + $displayName = "" + try { + $displayName = (Select-String -LiteralPath $_.FullName -Pattern "^displayName\s*=\s*" -ErrorAction SilentlyContinue | + Select-Object -First 1).Line + } catch { + $displayName = "" + } + $_.FullName -match "(^|[\\_\-\s])$HostAlias([\\_\-\s]|$)" -or + $displayName -match "(^|[\\_\-\s])$HostAlias([\\_\-\s]|$)" + } | Select-Object -First 1 if ($match) { return $match.FullName @@ -70,14 +103,18 @@ $($vmRows -join ",`n") Start-Service -Name "VMAuthdService" -ErrorAction SilentlyContinue Start-Service -Name "VMnetDHCP" -ErrorAction SilentlyContinue -Start-Service -Name "VMware NAT Service" -ErrorAction SilentlyContinue Start-Sleep -Seconds 30 +`$running = (& `$VmrunPath list 2>`$null) -join [Environment]::NewLine foreach (`$vm in `$VMs) { if (-not (Test-Path -LiteralPath `$vm.Path)) { Write-Output "VMX_MISSING alias=`$(`$vm.Alias) path=`$(`$vm.Path)" continue } + if (`$running -like "*`$(`$vm.Path)*") { + Write-Output "VM_ALREADY_RUNNING alias=`$(`$vm.Alias) path=`$(`$vm.Path)" + continue + } & `$VmrunPath -T ws start `$vm.Path nogui Write-Output "VM_START_REQUESTED alias=`$(`$vm.Alias) path=`$(`$vm.Path) exit=`$LASTEXITCODE" Start-Sleep -Seconds 20 @@ -126,6 +163,11 @@ $vmrunPresent = Test-Path -LiteralPath $VmrunPath Write-Output "AWOOOI_WINDOWS99_VMWARE_AUTOSTART=1" Write-Output "MODE=$Mode" Write-Output "VMRUN_PRESENT=$([int]$vmrunPresent)" +if ($SuppliedVmx["111"] -or $VmOrder -contains "111") { + Write-Output "HOST111_VMWARE_TARGET=explicit_or_required" +} else { + Write-Output "HOST111_VMWARE_TARGET=not_required_by_default_missing_no_vmx_found_on_99" +} foreach ($alias in $VmOrder) { Write-Output "VMX alias=$alias path=$($vmMap[$alias]) present=$([int][bool]$vmMap[$alias])" } @@ -155,7 +197,6 @@ if ($Mode -eq "DryRun") { Write-StartupScript -VmMap $vmMap Set-Service -Name "VMAuthdService" -StartupType Automatic -ErrorAction SilentlyContinue Set-Service -Name "VMnetDHCP" -StartupType Automatic -ErrorAction SilentlyContinue -Set-Service -Name "VMware NAT Service" -StartupType Automatic -ErrorAction SilentlyContinue Apply-ScheduledTask Apply-WindowsUpdatePolicy