bagage/s3/stat.go

131 lines
2.2 KiB
Go
Raw Normal View History

2021-11-19 18:54:49 +00:00
package s3
2021-08-23 18:40:03 +00:00
import (
2021-11-19 19:35:38 +00:00
"log"
2021-08-23 18:40:03 +00:00
"errors"
"io/fs"
"path"
"time"
"github.com/minio/minio-go/v7"
)
type S3Stat struct {
fs *S3FS
obj minio.ObjectInfo
path S3Path
}
/*
* Stat a path knowing its ObjectInfo
*/
func NewS3StatFromObjectInfo(fs *S3FS, bucket string, obj minio.ObjectInfo) (*S3Stat, error) {
s := new(S3Stat)
s.path = NewTrustedS3Path(bucket, obj)
s.obj = obj
s.fs = fs
2021-11-19 18:54:49 +00:00
fs.cache[s.path.Path] = s
2021-08-23 18:40:03 +00:00
return s, nil
}
/*
* Stat a path without additional information
*/
func NewS3Stat(fs *S3FS, path string) (*S3Stat, error) {
cache := fs.cache
if entry, ok := cache[path]; ok {
return entry, nil
}
s := new(S3Stat)
s.fs = fs
s.path = NewS3Path(path)
if err := s.Refresh(); err != nil {
return nil, err
}
2021-11-19 18:54:49 +00:00
if s.path.Class&OPAQUE_KEY != 0 {
2021-08-23 18:40:03 +00:00
return nil, errors.New("Failed to precisely determine the key type, this a logic error.")
}
cache[path] = s
2021-11-19 18:54:49 +00:00
cache[s.path.Path] = s
2021-08-23 18:40:03 +00:00
return s, nil
}
func (s *S3Stat) Refresh() error {
2021-11-19 18:54:49 +00:00
if s.path.Class == ROOT || s.path.Class == BUCKET {
2021-08-23 18:40:03 +00:00
return nil
}
mc := s.fs.mc
// Compute the prefix to have the desired behaviour for our stat logic
2021-11-19 18:54:49 +00:00
prefix := s.path.Key
2021-08-23 18:40:03 +00:00
if prefix[len(prefix)-1:] == "/" {
prefix = prefix[:len(prefix)-1]
}
// Get info and check if the key exists
2021-11-19 18:54:49 +00:00
objs_info := mc.ListObjects(s.fs.ctx, s.path.Bucket, minio.ListObjectsOptions{
2021-08-23 18:40:03 +00:00
Prefix: prefix,
Recursive: false,
})
found := false
for object := range objs_info {
if object.Err != nil {
return object.Err
}
if object.Key == prefix || object.Key == prefix+"/" {
s.obj = object
2021-11-19 18:54:49 +00:00
s.path = NewTrustedS3Path(s.path.Bucket, object)
2021-08-23 18:40:03 +00:00
found = true
break
}
}
if !found {
return fs.ErrNotExist
}
return nil
}
func (s *S3Stat) Name() string {
2021-11-19 18:54:49 +00:00
if s.path.Class == ROOT {
2021-08-23 18:40:03 +00:00
return "/"
2021-11-19 18:54:49 +00:00
} else if s.path.Class == BUCKET {
return s.path.Bucket
2021-08-23 18:40:03 +00:00
} else {
2021-11-19 18:54:49 +00:00
return path.Base(s.path.Key)
2021-08-23 18:40:03 +00:00
}
}
func (s *S3Stat) Size() int64 {
2021-11-19 19:35:38 +00:00
log.Println("stat size: ", s.obj.Size)
2021-08-23 18:40:03 +00:00
return s.obj.Size
}
func (s *S3Stat) Mode() fs.FileMode {
2021-11-19 18:54:49 +00:00
if s.path.Class == OBJECT {
2021-08-23 18:40:03 +00:00
return fs.ModePerm
} else {
return fs.ModeDir | fs.ModePerm
}
}
func (s *S3Stat) ModTime() time.Time {
return s.obj.LastModified
}
func (s *S3Stat) IsDir() bool {
2021-11-19 18:54:49 +00:00
return s.path.Class != OBJECT
2021-08-23 18:40:03 +00:00
}
func (s *S3Stat) Sys() interface{} {
return nil
}