src/public/AI/Stop-AitherService.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Stop an AitherOS service. .DESCRIPTION Stops the specified AitherOS service by terminating its process. .PARAMETER Name Service name or alias. Required. Examples: 'Node', 'AitherNode', 'MCP', 'Reasoning' .PARAMETER Force Force stop even if service is in use. .PARAMETER ShowOutput Display progress and status. .PARAMETER PassThru Return result object instead of display output. .EXAMPLE Stop-AitherService -Name Node # Stops AitherNode MCP server .EXAMPLE Stop-AitherService -Name Node -Force # Force stops AitherNode .NOTES Part of the AitherZero module. #> function Stop-AitherService { [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory, Position = 0)] [string]$Name, [Parameter()] [switch]$Force, [Parameter()] [switch]$ShowOutput, [Parameter()] [switch]$PassThru ) # Service definitions $AitherServices = @{ AitherNode = @{ Port = 8080; Alias = @('Node', 'MCP') } AitherReasoning = @{ Port = 8093; Alias = @('Reasoning', 'Traces') } AitherPulse = @{ Port = 8081; Alias = @('Pulse', 'Events') } AitherCanvas = @{ Port = 8188; Alias = @('Canvas', 'Comfy', 'ImageGen') } AitherVeil = @{ Port = 3000; Alias = @('Veil', 'Dashboard', 'UI') } AitherPrism = @{ Port = 8106; Alias = @('Prism', 'Video') } AitherTrainer = @{ Port = 8107; Alias = @('Trainer', 'Training') } vLLMOrchestrator = @{ Port = 8200; Alias = @('Orchestrator', 'LLM') } vLLMReasoning = @{ Port = 8201; Alias = @('Reasoning-vLLM') } vLLMVision = @{ Port = 8202; Alias = @('Vision-vLLM') } vLLMCoding = @{ Port = 8203; Alias = @('Coding-vLLM') } } # Resolve service name $svcName = $null if ($AitherServices.ContainsKey($Name)) { $svcName = $Name } else { foreach ($svc in $AitherServices.Keys) { if ($AitherServices[$svc].Alias -contains $Name) { $svcName = $svc break } } } if (-not $svcName) { Write-AitherLog -Level Warning -Message "Service '$Name' not found. Available: $($AitherServices.Keys -join ', ')" -Source 'Stop-AitherService' return } $def = $AitherServices[$svcName] $port = $def.Port $conn = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue if (-not $conn) { if ($ShowOutput) { Write-AitherLog -Level Information -Message "○ $svcName is not running" -Source 'Stop-AitherService' } $result = [PSCustomObject]@{ Name = $svcName; Status = 'NotRunning'; Port = $port; PID = $null } if ($PassThru) { return $result } return } $processId = $conn.OwningProcess if ($PSCmdlet.ShouldProcess($svcName, "Stop service (PID: $processId)")) { if ($ShowOutput) { Write-AitherLog -Level Information -Message "⏹ Stopping $svcName (PID: $processId)..." -Source 'Stop-AitherService' } try { Stop-Process -Id $processId -Force:$Force -ErrorAction Stop Start-Sleep -Seconds 1 $check = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue if (-not $check) { if ($ShowOutput) { Write-AitherLog -Level Information -Message "✓ $svcName stopped" -Source 'Stop-AitherService' } $result = [PSCustomObject]@{ Name = $svcName; Status = 'Stopped'; Port = $port; PID = $processId } } else { Write-AitherLog -Level Warning -Message "$svcName may still be running" -Source 'Stop-AitherService' $result = [PSCustomObject]@{ Name = $svcName; Status = 'StopFailed'; Port = $port; PID = $processId } } if ($PassThru) { return $result } } catch { Write-AitherLog -Level Error -Message "Failed to stop $svcName`: $_" -Source 'Stop-AitherService' -Exception $_ $result = [PSCustomObject]@{ Name = $svcName; Status = 'Error'; Port = $port; PID = $pid } if ($PassThru) { return $result } } } } |