diff --git a/scripts/windows/README.md b/scripts/windows/README.md new file mode 100644 index 0000000..dda7518 --- /dev/null +++ b/scripts/windows/README.md @@ -0,0 +1,50 @@ +# Windows host build/deploy scripts + +Helper scripts for the Windows host box (the RTX `.173` lab box, repo at +`C:\Users\Public\punktfunk-native`). Run them from the repo root in an **elevated** PowerShell. + +## One-time: persist the build environment + +```powershell +powershell -ExecutionPolicy Bypass -File scripts\windows\setup-build-env.ps1 +``` + +Persists (Machine scope) the three vars the NVENC build needs: + +| var | value | why | +| --- | --- | --- | +| `PUNKTFUNK_NVENC_LIB_DIR` | `C:\Users\Public\nvenc` | NVENC import lib (`nvencodeapi.lib`) | +| `LIBCLANG_PATH` | `C:\Program Files\LLVM\bin` | bindgen (`libclang.dll`) | +| `CMAKE_POLICY_VERSION_MINIMUM` | `3.5` | `audiopus_sys` / cmake crates | + +`FFMPEG_DIR` is **not** set — the `--features nvenc` build the RTX box uses does not link +libavcodec (that is only the `amf-qsv` feature). The VS C++ toolchain is loaded per-build via +`vcvars64.bat` (auto-discovered with `vswhere`). + +## Rebuild + redeploy the host service + +```powershell +powershell -ExecutionPolicy Bypass -File scripts\windows\deploy-host.ps1 +``` + +Stops `PunktfunkHost`, backs up the current binary (`punktfunk-host.exe.bak`), builds +`--release -p punktfunk-host --features nvenc` from the current source, then restarts the +service on the new binary — **with automatic rollback** if the build fails or the new binary +won't start. The service is down only for the build duration. + +## Rebuild + restart the web console + +```powershell +powershell -ExecutionPolicy Bypass -File scripts\windows\build-web.ps1 +``` + +`bun install && bun run build`, installs the externalized server deps into `.output/server` +(with the `@unom` `.npmrc`), then restarts the `PunktfunkWeb` task and checks `:3000/login`. + +## Typical flow after pulling new code + +```powershell +git pull +powershell -ExecutionPolicy Bypass -File scripts\windows\deploy-host.ps1 +powershell -ExecutionPolicy Bypass -File scripts\windows\build-web.ps1 +``` diff --git a/scripts/windows/build-web.ps1 b/scripts/windows/build-web.ps1 new file mode 100644 index 0000000..4e54e7b --- /dev/null +++ b/scripts/windows/build-web.ps1 @@ -0,0 +1,41 @@ +<# + Rebuild the web mgmt console from the CURRENT web/ source and restart the PunktfunkWeb task. + + powershell -ExecutionPolicy Bypass -File scripts\windows\build-web.ps1 + + bun = build tool, node = runtime (the Nitro bundle externalizes srvx/@unom for SSR, which + bun fails to resolve at runtime). The PunktfunkWeb scheduled task runs web\web-run.cmd -> + node .output\server\index.mjs on :3000. +#> +$ErrorActionPreference = 'Stop' +$repo = Split-Path (Split-Path $PSScriptRoot) +$web = Join-Path $repo 'web' +$bun = 'C:\Users\Public\bun\bin\bun.exe' +$task = 'PunktfunkWeb' +if (-not (Test-Path $bun)) { throw "bun not found at $bun" } + +Set-Location $web +Write-Host "bun install + build ..." +& $bun install +& $bun run build +if ($LASTEXITCODE -ne 0) { throw "web build failed (exit $LASTEXITCODE)" } + +# The Nitro server bundle externalizes its runtime deps - install them in .output/server, +# with the @unom registry .npmrc present (else @unom/* 404s on npmjs). +Write-Host "installing externalized server deps ..." +Copy-Item "$web\.npmrc" "$web\.output\server\.npmrc" -Force +Set-Location "$web\.output\server" +& $bun install + +Write-Host "restarting $task ..." +& schtasks /end /tn $task 2>$null | Out-Null +Get-CimInstance Win32_Process -Filter "Name='node.exe'" -ErrorAction SilentlyContinue | + Where-Object { $_.CommandLine -match 'index\.mjs' } | + ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } +Start-Sleep 2 +& schtasks /run /tn $task | Out-Null +Start-Sleep 5 +try { + $r = Invoke-WebRequest 'http://127.0.0.1:3000/login' -UseBasicParsing -TimeoutSec 10 + Write-Host "DONE - web /login -> HTTP $($r.StatusCode)" +} catch { Write-Warning "web restarted but /login check failed: $($_.Exception.Message)" } diff --git a/scripts/windows/deploy-host.ps1 b/scripts/windows/deploy-host.ps1 new file mode 100644 index 0000000..7d0d148 --- /dev/null +++ b/scripts/windows/deploy-host.ps1 @@ -0,0 +1,71 @@ +<# + Rebuild the punktfunk Windows host (release + NVENC) from the CURRENT source and + restart the LocalSystem service, with automatic rollback if the build fails or the + new binary won't start. + + powershell -ExecutionPolicy Bypass -File scripts\windows\deploy-host.ps1 + + Prereqs: run setup-build-env.ps1 once (persists the build env), and VS C++ build tools + installed (vcvars64.bat is auto-discovered via vswhere). The service is stopped for the + duration of the build (the running .exe is locked), then restarted on the new binary. +#> +$ErrorActionPreference = 'Stop' +$repo = Split-Path (Split-Path $PSScriptRoot) # scripts\windows -> repo root +$exe = Join-Path $repo 'target\release\punktfunk-host.exe' +$bak = "$exe.bak" +$svc = 'PunktfunkHost' + +function Find-VcVars { + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (Test-Path $vswhere) { + $ip = & $vswhere -latest -products * -property installationPath 2>$null + if ($ip) { $v = Join-Path $ip 'VC\Auxiliary\Build\vcvars64.bat'; if (Test-Path $v) { return $v } } + } + $fb = 'C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvars64.bat' + if (Test-Path $fb) { return $fb } + throw "vcvars64.bat not found - install the VS C++ build tools." +} + +function Svc-Running { (& sc.exe query $svc 2>$null) -match 'RUNNING' } + +Write-Host "== punktfunk host deploy ==" +$vcvars = Find-VcVars +Write-Host "vcvars : $vcvars" +Set-Location $repo + +# 1. stop the service so the .exe is writable +Write-Host "stopping $svc ..." +& sc.exe stop $svc | Out-Null +for ($i=0; $i -lt 30 -and (Svc-Running); $i++) { Start-Sleep 1 } + +# 2. back up the current binary for rollback +if (Test-Path $exe) { Copy-Item $exe $bak -Force; Write-Host "backup : $bak" } + +# 3. build (release + nvenc); build env is inherited from Machine scope (setup-build-env.ps1) +Write-Host "building: cargo build --release -p punktfunk-host --features nvenc" +& cmd.exe /c "call `"$vcvars`" >nul && cargo build --release -p punktfunk-host --features nvenc" +$built = ($LASTEXITCODE -eq 0) + +if (-not $built) { + Write-Warning "BUILD FAILED (exit $LASTEXITCODE) - restoring previous binary." + if (Test-Path $bak) { Copy-Item $bak $exe -Force } + & sc.exe start $svc | Out-Null + throw "build failed; previous binary restored and service restarted." +} + +# 4. start on the new binary and confirm it stays up +Write-Host "build OK - starting $svc ..." +& sc.exe start $svc | Out-Null +$running = $false +for ($i=0; $i -lt 20; $i++) { if (Svc-Running) { $running = $true; break }; Start-Sleep 1 } + +if (-not $running) { + Write-Warning "new binary did not start - rolling back." + & sc.exe stop $svc | Out-Null; Start-Sleep 2 + if (Test-Path $bak) { Copy-Item $bak $exe -Force } + & sc.exe start $svc | Out-Null + throw "new binary failed to start; rolled back to previous." +} + +Write-Host "DONE - $svc running the new binary:" +Get-Item $exe | Select-Object LastWriteTime, Length | Format-List diff --git a/scripts/windows/setup-build-env.ps1 b/scripts/windows/setup-build-env.ps1 new file mode 100644 index 0000000..f755f22 --- /dev/null +++ b/scripts/windows/setup-build-env.ps1 @@ -0,0 +1,27 @@ +<# + Persist the punktfunk Windows-host build environment (Machine scope, run once, elevated). + + After this, deploy-host.ps1 needs only the VS toolchain (it loads vcvars64.bat itself). + These are BUILD-time vars; runtime config lives in C:\ProgramData\punktfunk\host.env. + + powershell -ExecutionPolicy Bypass -File scripts\windows\setup-build-env.ps1 +#> +$ErrorActionPreference = 'Stop' + +$admin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() + ).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) +if (-not $admin) { throw "Run elevated (Machine-scope env requires Administrator)." } + +# NVENC import lib (nvencodeapi.lib); libclang for bindgen; cmake policy floor for audiopus_sys. +$vars = [ordered]@{ + 'PUNKTFUNK_NVENC_LIB_DIR' = 'C:\Users\Public\nvenc' + 'LIBCLANG_PATH' = 'C:\Program Files\LLVM\bin' + 'CMAKE_POLICY_VERSION_MINIMUM' = '3.5' + # FFMPEG_DIR is only needed for the `amf-qsv` feature (libavcodec). The RTX box builds + # `--features nvenc`, which does NOT link FFmpeg, so it is intentionally left unset. +} +foreach ($k in $vars.Keys) { + [Environment]::SetEnvironmentVariable($k, $vars[$k], 'Machine') + Write-Host ("set (Machine) {0} = {1}" -f $k, $vars[$k]) +} +Write-Host "Done. Open a fresh shell (or reboot) for these to be inherited by new processes."