Name the build slice without a dash so it sits beside user.slice, and restart it when its limits change (issue 1798)
mesh/merge-gate building on ace since 00:57
mesh/delivery superseded: a newer head of the same pull request
mesh/check failed: integration: github.com/novox/mesh-controller/internal/identity.TestACertificateChainsToTheMeshsOwnAuthority: authority_test.go:45:…

This commit is contained in:
2026-10-22 00:56:48 +02:00
parent 37119ea31f
commit b174d743c0
5 changed files with 29 additions and 12 deletions
+2 -2
View File
@@ -150,9 +150,9 @@ func TestAVolumeAlreadyGoneIsNoFailure(t *testing.T) {
func TestEveryContainerJoinsTheNodesBuildSlice(t *testing.T) { func TestEveryContainerJoinsTheNodesBuildSlice(t *testing.T) {
was := CgroupParent was := CgroupParent
defer func() { CgroupParent = was }() defer func() { CgroupParent = was }()
CgroupParent = "mesh-build.slice" CgroupParent = "meshbuild.slice"
got := LabelledArgs("docker", []string{"run", "--rm", "img", "sh"}, "build-1") got := LabelledArgs("docker", []string{"run", "--rm", "img", "sh"}, "build-1")
want := []string{"run", "--label", "mesh.build=build-1", "--cgroup-parent", "mesh-build.slice", "--rm", "img", "sh"} want := []string{"run", "--label", "mesh.build=build-1", "--cgroup-parent", "meshbuild.slice", "--rm", "img", "sh"}
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("1798/AC1: docker run became %v", got) t.Errorf("1798/AC1: docker run became %v", got)
} }
+1 -1
View File
@@ -6,4 +6,4 @@ MESH_NPM_TOKEN_FILE=/run/mesh/package-registry.secret
MESH_GENESIS_PACKAGE_REGISTRY=/run/mesh/genesis-package-registry.json MESH_GENESIS_PACKAGE_REGISTRY=/run/mesh/genesis-package-registry.json
MESH_WORKSPACE=${dir:workspace} MESH_WORKSPACE=${dir:workspace}
MESH_JUDGE_CACHE=${dir:judge-cache} MESH_JUDGE_CACHE=${dir:judge-cache}
MESH_BUILD_CGROUP_PARENT=mesh-build.slice MESH_BUILD_CGROUP_PARENT=meshbuild.slice
@@ -1,7 +1,7 @@
# Managed by the mesh (module build-agent). Replaced on every push; edit the module's settings instead. # Managed by the mesh (module build-agent). Replaced on every push; edit the module's settings instead.
# #
# Everything a build or check starts on this machine runs in this slice (novox/hq issue 1798): the build # Everything a build or check starts on this machine runs in this slice (novox/hq issue 1798): the build
# agent starts every container with --cgroup-parent=mesh-build.slice. The weights only bind while the machine # agent starts every container with --cgroup-parent=meshbuild.slice. The weights only bind while the machine
# is busy, so an idle machine still builds at full speed; the memory limits are the part that always binds. # is busy, so an idle machine still builds at full speed; the memory limits are the part that always binds.
[Slice] [Slice]
CPUWeight=${setting:cpu-weight} CPUWeight=${setting:cpu-weight}
+18 -4
View File
@@ -203,7 +203,7 @@ func TestTheBuildSliceCarriesTheMachinesLimits(t *testing.T) {
if err := json.Unmarshal(raw, &m); err != nil { if err := json.Unmarshal(raw, &m); err != nil {
t.Fatal(err) t.Fatal(err)
} }
slice, err := os.ReadFile("files/mesh-build.slice") slice, err := os.ReadFile("files/meshbuild.slice")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -217,17 +217,31 @@ func TestTheBuildSliceCarriesTheMachinesLimits(t *testing.T) {
} }
var placed, running bool var placed, running bool
for _, r := range read(t).Resources { for _, r := range read(t).Resources {
placed = placed || (r["type"] == "file" && r["path"] == "/etc/systemd/system/mesh-build.slice") placed = placed || (r["type"] == "file" && r["path"] == "/etc/systemd/system/meshbuild.slice")
running = running || (r["type"] == "service" && r["unit"] == "mesh-build.slice" && r["state"] == "running") running = running || (r["type"] == "service" && r["unit"] == "meshbuild.slice" && r["state"] == "running")
} }
if !placed || !running { if !placed || !running {
t.Errorf("1798/AC2: the slice must be placed (%v) and running (%v)", placed, running) t.Errorf("1798/AC2: the slice must be placed (%v) and running (%v)", placed, running)
} }
// 1798/AC3: a dash in a slice's name nests it in the slice named before the dash, and cgroup v2 weights only
// compare siblings, so the name has none and the slice sits at the top level beside user.slice.
for _, r := range read(t).Resources {
if r["type"] == "service" && r["unit"] == "meshbuild.slice" {
if strings.Contains(strings.TrimSuffix(r["unit"].(string), ".slice"), "-") {
t.Errorf("1798/AC3: slice name %v nests", r["unit"])
}
// 1798/AC4: a changed limit reaches systemd only if the unit restarts when its file changes.
restart, _ := r["restart-on"].([]any)
if len(restart) != 1 || restart[0] != "build-slice" {
t.Errorf("1798/AC4: the slice unit does not restart on its file: %v", restart)
}
}
}
env, err := os.ReadFile("files/build-agent.env") env, err := os.ReadFile("files/build-agent.env")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !strings.Contains(string(env), "MESH_BUILD_CGROUP_PARENT=mesh-build.slice") { if !strings.Contains(string(env), "MESH_BUILD_CGROUP_PARENT=meshbuild.slice") {
t.Error("1798/AC1: the agent is not told the slice's name") t.Error("1798/AC1: the agent is not told the slice's name")
} }
} }
+7 -4
View File
@@ -105,16 +105,19 @@
{ {
"id": "build-slice", "id": "build-slice",
"type": "file", "type": "file",
"path": "/etc/systemd/system/mesh-build.slice", "path": "/etc/systemd/system/meshbuild.slice",
"mode": "0644", "mode": "0644",
"trusted": false, "trusted": false,
"template": "files/mesh-build.slice" "template": "files/meshbuild.slice"
}, },
{ {
"id": "build-slice-unit", "id": "build-slice-unit",
"type": "service", "type": "service",
"unit": "mesh-build.slice", "unit": "meshbuild.slice",
"state": "running" "state": "running",
"restart-on": [
"build-slice"
]
}, },
{ {
"id": "agent-env", "id": "agent-env",