File size: 3,742 Bytes
d1f3f31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | param(
[Parameter(Mandatory=$true)][string]$ImageName,
[Parameter(Mandatory=$true)][string]$ContainerName,
[int]$DurationSeconds = 30,
[int]$PollIntervalSeconds = 1,
[int]$HealthTimeoutSeconds = 60
)
function Get-ContainerHealthStatus($name) {
$inspect = docker inspect $name --format '{{json .State}}' 2>$null | ConvertFrom-Json
if (-not $inspect) { return $null }
if ($inspect.Health) { return $inspect.Health.Status }
return $inspect.Status
}
$startTime = Get-Date
Write-Output "Starting container $ContainerName from image $ImageName"
docker rm -f $ContainerName 2>$null | Out-Null
$cid = docker run -d --name $ContainerName $ImageName
if (-not $cid) { Write-Error "Failed to start container"; exit 2 }
# Wait for container to be running
$running = $false
$waitStart = Get-Date
while (((Get-Date) - $waitStart).TotalSeconds -lt $HealthTimeoutSeconds) {
$state = (docker inspect $ContainerName --format '{{.State.Status}}') -as [string]
if ($state -eq 'running') { $running = $true; break }
Start-Sleep -Seconds 1
}
if (-not $running) { Write-Error "Container did not enter running state within timeout"; docker logs $ContainerName; exit 3 }
# If container has healthcheck, wait for healthy
$healthStart = Get-Date
$healthy = $false
$hasHealth = (docker inspect $ContainerName --format '{{.State.Health}}') -ne "<no value>"
if ($hasHealth) {
while (((Get-Date) - $healthStart).TotalSeconds -lt $HealthTimeoutSeconds) {
$h = Get-ContainerHealthStatus $ContainerName
if ($h -eq 'healthy') { $healthy = $true; break }
if ($h -eq 'unhealthy') { break }
Start-Sleep -Seconds 1
}
} else {
# no healthcheck; consider running state as healthy for timing purposes
$healthy = $true
}
$startupTimeSec = (Get-Date -Date (Get-Date)) - $startTime
# record the time when healthy or running
$readyTime = if ($healthy) { (Get-Date) } else { (Get-Date) }
$startupElapsed = ($readyTime - $startTime).TotalSeconds
Write-Output "Container started. Sampling resources for $DurationSeconds seconds..."
$cpuMax = 0.0
$memMaxBytes = 0
for ($i=0; $i -lt $DurationSeconds; $i++) {
$stat = docker stats --no-stream --format '{{.CPUPerc}}|{{.MemUsage}}' $ContainerName 2>$null
if ($stat) {
$parts = $stat -split '\|'
$cpuStr = $parts[0].TrimEnd('%')
[double]$cpuVal = 0
if ([double]::TryParse($cpuStr, [ref]$cpuVal)) { if ($cpuVal -gt $cpuMax) { $cpuMax = $cpuVal } }
$memStr = $parts[1]
# memStr like '12.34MiB / 1.944GiB'
$memUsed = $memStr -split '/' | Select-Object -First 1
$memUsed = $memUsed.Trim()
function Convert-MemToBytes($s) {
if ($s -match '([0-9\.]+)\s*(KiB|MiB|GiB|B)') {
$v = [double]$matches[1]
switch ($matches[2]) {
'B' { return [int64]$v }
'KiB' { return [int64]($v * 1024) }
'MiB' { return [int64]($v * 1024 * 1024) }
'GiB' { return [int64]($v * 1024 * 1024 * 1024) }
}
}
return 0
}
$bytes = Convert-MemToBytes $memUsed
if ($bytes -gt $memMaxBytes) { $memMaxBytes = $bytes }
}
Start-Sleep -Seconds $PollIntervalSeconds
}
# collect final logs
$logs = docker logs --tail 200 $ContainerName 2>$null
$result = [PSCustomObject]@{
Image = $ImageName
Container = $ContainerName
StartupSeconds = [math]::Round($startupElapsed,3)
Healthy = $healthy
CpuMaxPercent = [math]::Round($cpuMax,3)
MemMaxBytes = $memMaxBytes
Logs = $logs
}
$json = $result | ConvertTo-Json -Depth 4
Write-Output $json
docker rm -f $ContainerName | Out-Null
return 0
|