At 2026-11-02 22:55:58 the provisioner's first pass after a new membership read part of the picture, took the modules missing from it as handing nothing, set 21 route keys of running web apps retiring and asked the operator to remove them; 3 s later the next pass put every plan back. Only 3 asks reached the router; the other 18 were refused yet counted asked. Third of its kind (937, 1332), so the kind is fixed, not the instance. Quick fix: wait for the watched reads' first load before any pass. Thorough fix, chosen because the kind recurred three times and its obvious answer would cut running apps off their routes: - no pass judges before placement, wants, haves, the indexer's modules and the published compositions have loaded once; a read error fails the pass instead of reading as empty; - while a module's composition is not published at its build, no key on that node turns retiring and no plan is removed; a placed module with no known build is held, not counted as handing nothing; - a key whose consumer still has a want or a have on the node and no plan read in this pass is left as it is; - a pass that would retire most of a node's consumers at once (more than 3, or more than half and at least 2) retires and asks nothing and says it as a fault through provisioner_health (runtime-health, so a condition names the likely cause); provisioner_compose retire-many is the operator's word that such a removal is meant; - at most 3 asks stand open (the router's bound per asker); the rest wait and are raised as one ends, and an ask the router holds no record of a minute on is raised again. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
93 lines
1.8 KiB
JSON
93 lines
1.8 KiB
JSON
{
|
|
"module": "mesh-provisioner",
|
|
"version": "1",
|
|
"runs-as": "mesh-provisioner",
|
|
"claims": [
|
|
{
|
|
"name": "mesh-provisioner",
|
|
"scope": "mesh",
|
|
"serves": [
|
|
"provisioning"
|
|
]
|
|
}
|
|
],
|
|
"uses": [
|
|
"operator-channel"
|
|
],
|
|
"reads": [
|
|
"mesh-delivery-assigner.placement",
|
|
"mesh-delivery-assigner.wants",
|
|
"mesh-delivery-indexer.modules",
|
|
"mesh-delivery-indexer.manifests",
|
|
"node-engine.have",
|
|
"mesh-host.composed",
|
|
"gitea.bound",
|
|
"keycloak.bound",
|
|
"postgres.bound",
|
|
"route-adapter.bound",
|
|
"route-proxy.bound",
|
|
"node-tools.bound",
|
|
"mesh-vault.bound"
|
|
],
|
|
"tools": [
|
|
"provisioner_provisions",
|
|
"provisioner_plans",
|
|
"provisioner_compose",
|
|
"provisioner_decide",
|
|
"provisioner_health"
|
|
],
|
|
"state": [
|
|
"registry",
|
|
"needs",
|
|
"applied",
|
|
"collect",
|
|
"provisions",
|
|
"plans",
|
|
"refused"
|
|
],
|
|
"own-secrets": {
|
|
"broker": "${dir:state}/broker"
|
|
},
|
|
"secrets-owner": "mesh-provisioner",
|
|
"runtime-health": {
|
|
"kind": "tool",
|
|
"tool": "provisioner_health",
|
|
"interval": "60s",
|
|
"timeout": "10s",
|
|
"looks": 2,
|
|
"grace": "60s"
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "account",
|
|
"type": "user",
|
|
"name": "mesh-provisioner",
|
|
"shell": "/usr/bin/nologin",
|
|
"home": "/var/lib/mesh-provisioner"
|
|
},
|
|
{
|
|
"id": "state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"owner": "mesh-provisioner",
|
|
"place": ".",
|
|
"unknown": "program"
|
|
}
|
|
],
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "tools",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/mesh-provisioner",
|
|
"binary": "mesh-provisioner",
|
|
"loads": [
|
|
"mesh-provisioner"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|