hub v0.59.0: Direction-2a agent-plane immediate-sync poke sender + ep0 felhom-poke surface

- internal/poke: pinned-host-key SSH poke sender (wgsync sibling) + fire-and-forget Notifier (PokeHost/PokeAllHosts). Poke refuses non-WG targets pre-dial; contentless via ep0 forced command to the box WG /32:51822.
- wiring: Server.SetPoke; applyPBSDR pokes the host after each descriptor gen-bump; handleSetArtifacts (MinAgent floor) pokes all hosts. main.go env POKE_SSH_KEY_FILE (reuses peersync endpoint/hostkey).
- scripts/felhom-poke.sh (non-root forced command) + offsite-endpoint.md §11; manifests/hub.yaml Secret/agent-poke + POKE_SSH_KEY_FILE (image tag bump follows the build).
This commit is contained in:
2026-07-16 22:48:15 +02:00
parent bdb65a80e8
commit eb227486d0
11 changed files with 567 additions and 0 deletions
+25
View File
@@ -24,6 +24,7 @@ import (
"gitea.dooplex.hu/admin/felhom-hub/internal/pbsdrheal"
"gitea.dooplex.hu/admin/felhom-hub/internal/monitor"
"gitea.dooplex.hu/admin/felhom-hub/internal/notify"
"gitea.dooplex.hu/admin/felhom-hub/internal/poke"
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
"gitea.dooplex.hu/admin/felhom-hub/internal/web"
"gitea.dooplex.hu/admin/felhom-hub/internal/tenantsync"
@@ -425,6 +426,30 @@ func main() {
} else {
logger.Printf("[INFO] PBS DR tenantsync disabled (key or endpoint not configured)")
}
// Agent-plane immediate-sync SENDER (Direction-2a, v0.59.0; SPIKE-immediate-sync-transport):
// same endpoint + pinned host key + peersync user as wgsync/tenantsync, its OWN forced-command
// key (POKE_SSH_KEY_FILE, optional Secret). A poke is contentless + fire-and-forget; if this
// is unconfigured, an agent-plane save just bumps the generation and the box picks it up on its
// next ≤15-min report (no error to the operator).
pokeKeyFile := os.Getenv("POKE_SSH_KEY_FILE")
if wgAddr != "" && wgHostKey != "" && pokeKeyFile != "" {
keyPEM, err := os.ReadFile(pokeKeyFile)
if os.IsNotExist(err) {
logger.Printf("[INFO] agent-plane poke disabled (key %s not present)", pokeKeyFile)
} else if err != nil {
logger.Printf("[ERROR] agent-plane poke disabled: read key file %s: %v", pokeKeyFile, err)
} else if pokeClient, err := poke.New(poke.Config{
Addr: wgAddr, User: wgUser, PrivateKey: keyPEM, HostKeyLine: wgHostKey,
}, logger); err != nil {
logger.Printf("[ERROR] agent-plane poke disabled: %v", err)
} else {
webServer.SetPoke(poke.NewNotifier(dataStore, pokeClient, logger))
logger.Printf("[INFO] agent-plane poke enabled (endpoint %s, user %s)", wgAddr, wgUser)
}
} else {
logger.Printf("[INFO] agent-plane poke disabled (key or endpoint not configured)")
}
}
// PBS-DR self-heal reconciler (internal/pbsdrheal, from SPIKE-pbsdr-selfheal-2026-07-15). Re-arms