diff --git a/scripts/Deploy-Brass.ps1 b/scripts/Deploy-Brass.ps1 index 9567975..fe8c589 100644 --- a/scripts/Deploy-Brass.ps1 +++ b/scripts/Deploy-Brass.ps1 @@ -52,7 +52,10 @@ if (-not (Test-Path $cfgPath)) { . $cfgPath # Sanity-check required vars actually got set (template ships with CHANGE_ME). -foreach ($v in 'DeployShare','ServerSshHost','ServerSshKey','ServerBinaryRemote') { +# $ServerSshKey is only required for SSH-mode deploys; skip it when ServerSshHost = 'local'. +$requiredVars = @('DeployShare','ServerSshHost','ServerBinaryRemote') +if ($ServerSshHost -ne 'local') { $requiredVars += 'ServerSshKey' } +foreach ($v in $requiredVars) { $val = Get-Variable -Name $v -ValueOnly -ErrorAction Stop if ($val -match 'CHANGE_ME' -or [string]::IsNullOrWhiteSpace($val)) { throw "deploy.config.ps1 has placeholder/empty `$$v. Fill it in." @@ -120,14 +123,26 @@ if (($shouldRunPack -or $shouldRunLauncher) -and -not $DryRun -and -not $Force) # actually broken -- the atomic swap is safe with the daemon running). But # knowing the state up front lets us tailor the final "next steps" message # so a deploy success doesn't silently leave you on the old code. +# Set $ServerSshHost = 'local' in deploy.config.ps1 to skip SSH entirely +# and copy/inspect the server binary on the local filesystem. Use when the +# deploy machine IS the server (e.g. running Deploy-Brass.ps1 on glados). +$isLocalDeploy = ($ServerSshHost -eq 'local') + $daemonWasRunning = $false if ($shouldRunServer) { - Write-Host "Pre-flight: checking daemon state on $ServerSshHost..." -ForegroundColor DarkGray - # Single-quoted PS string so PowerShell doesn't try to interpret the - # bash-side metacharacters. The remote shell sees the literal pgrep - # command; the trailing $ anchors so we don't match run.sh wrappers. - $remoteCmd = 'pgrep -f /brass-sigil-server$ 2>/dev/null' - $pgrepOut = & ssh -i $ServerSshKey -o ConnectTimeout=5 -o BatchMode=yes $ServerSshHost $remoteCmd 2>$null + if ($isLocalDeploy) { + Write-Host "Pre-flight: checking daemon state locally..." -ForegroundColor DarkGray + $pgrepOut = & pgrep -f '/brass-sigil-server($| )' 2>$null + } else { + Write-Host "Pre-flight: checking daemon state on $ServerSshHost..." -ForegroundColor DarkGray + # Single-quoted PS string so PowerShell doesn't try to interpret the + # bash-side metacharacters. Match the binary path followed by either + # end-of-line OR a space, so we catch `brass-sigil-server run` (the + # actual invocation) without matching the `/brass-sigil-server/...` + # directory path that appears in the run.sh wrapper's argv. + $remoteCmd = 'pgrep -f /brass-sigil-server($| ) 2>/dev/null' + $pgrepOut = & ssh -i $ServerSshKey -o ConnectTimeout=5 -o BatchMode=yes $ServerSshHost $remoteCmd 2>$null + } $daemonWasRunning = -not [string]::IsNullOrWhiteSpace($pgrepOut) if ($daemonWasRunning) { Write-Host " Daemon is RUNNING. Atomic swap is safe -- but you'll need to" -ForegroundColor Yellow @@ -224,15 +239,27 @@ if ($shouldRunPack) { } } -# ─── Stage 6: scp + atomic swap server binary ────────────────────────────── +# ─── Stage 6: copy + atomic swap server binary ───────────────────────────── if ($shouldRunServer) { - Step "scp server binary -> $ServerSshHost`:$ServerBinaryRemote (atomic swap)" { - $remoteNew = "$ServerBinaryRemote.new" - & scp -i $ServerSshKey -o ConnectTimeout=15 $serverExe "$ServerSshHost`:$remoteNew" - if ($LASTEXITCODE -ne 0) { throw "scp failed with exit $LASTEXITCODE" } - $cmd = "chmod +x '$remoteNew' && mv '$remoteNew' '$ServerBinaryRemote' && md5sum '$ServerBinaryRemote'" - & ssh -i $ServerSshKey -o ConnectTimeout=10 $ServerSshHost $cmd - if ($LASTEXITCODE -ne 0) { throw "ssh swap failed with exit $LASTEXITCODE" } + if ($isLocalDeploy) { + Step "Copy server binary -> $ServerBinaryRemote (local atomic swap)" { + $localNew = "$ServerBinaryRemote.new" + Copy-Item $serverExe $localNew -Force + & chmod +x $localNew + if ($LASTEXITCODE -ne 0) { throw "chmod failed with exit $LASTEXITCODE" } + Move-Item $localNew $ServerBinaryRemote -Force + $md5 = (& md5sum $ServerBinaryRemote) -split '\s+' | Select-Object -First 1 + Write-Host " md5: $md5" -ForegroundColor DarkGray + } + } else { + Step "scp server binary -> $ServerSshHost`:$ServerBinaryRemote (atomic swap)" { + $remoteNew = "$ServerBinaryRemote.new" + & scp -i $ServerSshKey -o ConnectTimeout=15 $serverExe "$ServerSshHost`:$remoteNew" + if ($LASTEXITCODE -ne 0) { throw "scp failed with exit $LASTEXITCODE" } + $cmd = "chmod +x '$remoteNew' && mv '$remoteNew' '$ServerBinaryRemote' && md5sum '$ServerBinaryRemote'" + & ssh -i $ServerSshKey -o ConnectTimeout=10 $ServerSshHost $cmd + if ($LASTEXITCODE -ne 0) { throw "ssh swap failed with exit $LASTEXITCODE" } + } } Write-Host "" if ($daemonWasRunning) { diff --git a/scripts/deploy.config.template.ps1 b/scripts/deploy.config.template.ps1 index 205922c..28c1d64 100644 --- a/scripts/deploy.config.template.ps1 +++ b/scripts/deploy.config.template.ps1 @@ -19,13 +19,20 @@ $ManifestPublicUrl = 'https://CHANGE_ME/pack/manifest.json' # ─── Server (brass-sigil-server daemon host) ─────────────────────────────── # user@host for the Linux box running the daemon. +# +# Set to the literal string 'local' if Deploy-Brass.ps1 is being run on the +# server itself (e.g. on glados over the Telegram bridge). In local mode the +# script skips scp/ssh and copies the binary directly to $ServerBinaryRemote +# with an in-place atomic rename; $ServerSshKey is ignored. $ServerSshHost = 'user@CHANGE_ME' # Path to the local SSH private key authorised on the server. +# Ignored when $ServerSshHost = 'local'. $ServerSshKey = "$env:USERPROFILE\.ssh\id_ed25519" -# Absolute path on the Linux box where the brass-sigil-server binary lives. -# `Deploy-Brass.ps1` uploads to ".new" then `mv` over for atomic swap. +# Absolute path where the brass-sigil-server binary lives -- on the remote +# host in SSH mode, on the local filesystem in 'local' mode. +# `Deploy-Brass.ps1` writes to ".new" then renames over for atomic swap. $ServerBinaryRemote = '/home/user/brass-sigil-server/brass-sigil-server' # ─── Build outputs (don't normally need to change) ─────────────────────────