Files
GitHop/services/control-plane/cmd/hop-control-plane/main.go
T
Hop d9544b435b Add the runnable Gitea, PostgreSQL, and Hop control-plane foundation
Hop-State: A_06FN3QYA1N56NQYGZ81DWGR
Hop-Proposal: R_06FN3QXJRYPPEQZQA6S69QG
Hop-Task: T_06FN3MVGY3MT82ESQ89BND0
Hop-Attempt: AT_06FN3MVGY092BFA5MR9C7EG
2026-07-11 08:50:48 -07:00

78 lines
1.7 KiB
Go

package main
import (
"context"
"errors"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"hopweb/internal/config"
"hopweb/internal/gitea"
"hopweb/internal/httpapi"
"hopweb/internal/store"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
cfg, err := config.Load()
if err != nil {
logger.Error("invalid configuration", "error", err)
os.Exit(1)
}
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
db, err := store.Open(ctx, cfg.DatabaseURL)
if err != nil {
logger.Error("open database", "error", err)
os.Exit(1)
}
defer db.Close()
if err := db.Migrate(ctx); err != nil {
logger.Error("migrate database", "error", err)
os.Exit(1)
}
giteaClient, err := gitea.NewClient(cfg.GiteaBaseURL, cfg.GiteaAPIToken)
if err != nil {
logger.Error("configure gitea client", "error", err)
os.Exit(1)
}
server := &http.Server{
Addr: cfg.HTTPAddr,
Handler: httpapi.New(db, giteaClient, cfg.AdminToken, cfg.GiteaWebhookSecret, logger),
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
errCh := make(chan error, 1)
go func() {
logger.Info("control plane listening", "addr", cfg.HTTPAddr)
errCh <- server.ListenAndServe()
}()
select {
case err := <-errCh:
if !errors.Is(err, http.ErrServerClosed) {
logger.Error("serve", "error", err)
os.Exit(1)
}
case <-ctx.Done():
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownCancel()
if err := server.Shutdown(shutdownCtx); err != nil {
logger.Error("shutdown", "error", err)
os.Exit(1)
}
}
}