param( [string]$RestDockerHost = "ssh://docker-gpu.cin.su", [string]$McpDockerHost = "ssh://docker.cin.su", [string]$RestComposePath = "core/deploy/docker-gpu/adapter-1c/compose.yaml", [string]$McpComposePath = "core/deploy/docker/adapter-1c-mcp/compose.yaml", [string]$RestServiceName = "adapter-1c-rest", [string]$McpServiceName = "adapter-1c-mcp", [string[]]$BaseId, [string]$AdapterUrl = "http://docker-gpu.cin.su:8011", [string]$McpUrl = "http://docker.cin.su:8021", [string]$ObjectRef, [string]$ObjectKind, [string]$ObjectName, [string]$ObjectGuid, [ValidateSet("ConfigSave", "ConfigCASSave")] [string]$SavedStateTable = "ConfigSave", [int]$TimeoutSec = 120, [switch]$NoBuild, [switch]$SkipRest, [switch]$SkipMcp, [switch]$SkipVerify, [switch]$SkipWritePlanSafetySmoke, [switch]$SkipWriteRollbackSafetySmoke, [switch]$SkipSavedStateDiffSmoke, [switch]$SkipSavedStateWriteSmoke, [switch]$SkipCodeWriteSavedStateSmoke, [switch]$RequireSavedStateWriteSmoke, [switch]$RequireSelectorChainWritePlanComposition ) $ErrorActionPreference = "Stop" function Invoke-CheckedCommand { param( [string]$Label, [string[]]$Command ) Write-Host "[run] $Label" $exe = $Command[0] $args = $Command[1..($Command.Length - 1)] Write-Host ("[cmd] {0} {1}" -f $exe, ($args -join " ")) & $exe @args if ($LASTEXITCODE -ne 0) { throw "$Label failed with code=$LASTEXITCODE" } } function Invoke-ComposeUp { param( [string]$Label, [string]$DockerHost, [string]$ComposePath, [string]$ServiceName ) $command = @("docker", "--host", $DockerHost, "compose", "-f", $ComposePath, "up", "-d", "--no-deps") if (-not $NoBuild) { $command += "--build" } $command += $ServiceName Invoke-CheckedCommand -Label $Label -Command $command } function Ensure-RestServiceToken { if ($env:ONEC_ADAPTER_SERVICE_TOKEN) { return } if ($env:ONEC_ADAPTER_ALLOW_UNAUTHENTICATED_ADMIN -match '^(?i:true|1|yes|on)$') { Write-Host "[security] Test profile: deploying without REST service token because ONEC_ADAPTER_ALLOW_UNAUTHENTICATED_ADMIN is enabled" return } $inspectJson = & docker --host $RestDockerHost inspect $RestServiceName 2>$null if ($LASTEXITCODE -eq 0 -and $inspectJson) { $container = @($inspectJson | ConvertFrom-Json)[0] $tokenEntry = @($container.Config.Env | Where-Object { $_ -like "ONEC_ADAPTER_SERVICE_TOKEN=*" })[0] if ($tokenEntry) { $existingToken = ($tokenEntry -split "=", 2)[1] if ($existingToken) { $env:ONEC_ADAPTER_SERVICE_TOKEN = $existingToken Write-Host "[security] Reusing the existing REST service token without printing or persisting it" return } } } throw "ONEC_ADAPTER_SERVICE_TOKEN is empty and no protected existing REST container token can be reused. Refusing to deploy an unauthenticated adapter." } function Write-ContainerSummary { param( [string]$Label, [string]$DockerHost, [string]$ServiceName ) Write-Host "[status] $Label" & docker --host $DockerHost ps --filter "name=$ServiceName" --format "name={{.Names}} image={{.Image}} status={{.Status}} ports={{.Ports}}" if ($LASTEXITCODE -ne 0) { throw "$Label status failed with code=$LASTEXITCODE" } } function Get-DuplicateValues { param( [string[]]$Values ) $seen = @{} $duplicates = New-Object System.Collections.Generic.HashSet[string] foreach ($value in $Values) { if ($seen.ContainsKey($value)) { [void]$duplicates.Add($value) } else { $seen[$value] = $true } } return @($duplicates | Sort-Object) } function Normalize-BaseIds { param( [string[]]$Values ) $result = @() foreach ($value in $Values) { foreach ($part in ($value -split ",")) { $trimmed = $part.Trim() if ($trimmed) { $result += $trimmed } } } return $result } try { if (-not $SkipRest) { if (-not $env:ONEC_ADAPTER_ALLOW_UNAUTHENTICATED_ADMIN) { $env:ONEC_ADAPTER_ALLOW_UNAUTHENTICATED_ADMIN = "true" } Ensure-RestServiceToken Invoke-ComposeUp ` -Label "Deploy REST adapter" ` -DockerHost $RestDockerHost ` -ComposePath $RestComposePath ` -ServiceName $RestServiceName Write-ContainerSummary ` -Label "REST adapter container" ` -DockerHost $RestDockerHost ` -ServiceName $RestServiceName } if (-not $SkipMcp) { Invoke-ComposeUp ` -Label "Deploy MCP proxy" ` -DockerHost $McpDockerHost ` -ComposePath $McpComposePath ` -ServiceName $McpServiceName Write-ContainerSummary ` -Label "MCP proxy container" ` -DockerHost $McpDockerHost ` -ServiceName $McpServiceName } if (-not $SkipVerify) { $baseIds = @(Normalize-BaseIds -Values $BaseId) if (-not $baseIds) { Write-Host "[skip] BaseId was not provided; live verification skipped" } else { $duplicateBaseIds = @(Get-DuplicateValues -Values $baseIds) if ($duplicateBaseIds) { throw "Duplicate BaseId value(s): $($duplicateBaseIds -join ', ')" } $verifyCommand = @( "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "scripts/verify_1c_adapter_deployment.ps1", "-BaseId" ) $verifyCommand += ($baseIds -join ",") $verifyCommand += @( "-AdapterUrl", $AdapterUrl, "-McpUrl", $McpUrl, "-TimeoutSec", $TimeoutSec.ToString(), "-SavedStateTable", $SavedStateTable ) if ($ObjectRef) { $verifyCommand += @("-ObjectRef", $ObjectRef) } if ($ObjectKind) { $verifyCommand += @("-ObjectKind", $ObjectKind) } if ($ObjectName) { $verifyCommand += @("-ObjectName", $ObjectName) } if ($ObjectGuid) { $verifyCommand += @("-ObjectGuid", $ObjectGuid) } if ($SkipRest) { $verifyCommand += "-SkipRest" } if ($SkipMcp) { $verifyCommand += "-SkipMcp" } if ($SkipWritePlanSafetySmoke) { $verifyCommand += "-SkipWritePlanSafetySmoke" } if ($SkipWriteRollbackSafetySmoke) { $verifyCommand += "-SkipWriteRollbackSafetySmoke" } if ($SkipSavedStateDiffSmoke) { $verifyCommand += "-SkipSavedStateDiffSmoke" } if ($SkipSavedStateWriteSmoke) { $verifyCommand += "-SkipSavedStateWriteSmoke" } if ($SkipCodeWriteSavedStateSmoke) { $verifyCommand += "-SkipCodeWriteSavedStateSmoke" } if ($RequireSavedStateWriteSmoke) { $verifyCommand += "-RequireSavedStateWriteSmoke" } if ($RequireSelectorChainWritePlanComposition) { $verifyCommand += "-RequireSelectorChainWritePlanComposition" } Invoke-CheckedCommand -Label "Verify 1C adapter deployment" -Command $verifyCommand } } Write-Host "[done] 1C adapter stack deploy finished" exit 0 } catch { Write-Error $_ exit 1 }