feat: k8s informer for ServiceAdapter CRDs, bump CI to go1.26
Build and push / Build and push image (push) Successful in 2m7s
Build / Build and push image (push) Successful in 1m9s
CI / Test, vet, build (push) Successful in 4m10s

- Add dynamic-client informer to watch ServiceAdapter CRs in-cluster
- Remove typed scheme registration (dynamic client needs no DeepCopy)
- Bump Dockerfile + CI images from golang:1.25 to golang:1.26
  (k8s.io/[email protected] requires go>=1.26)
- Wire informer into main.go startup with graceful fallback
This commit is contained in:
Admin Bot
2026-08-26 14:38:12 -07:00
parent 0cdfae2a93
commit eaeeb97b2a
9 changed files with 380 additions and 74 deletions
+34 -5
View File
@@ -9,6 +9,9 @@ import (
"os/signal"
"syscall"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/config"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/proxy"
"forgejo.riotpiao.com/rock/homelab-frontend/internal/server"
@@ -37,7 +40,6 @@ func main() {
upstreamHandler := proxy.New(cfg)
// Create the Temporal workflow handler
// Temporal server address can be configured via environment variable
temporalHostPort := os.Getenv("TEMPORAL_HOST_PORT")
if temporalHostPort == "" {
temporalHostPort = "localhost:7233"
@@ -47,15 +49,39 @@ func main() {
// Create server with health checker
srv := server.New(cfg.ListenAddr, cfg.ShutdownTimeout, nil)
// Initialize health checker with config validity and auth status
healthChecker := server.NewHealthChecker(true, authEnabled)
srv.SetHealthChecker(healthChecker)
// Create ServiceAdapter registry and dispatcher (phase 8)
registry := serviceadapter.NewRegistry(nil) // nil uses default logger
registry := serviceadapter.NewRegistry(nil)
dispatcher := serviceadapter.NewDispatcher(registry)
// Start ServiceAdapter informer to watch CRDs (8.1 integration)
var informerMgr *serviceadapter.InformerManager
kubeConfig, err := rest.InClusterConfig()
if err != nil {
log.Printf("ServiceAdapter informer disabled: %v", err)
} else {
dynamicClient, err := dynamic.NewForConfig(kubeConfig)
if err != nil {
log.Printf("ServiceAdapter informer: failed to create k8s client: %v", err)
} else {
mgr, err := serviceadapter.NewInformerManager(dynamicClient, registry, "api")
if err != nil {
log.Printf("ServiceAdapter informer: failed to create manager: %v", err)
} else {
if err := mgr.Start(context.Background()); err != nil {
log.Printf("ServiceAdapter informer: failed to start: %v", err)
} else {
informerMgr = mgr
log.Printf("ServiceAdapter informer started")
}
}
}
}
// Create router that handles health endpoints, X-Service (ServiceAdapter) routing,
// temporal endpoints, and passes others to upstream handler
router := server.NewRouter(healthChecker, dispatcher, temporalHandler, upstreamHandler)
@@ -79,7 +105,10 @@ func main() {
sig := <-sigChan
log.Printf("received signal: %v", sig)
// Gracefully shutdown the server
if informerMgr != nil {
informerMgr.Stop()
}
if err := srv.Shutdown(context.Background()); err != nil {
fmt.Fprintf(os.Stderr, "shutdown error: %v\n", err)
os.Exit(1)