Files
UFL/Scripts/remote_worker_attach.ps1

200 lines
6.2 KiB
PowerShell
Raw Normal View History

2025-12-17 15:34:34 -07:00
param(
[Parameter(Mandatory = $true)]
[string]$WorkerName,
[Parameter(Mandatory = $true)]
[string]$WorkerType,
2025-12-17 16:46:35 -07:00
[string]$DataRoot = (Join-Path ([Environment]::GetFolderPath('LocalApplicationData')) 'UnifiedWorkers'),
2025-12-17 15:34:34 -07:00
[switch]$CommandOnly,
[string]$Command
)
2025-12-17 16:46:35 -07:00
$ErrorActionPreference = 'Continue'
# Ensure we can see output immediately
try {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
} catch {}
try {
$Host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(200, 9999)
} catch {}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Worker Attach Session Starting" -ForegroundColor Cyan
Write-Host "Worker: $WorkerName" -ForegroundColor White
Write-Host "Type: $WorkerType" -ForegroundColor White
Write-Host "========================================" -ForegroundColor Cyan
[Console]::Out.Flush()
# Ensure output is visible immediately
try {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
} catch {}
try {
$Host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(200, 9999)
} catch {}
Write-Host "Starting attach session..." -ForegroundColor Green
Write-Host "Worker: $WorkerName, Type: $WorkerType" -ForegroundColor Gray
[Console]::Out.Flush()
2025-12-17 15:34:34 -07:00
function Get-WorkerPaths {
param([string]$Root, [string]$Type, [string]$Name)
$instanceRoot = Join-Path -Path (Join-Path -Path $Root -ChildPath $Type) -ChildPath $Name
return [pscustomobject]@{
Metadata = Join-Path -Path $instanceRoot -ChildPath 'state\worker-info.json'
Command = Join-Path -Path $instanceRoot -ChildPath 'state\commands.txt'
Log = Join-Path -Path $instanceRoot -ChildPath 'logs\worker.log'
}
}
$paths = Get-WorkerPaths -Root $DataRoot -Type $WorkerType -Name $WorkerName
if (-not (Test-Path $paths.Metadata)) {
2025-12-17 16:46:35 -07:00
Write-Host ""
Write-Host "ERROR: No worker metadata found for $WorkerName ($WorkerType)." -ForegroundColor Red
Write-Host "Metadata path: $($paths.Metadata)" -ForegroundColor Gray
Write-Host "Data root: $DataRoot" -ForegroundColor Gray
Write-Host ""
Write-Host "Press any key to exit..."
try {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} catch {
Start-Sleep -Seconds 5
}
2025-12-17 15:34:34 -07:00
exit 1
}
try {
$metadata = Get-Content -Path $paths.Metadata -Raw | ConvertFrom-Json
}
catch {
Write-Host "Unable to read worker metadata: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
if (Test-Path $paths.Log) {
# ensure log file exists but do not truncate
$null = (Get-Item $paths.Log)
} else {
New-Item -Path $paths.Log -ItemType File -Force | Out-Null
}
if (-not (Test-Path $paths.Command)) {
New-Item -Path $paths.Command -ItemType File -Force | Out-Null
}
function Send-WorkerCommand {
param([string]$Value)
$clean = $Value.Trim()
if (-not $clean) {
return
}
Add-Content -Path $paths.Command -Value $clean -Encoding UTF8
Write-Host "Sent command '$clean' to $WorkerName." -ForegroundColor DarkGray
}
if ($CommandOnly) {
if (-not $Command) {
Write-Host "CommandOnly flag set but no command provided." -ForegroundColor Red
exit 1
}
Send-WorkerCommand -Value $Command
exit 0
}
2025-12-17 16:46:35 -07:00
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
2025-12-17 15:34:34 -07:00
Write-Host "Attaching to $WorkerName ($WorkerType) logs." -ForegroundColor Cyan
2025-12-17 16:46:35 -07:00
Write-Host "Log file: $($paths.Log)" -ForegroundColor Gray
Write-Host "========================================" -ForegroundColor Cyan
[Console]::Out.Flush()
[Console]::Error.WriteLine("Attach session initialized")
# Show initial log content if available
if (Test-Path $paths.Log) {
$initialLines = Get-Content -Path $paths.Log -Tail 50 -ErrorAction SilentlyContinue
if ($initialLines) {
Write-Host "--- Recent log output ---" -ForegroundColor DarkGray
$initialLines | ForEach-Object { Write-Host $_ }
Write-Host "--- End of initial output ---" -ForegroundColor DarkGray
} else {
Write-Host "Log file exists but is empty. Waiting for worker output..." -ForegroundColor Yellow
}
} else {
Write-Host "Log file does not exist yet. Waiting for worker to start..." -ForegroundColor Yellow
}
Write-Host ""
2025-12-17 15:34:34 -07:00
Write-Host "Type commands and press Enter. Type 'detach' to exit session." -ForegroundColor Yellow
2025-12-17 16:46:35 -07:00
Write-Host ""
2025-12-17 15:34:34 -07:00
2025-12-17 16:46:35 -07:00
# Use Register-ObjectEvent for file system watcher, or simpler: just tail in background and poll
2025-12-17 15:34:34 -07:00
$logJob = Start-Job -ScriptBlock {
param($LogPath)
2025-12-17 16:46:35 -07:00
if (Test-Path $LogPath) {
Get-Content -Path $LogPath -Tail 0 -Wait -ErrorAction SilentlyContinue
} else {
while (-not (Test-Path $LogPath)) {
Start-Sleep -Milliseconds 500
}
Get-Content -Path $LogPath -Tail 0 -Wait -ErrorAction SilentlyContinue
}
2025-12-17 15:34:34 -07:00
} -ArgumentList $paths.Log
try {
while ($true) {
2025-12-17 16:46:35 -07:00
# Check for new log output from background job (non-blocking)
$logOutput = Receive-Job -Job $logJob -ErrorAction SilentlyContinue
if ($logOutput) {
$logOutput | ForEach-Object { Write-Host $_ }
[Console]::Out.Flush()
}
# Use a timeout on Read-Host to allow periodic log checking
# Since Read-Host doesn't support timeout, we'll just check logs before each Read-Host
# This means logs will be checked whenever user presses Enter
2025-12-17 15:34:34 -07:00
$input = Read-Host "> "
if ($null -eq $input) {
continue
}
$normalized = $input.Trim()
if ($normalized.StartsWith(':')) {
$normalized = $normalized.TrimStart(':').Trim()
}
if ($normalized.Length -eq 0) {
continue
}
if ($normalized.ToLowerInvariant() -eq 'detach') {
break
}
Send-WorkerCommand -Value $input
}
}
2025-12-17 16:46:35 -07:00
catch {
Write-Host "Error in attach session: $($_.Exception.Message)" -ForegroundColor Red
Write-Host $_.ScriptStackTrace -ForegroundColor DarkRed
[Console]::Error.WriteLine("Attach error: $($_.Exception.Message)")
}
2025-12-17 15:34:34 -07:00
finally {
if ($logJob) {
Stop-Job -Job $logJob -ErrorAction SilentlyContinue
Remove-Job -Job $logJob -ErrorAction SilentlyContinue
}
Write-Host "Detached from worker $WorkerName." -ForegroundColor Cyan
}