Files
truf-server/deploy_capacity50.ps1
T
2026-09-30 20:30:56 +03:00

89 lines
3.0 KiB
PowerShell

[CmdletBinding()]
param(
[ValidateSet('Plan', 'Apply')]
[string]$Mode = 'Plan',
[string]$ServerHost = '2.27.25.56',
[string]$RemoteUser = 'root',
[string]$WslDistribution = 'Ubuntu-24.04',
[switch]$PrepareOnly
)
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
if ($ServerHost -notmatch '^[A-Za-z0-9.-]+$' -or $RemoteUser -notmatch '^[a-z_][a-z0-9_-]*$') {
throw 'Invalid SSH target'
}
$projectRoot = $PSScriptRoot
$releaseRoot = Join-Path $projectRoot 'build\capacity50-release'
$payloadRoot = Join-Path $releaseRoot 'payload\app'
$deploymentRoot = Join-Path $projectRoot 'deploy\capacity50'
$sourceNames = @(
'capacity_model.py',
'scanner_db.py',
'worker_assignment.py',
'worker_api.py',
'jsonl_projector.py',
'runtime_document.py',
'lifecycle_authority.py',
'config.linux.yaml'
)
if (Test-Path -LiteralPath $releaseRoot) {
Remove-Item -LiteralPath $releaseRoot -Recurse -Force
}
New-Item -ItemType Directory -Path $payloadRoot -Force | Out-Null
foreach ($name in $sourceNames) {
$source = Join-Path $projectRoot "app\$name"
if (-not (Test-Path -LiteralPath $source -PathType Leaf)) {
throw "Missing release source: $source"
}
Copy-Item -LiteralPath $source -Destination (Join-Path $payloadRoot $name)
}
foreach ($name in @(
'Dockerfile',
'deploy.sh',
'render_config.py',
'release_stopped_pipeline_leases.py'
)) {
Copy-Item -LiteralPath (Join-Path $deploymentRoot $name) -Destination (Join-Path $releaseRoot $name)
}
$checksumLines = Get-ChildItem -LiteralPath $releaseRoot -File -Recurse |
Where-Object Name -ne 'checksums.sha256' |
Sort-Object FullName |
ForEach-Object {
$relative = $_.FullName.Substring($releaseRoot.Length + 1).Replace('\', '/')
$hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
"$hash $relative"
}
[IO.File]::WriteAllLines(
(Join-Path $releaseRoot 'checksums.sha256'),
[string[]]$checksumLines,
[Text.UTF8Encoding]::new($false)
)
Write-Output "Prepared release bundle: $releaseRoot"
if ($PrepareOnly) {
return
}
$wslPath = (& wsl.exe -d $WslDistribution -- wslpath -a ($releaseRoot -replace '\', '/')).Trim()
if (-not $wslPath.StartsWith('/')) {
throw 'Could not resolve the release path inside WSL'
}
$remoteMode = $Mode.ToLowerInvariant()
$remoteCommand = "set -eu; install -d -m 0700 /var/lib/truf-deploy/stage; stage=`$(mktemp -d /var/lib/truf-deploy/stage/capacity50.XXXXXXXX); trap `"rm -rf `$stage`" EXIT; tar -xf - -C `"`$stage`"; cd `"`$stage`"; sha256sum -c checksums.sha256; bash deploy.sh $remoteMode `"`$stage`""
if ($wslPath.Contains("'")) {
throw 'Release path cannot contain an apostrophe'
}
$bashPath = "'$wslPath'"
$target = "$RemoteUser@$ServerHost"
$bashCommand = "tar -C $bashPath -cf - . | ssh -o StrictHostKeyChecking=yes $target '$remoteCommand'"
& wsl.exe -d $WslDistribution -- bash -lc $bashCommand
if ($LASTEXITCODE -ne 0) {
throw "Remote deployment failed with exit code $LASTEXITCODE"
}