catalogue: give host-network containers the mesh's names too #16

Merged
jschoubben merged 1 commits from feat/usage-store into main 2026-09-07 02:08:19 +00:00
2 changed files with 18 additions and 13 deletions
Showing only changes of commit 958bef56c7 - Show all commits
+8 -7
View File
@@ -693,6 +693,14 @@ func here(r Resolution, requirement string) *Needed {
//
// Copied rather than edited in place: these maps come from a module's manifest, and mutating one
// would change what the catalogue holds for every other machine running that module.
//
// A host-network container gets the names too. It was once skipped, on the belief that it "shares
// the machine's hosts file already" — but it does not: `docker run --network host` still gives the
// container its own /etc/hosts (localhost and its own id only), so every `<node>.internal` name the
// mesh wrote for the machine is invisible inside it, and a client that dials one gets EAI_AGAIN. The
// remedy is the same `--add-host` every other container gets — the runtime accepts it with
// `--network host` (verified), and without it a host-network consumer cannot reach a provider by the
// `.internal` address the mesh hands it as `${bound:...:at}`.
func withMeshNames(resources []map[string]any, names map[string]string) []map[string]any {
out := make([]map[string]any, 0, len(resources))
for _, r := range resources {
@@ -700,13 +708,6 @@ func withMeshNames(resources []map[string]any, names map[string]string) []map[st
out = append(out, r)
continue
}
// A container on the machine's own network shares its hosts file already, and a runtime
// refuses to write one for it. Adding names there would be an argument the runtime
// rejects, which fails the whole container for something it did not need.
if network, on := r["network"].(string); on && network == "host" {
out = append(out, r)
continue
}
copied := map[string]any{}
for k, v := range r {
+10 -6
View File
@@ -73,18 +73,22 @@ func TestAContainersOwnNamesAreKept(t *testing.T) {
}
}
// A container on the machine's own network already shares its hosts file, and a runtime refuses
// to write one for it — so adding names there fails the whole container for something it did not
// need.
func TestAContainerOnTheMachinesNetworkIsLeftAlone(t *testing.T) {
// A container on the machine's own network gets the names too — it does NOT share the machine's
// hosts file. `docker run --network host` still gives the container its own /etc/hosts (localhost
// and its own id only), so every `<node>.internal` name the mesh wrote is invisible inside it, and a
// client that dials one gets EAI_AGAIN. It gets the same `--add-host` entries every other container
// gets (the runtime accepts them with `--network host`), so a host-network consumer can reach a
// provider by the `.internal` address the mesh hands it.
func TestAContainerOnTheMachinesNetworkIsGivenTheNamesToo(t *testing.T) {
got := containersOf(t, Resolution{Node: "anchor", Modules: []Manifest{{
Module: "control",
Resources: []map[string]any{{"id": "c", "type": "container", "name": "c",
"image": "registry.example/c@sha256:" + strings.Repeat("a", 64), "network": "host"}},
}}}, Rendering{Names: map[string]string{"anchor.internal": "10.42.0.1"}})
if len(namesOf(got[0])) != 0 {
t.Fatalf("a host-networked container was given names a runtime will refuse: %v", got[0])
given := namesOf(got[0])
if len(given) != 1 || given[0] != "anchor.internal:10.42.0.1" {
t.Fatalf("a host-networked container was not given the mesh's names: %v", got[0])
}
}