Files
AetherForge/scripts/ci-docker-mining.ps1
AetherForge a32860b0d9
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
feat: alive UI wave, galaxy presence, spread and fleet enhancements
Dashboard ambient layer, comrade presence, Mission Deck and War Room, Emberwake supply chain, spread/docs publishing, fleet policy and modules API, CI docker mining, and refreshed USB pack.
2026-06-04 22:36:17 -07:00

129 lines
4.6 KiB
PowerShell

# CI Docker mining proof — Linux agent connects and reports hashrate > 0 (Windows + Docker Desktop).
param(
[string]$BaseUrl = "http://127.0.0.1:18989",
[string]$Username = "",
[string]$Password = "",
[string]$ExpectedWorker = "docker-e2e-linux",
[int]$WaitSeconds = 180,
[int]$PollIntervalSec = 5,
[switch]$SkipTeardown
)
$ErrorActionPreference = "Stop"
$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
$ComposeFile = Join-Path $Root "docker\docker-compose.yml"
if (-not $Username) { $Username = if ($env:AETHERFORGE_E2E_USER) { $env:AETHERFORGE_E2E_USER } else { "testuser" } }
if (-not $Password) { $Password = if ($env:AETHERFORGE_E2E_PASS) { $env:AETHERFORGE_E2E_PASS } else { "testpass" } }
$cred = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${Username}:${Password}"))
$authHeaders = @{ Authorization = "Basic $cred" }
function Write-Log([string]$Message) {
Write-Host "[ci-docker-mining] $Message"
}
function Ensure-Docker {
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
throw "docker not found — install Docker Desktop with compose v2"
}
docker compose version 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) { throw "docker compose plugin not available" }
}
function Invoke-Teardown {
if ($SkipTeardown) { return }
Write-Log "Tearing down compose…"
Push-Location $Root
try {
docker compose -f $ComposeFile down --rmi local -v --remove-orphans 2>$null
} finally {
Pop-Location
}
}
function Wait-ForHealth {
param([datetime]$Deadline)
while ((Get-Date) -lt $Deadline) {
try {
$r = Invoke-RestMethod "$BaseUrl/api/v1/health" -TimeoutSec 5
if ($r.status -eq "ok") {
Write-Log "Server healthy at $BaseUrl/api/v1/health"
return
}
} catch {}
Start-Sleep -Seconds $PollIntervalSec
}
throw "server not healthy within ${WaitSeconds}s ($BaseUrl/api/v1/health)"
}
function Assert-Mining {
param([datetime]$Deadline)
while ((Get-Date) -lt $Deadline) {
try {
$agents = Invoke-RestMethod "$BaseUrl/api/v1/agents" -Headers $authHeaders -TimeoutSec 10
$stats = Invoke-RestMethod "$BaseUrl/api/v1/dashboard/stats" -Headers $authHeaders -TimeoutSec 10
$online = @($agents | Where-Object {
$_.status -eq "online" -and (
[double]$_.hashrate_15s -gt 0 -or
[double]$_.hashrate_1m -gt 0 -or
[double]$_.hashrate_15m -gt 0
)
})
$named = @($online | Where-Object { $_.worker_name -eq $ExpectedWorker -or $_.name -eq $ExpectedWorker })
$hit = if ($named.Count -gt 0) { $named[0] } elseif ($online.Count -gt 0) { $online[0] } else { $null }
if ($hit) {
$hr = [Math]::Max([double]$hit.hashrate_15s, [Math]::Max([double]$hit.hashrate_1m, [double]$hit.hashrate_15m))
Write-Log "PASS: online agent $($hit.id) ($($hit.worker_name)) hashrate=$([math]::Round($hr, 2)) H/s"
Write-Log "Fleet stats: online=$($stats.online_agents) total_hr=$([math]::Round([double]$stats.total_hashrate, 2))"
return
}
Write-Log "Waiting… online_agents=$($stats.online_agents) total_hashrate=$($stats.total_hashrate) (need online + hashrate>0)"
} catch {
Write-Log "Waiting… agents/stats API not ready ($($_.Exception.Message))"
}
Start-Sleep -Seconds $PollIntervalSec
}
throw "no online agent with hashrate>0 within ${WaitSeconds}s (expected worker: $ExpectedWorker)"
}
function Show-FailureLogs {
Push-Location $Root
try {
Write-Log "Recent server logs:"
docker compose -f $ComposeFile logs --tail=80 server 2>$null
Write-Log "Recent agent logs:"
docker compose -f $ComposeFile logs --tail=80 agent 2>$null
} finally {
Pop-Location
}
}
Ensure-Docker
try {
Push-Location $Root
Write-Log "Starting docker compose (build may take several minutes)…"
docker compose -f $ComposeFile up --build -d
if ($LASTEXITCODE -ne 0) { throw "docker compose up failed (exit $LASTEXITCODE)" }
Pop-Location
$deadline = (Get-Date).AddSeconds($WaitSeconds)
Write-Log "Waiting up to ${WaitSeconds}s for health + mining proof…"
Wait-ForHealth -Deadline $deadline
Assert-Mining -Deadline $deadline
Write-Log "Docker mining proof succeeded"
exit 0
} catch {
Write-Host "[ci-docker-mining] ERROR: $($_.Exception.Message)" -ForegroundColor Red
Show-FailureLogs
exit 1
} finally {
Invoke-Teardown
}