92 lines
2.7 KiB
Go
92 lines
2.7 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strconv"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Settings configures the Metis service runtime.
|
||
|
|
type Settings struct {
|
||
|
|
BindAddr string
|
||
|
|
InventoryPath string
|
||
|
|
CacheDir string
|
||
|
|
ArtifactDir string
|
||
|
|
HistoryPath string
|
||
|
|
SnapshotsPath string
|
||
|
|
TargetsPath string
|
||
|
|
DefaultFlashHost string
|
||
|
|
FlashHosts []string
|
||
|
|
LocalHost string
|
||
|
|
AllowedUsers []string
|
||
|
|
AllowedGroups []string
|
||
|
|
MaxDeviceBytes int64
|
||
|
|
}
|
||
|
|
|
||
|
|
// FromEnv builds service settings with sensible defaults for local dev and in-cluster use.
|
||
|
|
func FromEnv() Settings {
|
||
|
|
dataDir := getenvDefault("METIS_DATA_DIR", "/var/lib/metis")
|
||
|
|
localHost := getenvDefault("METIS_LOCAL_HOST", hostnameOr("unknown"))
|
||
|
|
defaultFlashHost := getenvDefault("METIS_DEFAULT_FLASH_HOST", localHost)
|
||
|
|
flashHosts := splitList(getenvDefault("METIS_FLASH_HOSTS", defaultFlashHost))
|
||
|
|
return Settings{
|
||
|
|
BindAddr: getenvDefault("METIS_BIND_ADDR", ":8080"),
|
||
|
|
InventoryPath: getenvDefault("METIS_INVENTORY_PATH", "inventory.titan-rpi4.yaml"),
|
||
|
|
CacheDir: getenvDefault("METIS_CACHE_DIR", filepath.Join(dataDir, "cache")),
|
||
|
|
ArtifactDir: getenvDefault("METIS_ARTIFACT_DIR", filepath.Join(dataDir, "artifacts")),
|
||
|
|
HistoryPath: getenvDefault("METIS_HISTORY_PATH", filepath.Join(dataDir, "history.jsonl")),
|
||
|
|
SnapshotsPath: getenvDefault("METIS_SNAPSHOTS_PATH", filepath.Join(dataDir, "snapshots.json")),
|
||
|
|
TargetsPath: getenvDefault("METIS_TARGETS_PATH", filepath.Join(dataDir, "targets.json")),
|
||
|
|
DefaultFlashHost: defaultFlashHost,
|
||
|
|
FlashHosts: flashHosts,
|
||
|
|
LocalHost: localHost,
|
||
|
|
AllowedUsers: splitList(getenvDefault("METIS_ALLOWED_USERS", "")),
|
||
|
|
AllowedGroups: splitList(getenvDefault("METIS_ALLOWED_GROUPS", "admin,maintainer")),
|
||
|
|
MaxDeviceBytes: getenvInt64("METIS_MAX_DEVICE_BYTES", 300000000000),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getenvDefault(key, fallback string) string {
|
||
|
|
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
|
||
|
|
return value
|
||
|
|
}
|
||
|
|
return fallback
|
||
|
|
}
|
||
|
|
|
||
|
|
func getenvInt64(key string, fallback int64) int64 {
|
||
|
|
raw := strings.TrimSpace(os.Getenv(key))
|
||
|
|
if raw == "" {
|
||
|
|
return fallback
|
||
|
|
}
|
||
|
|
value, err := strconv.ParseInt(raw, 10, 64)
|
||
|
|
if err != nil {
|
||
|
|
return fallback
|
||
|
|
}
|
||
|
|
return value
|
||
|
|
}
|
||
|
|
|
||
|
|
func splitList(raw string) []string {
|
||
|
|
if strings.TrimSpace(raw) == "" {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
parts := strings.Split(raw, ",")
|
||
|
|
result := make([]string, 0, len(parts))
|
||
|
|
for _, part := range parts {
|
||
|
|
part = strings.TrimSpace(part)
|
||
|
|
if part == "" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
result = append(result, part)
|
||
|
|
}
|
||
|
|
return result
|
||
|
|
}
|
||
|
|
|
||
|
|
func hostnameOr(fallback string) string {
|
||
|
|
name, err := os.Hostname()
|
||
|
|
if err != nil || strings.TrimSpace(name) == "" {
|
||
|
|
return fallback
|
||
|
|
}
|
||
|
|
return strings.TrimSpace(name)
|
||
|
|
}
|