Files
RenewCMS/internal/infrastructure/update/fsRestartRequestStore.go
T

83 lines
2.2 KiB
Go

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
}