The rule was right about data and wrong about everything else. The builder mounts the container runtime's socket, which is not its data, does not belong to it, and must not be declared as one of its directories — and the check refused the builder's own manifest. Caught by the lab, though not honestly: the run was already going when this went in, so the builder binary was rebuilt mid-run with the check compiled into it and the failure was mine, not the mesh's. Confirmed against the manifest directly rather than inferred from the log. What it was protecting is real and stands — the fourteen mounts are all declared. But enforcing it needs a way to tell "the directory my data lives in" from "a machine facility I was granted", and the mesh has no vocabulary for the second. `capabilities` is the closest thing and does not name paths. That is a design decision, so it goes back to 04-ISSUES/026 rather than being invented here to make a check pass. The check that every real manifest still parses is kept. It costs nothing and it is how the next attempt at this finds out sooner.
61 lines
2.5 KiB
Go
61 lines
2.5 KiB
Go
package catalogue
|
|
|
|
import "testing"
|
|
|
|
// A module with nothing that publishes binds what it binds, and the mesh may not move it.
|
|
//
|
|
// This is the case that made novox/hq 04-ISSUES/028's fix wrong on its first pass: a port was
|
|
// assigned to every module that declared one, so a service listening directly had the rule set
|
|
// opened on a number nothing was listening on, and its real port shut. The firewall reported
|
|
// success and blocked the service, which is the exact failure the mechanism exists to prevent.
|
|
func TestAPortNothingPublishesIsNotTheMeshsToMove(t *testing.T) {
|
|
m := Manifest{Module: "talker", Listens: []Listening{{Port: 9101, From: FromMesh}}}
|
|
at, mayAssign := m.MachineSide(9101)
|
|
if mayAssign {
|
|
t.Fatal("the mesh took a port it cannot move: nothing translates it, so assigning one " +
|
|
"opens the wrong number and leaves the service unreachable")
|
|
}
|
|
if at != 9101 {
|
|
t.Fatalf("a port nothing publishes reaches the machine where it binds, not at %d", at)
|
|
}
|
|
}
|
|
|
|
// A container publishing in short form is exactly the case the mesh may choose.
|
|
func TestAContainerPublishingShortIsTheMeshsToChoose(t *testing.T) {
|
|
m := Manifest{Module: "store", Resources: []map[string]any{
|
|
{"type": "container", "id": "server", "ports": []any{"5432"}},
|
|
}}
|
|
if _, mayAssign := m.MachineSide(5432); !mayAssign {
|
|
t.Fatal("a container's mapping is what translates a port, so this one is the mesh's to " +
|
|
"choose; refusing it puts every module back on a number it guessed")
|
|
}
|
|
}
|
|
|
|
// A manifest that wrote its own mapping already chose, and the machine side is the outer one.
|
|
func TestAMappingTheManifestWroteIsNotReassigned(t *testing.T) {
|
|
m := Manifest{Module: "mail", Resources: []map[string]any{
|
|
{"type": "container", "id": "front", "ports": []any{"7080:80"}},
|
|
}}
|
|
for _, named := range []int{7080, 80} {
|
|
at, mayAssign := m.MachineSide(named)
|
|
if mayAssign {
|
|
t.Fatalf("%d was reassigned though the manifest published it explicitly, which "+
|
|
"would open a rule on a port the container does not publish", named)
|
|
}
|
|
if at != 7080 {
|
|
t.Fatalf("naming %d gave %d; the machine side of 7080:80 is 7080", named, at)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A port some other container publishes is not this port.
|
|
func TestAPortNotInTheMappingIsNotFound(t *testing.T) {
|
|
m := Manifest{Module: "mail", Resources: []map[string]any{
|
|
{"type": "container", "id": "front", "ports": []any{"25", "7080:80"}},
|
|
}}
|
|
if at, mayAssign := m.MachineSide(993); mayAssign || at != 993 {
|
|
t.Fatalf("993 is published by nothing here, so it binds where it binds: got %d, %v",
|
|
at, mayAssign)
|
|
}
|
|
}
|