Stop nothing the mesh cannot replace, give the tunnel back on failure, and take it over after enrolment
Review of the ADR 0105 build (hq ADR 0105). The takeover stopped the found unit and then found out whether the mesh's interface would do; a start that failed left the machine with no tunnel at all. Now nothing is stopped until the declared interface listens on the found port at the found address and the key file it names holds the found key — the refusal names the remedy — and a mesh interface that fails to start after the takeover has the found unit started again, with the account saying so. The account has three states (not taken, taken, down) and is given on every takeover, failure included. An interface raised by hand is looked at again for a moment and then refused naming `wg-quick down`. A found unit started again by hand beside the mesh's is said, not stopped: on the hub it cannot hold the port, and on a spoke two interfaces with one key would fight. `mesh-host overlay take --tunnel <iface>` is the path for a node that enrolled before the mesh knew to take a tunnel over: the found key becomes its overlay key — identity, sealing and serving keys untouched, so nothing sealed to the node is remade — and the mesh is told with a rekey signed by the identity key, over the key left, the key taken and the tunnel. Told first, written second, so a run again puts right whichever half did not happen.
This commit is contained in:
+25
-4
@@ -339,22 +339,32 @@ func ApplyKeeping(
|
||||
// it (novox/hq ADR 0105): its configuration kept, its unit stopped and disabled, never
|
||||
// flushed. A failure here fails the service too — the mesh's interface is not started on a
|
||||
// port the found one still holds.
|
||||
stoppedFound := false
|
||||
if svc, ok := resource.(*declaration.Service); ok && svc.TakesOver != nil {
|
||||
var outcome Outcome
|
||||
var facts TakenTunnel
|
||||
var err error
|
||||
if d.Adoption == nil {
|
||||
err = errNotAdopted
|
||||
facts = TakenTunnel{Interface: svc.TakesOver.Interface, State: NotTaken}
|
||||
} else {
|
||||
outcome, facts, err = takeOver(ctx, sys, svc, d, &known, run, keep, time.Now().UTC())
|
||||
outcome, facts, stoppedFound, err = takeOver(ctx, sys, svc, d, &known, run, keep, time.Now().UTC())
|
||||
}
|
||||
// Always an account, failure included: the last account standing must never be an
|
||||
// older "taken" over a machine whose takeover has since gone wrong.
|
||||
report.Tunnel = &facts
|
||||
if err != nil {
|
||||
report.Tunnel.Note = err.Error()
|
||||
if stoppedFound {
|
||||
// The found unit is down and the mesh's not up: the one state where the
|
||||
// peers reach nothing. Started again, and said.
|
||||
restoreFound(ctx, sys, svc.TakesOver.Unit, run, report.Tunnel)
|
||||
}
|
||||
failures = append(failures, &Error{Resource: svc.Identity(), Err: err, Done: report})
|
||||
log(fmt.Sprintf(" failed %s (%s): %v", svc.Identity(), svc.Unit, err))
|
||||
continue
|
||||
}
|
||||
report.Outcomes = append(report.Outcomes, outcome)
|
||||
report.Tunnel = &facts
|
||||
log(fmt.Sprintf(" held %s (%s): %s", outcome.ID, outcome.Target, outcome.Detail))
|
||||
}
|
||||
|
||||
@@ -377,6 +387,17 @@ func ApplyKeeping(
|
||||
failed := &Error{Resource: resource.Identity(), Err: err, Done: report}
|
||||
failures = append(failures, failed)
|
||||
log(fmt.Sprintf(" failed %s (%s): %v", resource.Identity(), outcome.Target, err))
|
||||
if svc, ok := resource.(*declaration.Service); ok && svc.TakesOver != nil && report.Tunnel != nil {
|
||||
// The mesh's interface did not come up after the found one was stopped: no
|
||||
// tunnel at all. The found unit is started again — the machine goes back to
|
||||
// what it had — and the account says so (novox/hq ADR 0105).
|
||||
report.Tunnel.Note = "the mesh's interface did not come up: " + err.Error()
|
||||
if stoppedFound {
|
||||
restoreFound(ctx, sys, svc.TakesOver.Unit, run, report.Tunnel)
|
||||
} else {
|
||||
report.Tunnel.State = tunnelState(ctx, sys, svc.TakesOver.Unit, svc.Unit, run)
|
||||
}
|
||||
}
|
||||
|
||||
// **A failed action stops what follows. Nothing else does.**
|
||||
//
|
||||
@@ -426,8 +447,8 @@ func ApplyKeeping(
|
||||
}
|
||||
if svc, ok := resource.(*declaration.Service); ok && svc.TakesOver != nil && report.Tunnel != nil {
|
||||
// The found interface is down and the mesh's is up in its place: the tunnel changed
|
||||
// hands (novox/hq ADR 0105).
|
||||
report.Tunnel.Taken = true
|
||||
// hands (novox/hq ADR 0105). Read from the machine, not assumed.
|
||||
report.Tunnel.State = tunnelState(ctx, sys, svc.TakesOver.Unit, svc.Unit, run)
|
||||
}
|
||||
report.Outcomes = append(report.Outcomes, outcome)
|
||||
if outcome.Action != "unchanged" {
|
||||
|
||||
Reference in New Issue
Block a user