Start no account's manager to look at its units (hq issue 764)
mesh/merge-gate head 62af89f85d0d merged into trunk 1a2677882380 — pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes wi…
mesh/repo-check head 62af89f85d0d merged into trunk 1a2677882380 — pass: its merge-check.sh passed
mesh/delivery delivered

Every 15 s the failed-units look read the own manager of every account
the declaration creates, and reading one is a login that starts it: six
module accounts' managers on the control node started and stopped all
day, most of its journal. A look only reads (ADR 0240 rule 6) and never
asks an account's manager (ADR 0177).

An account's manager is read now only when the declaration places a
user-scoped unit in it, and only after the machine's own manager says
user@<uid>.service is active, as the apply asks before it. A manager not
running is said away in the units statement, with no failed units; in
liveness its units read unknown with the apply's words, never down. The
operator's account on a desktop is still read while logged in, since a
module places a user unit there (issue 315's Razer daemon stays said).
This commit is contained in:
2026-10-15 00:33:34 +02:00
parent 1a26778823
commit 62af89f85d
8 changed files with 276 additions and 17 deletions
+21
View File
@@ -304,6 +304,27 @@ func For(name string) (System, error) {
name, strings.Join(names, ", "))
}
// userManagers is a service manager that runs a manager per account (novox/hq ADR 0177).
type userManagers interface {
UserManagerRunning(ctx context.Context, run Runner, account string) (running, exists bool, err error)
}
// ManagerRunning is whether account's own manager runs on a machine built for name, asked of the
// machine's manager through run — never of the account's, which a question would start (see
// arch.UserManagerRunning). A look asks it before it reads anything in an account's manager (novox/hq
// issue 764). A system with no manager per account is an error: nothing can be read there.
func ManagerRunning(ctx context.Context, name string, run Runner, account string) (running, exists bool, err error) {
sys, err := For(name)
if err != nil {
return false, false, err
}
um, ok := sys.(userManagers)
if !ok {
return false, false, fmt.Errorf("this machine's service manager (%s) has no manager per account", sys.Name())
}
return um.UserManagerRunning(ctx, run, account)
}
// All is every system the host can be built for.
func All() []System {
return []System{arch{}, alpine{}, android{}}