| 103 | } |
| 104 | |
| 105 | func Load() (*Config, error) { |
| 106 | cfg := DefaultConfig() |
| 107 | |
| 108 | // Data-dir overrides affect where config.toml lives, so apply them first. |
| 109 | if v := os.Getenv("PAD_DATA_DIR"); v != "" { |
| 110 | cfg.DataDir = v |
| 111 | cfg.DBPath = filepath.Join(v, "pad.db") |
| 112 | cfg.ConfigPath = filepath.Join(v, "config.toml") |
| 113 | } |
| 114 | if v := os.Getenv("PAD_DB_PATH"); v != "" { |
| 115 | cfg.DBPath = v |
| 116 | cfg.DataDir = filepath.Dir(cfg.DBPath) |
| 117 | cfg.ConfigPath = filepath.Join(cfg.DataDir, "config.toml") |
| 118 | } |
| 119 | |
| 120 | // Ensure data directory exists |
| 121 | if err := os.MkdirAll(cfg.DataDir, 0755); err != nil { |
| 122 | return nil, err |
| 123 | } |
| 124 | |
| 125 | // Ensure logs directory exists |
| 126 | if err := os.MkdirAll(filepath.Join(cfg.DataDir, "logs"), 0755); err != nil { |
| 127 | return nil, err |
| 128 | } |
| 129 | |
| 130 | // Load config file if it exists |
| 131 | if _, err := os.Stat(cfg.ConfigPath); err == nil { |
| 132 | cfg.LoadedFromFile = true |
| 133 | if _, err := toml.DecodeFile(cfg.ConfigPath, cfg); err != nil { |
| 134 | return nil, err |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // Environment variable overrides |
| 139 | if v := os.Getenv("PAD_MODE"); v != "" { |
| 140 | cfg.Mode = v |
| 141 | cfg.LoadedFromEnv = true |
| 142 | if v == ModeCloud { |
| 143 | // PAD_MODE=cloud is an explicit operator opt-in to running |
| 144 | // THIS server in cloud-tenant mode. See cloudServerOptIn. |
| 145 | cfg.cloudServerOptIn = true |
| 146 | } |
| 147 | } |
| 148 | if v := os.Getenv("PAD_HOST"); v != "" { |
| 149 | cfg.Host = v |
| 150 | cfg.LoadedFromEnv = true |
| 151 | } |
| 152 | if v := os.Getenv("PAD_PORT"); v != "" { |
| 153 | if port, err := strconv.Atoi(v); err == nil { |
| 154 | cfg.Port = port |
| 155 | cfg.LoadedFromEnv = true |
| 156 | } |
| 157 | } |
| 158 | if v := os.Getenv("PAD_URL"); v != "" { |
| 159 | cfg.URL = v |
| 160 | cfg.LoadedFromEnv = true |
| 161 | if cfg.Mode == "" { |
| 162 | cfg.Mode = ModeRemote |