package main import ( "context" _ "embed" "flag" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "github.com/example/glpi-env-controller/internal/app" ) //go:embed page.html var pageHTML string func main() { configPath := flag.String("config", "", "path to controller configuration") flag.Parse() logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) resolvedConfigPath, err := app.ResolveConfigPath(*configPath, os.Getenv("ENV_CONTROLLER_CONFIG")) if err != nil { logger.Error("resolve configuration", "error", err) os.Exit(1) } logger.Info("using configuration", "path", resolvedConfigPath) cfg, password, err := app.LoadConfig(resolvedConfigPath) if err != nil { logger.Error("load configuration", "error", err) os.Exit(1) } server, err := app.NewServer(cfg, password, pageHTML, logger) if err != nil { logger.Error("initialize server", "error", err) os.Exit(1) } ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() server.AutoImport(ctx) httpServer := &http.Server{Addr: cfg.ListenAddr, Handler: server.Handler(), ReadHeaderTimeout: 10 * time.Second, ReadTimeout: 30 * time.Second, WriteTimeout: 5 * time.Minute, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 1 << 20} go func() { <-ctx.Done() shutdownCtx, c := context.WithTimeout(context.Background(), 10*time.Second) defer c() _ = httpServer.Shutdown(shutdownCtx) }() logger.Info("env controller listening", "addr", cfg.ListenAddr) if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("server stopped", "error", err) os.Exit(1) } }