Fix bidirectional RF-001A coordination
This commit is contained in:
104
tools/capture_process_runner.ps1
Normal file
104
tools/capture_process_runner.ps1
Normal file
@@ -0,0 +1,104 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Executable,
|
||||
[Parameter(Mandatory = $true)][string]$ArgumentsJsonPath,
|
||||
[Parameter(Mandatory = $true)][string]$CapturePath,
|
||||
[Parameter(Mandatory = $true)][string]$StdoutPath,
|
||||
[Parameter(Mandatory = $true)][string]$StderrPath,
|
||||
[Parameter(Mandatory = $true)][string]$StartedStatusPath,
|
||||
[Parameter(Mandatory = $true)][string]$ResultStatusPath
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Write-JsonAtomically {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][object]$Value,
|
||||
[Parameter(Mandatory = $true)][string]$Path
|
||||
)
|
||||
|
||||
$temporaryPath = "$Path.tmp"
|
||||
$json = $Value | ConvertTo-Json -Depth 8
|
||||
$encoding = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText($temporaryPath, $json + [Environment]::NewLine, $encoding)
|
||||
Move-Item -LiteralPath $temporaryPath -Destination $Path -Force
|
||||
}
|
||||
|
||||
$decodedArguments = Get-Content -Raw -LiteralPath $ArgumentsJsonPath |
|
||||
ConvertFrom-Json
|
||||
if ($decodedArguments -isnot [System.Array]) {
|
||||
throw 'ArgumentsJsonPath must contain a JSON array.'
|
||||
}
|
||||
$childArguments = @(
|
||||
foreach ($argument in $decodedArguments) {
|
||||
[string]$argument
|
||||
}
|
||||
)
|
||||
$startedAt = [DateTimeOffset]::UtcNow
|
||||
$finishedAt = $null
|
||||
$childProcess = $null
|
||||
$exitCode = $null
|
||||
$runnerError = $null
|
||||
$captureSize = 0
|
||||
$sha256 = $null
|
||||
|
||||
try {
|
||||
$startParameters = @{
|
||||
FilePath = $Executable
|
||||
ArgumentList = $childArguments
|
||||
RedirectStandardOutput = $StdoutPath
|
||||
RedirectStandardError = $StderrPath
|
||||
PassThru = $true
|
||||
WindowStyle = 'Hidden'
|
||||
}
|
||||
$childProcess = Start-Process @startParameters
|
||||
# PowerShell 5 can lose ExitCode for redirected processes unless the
|
||||
# underlying process handle is opened before WaitForExit().
|
||||
$null = $childProcess.Handle
|
||||
|
||||
Write-JsonAtomically -Path $StartedStatusPath -Value ([ordered]@{
|
||||
state = 'RUNNING'
|
||||
pid = $childProcess.Id
|
||||
started_at = $startedAt.ToString('o')
|
||||
capture_path = $CapturePath
|
||||
})
|
||||
|
||||
$childProcess.WaitForExit()
|
||||
$childProcess.Refresh()
|
||||
$exitCode = [int]$childProcess.ExitCode
|
||||
} catch {
|
||||
$runnerError = $_.Exception.ToString()
|
||||
} finally {
|
||||
$finishedAt = [DateTimeOffset]::UtcNow
|
||||
if (Test-Path -LiteralPath $CapturePath) {
|
||||
try {
|
||||
$captureSize = [int64](Get-Item -LiteralPath $CapturePath).Length
|
||||
$sha256 = (
|
||||
Get-FileHash -LiteralPath $CapturePath -Algorithm SHA256
|
||||
).Hash.ToLowerInvariant()
|
||||
} catch {
|
||||
$additionalError = $_.Exception.ToString()
|
||||
if ([string]::IsNullOrWhiteSpace($runnerError)) {
|
||||
$runnerError = $additionalError
|
||||
} else {
|
||||
$runnerError = $runnerError + [Environment]::NewLine + $additionalError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-JsonAtomically -Path $ResultStatusPath -Value ([ordered]@{
|
||||
pid = if ($null -ne $childProcess) { $childProcess.Id } else { $null }
|
||||
started_at = $startedAt.ToString('o')
|
||||
finished_at = $finishedAt.ToString('o')
|
||||
duration = ($finishedAt - $startedAt).TotalSeconds
|
||||
exit_code = $exitCode
|
||||
capture_path = $CapturePath
|
||||
capture_size = $captureSize
|
||||
sha256 = $sha256
|
||||
runner_error = $runnerError
|
||||
})
|
||||
}
|
||||
|
||||
if ($null -eq $exitCode) {
|
||||
exit 255
|
||||
}
|
||||
exit $exitCode
|
||||
Reference in New Issue
Block a user