Skip to content

Commit 2520cbb

Browse files
committed
Align is_local_dolt_host with the is_remote 127.0.0.1 contract
The shared is_local_dolt_host classifier treated the whole 127.* block as the local managed server, but its comment claims to mirror the sibling gc-beads-bd is_remote/restart/recover scripts — all of which classify only 127.0.0.1 as local. A GC_DOLT_HOST=127.0.0.2 endpoint would read as local for health/status/logs but remote for restart/recover. Narrow 127.* to 127.0.0.1 so the classifier matches the three sibling scripts and the comment is accurate, and add a health test pinning that a non-.1 loopback host (127.0.0.2) classifies as external, so a future re-broadening is caught.
1 parent adbfee4 commit 2520cbb

2 files changed

Lines changed: 69 additions & 1 deletion

File tree

examples/bd/dolt/assets/scripts/runtime.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ GC_BEADS_BD_SCRIPT="$GC_CITY_PATH/.gc/scripts/gc-beads-bd.sh"
4343
# gc-beads-bd `is_remote` classification (gastownhall/gascity su-deol8).
4444
is_local_dolt_host() {
4545
case "$1" in
46-
""|0.0.0.0|127.*|localhost|::1|"[::1]") return 0 ;;
46+
""|127.0.0.1|0.0.0.0|localhost|::1|"[::1]") return 0 ;;
4747
*) return 1 ;;
4848
esac
4949
}

examples/bd/dolt/health_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,74 @@ exit 1
12881288
}
12891289
}
12901290

1291+
// TestHealthScriptNonOneLoopbackHostIsExternal pins the host-classification
1292+
// contract for a non-.1 loopback address (127.0.0.2): it must be treated as an
1293+
// external endpoint (server.external=true), matching the sibling gc-beads-bd
1294+
// `is_remote`/`restart`/`recover` scripts, which classify only 127.0.0.1 as the
1295+
// local managed server. A future re-broadening of is_local_dolt_host back to the
1296+
// whole 127.* block — which would split the health/status/logs commands from the
1297+
// restart/recover contract — is caught here (su-deol8).
1298+
func TestHealthScriptNonOneLoopbackHostIsExternal(t *testing.T) {
1299+
cityPath := t.TempDir()
1300+
if err := os.MkdirAll(filepath.Join(cityPath, ".beads"), 0o755); err != nil {
1301+
t.Fatal(err)
1302+
}
1303+
if err := os.WriteFile(filepath.Join(cityPath, ".beads", "metadata.json"),
1304+
[]byte(`{"database":"dolt","backend":"dolt","dolt_database":"city"}`), 0o644); err != nil {
1305+
t.Fatalf("write metadata: %v", err)
1306+
}
1307+
1308+
root := repoRoot(t)
1309+
fakeBin := t.TempDir()
1310+
emptyDataDir := t.TempDir()
1311+
1312+
// Local managed precheck must fail so classification alone decides the path;
1313+
// the smart fake answers the external SELECT 1 / SHOW DATABASES probes.
1314+
writeExecutable(t, filepath.Join(fakeBin, "gc"), "#!/bin/sh\nexit 1\n")
1315+
writeExecutable(t, filepath.Join(fakeBin, "lsof"), "#!/bin/sh\nexit 1\n")
1316+
writeExecutable(t, filepath.Join(fakeBin, "nc"), "#!/bin/sh\nexit 1\n")
1317+
writeExecutable(t, filepath.Join(fakeBin, "dolt"), smartFakeDoltForExternal)
1318+
1319+
cmd := exec.Command("sh", filepath.Join(root, healthScript), "--json")
1320+
cmd.Env = append(filteredEnv("GC_CITY_PATH", "GC_PACK_DIR", "GC_DOLT_HOST", "GC_DOLT_PORT",
1321+
"GC_DOLT_USER", "GC_DOLT_PASSWORD", "GC_HEALTH_SKIP_ZOMBIE_SCAN", "PATH", "GC_DOLT_DATA_DIR"),
1322+
"GC_CITY_PATH="+cityPath,
1323+
"GC_PACK_DIR="+root,
1324+
"GC_DOLT_DATA_DIR="+emptyDataDir,
1325+
"GC_DOLT_HOST=127.0.0.2",
1326+
"GC_DOLT_PORT=3306",
1327+
"GC_DOLT_USER=root",
1328+
"GC_DOLT_PASSWORD=",
1329+
"GC_HEALTH_SKIP_ZOMBIE_SCAN=1",
1330+
"PATH="+fakeBin+string(os.PathListSeparator)+os.Getenv("PATH"),
1331+
)
1332+
1333+
out, err := cmd.CombinedOutput()
1334+
if err != nil {
1335+
t.Fatalf("health.sh --json failed: %v\n%s", err, out)
1336+
}
1337+
1338+
var report struct {
1339+
Server struct {
1340+
Running bool `json:"running"`
1341+
Reachable bool `json:"reachable"`
1342+
External bool `json:"external"`
1343+
} `json:"server"`
1344+
}
1345+
if err := json.Unmarshal(out, &report); err != nil {
1346+
t.Fatalf("health.sh --json returned invalid JSON: %v\n%s", err, out)
1347+
}
1348+
if !report.Server.External {
1349+
t.Fatalf("server.external = false for 127.0.0.2; a non-.1 loopback host must classify as external to match the is_remote contract\n%s", out)
1350+
}
1351+
if report.Server.Running {
1352+
t.Fatalf("server.running = true for 127.0.0.2; the local-process signal must stay false for a non-local host\n%s", out)
1353+
}
1354+
if !report.Server.Reachable {
1355+
t.Fatalf("server.reachable = false; the fake external endpoint answers SELECT 1\n%s", out)
1356+
}
1357+
}
1358+
12911359
// TestHealthScriptZombieScanExcludesRigLocalServers verifies that
12921360
// Dolt processes on rig-configured ports are not flagged as zombies.
12931361
// Regression guard for the bug where deacon patrol killed rig-local

0 commit comments

Comments
 (0)