cairn/cmd/cairn-server/main.go

86 lines
2.1 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/mattnite/cairn/internal/blob"
"github.com/mattnite/cairn/internal/config"
"github.com/mattnite/cairn/internal/database"
"github.com/mattnite/cairn/internal/forgejo"
"github.com/mattnite/cairn/internal/web"
)
func main() {
cfg, err := config.Load()
if err != nil {
log.Fatalf("Loading config: %v", err)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
pool, err := database.Connect(ctx, cfg.DatabaseURL)
if err != nil {
log.Fatalf("Connecting to database: %v", err)
}
defer pool.Close()
if err := database.Migrate(ctx, pool); err != nil {
log.Fatalf("Running migrations: %v", err)
}
store, err := blob.NewS3Store(cfg.S3Endpoint, cfg.S3AccessKey, cfg.S3SecretKey, cfg.S3Bucket, cfg.S3UseSSL)
if err != nil {
log.Fatalf("Creating blob store: %v", err)
}
if err := store.EnsureBucket(ctx); err != nil {
log.Fatalf("Ensuring bucket: %v", err)
}
var forgejoClient *forgejo.Client
if cfg.ForgejoURL != "" && cfg.ForgejoToken != "" {
forgejoClient = forgejo.NewClient(cfg.ForgejoURL, cfg.ForgejoToken)
log.Printf("Forgejo integration enabled: %s", cfg.ForgejoURL)
}
router, err := web.NewRouter(web.RouterConfig{
Pool: pool,
Store: store,
ForgejoClient: forgejoClient,
WebhookSecret: cfg.ForgejoWebhookSecret,
})
if err != nil {
log.Fatalf("Creating router: %v", err)
}
srv := &http.Server{
Addr: cfg.ListenAddr,
Handler: router,
ReadTimeout: 30 * time.Second,
WriteTimeout: 60 * time.Second,
IdleTimeout: 120 * time.Second,
}
go func() {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
log.Println("Shutting down...")
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownCancel()
srv.Shutdown(shutdownCtx)
}()
log.Printf("Cairn server listening on %s", cfg.ListenAddr)
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatalf("Server error: %v", err)
}
}