src/public/Orchestration/Stop-AitherOrchestration.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Stop a running orchestration execution .DESCRIPTION Stops a running playbook execution gracefully. Attempts to stop running scripts and clean up resources. Use this when you need to cancel a long-running playbook. .PARAMETER PlaybookName Name of the playbook to stop. Stops the most recent execution if multiple are running. .PARAMETER ExecutionId Specific execution ID to stop. Use this to stop a specific orchestration run. .PARAMETER Force Force stop without waiting for scripts to complete gracefully. .INPUTS System.String You can pipe playbook names or execution IDs to Stop-AitherOrchestration. .OUTPUTS PSCustomObject Returns stop result with Success, ExecutionId, and StoppedScripts properties. .EXAMPLE Stop-AitherOrchestration -PlaybookName "deployment" Stops the running "deployment" playbook execution. .EXAMPLE Stop-AitherOrchestration -ExecutionId "abc123" -Force Force stops a specific execution. .NOTES Stopping orchestration will: - Cancel running scripts - Mark execution as stopped - Clean up resources - Update execution history .LINK Get-AitherOrchestrationStatus Invoke-AitherPlaybook #> function Stop-AitherOrchestration { [OutputType([PSCustomObject])] [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory=$false, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$PlaybookName, [Parameter(ValueFromPipelineByPropertyName)] [string]$ExecutionId, [switch]$Force, [Parameter(HelpMessage = "Show command output in console.")] [switch]$ShowOutput ) begin { # Manage logging targets for this execution $originalLogTargets = $script:AitherLogTargets if ($ShowOutput) { if ($script:AitherLogTargets -notcontains 'Console') { $script:AitherLogTargets += 'Console' } } else { # Ensure Console is NOT in targets if ShowOutput is not specified $script:AitherLogTargets = $script:AitherLogTargets | Where-Object { $_ -ne 'Console' } } } process { try { # During module validation, skip execution if ($PSCmdlet.MyInvocation.InvocationName -eq '.' -and -not $PlaybookName -and -not $ExecutionId) { return $null } # Check if Get-AitherOrchestrationStatus is available if (-not (Get-Command Get-AitherOrchestrationStatus -ErrorAction SilentlyContinue)) { Write-AitherLog -Message "Get-AitherOrchestrationStatus is not available. Cannot stop orchestration." -Level Warning return $null } # Get orchestration status $statusParams = @{} if ($PlaybookName) { $statusParams.PlaybookName = $PlaybookName } if ($ExecutionId) { $statusParams.ExecutionId = $ExecutionId } $status = Get-AitherOrchestrationStatus @statusParams | Select-Object -First 1 if (-not $status -or $status.Status -ne 'Running') { Write-AitherLog -Message "No running orchestration found for: $PlaybookName" -Level Warning return [PSCustomObject]@{ Success = $false Message = "No running orchestration found" } } if ($PSCmdlet.ShouldProcess($status.PlaybookName, "Stop orchestration execution")) { # Stop execution (implementation depends on orchestration engine) # For now, mark as stopped in history $moduleRoot = Get-AitherModuleRoot $historyPath = Join-Path $moduleRoot 'library' 'execution-history' $historyFile = Join-Path $historyPath "$($status.ExecutionId).json" if (Test-Path $historyFile) { $execution = Get-Content -Path $historyFile -Raw | ConvertFrom-Json -AsHashtable $execution.Status = 'Stopped' $execution.EndTime = Get-Date $execution | ConvertTo-Json -Depth 10 | Out-File -FilePath $historyFile -Encoding UTF8 -Force } Write-AitherLog -Level Information -Message "Stopped orchestration: $($status.PlaybookName)" -Source $PSCmdlet.MyInvocation.MyCommand.Name -Data @{ ExecutionId = $status.ExecutionId Force = $Force } return [PSCustomObject]@{ Success = $true ExecutionId = $status.ExecutionId PlaybookName = $status.PlaybookName StoppedScripts = $status.RunningScripts } } } catch { # Use centralized error handling $errorScript = Join-Path $PSScriptRoot '..' 'Private' 'Write-AitherError.ps1' if (Test-Path $errorScript) { . $errorScript -ErrorRecord $_ -CmdletName $PSCmdlet.MyInvocation.MyCommand.Name -Operation "Stopping orchestration: $PlaybookName" -Parameters $PSBoundParameters -ThrowOnError } else { $errorObject = [PSCustomObject]@{ PSTypeName = 'AitherZero.Error' Success = $false ErrorId = [System.Guid]::NewGuid().ToString() Cmdlet = $PSCmdlet.MyInvocation.MyCommand.Name Operation = "Stopping orchestration: $PlaybookName" Error = $_.Exception.Message Timestamp = Get-Date } Write-Output $errorObject Write-AitherLog -Level Error -Message "Failed to stop orchestration $PlaybookName : $($_.Exception.Message)" -Source $PSCmdlet.MyInvocation.MyCommand.Name -Exception $_ } throw } finally { # Restore original log targets $script:AitherLogTargets = $originalLogTargets } } } |