burrow/services/forgejo-nsc/cmd/forgejo-nsc-dispatcher/main.go

90 lines
2.5 KiB
Go

package main
import (
"context"
"flag"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/burrow/forgejo-nsc/internal/app"
"github.com/burrow/forgejo-nsc/internal/config"
"github.com/burrow/forgejo-nsc/internal/forgejo"
"github.com/burrow/forgejo-nsc/internal/nsc"
"github.com/burrow/forgejo-nsc/internal/server"
)
func main() {
var configPath string
flag.StringVar(&configPath, "config", "config.yaml", "Path to the dispatcher config file.")
flag.Parse()
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
cfg, err := config.Load(configPath)
if err != nil {
logger.Error("failed to load config", "error", err)
os.Exit(1)
}
scope, err := cfg.Forgejo.DefaultScope.ToScope()
if err != nil {
logger.Error("invalid default scope", "error", err)
os.Exit(1)
}
forgejoClient, err := forgejo.NewClient(cfg.Forgejo.BaseURL, cfg.Forgejo.Token)
if err != nil {
logger.Error("failed to create forgejo client", "error", err)
os.Exit(1)
}
dispatcher, err := nsc.NewDispatcher(nsc.Options{
BinaryPath: cfg.Namespace.NSCBinary,
ComputeBaseURL: cfg.Namespace.ComputeBaseURL,
DefaultImage: cfg.Namespace.Image,
DefaultMachine: cfg.Namespace.MachineType,
MacosBaseImageID: cfg.Namespace.MacosBaseImageID,
MacosMachineArch: cfg.Namespace.MacosMachineArch,
DefaultDuration: cfg.Namespace.Duration.Duration,
WorkDir: cfg.Namespace.WorkDir,
MaxParallel: cfg.Namespace.MaxParallel,
RunnerNamePrefix: cfg.Runner.NamePrefix,
Executor: cfg.Runner.Executor,
Network: cfg.Namespace.Network,
Logger: logger,
})
if err != nil {
logger.Error("failed to create dispatcher", "error", err)
os.Exit(1)
}
service := app.NewService(app.Config{
DefaultScope: scope,
DefaultLabels: cfg.Forgejo.DefaultLabels,
InstanceURL: cfg.Forgejo.InstanceURL,
DefaultTTL: cfg.Namespace.Duration.Duration,
AllowLabels: cfg.Namespace.AllowLabels,
AllowScopes: cfg.Namespace.AllowScopes,
}, forgejoClient, dispatcher, logger)
srv := server.New(cfg.Listen, service, logger)
go func() {
logger.Info("dispatcher listening", "addr", cfg.Listen)
if err := srv.ListenAndServe(); err != nil && err != context.Canceled && err != http.ErrServerClosed {
logger.Error("server terminated", "error", err)
}
}()
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, syscall.SIGTERM, syscall.SIGINT)
<-interrupt
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_ = srv.Shutdown(ctx)
}