feat(hub): operator OOB peer + oob_peer_ip desired-state merge (H1 Part 1)
store.SetOperatorOOBPeer/GetOperatorOOBPeer (empty-host_id wg_peers row, explicit /32, validated in-subnet/not-reserved/not-taken, last-write-wins rotation). PUT/GET /admin/wg/operator-peer (global key). mergeWireguard adds oob_peer_ip when an operator peer exists (absent = byte-identical). BumpAllHostGenerations forces fleet re-fetch. Non-hollow tests both sides. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1500,6 +1500,19 @@ func (s *Store) BumpHostDesired(hostID string) (int64, error) {
|
||||
return gen, nil
|
||||
}
|
||||
|
||||
// BumpAllHostGenerations advances EVERY host's desired_generation (TASK H1). Used when a FLEET-WIDE
|
||||
// hub-owned served-state value changes — the operator OOB peer's /32 flows into every host's
|
||||
// merge-at-read wireguard block (oob_peer_ip), so every agent must re-fetch + re-render. Returns the
|
||||
// number of hosts bumped.
|
||||
func (s *Store) BumpAllHostGenerations() (int64, error) {
|
||||
res, err := s.db.Exec(`UPDATE hosts SET desired_generation = desired_generation + 1, updated_at = datetime('now')`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n, _ := res.RowsAffected()
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// SignedJob is one OPAQUE operator-signed destructive-op blob queued for a host (slice 10A). The
|
||||
// hub stores + serves the bytes; it never forges, opens, or executes them (10B owns verify+run).
|
||||
type SignedJob struct {
|
||||
|
||||
Reference in New Issue
Block a user