Commit Graph
13 Commits
Author SHA1 Message Date
gregandClaude Opus 5.5 0c868f7bac fix(worker): start with a repository-only token
Validate game templates / validate (push) Successful in 20s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
The start-up check read the token's account with GET /user, which needs the
read:user scope. A token with only repository scope, which is all the worker
needs, got 403 and the worker exited in a restart loop. On 403 it now
names the commit author from BOT_NAME (default gbr-bot) and still checks
push access on the games repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 17:18:22 -04:00
gregandClaude Opus 5.5 f3a2a1f099 fix(worker): commit as the token's account and check it can push
Validate game templates / validate (push) Successful in 21s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
The worker committed as a hard-coded "gbr-bot", and a token without Write
access only showed up when a build finished and its push failed. On start it
now reads the token's account (GET /user) for the commit author, and
refuses to run if that account can't push to the games repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 16:28:54 -04:00
gregandClaude Opus 5.5 5dfc0cc794 fix(builder): drafts don't use CI secrets, and a missing one is fed back
Validate game templates / validate (push) Successful in 20s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
The second Valheim build stopped before its boot test: told that
test.yaml's password "looks like a credential; map it under 'secrets'",
the model mapped it to a CI secret nobody created, and boottest-payload's
missing-secret exit ended the build.

- The validator now says to remove a test password first (boot tests fill
  password settings with a throwaway value); secrets only when the server
  can't start without a real one.
- Drafts with test.yaml 'secrets' fail the draft checks.
- build turns boottest-payload's missing-secret exit into feedback for the
  model instead of an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 15:52:18 -04:00
gregandClaude Opus 5.5 c2b22d3955 feat(draft): catch split text settings and owner-editable game ports
Validate game templates / validate (push) Successful in 19s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
Two problems a draft can boot fine with but break once an owner changes a
setting, both in the builder's Valheim draft:

- splitSettings: text settings used unquoted on the command line, directly
  or through ARGS="-name ${SERVER_NAME}"; ./server $ARGS, so "GBRHosting -
  My Server" reaches the game as several arguments. Suggests quoting or a
  bash array.
- portSettings: game-port settings whose default isn't in defaultPorts, or
  that owners can change although nodes always publish the same container
  port. Internal ports (RCON, REST) and {PUBLIC_PORT_n} values are left out.

Both run on drafts only; AUTHORING.md gets the matching rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 15:43:27 -04:00
gregandClaude Opus 5.5 c75190d8c4 feat(builder): research, build and a worker for the AI builder
Validate game templates / validate (push) Successful in 19s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
- research: searches SearXNG, reads the best pages through the reader, has the
  model list the server's variants, then checks every Docker image and Steam
  app it named for real before an admin sees it.
- build: first boot of the variant's images (skipping ones that need root),
  a draft by the model, then the draft deployed with the node-agent's
  BootTest like CI does; crashes, error lines and saves outside /server go
  back to the model, three boots at most.
- worker: polls the panel's builder queue (outbound only), runs research or
  build in a fresh clone, streams the output as the job log, and opens the
  result as a pull request from the bot account.
- Dockerfile.builder, a workflow publishing gbr-builder:latest, and
  BUILDER.md. Everything about where it runs comes from environment
  variables; deployment files live outside this public repo.

draft now keeps its conversation in a drafter, so build can send boot
failures back to the same model session. The boot-test runner comment no
longer names its VM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:51:29 -04:00
gregandClaude Opus 5.5 da4ffc86d2 feat: draft new game templates with an AI model
Validate game templates / validate (push) Successful in 9m35s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
`gbrgames draft -name <game> -image <image> [-steam-app ID]
[-first-boot report.json]` has a model write games/<id>/game.yaml and
test.yaml, then checks them like any template and sends problems back
for up to three fix rounds. Ollama (default qwen3.8:27b, OLLAMA_URL) or
Gemini (GEMINI_API_KEY).

The model gets AUTHORING.md (new: the house rules, from how nodes really
run servers and today's bugs: x-generate passwords, no published RCON
ports, containerUser, heap below the limit, env var naming, ready lines),
the inspect-image facts, the first-boot report and the two smallest
templates as examples. With Ollama the answer is forced into the
template schema, tightened for drafts so ports, install config, settings
and their descriptions can't be left out or null.

On top of validation and the image checks, drafts must:
- be complete: player ports, >=3 settings each described, real memory,
  a readyPattern or settleSec
- name settings so they reach the container as variables the image reads
  (ServerPassword -> SERVER_PASSWORD when the image reads SERVER_PASS)
- not leave files first boot saw outside /server (lost on every start)
A first boot showing the image dies within seconds on permission errors
(it needs root) stops the draft before any model call. A missing
readyPattern is filled from first boot's verified suggestion.

Valheim, which we have no template for: lloesche/valheim-server was
rejected as root-only; via SteamCMD (app 896660) qwen3.8:27b on a local
3090 Ti wrote a passing template in two rounds (~1 min). It is about
70% there: it chose "--save-dir /server", which Valheim doesn't have
(-savedir), and missed -crossplay and 2457/udp. The save check is a text
check; booting the draft itself is the next step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 03:01:22 -04:00
gregandClaude Opus 5.5 c9d9cd6ff5 feat: first-boot records what a server does with no settings
Validate game templates / validate (push) Successful in 9m34s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
`gbrgames first-boot -game <id>` (or -image for a game with no template)
starts the server once like the node-agent does (same volumes, user,
SteamCMD install and startup prefix) but with none of the template's
settings and no restart policy, in the isolated gbr-boottest network.
It watches the console until the server exits, goes quiet or hits -max,
stops it gracefully (many servers write their settings on shutdown) and
records:
- the console with timings, plus ready and error lines; the last strong
  ready line before the stop becomes a readyPattern / readyExample pair
