package storage import ( "errors" "fmt" "sync" "gitea.avt.data-center.id/othman.suseno/atlas/internal/models" ) var ( ErrNFSExportNotFound = errors.New("NFS export not found") ErrNFSExportExists = errors.New("NFS export already exists") ) // NFSStore manages NFS exports type NFSStore struct { mu sync.RWMutex exports map[string]*models.NFSExport nextID int } // NewNFSStore creates a new NFS export store func NewNFSStore() *NFSStore { return &NFSStore{ exports: make(map[string]*models.NFSExport), nextID: 1, } } // List returns all NFS exports func (s *NFSStore) List() []models.NFSExport { s.mu.RLock() defer s.mu.RUnlock() exports := make([]models.NFSExport, 0, len(s.exports)) for _, export := range s.exports { exports = append(exports, *export) } return exports } // Get returns an export by ID func (s *NFSStore) Get(id string) (*models.NFSExport, error) { s.mu.RLock() defer s.mu.RUnlock() export, ok := s.exports[id] if !ok { return nil, ErrNFSExportNotFound } return export, nil } // GetByPath returns an export by path func (s *NFSStore) GetByPath(path string) (*models.NFSExport, error) { s.mu.RLock() defer s.mu.RUnlock() for _, export := range s.exports { if export.Path == path { return export, nil } } return nil, ErrNFSExportNotFound } // Create creates a new NFS export func (s *NFSStore) Create(path, dataset string, clients []string, readOnly, rootSquash bool) (*models.NFSExport, error) { s.mu.Lock() defer s.mu.Unlock() // Check if path already exists for _, export := range s.exports { if export.Path == path { return nil, ErrNFSExportExists } } id := fmt.Sprintf("nfs-%d", s.nextID) s.nextID++ export := &models.NFSExport{ ID: id, Path: path, Dataset: dataset, Clients: clients, ReadOnly: readOnly, RootSquash: rootSquash, Enabled: true, } s.exports[id] = export return export, nil } // Update updates an existing export func (s *NFSStore) Update(id string, clients []string, readOnly, rootSquash, enabled bool) error { s.mu.Lock() defer s.mu.Unlock() export, ok := s.exports[id] if !ok { return ErrNFSExportNotFound } export.ReadOnly = readOnly export.RootSquash = rootSquash export.Enabled = enabled if clients != nil { export.Clients = clients } return nil } // Delete removes an export func (s *NFSStore) Delete(id string) error { s.mu.Lock() defer s.mu.Unlock() if _, ok := s.exports[id]; !ok { return ErrNFSExportNotFound } delete(s.exports, id) return nil }