121 lines
4.6 KiB
PowerShell
121 lines
4.6 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$BuildContext,
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidatePattern("^[A-Za-z0-9._-]{1,96}$")]
|
|
[string]$RunId,
|
|
[string]$OutputRoot = "D:\NDC_MISSIONCORE\runtime\results\m49-t1-gseg3d"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$ProgressPreference = "SilentlyContinue"
|
|
|
|
function Assert-LastExitCode([string]$Operation) {
|
|
if ($LASTEXITCODE -ne 0) { throw "$Operation failed with exit code $LASTEXITCODE" }
|
|
}
|
|
|
|
function Resolve-DDirectory([string]$Path, [string]$Label, [bool]$Create) {
|
|
if ($Create -and -not (Test-Path -LiteralPath $Path)) {
|
|
$null = New-Item -ItemType Directory -Path $Path
|
|
}
|
|
$item = Get-Item -LiteralPath (Resolve-Path -LiteralPath $Path).Path -Force
|
|
if (
|
|
-not $item.PSIsContainer -or
|
|
($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
|
|
[IO.Path]::GetPathRoot($item.FullName).TrimEnd("\") -ine "D:"
|
|
) {
|
|
throw "$Label must be a real D: directory"
|
|
}
|
|
return $item.FullName
|
|
}
|
|
|
|
function Get-Container([string]$Name) {
|
|
$rows = @((& docker inspect $Name) | ConvertFrom-Json)
|
|
Assert-LastExitCode "Docker inspection for $Name"
|
|
if ($rows.Count -ne 1) { throw "Container identity for $Name is not unique" }
|
|
return $rows[0]
|
|
}
|
|
|
|
if ($env:COMPUTERNAME -cne "DESKTOP-OPJ8J04") {
|
|
throw "M49 T1 is pinned to Worker 006"
|
|
}
|
|
|
|
$context = Resolve-DDirectory $BuildContext "M49 T1 build context" $false
|
|
$output = Resolve-DDirectory $OutputRoot "M49 T1 output root" $true
|
|
$runOutput = Join-Path $output $RunId
|
|
if (Test-Path -LiteralPath $runOutput) { throw "M49 T1 output already exists" }
|
|
$null = New-Item -ItemType Directory -Path $runOutput
|
|
$runOutput = Resolve-DDirectory $runOutput "M49 T1 run output" $false
|
|
$dockerConfig = Join-Path $runOutput "docker-config"
|
|
$null = New-Item -ItemType Directory -Path $dockerConfig
|
|
'{"auths":{}}' | Set-Content -LiteralPath (Join-Path $dockerConfig "config.json") -Encoding ascii
|
|
$env:DOCKER_CONFIG = $dockerConfig
|
|
|
|
$os = Get-CimInstance Win32_OperatingSystem
|
|
$freeMemoryGiB = [double]$os.FreePhysicalMemory / 1MB
|
|
if ($freeMemoryGiB -lt 16.0) {
|
|
throw ("M49 T1 requires 16 GiB free memory; observed {0:N2} GiB" -f $freeMemoryGiB)
|
|
}
|
|
|
|
$canonicalTriton = Get-Container "ndc-mission-core-triton"
|
|
if (-not $canonicalTriton.State.Running -or $canonicalTriton.State.Health.Status -cne "healthy") {
|
|
throw "Canonical Mission Core Triton must remain healthy during M49 T1"
|
|
}
|
|
|
|
$containerName = "ndc-mission-core-m49-t1-gseg3d-$RunId"
|
|
if (& docker ps -a --format "{{.Names}}" --filter "name=^/$containerName$") {
|
|
throw "M49 T1 container name already exists"
|
|
}
|
|
|
|
$imageTag = "ndc/mission-core-m49-t1-gseg3d:20260826"
|
|
$buildStarted = [DateTimeOffset]::UtcNow
|
|
& docker build --pull=false --tag $imageTag $context
|
|
Assert-LastExitCode "M49 T1 image build"
|
|
$buildCompleted = [DateTimeOffset]::UtcNow
|
|
|
|
$runStarted = [DateTimeOffset]::UtcNow
|
|
try {
|
|
& docker run --rm --name $containerName --cpus 16 --memory 24g `
|
|
--volume ((($runOutput -replace "\\", "/")) + ":/evidence") `
|
|
$imageTag
|
|
Assert-LastExitCode "M49 T1 upstream qualification"
|
|
} finally {
|
|
if (& docker ps -a --format "{{.Names}}" --filter "name=^/$containerName$") {
|
|
& docker rm --force $containerName *> $null
|
|
}
|
|
}
|
|
$runCompleted = [DateTimeOffset]::UtcNow
|
|
|
|
$image = @((& docker image inspect $imageTag) | ConvertFrom-Json)[0]
|
|
Assert-LastExitCode "M49 T1 image inspection"
|
|
$resultPath = Join-Path $runOutput "result.json"
|
|
if (-not (Test-Path -LiteralPath $resultPath -PathType Leaf)) {
|
|
throw "M49 T1 result.json is missing"
|
|
}
|
|
$result = Get-Content -LiteralPath $resultPath -Raw | ConvertFrom-Json
|
|
if ($result.status -cne "passed") { throw "M49 T1 qualification did not pass" }
|
|
|
|
$summary = [ordered]@{
|
|
schema_version = "missioncore.m49-t1-worker-summary/v1"
|
|
worker_id = "worker-006"
|
|
run_id = $RunId
|
|
image_tag = $imageTag
|
|
image_id = [string]$image.Id
|
|
image_size_bytes = [long]$image.Size
|
|
build_started_utc = $buildStarted.ToString("o")
|
|
build_wall_seconds = [math]::Round(($buildCompleted - $buildStarted).TotalSeconds, 6)
|
|
qualification_wall_seconds = [math]::Round(($runCompleted - $runStarted).TotalSeconds, 6)
|
|
free_memory_gib_before = [math]::Round($freeMemoryGiB, 6)
|
|
canonical_triton_id = [string]$canonicalTriton.Id
|
|
canonical_triton_health = [string]$canonicalTriton.State.Health.Status
|
|
candidate_accepted = $true
|
|
ravnoves00_quality_accepted = $false
|
|
realtime_accepted = $false
|
|
navigation_or_actuation_allowed = $false
|
|
}
|
|
$summary | ConvertTo-Json -Depth 3 | Set-Content -LiteralPath (
|
|
Join-Path $runOutput "worker-summary.json"
|
|
) -Encoding utf8
|
|
$summary | ConvertTo-Json -Depth 3
|