Each node's reflector ranked its own list on its own timer, and on 2026-10-31 one node's lagging first mirror left it a Node.js version behind the rest. The list is now the module's state mirrors, key list: the node that opens a week's round ranks it with the module's reflector options, keeps only mirrors whose last sync is no older than the newest found, and the round's key names the list's revision. Every keeper writes /etc/pacman.d/mirrorlist whole from the key through the root helper's new verb mirrorlist, when the key changes and when the file differs, and never writes an empty or unreadable list. reflector.timer is declared stopped and disabled, and reflector.conf saves nothing. pacman_mirrors answers the shared list, its ranker and age and whether this node's file matches; with refresh it asks this node's keeper to rank again, refused while a round runs, naming it. The round's integration test proves the opening write and both nodes' files. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
258 lines
5.9 KiB
JSON
258 lines
5.9 KiB
JSON
{
|
|
"module": "pacman",
|
|
"version": "1",
|
|
"capabilities": [
|
|
"package-manager",
|
|
"service-manager"
|
|
],
|
|
"claims": [
|
|
{
|
|
"name": "node-package-manager",
|
|
"scope": "node"
|
|
}
|
|
],
|
|
"reads": [
|
|
"mesh-host.packages",
|
|
"mesh-controller.declared-packages"
|
|
],
|
|
"uses": [
|
|
"operator-channel"
|
|
],
|
|
"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",
|
|
"mirrors"
|
|
],
|
|
"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",
|
|
"pacman_installed",
|
|
"pacman_packages",
|
|
"pacman_owns",
|
|
"pacman_files",
|
|
"pacman_updates",
|
|
"pacman_upgrade",
|
|
"pacman_upgrade_health",
|
|
"pacman_upgrades",
|
|
"pacman_rollback",
|
|
"pacman_round",
|
|
"pacman_orphans",
|
|
"pacman_remove_orphans",
|
|
"pacman_cache",
|
|
"pacman_history",
|
|
"pacman_mirrors",
|
|
"pacman_foreign",
|
|
"pacman_news",
|
|
"pacman_config"
|
|
],
|
|
"resources": [
|
|
{
|
|
"id": "package",
|
|
"type": "package",
|
|
"package": "pacman"
|
|
},
|
|
{
|
|
"id": "config",
|
|
"type": "file",
|
|
"path": "/etc/pacman.conf",
|
|
"mode": "0644",
|
|
"template": "files/pacman.conf"
|
|
},
|
|
{
|
|
"id": "contrib",
|
|
"type": "package",
|
|
"package": "pacman-contrib"
|
|
},
|
|
{
|
|
"id": "reflector",
|
|
"type": "package",
|
|
"package": "reflector"
|
|
},
|
|
{
|
|
"id": "mirrors",
|
|
"type": "file",
|
|
"path": "/etc/xdg/reflector/reflector.conf",
|
|
"mode": "0644",
|
|
"template": "files/reflector.conf"
|
|
},
|
|
{
|
|
"id": "mirror-refresh",
|
|
"type": "service",
|
|
"unit": "reflector.timer",
|
|
"state": "stopped",
|
|
"boot": "disabled"
|
|
},
|
|
{
|
|
"id": "cache-cleaning",
|
|
"type": "service",
|
|
"unit": "paccache.timer",
|
|
"state": "running",
|
|
"boot": "enabled",
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
},
|
|
{
|
|
"id": "keeper-account",
|
|
"type": "user",
|
|
"name": "pacman-keeper",
|
|
"shell": "/usr/bin/nologin"
|
|
},
|
|
{
|
|
"id": "state",
|
|
"type": "directory",
|
|
"mode": "0711",
|
|
"place": "mesh",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"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": "root-helper",
|
|
"type": "process",
|
|
"name": "pacman-root",
|
|
"artifact": "tools",
|
|
"run": [
|
|
"./pacman-tools",
|
|
"root"
|
|
],
|
|
"env": {
|
|
"PACMAN_ROOT_SOCKET": "${dir:state}/root/helper.sock",
|
|
"PACMAN_ROOT_PEER": "pacman-keeper"
|
|
},
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
},
|
|
{
|
|
"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",
|
|
"PACMAN_ROOT_SOCKET": "${dir:state}/root/helper.sock"
|
|
},
|
|
"restart-on": [
|
|
"keeper-config"
|
|
],
|
|
"bus": {
|
|
"state": [
|
|
"installed",
|
|
"updates",
|
|
"runs",
|
|
"records",
|
|
"rounds",
|
|
"asks",
|
|
"mirrors"
|
|
],
|
|
"emits": [
|
|
"package.changed",
|
|
"upgrade.recorded",
|
|
"upgrade.kernel-held",
|
|
"upgrade.started",
|
|
"upgrade.finished",
|
|
"upgrade.failed",
|
|
"upgrade.checked",
|
|
"rollback.started",
|
|
"rollback.finished"
|
|
],
|
|
"asks": true
|
|
},
|
|
"health": {
|
|
"kind": "tool",
|
|
"tool": "pacman_upgrade_health",
|
|
"interval": "60s",
|
|
"timeout": "20s",
|
|
"looks": 2,
|
|
"grace": "60s"
|
|
}
|
|
}
|
|
],
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "tools",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/pacman-tools",
|
|
"binary": "pacman-tools",
|
|
"loads": [
|
|
"pacman-tools"
|
|
],
|
|
"env": {
|
|
"PACMAN_KEEPER_CONFIG": "${dir:state}/keeper.json"
|
|
}
|
|
},
|
|
{
|
|
"name": "files",
|
|
"kind": "archive",
|
|
"from": "files"
|
|
}
|
|
]
|
|
}
|
|
}
|