15 Commits
Author SHA1 Message Date
Claude bec9228c55 Back up existing files before every service overwrites them
Confirmed live: install_frigate()'s fresh-install path overwrote a
working, hand-crafted docker-compose.yml (Frigate + mosquitto +
frigate-notify) with zero backup, because that file's shape didn't match
what frigate.sh's own "existing install" detection knew how to recognize.
Every service's own detection is a judgment call about what counts as
"already installed" and can miss a real setup built outside this repo's
conventions.

lib/common.sh gains backup_if_exists(FILE) — copies FILE to
FILE.bak.<timestamp> if it exists, no-ops otherwise (including DRY_RUN).
Applied before every service's own `cat > docker-compose.yml`/`cat > .env`
write across all 60 services that do one (115 call sites), plus a matching
standalone-mode stub added to every service's own bootstrap block, same
convention already used for port_in_use/find_free_port. This doesn't
replace a service's own update/fresh-reinstall detection — it's the safety
net underneath it, so a wrong detection costs a .bak file to restore from
instead of the original silently disappearing.

Also fixes the actual gap that surfaced this: services/frigate.sh's
Authelia offer only checked for Authelia installed locally on Frigate's
own box, which is never true for a dedicated NVR box with no local Caddy
either (the common shape — Caddy lives elsewhere, snippet-generation mode
already handles that). Now offers Authelia protection unconditionally and,
when Authelia isn't local, asks whether it lives on the same machine as
Caddy (still "import authelia", since that's local to wherever Caddy ends
up) or on a genuinely separate third machine (the explicit
header-pinned forward_auth form, per CLAUDE.md's "forward_auth to a remote
Authelia" note, needed because a bare authelia:9091 shortcut only works
one hop).
2026-08-26 17:26:17 +00:00
Claude 71ef582873 kyber-server: fix Wine crash + map rotation format
Three root-cause fixes found by reading the Docker image source:

1. Wine/Proton page fault: Docker's default seccomp profile blocks
   system calls that Wine Proton GE requires. Fix: security_opt:
   seccomp=unconfined + shm_size: 256m (Xvfb needs /dev/shm for
   MIT-SHM extension; 64 MB default is too small).
   Added network_mode: host for game traffic (dynamic UDP ports).

2. KYBER_MAP_ROTATION exit 64: the Kyber CLI decodes base64 and
   parses newline-separated "MODE;MAP_PATH" lines, not JSON objects.
   Our JSON [{map:...,mode:...}] format split on semicolons into one
   field → ExitCode.usage (64). Fixed builder to emit MODE;MAP_PATH\n
   lines and updated .env comment + README example.

3. GPU passthrough removed: Proton GE includes DXVK which crashes
   headlessly when a GPU is passed through (no Vulkan display). The
   server needs no GPU; removing passthrough is the correct fix.

Also: install libgamemode0:i386 on the host (Wine/Proton dep),
add alphanumeric-password warning (special chars → INVALID_PASSWORD).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014be1aK9G8CY2msho5LjxR4
2026-06-26 15:26:55 +00:00
Claude f2d662a680 kyber-server: add interactive map rotation selection
Shows a numbered menu of 12 known SWBF2 maps (Galactic Assault, Planetary
Battles, Starfighter Assault) during install. Selected maps are encoded as
base64 JSON and written to KYBER_MAP_ROTATION in .env.

