package registry import ( "encoding/json" "fmt" "os" "path" "sync" "time" "git.wzray.com/homelab/mastermind/internal/types" ) type FileStorage struct { filename string lock sync.Mutex } func NewFileStorage(filename string) *FileStorage { return &FileStorage{ filename: filename, } } func (fs *FileStorage) EnsureExists() { dirname := path.Dir(fs.filename) if _, err := os.Stat(dirname); os.IsNotExist(err) { os.MkdirAll(dirname, 0755) } if _, err := os.Stat(fs.filename); os.IsNotExist(err) { fs.Save(&storedConfig{ LastUpdate: time.Now().UnixMilli(), Nodes: make(map[string]types.Node), }) } } func (fs *FileStorage) Save(cfg *storedConfig) error { fs.lock.Lock() defer fs.lock.Unlock() buf, err := json.Marshal(cfg) if err != nil { return fmt.Errorf("marshal registry: %w", err) } if err := os.WriteFile(fs.filename, buf, 0644); err != nil { return fmt.Errorf("write registry file: %w", err) } return nil } func (fs *FileStorage) Load(cfg *storedConfig) error { fs.lock.Lock() defer fs.lock.Unlock() data, err := os.ReadFile(fs.filename) if err != nil { return fmt.Errorf("read registry file: %w", err) } if err := json.Unmarshal(data, cfg); err != nil { return fmt.Errorf("unmarshal registry: %w", err) } return nil }