feat: complete Windows client control and recovery paths
This commit is contained in:
@@ -6,14 +6,18 @@ param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidatePattern('^[a-z0-9][a-z0-9-]{0,63}$')]
|
||||
[string] $RunId = '',
|
||||
[string] $VmName = $(if ($env:RVBOX_WINDOWS_VM) { $env:RVBOX_WINDOWS_VM } else { 'rvbox-win10-test' }),
|
||||
[string] $Snapshot = $(if ($env:RVBOX_WINDOWS_BASELINE_SNAPSHOT) { $env:RVBOX_WINDOWS_BASELINE_SNAPSHOT } else { 'baseline-disk-first' })
|
||||
[string] $VmName = $(if ($env:RVBOX_WINDOWS_VM) { $env:RVBOX_WINDOWS_VM } elseif ($env:RVBOX_TEST_VBOX_VM) { $env:RVBOX_TEST_VBOX_VM } else { 'rvbox-win10-test' }),
|
||||
[string] $Snapshot = $(if ($env:RVBOX_WINDOWS_BASELINE_SNAPSHOT) { $env:RVBOX_WINDOWS_BASELINE_SNAPSHOT } elseif ($env:RVBOX_TEST_VBOX_SNAPSHOT) { $env:RVBOX_TEST_VBOX_SNAPSHOT } else { 'baseline-disk-first' })
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$VBoxManage = if ($env:VBOXMANAGE) { $env:VBOXMANAGE } else { 'VBoxManage' }
|
||||
$GuestUser = $env:RVBOX_WINDOWS_GUEST_USER
|
||||
$GuestPassword = $env:RVBOX_WINDOWS_GUEST_PASSWORD
|
||||
$GuestUser = if ($env:RVBOX_WINDOWS_GUEST_USER) { $env:RVBOX_WINDOWS_GUEST_USER } else { $env:RVBOX_TEST_GUEST_USER }
|
||||
$GuestPasswordFile = if ($env:RVBOX_WINDOWS_GUEST_PASSWORD_FILE) {
|
||||
$env:RVBOX_WINDOWS_GUEST_PASSWORD_FILE
|
||||
} else {
|
||||
$env:RVBOX_TEST_GUEST_PASSWORD_FILE
|
||||
}
|
||||
$LeaseRoot = if ($env:RVBOX_WINDOWS_LEASE_DIR) { $env:RVBOX_WINDOWS_LEASE_DIR } else { Join-Path $PSScriptRoot '..\..\.test-runs\windows' }
|
||||
|
||||
function Invoke-VBox([string[]] $Arguments) {
|
||||
@@ -45,10 +49,33 @@ function Release-Lease {
|
||||
}
|
||||
|
||||
function Guest-Args([string[]] $Arguments) {
|
||||
if ([string]::IsNullOrWhiteSpace($GuestUser) -or [string]::IsNullOrWhiteSpace($GuestPassword)) {
|
||||
throw 'Set RVBOX_WINDOWS_GUEST_USER and RVBOX_WINDOWS_GUEST_PASSWORD in the host environment; secrets are never read from repository files or printed.'
|
||||
if ([string]::IsNullOrWhiteSpace($GuestUser) -or [string]::IsNullOrWhiteSpace($GuestPasswordFile)) {
|
||||
throw 'Set the guest user and password-file environment variables in the host environment; secrets are never read from repository files or printed.'
|
||||
}
|
||||
return @('guestcontrol', $VmName, '--username', $GuestUser, '--password', $GuestPassword) + $Arguments
|
||||
if (-not (Test-Path -LiteralPath $GuestPasswordFile -PathType Leaf)) {
|
||||
throw "Guest password file does not exist: $GuestPasswordFile"
|
||||
}
|
||||
return @('guestcontrol', $VmName, '--username', $GuestUser, '--passwordfile', $GuestPasswordFile) + $Arguments
|
||||
}
|
||||
|
||||
function Wait-PowerOff {
|
||||
for ($attempt = 0; $attempt -lt 60; $attempt++) {
|
||||
$current = (Invoke-VBox @('showvminfo', $VmName, '--machinereadable') | Where-Object { $_ -like 'VMState=*' }) -replace '^VMState="?([^"\r\n]+)"?$', '$1'
|
||||
if ($current -eq 'poweroff') { return }
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
throw "VM did not power off within the bounded stop deadline: $VmName"
|
||||
}
|
||||
|
||||
function Wait-GuestReady {
|
||||
for ($attempt = 0; $attempt -lt 60; $attempt++) {
|
||||
$properties = Invoke-VBox @('guestproperty', 'enumerate', $VmName)
|
||||
if (($properties -match '/GuestAdd/Version') -and ($properties -match '/GuestInfo/OS/Release')) {
|
||||
return
|
||||
}
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
throw "Guest Additions did not become ready within the bounded boot deadline: $VmName"
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -62,18 +89,18 @@ try {
|
||||
$state = (Invoke-VBox @('showvminfo', $VmName, '--machinereadable') | Where-Object { $_ -like 'VMState=*' }) -replace '^VMState="?([^"\r\n]+)"?$', '$1'
|
||||
switch ($Action) {
|
||||
'Prepare' {
|
||||
if ($state -eq 'running') { Invoke-VBox (Guest-Args @('run', 'C:\Windows\System32\whoami.exe', '--', '/groups')) | Out-Null }
|
||||
if ($state -eq 'running') { Wait-GuestReady }
|
||||
else {
|
||||
Invoke-VBox @('startvm', $VmName, '--type', 'headless') | Out-Null
|
||||
Start-Sleep -Seconds 5
|
||||
Invoke-VBox (Guest-Args @('run', 'C:\Windows\System32\whoami.exe', '--', '/groups')) | Out-Null
|
||||
Wait-GuestReady
|
||||
}
|
||||
Invoke-VBox (Guest-Args @('run', 'C:\Windows\System32\query.exe', '--', 'user')) | Out-Null
|
||||
Invoke-VBox (Guest-Args @('run', '--exe', 'C:\Windows\System32\whoami.exe', '--wait-stdout', '--wait-stderr', '--unquoted-args', '--', '/groups')) | Out-Null
|
||||
Invoke-VBox (Guest-Args @('run', '--exe', 'C:\Windows\System32\query.exe', '--wait-stdout', '--wait-stderr', '--unquoted-args', '--', 'user')) | Out-Null
|
||||
Write-Output "prepared VM=$VmName run=$RunId"
|
||||
}
|
||||
'Run' {
|
||||
$guestBinary = if ($env:RVBOX_WINDOWS_GUEST_BINARY) { $env:RVBOX_WINDOWS_GUEST_BINARY } else { 'C:\ProgramData\RVBox\test\rvbox.exe' }
|
||||
Invoke-VBox (Guest-Args @('run', $guestBinary, '--', '--check-config', '--config', 'C:\ProgramData\RVBox\client.toml')) | Out-Null
|
||||
Invoke-VBox (Guest-Args @('run', '--exe', $guestBinary, '--wait-stdout', '--wait-stderr', '--unquoted-args', '--', '--check-config', '--config', 'C:\ProgramData\RVBox\client.toml')) | Out-Null
|
||||
Write-Output "ran native Windows smoke run=$RunId"
|
||||
}
|
||||
'Collect' {
|
||||
@@ -84,11 +111,11 @@ try {
|
||||
Write-Output "collected native artifacts under $destination"
|
||||
}
|
||||
'Stop' {
|
||||
if ($state -eq 'running') { Invoke-VBox @('controlvm', $VmName, 'acpipowerbutton') | Out-Null }
|
||||
if ($state -eq 'running') { Invoke-VBox @('controlvm', $VmName, 'acpipowerbutton') | Out-Null; Wait-PowerOff }
|
||||
Write-Output "requested graceful stop VM=$VmName"
|
||||
}
|
||||
'Reset' {
|
||||
if ($state -eq 'running') { Invoke-VBox @('controlvm', $VmName, 'acpipowerbutton') | Out-Null; Start-Sleep -Seconds 3 }
|
||||
if ($state -eq 'running') { Invoke-VBox @('controlvm', $VmName, 'acpipowerbutton') | Out-Null; Wait-PowerOff }
|
||||
Invoke-VBox @('snapshot', $VmName, 'restore', $Snapshot) | Out-Null
|
||||
Write-Output "restored baseline snapshot=$Snapshot VM=$VmName run=$RunId"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user