fix(builder): boot drafts with the settings a new server really gets #18

Merged
greg merged 1 commits from fix/builder-boot-as-deployed into main 2026-10-26 01:31:14 +00:00
3 changed files with 25 additions and 4 deletions
Showing only changes of commit 72a4280d44 - Show all commits

No files matched your search

+5 -2
View File
@@ -32,6 +32,8 @@ func runBootTestPayload(args []string) error {
fs := flag.NewFlagSet("boottest-payload", flag.ExitOnError) fs := flag.NewFlagSet("boottest-payload", flag.ExitOnError)
gamesDir := fs.String("games", "games", "directory holding one folder per game") gamesDir := fs.String("games", "games", "directory holding one folder per game")
out := fs.String("out", "", "file to write (default stdout)") out := fs.String("out", "", "file to write (default stdout)")
asDeployed := fs.Bool("as-deployed", false, "settings exactly as a new server gets them: only x-generate fields filled, "+
"no throwaway passwords (the AI builder boots drafts this way)")
fs.Parse(args) fs.Parse(args)
if fs.NArg() != 1 { if fs.NArg() != 1 {
return errors.New("boottest-payload needs a game id") return errors.New("boottest-payload needs a game id")
@@ -72,10 +74,11 @@ func runBootTestPayload(args []string) error {
} }
} }
// Like the panel fills blank x-generate fields on deploy; other blank passwords (which an owner // Like the panel fills blank x-generate fields on deploy; other blank passwords (which an owner
// would type in, and some games refuse to start without) get a throwaway value too // would type in, and some games refuse to start without) get a throwaway value too, except
// -as-deployed: a draft must start with exactly what a new server gets
for key, p := range schemaProperties(g) { for key, p := range schemaProperties(g) {
prop, _ := p.(map[string]any) prop, _ := p.(map[string]any)
if prop["x-generate"] == nil && !passwordKey.MatchString(key) { if prop["x-generate"] == nil && (*asDeployed || !passwordKey.MatchString(key)) {
continue continue
} }
// Only missing or empty text: ports, booleans and other values are never touched // Only missing or empty text: ports, booleans and other values are never touched
+16
View File
@@ -63,4 +63,20 @@ configSchema:
if c["MOTD"] != "gbr-boot-test on 25565" { if c["MOTD"] != "gbr-boot-test on 25565" {
t.Errorf("placeholders not resolved: %v", c["MOTD"]) t.Errorf("placeholders not resolved: %v", c["MOTD"])
} }
// As a new server gets it (what the AI builder boots): only x-generate is filled, a blank join password stays blank
if err := runBootTestPayload([]string{"-as-deployed", "-games", filepath.Join(dir, "games"), "-out", out, "demo"}); err != nil {
t.Fatal(err)
}
raw, _ = os.ReadFile(out)
payload.GameConfig = nil
if err := json.Unmarshal(raw, &payload); err != nil {
t.Fatal(err)
}
if s, _ := payload.GameConfig["RCON_PASSWORD"].(string); !strings.HasPrefix(s, "boot-") {
t.Errorf("as deployed: x-generate RCON_PASSWORD not filled: %v", payload.GameConfig["RCON_PASSWORD"])
}
if payload.GameConfig["ServerPassword"] != "" {
t.Errorf("as deployed: ServerPassword should stay empty, got %v", payload.GameConfig["ServerPassword"])
}
} }
+4 -2
View File
@@ -240,7 +240,7 @@ func bootCheck(gamesDir, id, agentImage string, wantOutside bool) (problems, ver
// and the next deploy under the same name would trip over them // and the next deploy under the same name would trip over them
runCmd("docker", "rm", "-f", "boottest-"+id) runCmd("docker", "rm", "-f", "boottest-"+id)
runCmd("docker", "volume", "rm", "-f", "boottest-"+id+"-data") runCmd("docker", "volume", "rm", "-f", "boottest-"+id+"-data")
payloadCmd := exec.Command(self, "boottest-payload", "-games", gamesDir, id) payloadCmd := exec.Command(self, "boottest-payload", "-as-deployed", "-games", gamesDir, id)
var stderr bytes.Buffer var stderr bytes.Buffer
payloadCmd.Stderr = &stderr payloadCmd.Stderr = &stderr
payload, err := payloadCmd.Output() payload, err := payloadCmd.Output()
@@ -310,7 +310,9 @@ func bootFailure(output string) string {
lines = append(lines[:1], lines[len(lines)-59:]...) lines = append(lines[:1], lines[len(lines)-59:]...)
} }
return "booting your template with the node-agent (the real deploy code) failed: " + verdict + return "booting your template with the node-agent (the real deploy code) failed: " + verdict +
". Find the cause in the server's output below and fix the template (startup command, settings, " + ". It was started with your defaults exactly as a new server gets them: settings left empty stay empty " +
"(only x-generate fields are filled), so a server that needs a value must get it from a default or " +
"x-generate. Find the cause in the server's output below and fix the template (startup command, settings, " +
"ready pattern, memory):\n" + strings.Join(lines, "\n") "ready pattern, memory):\n" + strings.Join(lines, "\n")
} }