|
- package local
-
- import (
- "crypto/sha256"
- "io"
- "os"
- "path/filepath"
-
- "gitlink.org.cn/cloudream/common/pkgs/logger"
- "gitlink.org.cn/cloudream/common/utils/io2"
- stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
- jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
- )
-
- type BaseStore struct {
- root string
- detail *jcstypes.UserSpaceDetail
- }
-
- func NewBaseStore(root string, detail *jcstypes.UserSpaceDetail) (*BaseStore, error) {
- return &BaseStore{
- root: root,
- detail: detail,
- }, nil
- }
-
- func (s *BaseStore) Write(pat jcstypes.JPath, stream io.Reader, opt stgtypes.WriteOption) (stgtypes.FileInfo, error) {
- log := s.getLogger()
-
- absObjPath := filepath.Join(s.root, pat.String())
-
- err := os.MkdirAll(filepath.Dir(absObjPath), 0755)
- if err != nil {
- return stgtypes.FileInfo{}, err
- }
-
- f, err := os.Create(absObjPath)
- if err != nil {
- return stgtypes.FileInfo{}, err
- }
- defer f.Close()
-
- counter := io2.Counter(stream)
- hasher := io2.NewReadHasher(sha256.New(), counter)
-
- _, err = io.Copy(f, hasher)
- if err != nil {
- return stgtypes.FileInfo{}, err
- }
-
- if !opt.ModTime.IsZero() {
- err := os.Chtimes(absObjPath, opt.ModTime, opt.ModTime)
- if err != nil {
- log.Warnf("change file %v mod time: %v", absObjPath, err)
- }
- }
-
- return stgtypes.FileInfo{
- Path: pat,
- Size: counter.Count(),
- Hash: jcstypes.NewFullHash(hasher.Sum()),
- }, nil
- }
-
- func (s *BaseStore) Read(objPath jcstypes.JPath, opt stgtypes.OpenOption) (io.ReadCloser, error) {
- absObjPath := filepath.Join(s.root, objPath.JoinOSPath())
- file, err := os.Open(absObjPath)
- if err != nil {
- return nil, err
- }
-
- if opt.Offset > 0 {
- _, err = file.Seek(opt.Offset, io.SeekStart)
- if err != nil {
- file.Close()
- return nil, err
- }
- }
-
- var ret io.ReadCloser = file
-
- if opt.Length >= 0 {
- ret = io2.Length(ret, opt.Length)
- }
-
- return ret, nil
- }
-
- func (s *BaseStore) Mkdir(path jcstypes.JPath) error {
- absObjPath := filepath.Join(s.root, path.JoinOSPath())
- err := os.MkdirAll(absObjPath, 0755)
- if err != nil {
- return err
- }
-
- return nil
- }
-
- func (s *BaseStore) ReadDir(pat jcstypes.JPath) stgtypes.DirReader {
- return &DirReader{
- absRootPath: filepath.Join(s.root, pat.JoinOSPath()),
- rootJPath: pat.Clone(),
- }
- }
-
- func (s *BaseStore) CleanTemps() {
- log := s.getLogger()
-
- tempDir := filepath.Join(s.root, s.detail.UserSpace.WorkingDir.JoinOSPath(), stgtypes.TempWorkingDir)
- entries, err := os.ReadDir(tempDir)
- if err != nil {
- log.Warnf("read temp dir: %v", err)
- return
- }
-
- for _, entry := range entries {
- if entry.IsDir() {
- continue
- }
-
- info, err := entry.Info()
- if err != nil {
- log.Warnf("get temp file %v info: %v", entry.Name(), err)
- continue
- }
-
- path := filepath.Join(tempDir, entry.Name())
- err = os.Remove(path)
- if err != nil {
- log.Warnf("remove temp file %v: %v", path, err)
- } else {
- log.Infof("remove unused temp file %v, size: %v, last mod time: %v", path, info.Size(), info.ModTime())
- }
- }
- }
-
- func (s *BaseStore) Test() error {
- _, err := os.Stat(s.root)
- return err
- }
-
- func (s *BaseStore) getLogger() logger.Logger {
- return logger.WithField("BaseStore", "Local").WithField("UserSpace", s.detail.UserSpace)
- }
|