47990 is the management API's port and also Sunshine's (and Apollo's, and Vibeshine's) web UI port. With the GameStream planes off it is the ONLY port the two still share, so moving it is the whole of what "run both on one box" needs — except moving it was barely possible: * `--mgmt-bind` was the sole route, and it lives in a unit file / service registration that a package upgrade rewrites. There was no `host.env` key, so the change did not survive. * The literal 47990 appeared in SIX places — mgmt::DEFAULT_PORT, the Windows service's console launch, scripts/punktfunk-web.service, the NixOS module, web/web-run.cmd, and the console's own default. Nothing downstream could learn a different port, so moving the listener silently left the console proxying to a port nothing was listening on. Now there is one source of truth. `PUNKTFUNK_MGMT_BIND` joins `host.env` (the `--gamestream` / PUNKTFUNK_GAMESTREAM shape: either source works, the CLI flag wins), and `serve` publishes the port it ACTUALLY bound to ~/.config/punktfunk/mgmt-endpoint, in the same KEY=VALUE form mgmt-token already uses so it is sourceable as a systemd EnvironmentFile and readable by the Windows service's existing read_env_file_value. Every consumer derives from that; the 47990 literals survive only as the fallback that keeps an OLD host working with a NEW console. The two unit files drop their hardcoded `Environment=PUNKTFUNK_MGMT_URL=` rather than layering a default beneath the file: whether Environment= or EnvironmentFile= wins is a directive-ordering question, and the hand-written unit and the Nix-generated one do not order the same way. No default, no precedence puzzle — the server's own built-in fallback covers a host that never wrote the file. Two robustness details worth naming, because both fail in the same direction: * mgmt-endpoint is written write-then-rename. A torn read would set PUNKTFUNK_MGMT_URL to EMPTY, which is worse than a missing file — a built-in default only rescues an *unset* variable. * mgmtUrl() now treats blank as unset, which `??` alone does not. The publish happens in parse_serve next to the token persistence, so both files appear together; the console's unit gates on mgmt-token, and its Restart=always picks up a lost race anyway. What this does NOT change: a lost 47990 bind is still fatal to the whole host (the bind sits in tokio::try_join! with the native plane), and running two Moonlight-compatible hosts at once is still unsupported — on Windows the exclusive display topology is a second, independent conflict. Both are documented rather than altered. Verified on Linux in punktfunk-rust-ci (amd64): cargo check --all-targets clean for punktfunk-host and pf-host-config with the "Checking punktfunk-host" marker confirmed present (a first run exited 0 having compiled nothing — the warm shared target dir judged it fresh), 40/40 mgmt tests pass including the new one pinning the published line against both parsers that consume it. Console: tsc --noEmit clean, bun test server/ 9/9. cargo fmt --all --check clean.
66 lines
3.5 KiB
Batchfile
66 lines
3.5 KiB
Batchfile
@echo off
|
|
rem punktfunk web console launcher - DEV convenience, run BY HAND (in-repo tree). On an installed
|
|
rem host the PunktfunkHost service supervises the console itself (service.rs "web console child" -
|
|
rem no scheduled task, no launcher script); a dev host running from target\release has no installed
|
|
rem web payload next to its exe, so this script is how you serve the in-repo web\.output against it.
|
|
rem It sources the host's mgmt bearer token + the console login password from %ProgramData%\punktfunk\,
|
|
rem points the /api proxy at the host's loopback HTTPS mgmt API, and serves the self-contained
|
|
rem (no-node_modules) Nitro console over HTTPS (HTTP/1.1 over TLS) on :47992 with the host's identity
|
|
rem cert. %~dp0 = <repo>\web\ . The console runs on bun (the Nitro `bun` preset + Bun.serve TLS
|
|
rem entry) - set BUN below to your bun.exe. Rebuild after a web change with `bun run build` in web\ .
|
|
setlocal EnableExtensions
|
|
|
|
set "PFDATA=%ProgramData%\punktfunk"
|
|
set "TOKENFILE=%PFDATA%\mgmt-token"
|
|
set "PWFILE=%PFDATA%\web-password"
|
|
set "CERTFILE=%PFDATA%\cert.pem"
|
|
set "KEYFILE=%PFDATA%\key.pem"
|
|
|
|
rem The host's `serve` writes the mgmt token + identity cert on first run. Until they exist the proxy
|
|
rem has no credential and no TLS material, so WAIT for them (mirrors the service supervisor's gate)
|
|
rem rather than silently serving plain HTTP. ~5 min at 2 s, then give up.
|
|
set /a PFWAITS=0
|
|
:pfwait
|
|
if exist "%TOKENFILE%" if exist "%CERTFILE%" goto pfready
|
|
if %PFWAITS% GEQ 150 (
|
|
echo [punktfunk-web] gave up waiting for "%TOKENFILE%" + "%CERTFILE%" - is the punktfunk host running?
|
|
exit /b 1
|
|
)
|
|
if %PFWAITS%==0 echo [punktfunk-web] waiting for the host to write the mgmt token + identity cert...
|
|
set /a PFWAITS+=1
|
|
ping -n 3 127.0.0.1 >nul 2>&1
|
|
goto pfwait
|
|
:pfready
|
|
|
|
rem Both files are single KEY=VALUE lines: PUNKTFUNK_MGMT_TOKEN=... and PUNKTFUNK_UI_PASSWORD=... .
|
|
rem Split on the first '=' and import each into the environment.
|
|
for /f "usebackq tokens=1* delims==" %%A in ("%TOKENFILE%") do set "%%A=%%B"
|
|
if exist "%PWFILE%" for /f "usebackq tokens=1* delims==" %%A in ("%PWFILE%") do set "%%A=%%B"
|
|
|
|
rem Fixed deployment wiring (the Windows analogue of scripts/punktfunk-web.service).
|
|
set "PORT=47992"
|
|
set "HOST=0.0.0.0"
|
|
set "PUNKTFUNK_MGMT_URL=https://127.0.0.1:47990"
|
|
rem ...unless the host published a different one. `serve` writes mgmt-endpoint in the same single
|
|
rem KEY=VALUE form as the token above, carrying the port it ACTUALLY bound - so a host moved off
|
|
rem 47990 (PUNKTFUNK_MGMT_BIND, e.g. to share the box with a Sunshine fork whose web UI owns that
|
|
rem port) brings the console with it. Imported AFTER the default so it wins; absent on an older host,
|
|
rem and then the default above stands.
|
|
set "ENDPOINTFILE=%PFDATA%\mgmt-endpoint"
|
|
if exist "%ENDPOINTFILE%" for /f "usebackq tokens=1* delims==" %%A in ("%ENDPOINTFILE%") do set "%%A=%%B"
|
|
rem No NODE_TLS_REJECT_UNAUTHORIZED: the host's self-signed cert is accepted only for the loopback
|
|
rem proxy hop, scoped inside the proxy code (Bun per-request TLS), not process-wide.
|
|
rem Serve HTTPS (HTTP/1.1 over TLS) with the host's identity cert; mark the session cookie Secure.
|
|
set "PUNKTFUNK_UI_TLS_CERT=%CERTFILE%"
|
|
set "PUNKTFUNK_UI_TLS_KEY=%KEYFILE%"
|
|
set "PUNKTFUNK_UI_SECURE=1"
|
|
|
|
rem Bun runtime (override BUN if yours lives elsewhere / is on PATH as just `bun`).
|
|
if not defined BUN set "BUN=bun.exe"
|
|
set "SERVER=%~dp0.output\server\index.mjs"
|
|
if not exist "%SERVER%" (
|
|
echo [punktfunk-web] built server missing at "%SERVER%" - build it: cd web ^&^& bun run build
|
|
exit /b 1
|
|
)
|
|
"%BUN%" "%SERVER%"
|