Feature 57 (config and provisioning): modules declare config and provisions, their files rendered from templates; synced with main (issues of feature 57, 874)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// The module's directory, where its manifest and its files/ are.
|
||||
const moduleDir = "../.."
|
||||
|
||||
// templateText is the text a file resource places on the machine: its template's, in the module's files/
|
||||
// (novox/hq ADR 0349 §2). A resource that names no template, or a template that is not there, fails the test.
|
||||
func templateText(t *testing.T, r map[string]any) string {
|
||||
t.Helper()
|
||||
name, _ := r["template"].(string)
|
||||
if name == "" {
|
||||
t.Fatalf("resource %v names no template", r["id"])
|
||||
}
|
||||
raw, err := os.ReadFile(filepath.Join(moduleDir, filepath.FromSlash(name)))
|
||||
if err != nil {
|
||||
t.Fatalf("resource %v names %s: %v", r["id"], name, err)
|
||||
}
|
||||
return string(raw)
|
||||
}
|
||||
|
||||
// No file resource carries its text inline: each names its template in files/, and the build packs files/
|
||||
// into the one archive the controller reads the templates back from (novox/hq ADR 0349 §2).
|
||||
func TestEveryFileTakesItsTextFromATemplate(t *testing.T) {
|
||||
raw, err := os.ReadFile(filepath.Join(moduleDir, "module.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m struct {
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Build struct {
|
||||
Artifacts []map[string]any `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, r := range m.Resources {
|
||||
if _, inline := r["content"]; inline {
|
||||
t.Errorf("resource %v keeps its text inline: keep it in files/ and name it as the template", r["id"])
|
||||
}
|
||||
if r["type"] == "file" {
|
||||
templateText(t, r)
|
||||
}
|
||||
}
|
||||
packs := 0
|
||||
for _, a := range m.Build.Artifacts {
|
||||
if a["kind"] == "archive" && a["from"] == "files" {
|
||||
packs++
|
||||
if a["name"] != "files" {
|
||||
t.Errorf("the templates archive is named %v, not files", a["name"])
|
||||
}
|
||||
}
|
||||
}
|
||||
if packs != 1 {
|
||||
t.Errorf("the build packs files/ into %d archives, not one", packs)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd kills the worst unit before the kernel's OOM killer freezes the machine: when swap is
|
||||
# 90 % used, or when a watched unit stalls on memory for 20 s above its limit.
|
||||
[OOM]
|
||||
SwapUsedLimit=90%
|
||||
DefaultMemoryPressureLimit=60%
|
||||
DefaultMemoryPressureDurationSec=20s
|
||||
@@ -0,0 +1,5 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd may act on swap exhaustion across the whole machine.
|
||||
[Slice]
|
||||
ManagedOOMSwap=kill
|
||||
@@ -0,0 +1,9 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# Swap-in reads one page, not eight: read-ahead exists to amortise a disk's seek, and compressed swap in
|
||||
# RAM has none — the speculation only costs decompression and memory.
|
||||
vm.page-cluster = 0
|
||||
#
|
||||
# vm.swappiness is deliberately left alone. The usual zram advice (150-180) holds only while the
|
||||
# compressed swap has room; once it is full, a higher swappiness moves pages to the disk swap, the thing
|
||||
# being avoided. Raise it only together with zram-size.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# systemd-oomd may kill the worst unit in a person's service manager when its memory pressure stays
|
||||
# above 80 % — instead of the kernel freezing the machine.
|
||||
[Service]
|
||||
ManagedOOMMemoryPressure=kill
|
||||
ManagedOOMMemoryPressureLimit=80%
|
||||
@@ -0,0 +1,11 @@
|
||||
# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.
|
||||
#
|
||||
# Compressed swap in RAM: fast, at a higher priority than any swap on disk, so it takes the everyday
|
||||
# pressure before anything spills to a disk. Half the RAM, at most 16 GiB, compressed with zstd.
|
||||
# The swap on disk, its size and whether one exists at all are the machine's, not this module's.
|
||||
#
|
||||
# Read by the generator at boot: a change applies at the next boot.
|
||||
[zram0]
|
||||
zram-size = min(ram / 2, 16384)
|
||||
compression-algorithm = zstd
|
||||
swap-priority = 100
|
||||
@@ -28,7 +28,7 @@
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/zram-generator.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# Compressed swap in RAM: fast, at a higher priority than any swap on disk, so it takes the everyday\n# pressure before anything spills to a disk. Half the RAM, at most 16 GiB, compressed with zstd.\n# The swap on disk, its size and whether one exists at all are the machine's, not this module's.\n#\n# Read by the generator at boot: a change applies at the next boot.\n[zram0]\nzram-size = min(ram / 2, 16384)\ncompression-algorithm = zstd\nswap-priority = 100\n"
|
||||
"template": "files/zram-generator.conf"
|
||||
},
|
||||
{
|
||||
"id": "sysctl-drop-ins",
|
||||
@@ -41,7 +41,7 @@
|
||||
"type": "file",
|
||||
"path": "/etc/sysctl.d/90-memory-pressure.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# Swap-in reads one page, not eight: read-ahead exists to amortise a disk's seek, and compressed swap in\n# RAM has none — the speculation only costs decompression and memory.\nvm.page-cluster = 0\n#\n# vm.swappiness is deliberately left alone. The usual zram advice (150-180) holds only while the\n# compressed swap has room; once it is full, a higher swappiness moves pages to the disk swap, the thing\n# being avoided. Raise it only together with zram-size.\n"
|
||||
"template": "files/sysctl.conf"
|
||||
},
|
||||
{
|
||||
"id": "sysctl",
|
||||
@@ -62,7 +62,7 @@
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/oomd.conf.d/memory-pressure.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd kills the worst unit before the kernel's OOM killer freezes the machine: when swap is\n# 90 % used, or when a watched unit stalls on memory for 20 s above its limit.\n[OOM]\nSwapUsedLimit=90%\nDefaultMemoryPressureLimit=60%\nDefaultMemoryPressureDurationSec=20s\n"
|
||||
"template": "files/oomd.conf"
|
||||
},
|
||||
{
|
||||
"id": "root-slice-drop-ins",
|
||||
@@ -75,7 +75,7 @@
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/-.slice.d/10-oomd.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd may act on swap exhaustion across the whole machine.\n[Slice]\nManagedOOMSwap=kill\n"
|
||||
"template": "files/root-slice.conf"
|
||||
},
|
||||
{
|
||||
"id": "user-manager-drop-ins",
|
||||
@@ -88,7 +88,7 @@
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/user@.service.d/10-oomd.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd may kill the worst unit in a person's service manager when its memory pressure stays\n# above 80 % — instead of the kernel freezing the machine.\n[Service]\nManagedOOMMemoryPressure=kill\nManagedOOMMemoryPressureLimit=80%\n"
|
||||
"template": "files/user-manager.conf"
|
||||
},
|
||||
{
|
||||
"id": "oomd",
|
||||
@@ -115,6 +115,11 @@
|
||||
"loads": [
|
||||
"memory-pressure"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "files",
|
||||
"kind": "archive",
|
||||
"from": "files"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user