package config import ( "os" "path/filepath" "gopkg.in/yaml.v3" ) // Config holds the arca configuration. type Config struct { Devices map[string]DeviceConfig `yaml:"devices"` } // DeviceConfig holds per-device settings. type DeviceConfig struct { UUID string `yaml:"uuid"` Mountpoint string `yaml:"mountpoint,omitempty"` Methods []string `yaml:"methods,omitempty"` Keyfile string `yaml:"keyfile,omitempty"` } // ResolvedDevice holds the effective settings for a device lookup. type ResolvedDevice struct { UUID string Mountpoint string Methods []string Keyfile string } // Load reads the config file. Returns an empty config if the file doesn't exist. func Load() *Config { cfg := &Config{ Devices: make(map[string]DeviceConfig), } data, err := os.ReadFile(configPath()) if err != nil { return cfg } yaml.Unmarshal(data, cfg) return cfg } // ResolveDevice looks up by alias name first, then checks if the argument // is a device path matching a known alias (e.g. "/dev/sda1" matches "sda1"). // If nothing matches, returns defaults for a bare device path. func (c *Config) ResolveDevice(nameOrPath string) ResolvedDevice { // Direct alias match. if dev, ok := c.Devices[nameOrPath]; ok { return resolvedFrom(dev) } // Match device path against aliases: "/dev/sda1" matches alias "sda1". base := filepath.Base(nameOrPath) if dev, ok := c.Devices[base]; ok { return resolvedFrom(dev) } return ResolvedDevice{ Methods: []string{"passphrase"}, } } func resolvedFrom(dev DeviceConfig) ResolvedDevice { methods := dev.Methods if len(methods) == 0 { methods = []string{"passphrase"} } return ResolvedDevice{ UUID: dev.UUID, Mountpoint: dev.Mountpoint, Methods: methods, Keyfile: dev.Keyfile, } } // AliasFor returns the config alias for a given UUID, or "" if none. func (c *Config) AliasFor(uuid string) string { for name, dev := range c.Devices { if dev.UUID == uuid { return name } } return "" } // Path returns the config file path, respecting XDG_CONFIG_HOME. func Path() string { return configPath() } func configPath() string { if dir := os.Getenv("XDG_CONFIG_HOME"); dir != "" { return filepath.Join(dir, "arca", "config.yaml") } home, _ := os.UserHomeDir() return filepath.Join(home, ".config", "arca", "config.yaml") }