Serve reset-failed and wanted-by in the systemd module (hq issue 332)
mesh/merge-gate fail: builds systemd → ace, g14, novox, shanks; no bus step; a manifest the change touches fails the module check: systemd claims node-serv…
mesh/repo-check fail: its merge-check.sh failed: long-running resources without health: 70
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate fail: builds systemd → ace, g14, novox, shanks; no bus step; a manifest the change touches fails the module check: systemd claims node-serv…
mesh/repo-check fail: its merge-check.sh failed: long-running resources without health: 70
mesh/delivery superseded: a newer head of the same pull request
So a leftover unit's trigger is found and its failed record cleared through the seat, not a shell: wanted-by reads the manager's reverse dependencies and the enable links naming the unit, saying which dangle.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// systemd's tools: the node-service-manager seat's nine verbs — the units on this machine in both scopes,
|
||||
// read and acted on by name, their journal, and what has failed (novox/hq ADR 0177). The node
|
||||
// tools runtime launches this bundle as a process of its own and serves what it serves (ADR 0188, ADR 0193);
|
||||
// systemd's tools: the node-service-manager seat's eleven verbs — the units on this machine in both scopes,
|
||||
// read and acted on by name, their journal, what has failed, what wants a unit, and a failed record cleared
|
||||
// (novox/hq ADR 0177, issue 332). The node tools runtime launches this bundle as a process of its own and serves what it serves (ADR 0188, ADR 0193);
|
||||
// it runs as the operator account, so acts on the system manager, and reads of its journal, escalate with
|
||||
// sudo -n, and the user scope is the account's own manager (client.go). The host applies units; this answers
|
||||
// about them. stdout is the MCP channel; this says nothing else.
|
||||
@@ -123,6 +123,28 @@ func tools(m *Manager) []stdio.Tool {
|
||||
}
|
||||
return m.Journal(scope, unit, q)
|
||||
}},
|
||||
// **Clearing a failed record** (novox/hq issue 332): a unit whose file is gone keeps its failed state,
|
||||
// and its start-limit count, in its manager until it is reset. A unit's name is required, so the
|
||||
// verb never resets every failed unit at once.
|
||||
act("reset-failed", "Clear one unit's failed record in its manager — its failed state and its start-limit count — and answer its state after. It removes no file and starts nothing."),
|
||||
{Name: seat + ".wanted-by",
|
||||
Description: "What wants, requires or triggers one unit, read-only: the manager's reverse dependencies " +
|
||||
"(WantedBy, RequiredBy, UpheldBy, BoundBy, TriggeredBy and the rest, and the units that pull those in) and every " +
|
||||
"enable link naming it in the scope's configuration directories (*.wants, *.requires, *.upholds) — the " +
|
||||
"operator account's own ~/.config/systemd/user in user scope — each with where it points, whether it " +
|
||||
"dangles and whose directory it is in; and what that means, in words.",
|
||||
Input: map[string]any{"scope": scopeArg, "unit": unitArgS},
|
||||
Run: func(a map[string]any) (any, error) {
|
||||
scope, err := scopeOf(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unit, err := unitOf(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.WantedBy(scope, unit)
|
||||
}},
|
||||
// Was the module's own systemd_failed; on the seat since the operator's direction of 2026-10-07, so
|
||||
// whatever holds the role answers it and every machine is asked the same way.
|
||||
{Name: seat + ".failed",
|
||||
@@ -157,7 +179,12 @@ func fromEnv() *Manager {
|
||||
uid = n
|
||||
}
|
||||
}
|
||||
return &Manager{Account: account, UID: uid, User: name, Run: execRunner, Read: readFile, Env: os.Environ()}
|
||||
home := strings.TrimSpace(os.Getenv("MESH_OPERATOR_HOME"))
|
||||
if home == "" && account == name {
|
||||
home, _ = os.UserHomeDir()
|
||||
}
|
||||
return &Manager{Account: account, UID: uid, User: name, Run: execRunner, Read: readFile, Env: os.Environ(),
|
||||
Home: home, ReadDir: readDir}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
Reference in New Issue
Block a user