76 lines
3.6 KiB
Python
76 lines
3.6 KiB
Python
"""Back up and deploy the VDD login refresh script in VM100, without rebooting."""
|
|
import argparse
|
|
import base64
|
|
from pathlib import Path
|
|
import runpy
|
|
import sys
|
|
|
|
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.parse_args()
|
|
root = Path(__file__).resolve().parent
|
|
term = runpy.run_path(str(root / "pve_term_exec.py"))
|
|
vm = runpy.run_path(str(root / "pve_vm.py"))
|
|
ticket, csrf = term["login"]()
|
|
state = vm["api"]("/api2/json/nodes/starhe/qemu/100/status/current", ticket=ticket)
|
|
if state.get("status") != "running":
|
|
sys.exit("VM100 is not running; nothing changed")
|
|
payload = base64.b64encode((root / "set-2k-display.ps1").read_bytes()).decode()
|
|
command = r"""
|
|
$ErrorActionPreference='Stop'
|
|
$target='C:\ProgramData\VDI\set-2k-display.ps1'
|
|
$task='VDISet2KDisplay'
|
|
$entry=Get-ScheduledTask -TaskName $task
|
|
if($entry.State -eq 'Running') { throw 'Display task is already running; inspect before deployment' }
|
|
if(-not (Test-Path -LiteralPath $target)) { throw 'Original display script is missing' }
|
|
if(($entry.Actions | Select-Object -First 1).Arguments -notlike '*set-2k-display.ps1*') {
|
|
throw 'Unexpected display task action; do not change it'
|
|
}
|
|
$backup='C:\ProgramData\VDI\backups\display-refresh-'+(Get-Date -Format 'yyyyMMdd-HHmmss')
|
|
New-Item -ItemType Directory -Path $backup | Out-Null
|
|
Copy-Item -LiteralPath $target -Destination "$backup\set-2k-display.ps1"
|
|
Export-ScheduledTask -TaskName $task | Set-Content -Encoding UTF8 "$backup\VDISet2KDisplay.xml"
|
|
if(Test-Path 'C:\ProgramData\VDI\set-2k-result.txt') {
|
|
Copy-Item 'C:\ProgramData\VDI\set-2k-result.txt' "$backup\previous-result.txt"
|
|
}
|
|
$temporary=$target+'.new'
|
|
try {
|
|
[IO.File]::WriteAllBytes($temporary,[Convert]::FromBase64String('__PAYLOAD__'))
|
|
Move-Item -LiteralPath $temporary -Destination $target -Force
|
|
# Prove freshness by a newly created result file; scheduler LastRunTime can
|
|
# lag wall-clock time after VM clock correction and is not a reliable token.
|
|
Remove-Item -LiteralPath 'C:\ProgramData\VDI\set-2k-result.txt' -ErrorAction SilentlyContinue
|
|
Start-ScheduledTask -TaskName $task
|
|
Start-Sleep -Seconds 2
|
|
for($i=0;$i -lt 20;$i++) {
|
|
if((Get-ScheduledTask -TaskName $task).State -ne 'Running') { break }
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
$info=Get-ScheduledTaskInfo -TaskName $task
|
|
if((Get-ScheduledTask -TaskName $task).State -eq 'Running' -or
|
|
$info.LastTaskResult -ne 0) {
|
|
throw 'New display task did not complete successfully'
|
|
}
|
|
$log=Get-Content 'C:\ProgramData\VDI\set-2k-result.txt' -Raw
|
|
if($log -notmatch 'result=0 mode=2560x1440@60') { throw '60Hz read-back missing in display task log' }
|
|
@{backup=$backup; task_result=$info.LastTaskResult; result=$log.Trim()} | ConvertTo-Json -Compress
|
|
} catch {
|
|
if(Test-Path 'C:\ProgramData\VDI\set-2k-result.txt') {
|
|
Copy-Item 'C:\ProgramData\VDI\set-2k-result.txt' "$backup\failed-result.txt"
|
|
Get-Content "$backup\failed-result.txt"
|
|
}
|
|
if($info) { $info | Select-Object LastTaskResult,LastRunTime | ConvertTo-Json -Compress }
|
|
Stop-ScheduledTask -TaskName $task -ErrorAction SilentlyContinue
|
|
Copy-Item -LiteralPath "$backup\set-2k-display.ps1" -Destination $target -Force
|
|
Start-ScheduledTask -TaskName $task
|
|
throw
|
|
} finally {
|
|
Remove-Item -LiteralPath $temporary -ErrorAction SilentlyContinue
|
|
}
|
|
""".replace("__PAYLOAD__", payload)
|
|
out, error = vm["agent"](ticket, csrf, ["powershell.exe", "-NoProfile", "-Command", command])
|
|
print(out)
|
|
if error or '"task_result":0' not in out:
|
|
print(error, file=sys.stderr)
|
|
sys.exit(1)
|