package update import ( domain "RenewCMS/internal/domain/update" "encoding/json" "errors" "fmt" "io/fs" ) type FSRestartRequestStore struct { files domain.HelperFilesystem path string } var _ domain.RestartRequestStore = &FSRestartRequestStore{} func NewFSRestartRequestStore(files domain.HelperFilesystem, path string) *FSRestartRequestStore { return &FSRestartRequestStore{files: files, path: path} } func (s *FSRestartRequestStore) Write(request domain.RestartRequest) error { return writeJSONThroughTemporary(s.files, s.path, request, statusFilePermissions) } func (s *FSRestartRequestStore) Read() (domain.RestartRequest, error) { info, err := s.files.Lstat(s.path) if errors.Is(err, fs.ErrNotExist) { return domain.RestartRequest{}, domain.ErrNoRestartRequest } if err != nil { return domain.RestartRequest{}, err } if info.IsSymlink { return domain.RestartRequest{}, domain.SymlinkError{Path: s.path} } if !info.IsRegular { return domain.RestartRequest{}, fmt.Errorf("%s is not a regular file", s.path) } content, err := s.files.ReadFile(s.path) if err != nil { return domain.RestartRequest{}, err } var request domain.RestartRequest return request, json.Unmarshal(content, &request) } func (s *FSRestartRequestStore) Delete() error { return removeThrough(s.files, s.path) } func removeThrough(files domain.HelperFilesystem, path string) error { if err := files.Remove(path); err != nil && !errors.Is(err, fs.ErrNotExist) { return err } return nil } func writeJSONThroughTemporary(files domain.HelperFilesystem, path string, value any, mode uint32) error { content, err := json.Marshal(value) if err != nil { return err } return writeThroughTemporary(files, path, content, mode) } func writeThroughTemporary(files domain.HelperFilesystem, path string, content []byte, mode uint32) error { temporary := path + domain.ResultTempSuffix if _, err := files.Lstat(temporary); err == nil { if err := files.Remove(temporary); err != nil { return err } } if err := files.CreateExclusive(temporary, content, mode); err != nil { return err } if err := files.Rename(temporary, path); err != nil { _ = files.Remove(temporary) return err } return nil }