package config import ( "fmt" "os" "time" ) type Config struct { DataDir string QuadletDir string EnrollmentFile string HTTPAddr string SocketPath string PodmanSocket string SystemdBus string ThemeCSSFile string PollInterval time.Duration StopTimeout time.Duration } // DefaultSocketPath is the local administration transport, authenticated by filesystem permission. const DefaultSocketPath = "/run/toad/toad.sock" func Load() (Config, error) { var cfg Config var missing []string required := func(name string) string { value := os.Getenv(name) if value == "" { missing = append(missing, name) } return value } optional := func(name, fallback string) string { if value := os.Getenv(name); value != "" { return value } return fallback } cfg.DataDir = required("TOAD_DATA_DIR") cfg.QuadletDir = required("TOAD_QUADLET_DIR") cfg.EnrollmentFile = required("TOAD_ENROLLMENT_FILE") cfg.HTTPAddr = optional("TOAD_HTTP_ADDR", "127.0.0.1:8090") cfg.SocketPath = optional("TOAD_SOCKET", DefaultSocketPath) cfg.PodmanSocket = optional("TOAD_PODMAN_SOCKET", "/run/podman/podman.sock") cfg.SystemdBus = optional("TOAD_SYSTEMD_BUS", "unix:path=/run/toad/user-bus") cfg.ThemeCSSFile = os.Getenv("TOAD_THEME_CSS") if len(missing) > 0 { return Config{}, fmt.Errorf("missing configuration: %v", missing) } var err error if cfg.PollInterval, err = duration("TOAD_POLL_INTERVAL", "2s"); err != nil { return Config{}, err } if cfg.StopTimeout, err = duration("TOAD_STOP_TIMEOUT", "90s"); err != nil { return Config{}, err } return cfg, nil } func duration(name, fallback string) (time.Duration, error) { text := os.Getenv(name) if text == "" { text = fallback } value, err := time.ParseDuration(text) if err != nil || value <= 0 { return 0, fmt.Errorf("invalid %s %q", name, text) } return value, nil }