src/public/Docker/Get-AitherContainer.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Get the status of AitherOS Docker containers. .DESCRIPTION Lists all AitherOS containers with their status, health, ports, CPU/memory usage, and uptime. Detects orphaned containers (hash-prefixed names) and warns about them. Supports filtering by name, profile, status (running/stopped/unhealthy), and pipeline output for further processing. .PARAMETER Name Filter by service name (supports wildcards). E.g., 'moltbook', '*social*', 'genesis'. .PARAMETER Profile Filter to services belonging to a specific compose profile. .PARAMETER Running Show only running containers. .PARAMETER Stopped Show only stopped/exited containers. .PARAMETER Unhealthy Show only unhealthy or restarting containers. .PARAMETER Orphaned Show only orphaned containers (hash-prefixed names not managed by compose). .PARAMETER Raw Return raw PSCustomObjects instead of formatted table output. .EXAMPLE Get-AitherContainer # Lists all AitherOS containers with status .EXAMPLE Get-AitherContainer -Running # Lists only running containers .EXAMPLE Get-AitherContainer -Unhealthy # Lists containers that are unhealthy or restarting .EXAMPLE Get-AitherContainer -Name '*mcp*' # Lists all MCP-related containers .EXAMPLE Get-AitherContainer -Orphaned # Detects orphaned/hash-prefixed containers (the bug we fixed) .NOTES Part of the AitherZero Docker management module. Copyright © 2025 Aitherium Corporation #> function Get-AitherContainer { [CmdletBinding(DefaultParameterSetName = 'All')] [OutputType([PSCustomObject[]])] param( [Parameter(Position = 0)] [SupportsWildcards()] [string]$Name, [Parameter()] [ValidateSet('core', 'intelligence', 'perception', 'memory', 'training', 'autonomic', 'security', 'agents', 'social', 'creative', 'gpu', 'gateway', 'mcp', 'external', 'desktop', 'all')] [string]$Profile, [Parameter(ParameterSetName = 'Running')] [switch]$Running, [Parameter(ParameterSetName = 'Stopped')] [switch]$Stopped, [Parameter(ParameterSetName = 'Unhealthy')] [switch]$Unhealthy, [Parameter(ParameterSetName = 'Orphaned')] [switch]$Orphaned, [Parameter()] [switch]$Raw ) # Verify Docker is available if (-not (Get-Command docker -ErrorAction SilentlyContinue)) { Write-Error 'Docker is not installed or not in PATH.' return } # Get all aitheros containers $format = '{{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}\t{{.State}}' $rawLines = docker ps -a --filter "name=aitheros" --format $format 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "Docker command failed: $rawLines" return } $containers = @() foreach ($line in $rawLines) { if ([string]::IsNullOrWhiteSpace($line)) { continue } $parts = $line -split '\t' if ($parts.Count -lt 5) { continue } $containerName = $parts[0] $isOrphaned = $containerName -match '^\w{12}_aitheros-' $cleanName = if ($isOrphaned) { ($containerName -split '_', 2)[1] } else { $containerName } $serviceName = $cleanName -replace '^aitheros-', '' # Parse health from status string $statusStr = $parts[1] $health = if ($statusStr -match '\(healthy\)') { 'healthy' } elseif ($statusStr -match '\(unhealthy\)') { 'unhealthy' } elseif ($statusStr -match '\(starting\)') { 'starting' } elseif ($statusStr -match 'Restarting') { 'restarting' } elseif ($parts[4] -eq 'exited') { 'stopped' } else { 'unknown' } $containers += [PSCustomObject]@{ PSTypeName = 'AitherOS.Container' Service = $serviceName ContainerName = $containerName Status = $parts[4] # running, exited, restarting, created Health = $health StatusDetail = $statusStr Image = $parts[2] Ports = $parts[3] Orphaned = $isOrphaned } } # Apply filters if ($Name) { $containers = $containers | Where-Object { $_.Service -like $Name -or $_.ContainerName -like $Name } } if ($Running) { $containers = $containers | Where-Object { $_.Status -eq 'running' } } elseif ($Stopped) { $containers = $containers | Where-Object { $_.Status -in @('exited', 'created') } } elseif ($Unhealthy) { $containers = $containers | Where-Object { $_.Health -in @('unhealthy', 'restarting') } } elseif ($Orphaned) { $containers = $containers | Where-Object { $_.Orphaned } } # Sort by service name $containers = $containers | Sort-Object Service # Warn about orphaned containers $orphanCount = ($containers | Where-Object Orphaned).Count if ($orphanCount -gt 0 -and -not $Orphaned) { Write-Warning "$orphanCount orphaned container(s) detected (hash-prefixed names). Run 'Repair-AitherContainer' to fix." } if ($Raw) { return $containers } # Formatted output if ($containers.Count -eq 0) { Write-Host 'No AitherOS containers found matching criteria.' -ForegroundColor Yellow return } foreach ($c in $containers) { $statusColor = switch ($c.Health) { 'healthy' { 'Green' } 'starting' { 'Cyan' } 'unhealthy' { 'Red' } 'restarting' { 'Yellow' } 'stopped' { 'DarkGray' } default { 'Gray' } } $orphanTag = if ($c.Orphaned) { ' [ORPHANED]' } else { '' } $icon = switch ($c.Health) { 'healthy' { '[OK]' } 'starting' { '[..]' } 'unhealthy' { '[!!]' } 'restarting' { '[~~]' } 'stopped' { '[--]' } default { '[??]' } } Write-Host "$icon " -ForegroundColor $statusColor -NoNewline Write-Host "$($c.Service.PadRight(28))" -ForegroundColor White -NoNewline Write-Host "$($c.Health.PadRight(12))" -ForegroundColor $statusColor -NoNewline if ($orphanTag) { Write-Host $orphanTag -ForegroundColor Red -NoNewline } Write-Host " $($c.Ports)" -ForegroundColor DarkGray } Write-Host "`n Total: $($containers.Count) containers" -ForegroundColor DarkGray $runCount = ($containers | Where-Object { $_.Status -eq 'running' }).Count $stoppedCount = ($containers | Where-Object { $_.Status -ne 'running' }).Count Write-Host " Running: $runCount Stopped: $stoppedCount" -ForegroundColor DarkGray # Return objects for pipeline return $containers } |