stela ops usage fixes roles propagation and timoeut, one account to support multi tenants, migrations consolidation, search to support documentation, doctor and open api vector db search

This commit is contained in:
master
2026-02-22 19:27:54 +02:00
parent a29f438f53
commit bd8fee6ed8
373 changed files with 832097 additions and 3369 deletions

View File

@@ -0,0 +1,129 @@
param(
[ValidateSet("microservice", "reverseproxy")]
[string]$Mode = "microservice",
[string]$ComposeFile = "docker-compose.stella-ops.yml",
[int]$WaitTimeoutSeconds = 1200,
[int]$RecoveryAttempts = 2,
[int]$RecoveryWaitSeconds = 180
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$configPath = switch ($Mode) {
"microservice" { "./router-gateway-local.json" }
"reverseproxy" { "./router-gateway-local.reverseproxy.json" }
default { throw "Unsupported mode: $Mode" }
}
Write-Host "Redeploy mode: $Mode"
Write-Host "Gateway config: $configPath"
Write-Host "Compose file: $ComposeFile"
$env:ROUTER_GATEWAY_CONFIG = $configPath
function Invoke-Compose {
param(
[Parameter(Mandatory = $true)]
[string[]]$Args,
[switch]$IgnoreExitCode
)
& docker compose -f $ComposeFile @Args
$exitCode = $LASTEXITCODE
if (-not $IgnoreExitCode -and $exitCode -ne 0) {
throw "docker compose $($Args -join ' ') failed with exit code $exitCode."
}
return $exitCode
}
function Get-UnhealthyContainers {
$containers = & docker ps --filter "health=unhealthy" --format "{{.Names}}"
if ($LASTEXITCODE -ne 0) {
throw "Failed to query unhealthy containers."
}
$filtered = @($containers | Where-Object { -not [string]::IsNullOrWhiteSpace($_) -and $_ -like "stellaops-*" })
return [string[]]$filtered
}
function Get-ComposeServiceName {
param(
[Parameter(Mandatory = $true)]
[string]$ContainerName
)
$service = & docker inspect --format "{{ index .Config.Labels \"com.docker.compose.service\" }}" $ContainerName 2>$null
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($service)) {
return $null
}
return $service.Trim()
}
function Wait-ForContainerHealth {
param(
[Parameter(Mandatory = $true)]
[string]$ContainerName,
[Parameter(Mandatory = $true)]
[int]$TimeoutSeconds
)
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ((Get-Date) -lt $deadline) {
$status = (& docker inspect --format "{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}" $ContainerName 2>$null).Trim()
if ($LASTEXITCODE -ne 0) {
return $false
}
if ($status -eq "healthy" -or $status -eq "none") {
return $true
}
Start-Sleep -Seconds 5
}
return $false
}
Invoke-Compose -Args @("down", "-v", "--remove-orphans") | Out-Null
$upExitCode = Invoke-Compose -Args @("up", "-d", "--wait", "--wait-timeout", $WaitTimeoutSeconds.ToString()) -IgnoreExitCode
if ($upExitCode -ne 0) {
Write-Warning "docker compose up returned exit code $upExitCode. Running unhealthy-service recovery."
}
for ($attempt = 1; $attempt -le $RecoveryAttempts; $attempt++) {
$unhealthyContainers = @(Get-UnhealthyContainers)
if ($unhealthyContainers.Count -eq 0) {
break
}
Write-Warning "Recovery attempt ${attempt}: unhealthy containers detected: $($unhealthyContainers -join ', ')"
$services = New-Object System.Collections.Generic.HashSet[string]([System.StringComparer]::OrdinalIgnoreCase)
foreach ($containerName in $unhealthyContainers) {
$serviceName = Get-ComposeServiceName -ContainerName $containerName
if (-not [string]::IsNullOrWhiteSpace($serviceName)) {
[void]$services.Add($serviceName)
}
}
foreach ($serviceName in $services) {
Write-Host "Recreating service: $serviceName"
Invoke-Compose -Args @("up", "-d", "--force-recreate", "--no-deps", $serviceName) | Out-Null
}
foreach ($containerName in $unhealthyContainers) {
[void](Wait-ForContainerHealth -ContainerName $containerName -TimeoutSeconds $RecoveryWaitSeconds)
}
}
$remainingUnhealthy = @(Get-UnhealthyContainers)
if ($remainingUnhealthy.Count -gt 0) {
throw "Redeploy completed with unresolved unhealthy containers: $($remainingUnhealthy -join ', ')"
}
Write-Host "Redeploy complete for mode '$Mode'."