Give back only the groups the mesh added, and say when a new login is needed (hq ADR 0252, issue 247)
mesh/merge-gate pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/module-groups delivered: every member is delivered
mesh/merge-gate pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/module-groups delivered: every member is delivered
A module puts the operator's account in a group by declaring the account with that group alone. The node-engine now records each group it added, takes back only those when nothing declared still asks for them, refuses a group the machine lacks before usermod runs, and states each such account as its module's resource of kind account: relogin needed while the running session lacks the group.
This commit is contained in:
+46
-3
@@ -28,6 +28,7 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/novox/mesh-host/internal/accounts"
|
||||
"github.com/novox/mesh-host/internal/apply"
|
||||
"github.com/novox/mesh-host/internal/bundle"
|
||||
"github.com/novox/mesh-host/internal/declaration"
|
||||
@@ -1093,6 +1094,8 @@ func runLink(ctx context.Context, opts options) error {
|
||||
judging = j
|
||||
// And which units its service managers say failed, and whose each is (novox/hq issue 315).
|
||||
unitJudge = units.New(units.Exec{Run: apply.ExecRunner, System: builtFor})
|
||||
// And whether an account a module put in a group has it where it runs (novox/hq ADR 0252).
|
||||
accountJudge = accounts.New(accounts.Exec{Run: accounts.Runner(apply.ExecRunner)})
|
||||
}
|
||||
|
||||
// **Standing aside for a successor happens between reconciles and nowhere else** (novox/hq ADR
|
||||
@@ -1391,6 +1394,10 @@ var judging *liveness.Judge
|
||||
// issue 315); nil where judging is.
|
||||
var unitJudge *units.Judge
|
||||
|
||||
// accountJudge reads whether an account a module put in a group has it in its running session (novox/hq
|
||||
// ADR 0252); nil where judging is.
|
||||
var accountJudge *accounts.Judge
|
||||
|
||||
// netJudge is the serving host's judge of its machine's networking (novox/hq ADR 0241); empty in a
|
||||
// one-shot command and in a test, which say nothing of the network.
|
||||
var netJudge networkJudge
|
||||
@@ -1496,6 +1503,19 @@ func judgeWhatRuns(ctx context.Context, j *liveness.Judge, queue *link.Queue, sa
|
||||
}
|
||||
}
|
||||
}
|
||||
var accountSt *accounts.Statement
|
||||
if a := accountJudge; a != nil {
|
||||
as, accountsChanged := a.Look(ctx)
|
||||
accountSt = &as
|
||||
owed = owed || accountsChanged
|
||||
if accountsChanged {
|
||||
for _, v := range as.Accounts {
|
||||
if v.State != accounts.Healthy {
|
||||
say(fmt.Sprintf("%s (account %s) is %s: %s", v.ID, v.Name, v.State, v.Reason))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var netSt *network.Statement
|
||||
if n := netJudge.get(); n != nil {
|
||||
ns, netChanged := n.Look(ctx)
|
||||
@@ -1519,7 +1539,7 @@ func judgeWhatRuns(ctx context.Context, j *liveness.Judge, queue *link.Queue, sa
|
||||
}
|
||||
since := time.Since(lastSaid)
|
||||
healthy := st.Healthy() && (netSt == nil || netSt.State != network.Unhealthy) &&
|
||||
(unitSt == nil || len(unitSt.Failed) == 0)
|
||||
(unitSt == nil || len(unitSt.Failed) == 0) && (accountSt == nil || accountSt.Healthy())
|
||||
if !owed && !(!healthy && since >= sayUnhealthyAgain) && since < sayAnyway {
|
||||
continue
|
||||
}
|
||||
@@ -1531,7 +1551,7 @@ func judgeWhatRuns(ctx context.Context, j *liveness.Judge, queue *link.Queue, sa
|
||||
}
|
||||
}
|
||||
}
|
||||
if queue.SayHealth(ctx, *withUnits(healthAsReported(st, netSt), unitSt)) {
|
||||
if queue.SayHealth(ctx, *withAccounts(withUnits(healthAsReported(st, netSt), unitSt), accountSt)) {
|
||||
lastSaid, owed = time.Now(), false
|
||||
}
|
||||
}
|
||||
@@ -1585,6 +1605,21 @@ func withUnits(h *link.Health, us *units.Statement) *link.Health {
|
||||
return h
|
||||
}
|
||||
|
||||
// withAccounts adds to a statement every account a module put in a group (novox/hq ADR 0252), as that
|
||||
// module's resource of kind account: healthy, or unhealthy with why — "relogin needed" when the account's
|
||||
// running session began before it was put in the group. Nil says nothing of them.
|
||||
func withAccounts(h *link.Health, as *accounts.Statement) *link.Health {
|
||||
if as == nil {
|
||||
return h
|
||||
}
|
||||
for _, v := range as.Accounts {
|
||||
h.Resources = append(h.Resources, link.ResourceHealth{Module: v.Module, Resource: v.ID,
|
||||
Kind: link.KindAccount, Target: v.Name, State: v.State, Reason: v.Reason, Since: v.Since.UTC(),
|
||||
Streak: v.Streak})
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// failedUnitWords is a failed unit as the console says it.
|
||||
func failedUnitWords(f units.Failed) string {
|
||||
whose := "no module places it"
|
||||
@@ -1844,7 +1879,15 @@ func applyAndKeepHeld(ctx context.Context, opts options, raw []byte, signed *sto
|
||||
us := u.Last()
|
||||
unitSt = &us
|
||||
}
|
||||
report.Health = withUnits(healthAsReported(st, netSt), unitSt)
|
||||
// Looked at now, not taken from the last look: an apply that just put the account in a group is
|
||||
// said with it, relogin needed included, in the report that says the apply.
|
||||
var accountSt *accounts.Statement
|
||||
if a := accountJudge; a != nil {
|
||||
a.Set(accounts.Of(declared, held))
|
||||
as, _ := a.Look(ctx)
|
||||
accountSt = &as
|
||||
}
|
||||
report.Health = withAccounts(withUnits(healthAsReported(st, netSt), unitSt), accountSt)
|
||||
}
|
||||
// Which of this machine's links face outside, for the filter the mesh writes around them
|
||||
// (novox/hq ADR 0140). Reported whatever the node's mode: a converged node's filter needs it,
|
||||
|
||||
Reference in New Issue
Block a user