refactor(config): rename default Garmin token-store dir to .garmin
Shorter, more conventional dotdir name than garmin-tokenstores. Restore the "next to DBPath" join that got dropped when the default was inlined via getEnvDefault -- an explicit GARMIN_TOKENSTORE still wins verbatim, but the implicit default must still resolve relative to the DB file's directory, not the process's CWD. internal/garmin/client.go's GARMIN_TOKENSTORE env var is now always set (TokenStorePath can no longer be empty), so the conditional that only appended it when non-empty is dead code.
This commit is contained in:
@@ -7,7 +7,6 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -29,7 +28,7 @@ type Config struct {
|
||||
// GarminTokenStoreRoot is the root directory under which each user's
|
||||
// Garmin session cache lives (one subdirectory per user id, e.g.
|
||||
// "<root>/3"). Read from the GARMIN_TOKENSTORE env var; if unset, it
|
||||
// defaults to a "garmin-tokenstores" directory next to DBPath so every
|
||||
// defaults to a ".garmin" directory next to DBPath so every
|
||||
// deployment gets per-user isolation automatically -- multi-tenant
|
||||
// operation always relies on this being a real, distinct-per-user path
|
||||
// (see api.Server.garminFor), so it can never be silently left empty.
|
||||
@@ -69,11 +68,12 @@ type Config struct {
|
||||
// Load reads configuration from environment variables, applying defaults
|
||||
// for anything optional. Returns an error if a required variable is unset.
|
||||
func Load() (Config, error) {
|
||||
dbPath := getEnvDefault("GENIUSRUN_DB_PATH", "geniusrun.db")
|
||||
cfg := Config{
|
||||
Addr: getEnvDefault("GENIUSRUN_ADDR", ":8080"),
|
||||
DBPath: getEnvDefault("GENIUSRUN_DB_PATH", "geniusrun.db"),
|
||||
DBPath: dbPath,
|
||||
GarminPythonPath: getEnvDefault("GARMIN_WRAPPER_PYTHON", "python3"),
|
||||
GarminTokenStoreRoot: os.Getenv("GARMIN_TOKENSTORE"),
|
||||
GarminTokenStoreRoot: getEnvDefault("GARMIN_TOKENSTORE", filepath.Join(filepath.Dir(dbPath), ".garmin")),
|
||||
MinConfidence: getEnvFloat("GENIUSRUN_MIN_CONFIDENCE", 0.6),
|
||||
LogLevel: getEnvDefault("GENIUSRUN_LOG_LEVEL", "info"),
|
||||
BackendURL: strings.TrimRight(os.Getenv("GENIUSRUN_BACKEND_URL"), "/"),
|
||||
@@ -84,15 +84,11 @@ func Load() (Config, error) {
|
||||
SessionDuration: getEnvDuration("GENIUSRUN_SESSION_DURATION", 720*time.Hour),
|
||||
}
|
||||
|
||||
if cfg.GarminTokenStoreRoot == "" {
|
||||
cfg.GarminTokenStoreRoot = filepath.Join(filepath.Dir(cfg.DBPath), "garmin-tokenstores")
|
||||
log.Printf("GARMIN_TOKENSTORE not set, defaulting to %q", cfg.GarminTokenStoreRoot)
|
||||
}
|
||||
|
||||
if cfg.BackendURL == "" {
|
||||
return cfg, fmt.Errorf("GENIUSRUN_BACKEND_URL is required (e.g. https://geniusrun.example.com)")
|
||||
}
|
||||
cfg.FrontendURL = strings.TrimRight(getEnvDefault("GENIUSRUN_FRONTEND_URL", cfg.BackendURL), "/")
|
||||
|
||||
if cfg.OIDCIssuerURL == "" {
|
||||
return cfg, fmt.Errorf("GENIUSRUN_OIDC_ISSUER_URL is required")
|
||||
}
|
||||
@@ -102,12 +98,13 @@ func Load() (Config, error) {
|
||||
if cfg.OIDCClientSecret == "" {
|
||||
return cfg, fmt.Errorf("GENIUSRUN_OIDC_CLIENT_SECRET is required")
|
||||
}
|
||||
cfg.OIDCRedirectURL = cfg.BackendURL + "/api/session/callback"
|
||||
|
||||
sessionSecret := os.Getenv("GENIUSRUN_SESSION_SECRET")
|
||||
if len(sessionSecret) < 32 {
|
||||
return cfg, fmt.Errorf("GENIUSRUN_SESSION_SECRET is required and must be at least 32 characters")
|
||||
}
|
||||
cfg.SessionSecret = []byte(sessionSecret)
|
||||
cfg.OIDCRedirectURL = cfg.BackendURL + "/api/session/callback"
|
||||
cfg.SessionSecure = strings.HasPrefix(cfg.BackendURL, "https://")
|
||||
|
||||
return cfg, nil
|
||||
|
||||
@@ -88,7 +88,7 @@ func TestLoad_GarminTokenStoreRootDefaultsNextToDBPath(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
want := filepath.Join("/var/lib/geniusrun", "garmin-tokenstores")
|
||||
want := filepath.Join("/var/lib/geniusrun", ".garmin")
|
||||
if cfg.GarminTokenStoreRoot != want {
|
||||
t.Errorf("GarminTokenStoreRoot = %q, want %q", cfg.GarminTokenStoreRoot, want)
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ type Config struct {
|
||||
PythonPath string
|
||||
GarminEmail string
|
||||
GarminPassword string
|
||||
// TokenStorePath, if set, is passed as GARMIN_TOKENSTORE so the wrapper
|
||||
// persists/resumes a Garmin session there instead of the default ~/.garth.
|
||||
// TokenStorePath is passed as GARMIN_TOKENSTORE so the wrapper
|
||||
// persists/resumes a Garmin session there.
|
||||
TokenStorePath string
|
||||
}
|
||||
|
||||
@@ -155,11 +155,9 @@ func (c *subprocessClient) ensureStarted(ctx context.Context) error {
|
||||
extraEnv := []string{
|
||||
"GARMIN_EMAIL=" + c.cfg.GarminEmail,
|
||||
"GARMIN_PASSWORD=" + c.cfg.GarminPassword,
|
||||
"GARMIN_TOKENSTORE=" + c.cfg.TokenStorePath,
|
||||
"PYTHONUNBUFFERED=1",
|
||||
}
|
||||
if c.cfg.TokenStorePath != "" {
|
||||
extraEnv = append(extraEnv, "GARMIN_TOKENSTORE="+c.cfg.TokenStorePath)
|
||||
}
|
||||
cmd.Env = append(os.Environ(), extraEnv...)
|
||||
|
||||
stdin, err := cmd.StdinPipe()
|
||||
@@ -199,7 +197,6 @@ func (c *subprocessClient) ensureStarted(ctx context.Context) error {
|
||||
|
||||
applog.FromContext(ctx).Info("garmin wrapper spawning",
|
||||
"python_path", pythonPath,
|
||||
"token_store_configured", c.cfg.TokenStorePath != "",
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user