Map IDs decoded from maprotation.hive binary: Geonosis, Kamino, Endor,
Tatooine, Death Star II, Starkiller Base, Crait, Hoth, Fondor (space).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 06:00:00 +00:00
Claude 1087b59424 Fix write_readme missing from standalone bootstrap fallback
When run directly without setup.sh, write_readme is not defined.
Add a minimal implementation to the else block of both kyber-server.sh
and sunshine.sh so standalone runs no longer fail with command not found.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 05:07:11 +00:00
Claude 7d3cd46d9d kyber-server: offer to set up kyber-launcher at end of install
If the kyber bin symlink and desktop entry are not present, prompt to
set up the launcher. Calls install_kyber_launcher directly if already
loaded (wizard), or sources kyber-launcher.sh when run standalone.
Skips the prompt on rerun if the launcher is already installed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:55:36 +00:00
Claude 8b13928cc0 kyber-server: auto-launch AppImage for EA login if no token found
If auth.toml has no token, launch the Kyber AppImage as the actual user
(with DISPLAY/XAUTHORITY passed through), prompt the user to log in via
the EA Account button, then re-read auth.toml once they close Kyber.
Falls back to manual token paste if auth.toml still has nothing.
Skips the AppImage entirely on rerun when a token is already cached.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:51:17 +00:00
Claude 1b392472bc kyber-server: read EA token from auth.toml instead of browser flow
Running kyber_cli get_token under sudo opens a broken browser OAuth flow.
Instead, read the token directly from ~/.local/share/maxima/auth.toml which
Kyber writes after a normal GUI login. If missing, show clear instructions
to run the AppImage as yourself first, then re-run the installer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:44:50 +00:00
Claude 87384980da kyber-server: mount SWBF2 folder read-write not read-only
The Kyber server patches vivoxsdk.dll into the game folder at startup.
Mounting it :ro caused a loop of cp permission errors. Removed the :ro flag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:32:31 +00:00
Claude 472a8fb72b kyber-server: fresh start option and special char safe .env quoting
On rerun, if ~/.local/share/maxima exists, offer to wipe it so EA login
starts completely fresh (fixes stuck/broken auth states).

Single-quote all .env values so passwords and tokens containing $, !, &,
spaces, and other shell special characters are written safely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:30:22 +00:00
Claude 3654167596 kyber-server: find SWBF2 in custom Steam library locations
The standard Steam path search missed installs on secondary drives.
Now also reads libraryfolders.vdf to find all Steam library paths, then
falls back to a broad find across home/mnt/media. Wolf's copy is excluded
from the fallback search to prefer the native Steam install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 04:01:33 +00:00
Claude 5d209db925 kyber-server: offer to rsync SWBF2 files from remote machine
When SWBF2 is not found locally, prompt to rsync from a remote host.
Asks for remote host, username, and path (defaults to the standard Steam
Linux path). Files land in ~/docker/kyber-server/swbf2/ and that path is
used automatically. Falls back to manual local path entry if rsync declined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 02:50:42 +00:00
Claude 06d7e95dc0 kyber-server: prompt for manual SWBF2 path if not found via Steam
Instead of hard-failing, show an rsync example for copying game files from
another machine, then prompt for the path. Validates that starwarsbattlefrontii.exe
exists at the given location before continuing.

Also silence "register_service: command not found" in all three services when
run standalone (guard with command -v check).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 02:33:26 +00:00
Claude db9fafb626 Fix standalone bootstrap: move to after function definition
When run directly (sudo bash services/foo.sh), bash executes the bootstrap
block before reaching the install_* function definition below it, causing
"command not found". Moving the bootstrap to the end of each file ensures
the function is defined by the time the bootstrap calls it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-26 00:53:55 +00:00
Claude 0b4fcef02c kyber-server: add KYBER_SERVER_PASSWORD prompt and .env entry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-25 23:23:25 +00:00
Claude e1c3977d8d gaming: add kyber-server service (headless SWBF2 dedicated server via Docker)
- Auto-detects SWBF2 install path; loud error with install instructions if missing
- Downloads Kyber AppImage if not present, extracts kyber_cli, runs get_token
  (opens browser for EA OAuth — one-time step, token never expires)
- Prompts for EA credentials (written to .env, chmod 600) and server name
- Auto-detects GPU (NVIDIA/Intel/AMD) and adds appropriate passthrough config
- Writes docker-compose.yml + .env to ~/docker/kyber-server/
- Map rotation left blank by default with instructions in .env comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-25 23:20:02 +00:00