repo init
This commit is contained in:
commit
7e44db87b2
48 files changed
+5346
No files matched your search
@@ -0,0 +1,85 @@
|
||||
// Command validator-agent runs on a validator VM. It is stateless: every
|
||||
// decision it makes is driven by polling the Control API, per the
|
||||
// deployment constraint that validators must be able to restart freely
|
||||
// without any local state to reconcile.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log/slog"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"cloudipvalidator/internal/agentcore"
|
||||
"cloudipvalidator/internal/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
configPath := flag.String("config", "configs/validator-agent.yaml", "path to validator-agent config file")
|
||||
stubPorts := flag.String("stub-ports", "", "TEST ONLY: comma-separated TCP ports to accept-and-close on, standing in for the validator's real listening services in the offline end-to-end harness (see docs/LOCAL_E2E.md)")
|
||||
flag.Parse()
|
||||
|
||||
log := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
|
||||
|
||||
cfg, err := config.LoadValidatorAgent(*configPath)
|
||||
if err != nil {
|
||||
log.Error("load config", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
if *stubPorts != "" {
|
||||
startStubListeners(ctx, log, *stubPorts)
|
||||
}
|
||||
|
||||
agent := agentcore.New(cfg, log)
|
||||
if err := agent.Run(ctx); err != nil && err != context.Canceled {
|
||||
log.Error("agent stopped", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// startStubListeners binds trivial accept-and-close TCP listeners on the
|
||||
// given ports, standing in for the base-minimum services (22/80/443/8080)
|
||||
// a real validator would already run, so an offline prober has something
|
||||
// to successfully connect to. ICMP needs no stub: the kernel answers echo
|
||||
// requests to any locally-bound address on its own.
|
||||
func startStubListeners(ctx context.Context, log *slog.Logger, portsCSV string) {
|
||||
for _, p := range strings.Split(portsCSV, ",") {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
port, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
log.Error("invalid stub port", "value", p, "err", err)
|
||||
continue
|
||||
}
|
||||
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
log.Error("stub listener", "port", port, "err", err)
|
||||
continue
|
||||
}
|
||||
log.Info("stub listener up", "port", port)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
ln.Close()
|
||||
}()
|
||||
go func() {
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user