- every file created; config files are copied out and parsed into
  settings with their defaults (INI, properties, JSON, YAML, Unreal
  OptionSettings=(...) lists); log files are scanned for ready lines too
- files written outside the volumes, which a recreated container loses

Minecraft: ready line `Done \([0-9.]+s\)! For help, type "help"` and 76
settings (69 from server.properties) found with no template input. ARK:
showed its image retries nothing when SteamCMD fails with "Missing
configuration" and starts a server that was never installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 02:18:21 -04:00
gregandClaude Opus 5.5 40e7372dab feat: inspect-image reads what a game's image needs
Validate game templates / validate (push) Successful in 9m33s
Validate game templates / boot-test (push) Skipped
Validate game templates / publish (push) Skipped
`gbrgames inspect-image -game <id>` pulls the image and reads, without
starting the game (probe runs with --network none and bypasses the
entrypoint): its user, accounts, home folder owners and modes, tools
(java, steamcmd, proton...), startup scripts and the variables they read.

It then checks the template against those facts:
- an image built around its own user (a locked home owned by another uid,
  or a declared USER) needs a matching containerUser
- the startup command must read settings under the names the node gives
  them (the agent's toUpperSnakeCase), and must not read unset variables
  that have no default

On the template from the first commit it reports both ARK bugs found by
boot tests today (uid 25000; ${RCON_PORT} vs RCONPORT); the current five
templates pass. Boot tests now run it first, so such templates fail in
seconds instead of after a boot. -json prints the facts for tooling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 01:42:55 -04:00
gregandClaude Opus 5.5 2ad445ffdd fix(ark): run as the image's own user; honour custom RCON ports
Validate game templates / validate (push) Successful in 9m32s
Validate game templates / boot-test (push) Failing after 11m8s
Validate game templates / publish (push) Skipped
ARK's image is built around user gameserver (uid 25000) and locks
/home/gameserver to it, so under the node's default 1000:1000 the
startup script got "Permission denied" and the server restart-looped,
on real nodes as well as in boot tests. Set containerUser 25000:25000
(needs node-agent and panel support for containerUser).

The startup command read ${RCON_PORT}, but the node passes the RCONPort
setting as RCONPORT, so custom RCON ports were ignored for 27020.

Boot-tested in the Linux agent image: up 30 minutes with no restart.
The test now waits 10 minutes, covering the first ~13 GB download.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 22:17:03 -04:00
gregandClaude Opus 5.5 944b5fdd3e fix(boot-test): never overwrite non-password settings
Validate game templates / validate (push) Successful in 9m32s
Validate game templates / boot-test (push) Failing after 11m5s
Validate game templates / publish (push) Skipped
The payload builder filled anything matching the validator's broad
credential pattern that wasn't a non-empty string, so RCON_PORT,
ENABLE_RCON and ARK's RCONEnabled/RCONPort became 'boot-123456' in the
first runner run. Only fill keys named like passwords (or x-generate),
and only when missing or an empty string. Adds a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 21:33:29 -04:00
gregandClaude Opus 5.5 e9ff989246 ci: boot-test changed games before publishing
Validate game templates / validate (push) Successful in 9m32s
Validate game templates / publish (push) Canceled after 0s
Validate game templates / boot-test (push) Canceled after 5m15s
Only games whose folder changed are boot-tested (against the previous
main commit, or against main on branches; manual runs pick games). Each
one is deployed by the node-agent's real deploy code on a dedicated
game-test runner, in a network that can reach the internet but not the
LAN. Publishing to the panel runs only if they all booted.

- boottest-payload builds the DEPLOY_SERVER message the panel would send
- readyPattern/failPatterns in game.yaml; readyExample in test.yaml is
  checked against the pattern during validation
- secrets in test.yaml come from CI; a game missing one is skipped
- Minecraft gets a ready pattern; Dragonwilds needs DRAGONWILDS_OWNER_ID
- RUNNER.md + scripts/runner: runner, isolated network, systemd unit

Also fixes newline values ("\n" separators/footers) that yaml.v3 wrote
as "" on import, which would have broken ARK and Dragonwilds config
files once synced, and adds a round-trip test for the importer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 17:49:19 -04:00
gregandClaude Opus 5.5 5fb7736be2 ci: publish templates to the control panel on main
Validate game templates / validate (push) Successful in 9m31s
Adds `gbrgames export`, which builds the games_published payload from
every game.yaml, and a CI step that posts it to the panel webhook after
validation on main. Unlike the node-agent notify, a failed publish fails
the run so stale templates in the panel never go unnoticed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 17:12:50 -04:00
gregandClaude Opus 5.5 822b44e2e5 feat: game templates, schemas and validator
Validate game templates / validate (push) Successful in 10m6s
Public game templates for GBR Hosting, one games/<id>/game.yaml per game,
imported from the panel. A Go tool validates them against JSON Schemas and
checks for credentials, private addresses and consents that default to
accepted; CI runs it on every push.

Admin/RCON passwords are no longer shared defaults: they are blank with
x-generate so the panel creates one per server, and Palworld/ARK no longer
publish their RCON/REST ports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:21 -04:00