package main // main.go — lvmh daemon entrypoint: env wiring, flags, HTTP server. import ( "context" "flag" "log" "net/http" "os" "os/signal" "path/filepath" "syscall" "time" ) // Server and env wiring constants. const ( envDB string = "LVMH_DB" defaultDBPath string = "/data/lvmh.db" envGitLabBaseURL string = "GITLAB_BASE_URL" defaultGitLabBase string = "https://git.westphal.fr" defaultListenAddr string = ":8686" shutdownGrace time.Duration = 10 * time.Second webDistDefault string = "/app/web-dist" ) func main() { var ( addr = flag.String("addr", defaultListenAddr, "listen address") dbPath = flag.String("db", envOr(envDB, defaultDBPath), "sqlite database path") webdist = flag.String("webdist", webDistDefault, "serve web UI from this directory instead of the embedded build") ) flag.Parse() // Fall back to the embedded UI when the override directory is absent. if st, err := os.Stat(*webdist); err != nil || !st.IsDir() { *webdist = "" } daemonToken = os.Getenv(envToken) if daemonToken == "" { log.Fatalf("LVMH_TOKEN must be set") } if dir := filepath.Dir(*dbPath); dir != "" && dir != "." { if err := os.MkdirAll(dir, 0o755); err != nil { log.Fatalf("create db dir: %v", err) } } store, err := OpenStore(*dbPath) if err != nil { log.Fatalf("open store: %v", err) } defer store.Close() hub := NewHub(store) gitlab := NewGitLab(store, envOr(envGitLabBaseURL, defaultGitLabBase)) spawner, err := NewSpawner(store, hub, envOr(envGitLabBaseURL, defaultGitLabBase)) if err != nil { log.Fatalf("docker client: %v", err) } srv := NewServer(store, hub, spawner, gitlab) httpServer := &http.Server{ Addr: *addr, Handler: srv.Routes(*webdist), ReadHeaderTimeout: 10 * time.Second, } go func() { log.Printf("lvmh daemon listening on %s (db %s)", *addr, *dbPath) if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %v", err) } }() stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) <-stop log.Printf("shutting down") ctx, cancel := context.WithTimeout(context.Background(), shutdownGrace) defer cancel() if err := httpServer.Shutdown(ctx); err != nil { log.Printf("shutdown: %v", err) } }