Declare the pacman keeper and its bus shapes, so upgrades run as rounds on the bus instead of a weekly timer on every node at once (issue 1841/S1, with 1840/S5's manifest)

The keeper process runs under its own account with a bus account of its own,
keeps the six states and emits the nine events of ADR 0507 and ADR 0508; its
config (upgrade-order, record-days, round-start-minutes) lands in its config
file and restarts it. shapes.go fixes every key's value and event body as the
interface the keeper and the verbs share. The weekly timer and its service are
dropped, which the node-engine removes.
This commit is contained in:
2026-10-22 14:23:22 +02:00
parent 7bf63b0ac5
commit eb717cc514
10 changed files with 994 additions and 93 deletions
+110 -18
View File
@@ -11,6 +11,57 @@
"scope": "node"
}
],
"reads": [
"mesh-controller.declared-packages"
],
"config": {
"upgrade-order": {
"type": "list",
"description": "The nodes in the order they upgrade, each by its name: the first opens each week's round on Saturday at 04:00 local time, and each node upgrades after the one before it passed its after-upgrade check (novox/hq ADR 0508 §5). Empty: no round starts, and every node's health says why. Falls back to the mesh-level key of the same name.",
"trusted": true,
"predefined": "upgrade-order",
"default": []
},
"record-days": {
"type": "number",
"description": "How many days a package record taken before an upgrade is kept on the bus before it is deleted (novox/hq ADR 0508 §2); a rollback can return only to a record still kept.",
"minimum": 1,
"trusted": false,
"default": 180
},
"round-start-minutes": {
"type": "number",
"description": "How many minutes a node whose turn in the round came may take to start its upgrade before the round is said to stand still, in that node's and the waiting nodes' health (novox/hq ADR 0508 §6).",
"minimum": 1,
"trusted": false,
"default": 120
}
},
"own-secrets": {
"broker-keeper": {
"path": "${dir:state}/broker-keeper.secret",
"owner": "pacman-keeper"
}
},
"state": [
"installed",
"updates",
"runs",
"records",
"rounds",
"asks"
],
"emits": [
"package.changed",
"upgrade.recorded",
"upgrade.kernel-held",
"upgrade.started",
"upgrade.finished",
"upgrade.failed",
"upgrade.checked",
"rollback.started",
"rollback.finished"
],
"tools": [
"pacman_search",
"pacman_info",
@@ -80,29 +131,70 @@
}
},
{
"id": "upgrade-service",
"type": "file",
"path": "/etc/systemd/system/mesh-pacman-weekly-upgrade.service",
"mode": "0644",
"template": "files/mesh-pacman-weekly-upgrade.service"
"id": "keeper-account",
"type": "user",
"name": "pacman-keeper",
"shell": "/usr/bin/nologin"
},
{
"id": "upgrade-timer",
"type": "file",
"path": "/etc/systemd/system/mesh-pacman-weekly-upgrade.timer",
"mode": "0644",
"template": "files/mesh-pacman-weekly-upgrade.timer"
"id": "state",
"type": "directory",
"mode": "0711",
"place": ".",
"unknown": "program"
},
{
"id": "weekly-upgrade",
"type": "service",
"unit": "mesh-pacman-weekly-upgrade.timer",
"state": "running",
"boot": "enabled",
"restart-on": [
"upgrade-service",
"upgrade-timer"
"id": "keeper-config",
"type": "file",
"path": "${dir:state}/keeper.json",
"mode": "0644",
"takes-config": [
"upgrade-order",
"record-days",
"round-start-minutes"
],
"merge": "json",
"template": "files/keeper.json",
"trusted": true
},
{
"id": "keeper",
"type": "process",
"name": "pacman-keeper",
"artifact": "tools",
"run": [
"./pacman-tools",
"keeper"
],
"user": "pacman-keeper",
"env": {
"PACMAN_KEEPER_BROKER": "${dir:state}/broker-keeper.secret",
"PACMAN_KEEPER_CONFIG": "${dir:state}/keeper.json"
},
"restart-on": [
"keeper-config"
],
"bus": {
"state": [
"installed",
"updates",
"runs",
"records",
"rounds",
"asks"
],
"emits": [
"package.changed",
"upgrade.recorded",
"upgrade.kernel-held",
"upgrade.started",
"upgrade.finished",
"upgrade.failed",
"upgrade.checked",
"rollback.started",
"rollback.finished"
]
},
"health": {
"kind": "tool",
"tool": "pacman_upgrade_health",