89 lines
3.0 KiB
PowerShell
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"
|
|
}
|