package gopkgserver import ( "context" _ "embed" "fmt" "io/fs" "strconv" "log/slog" "net/http" "os" "github.com/pelletier/go-toml/v2" "go.sudomsg.com/gopkgserver/repo" httpServer "go.sudomsg.com/kit/http" "go.sudomsg.com/kit/logging" logHandler "go.sudomsg.com/kit/logging/http" "go.sudomsg.com/kit/runner" ) type ServerConfig struct { Network httpServer.NetType `toml:"network"` Address string `toml:"address"` Mode string `toml:"mode"` } func RawServerConfig(rawCfg []ServerConfig) ([]httpServer.ServerConfig, error) { cfg := make([]httpServer.ServerConfig, 0, len(rawCfg)) for _, srv := range rawCfg { var mode uint64 if srv.Mode != "" { var err error mode, err = strconv.ParseUint(srv.Mode, 8, 32) if err != nil { return nil, fmt.Errorf("failed to convert mode %s: %w", srv.Mode, err) } } cfg = append(cfg, httpServer.ServerConfig{ Network: srv.Network, Address: srv.Address, Mode: fs.FileMode(mode), }) } return cfg, nil } type Config struct { Server []ServerConfig `toml:"server"` Logging logging.LogConfig `toml:"logging"` Repos map[string]repo.Repo `toml:"repo"` } func Run(ctx context.Context, fs *runner.CommandSet, args []string) error { var cfgFile string fs.StringVar(&cfgFile, "config", "config.toml", "Path to config file") if err := fs.Parse(args); err != nil{ return err } cfg, err := LoadConfig(cfgFile) if err != nil { return err } if err := logging.Setup(cfg.Logging); err != nil { return err } ctx = logging.WithLogger(ctx, slog.Default()) h, err := repo.New(cfg.Repos) if err != nil { return fmt.Errorf(": %v", err) } mux := http.NewServeMux() mux.Handle("GET /robots.txt", Robot()) mux.Handle("GET /", h) handler := logHandler.New(mux) srvCfg, err := RawServerConfig(cfg.Server) if err != nil { return err } lns, err := httpServer.OpenListeners(ctx, srvCfg) if err != nil { return err } defer lns.CloseAll() return httpServer.RunHTTPServers(ctx, lns, handler) } func LoadConfig(cfgFile string) (Config, error) { data, err := os.ReadFile(cfgFile) if err != nil { return Config{}, fmt.Errorf("read config: %w", err) } var cfg Config if err := toml.Unmarshal(data, &cfg); err != nil { return Config{}, fmt.Errorf("parse config: %w", err) } return cfg, nil }