extend virtual folders support to all storage backends

Fixes #241
This commit is contained in:
Nicola Murino
2021-03-21 19:15:47 +01:00
parent 0286da2356
commit d6dc3a507e
70 changed files with 6825 additions and 3740 deletions

View File

@@ -35,8 +35,10 @@ var (
// GCSFs is a Fs implementation for Google Cloud Storage.
type GCSFs struct {
connectionID string
localTempDir string
connectionID string
localTempDir string
// if not empty this fs is mouted as virtual folder in the specified path
mountPath string
config *GCSFsConfig
svc *storage.Client
ctxTimeout time.Duration
@@ -48,11 +50,16 @@ func init() {
}
// NewGCSFs returns an GCSFs object that allows to interact with Google Cloud Storage
func NewGCSFs(connectionID, localTempDir string, config GCSFsConfig) (Fs, error) {
func NewGCSFs(connectionID, localTempDir, mountPath string, config GCSFsConfig) (Fs, error) {
if localTempDir == "" {
localTempDir = filepath.Clean(os.TempDir())
}
var err error
fs := &GCSFs{
connectionID: connectionID,
localTempDir: localTempDir,
mountPath: mountPath,
config: &config,
ctxTimeout: 30 * time.Second,
ctxLongTimeout: 300 * time.Second,
@@ -152,7 +159,7 @@ func (fs *GCSFs) Open(name string, offset int64) (File, *pipeat.PipeReaderAt, fu
ctx, cancelFn := context.WithCancel(context.Background())
objectReader, err := obj.NewRangeReader(ctx, offset, -1)
if err == nil && offset > 0 && objectReader.Attrs.ContentEncoding == "gzip" {
err = fmt.Errorf("Range request is not possible for gzip content encoding, requested offset %v", offset)
err = fmt.Errorf("range request is not possible for gzip content encoding, requested offset %v", offset)
objectReader.Close()
}
if err != nil {
@@ -230,7 +237,7 @@ func (fs *GCSFs) Rename(source, target string) error {
return err
}
if hasContents {
return fmt.Errorf("Cannot rename non empty directory: %#v", source)
return fmt.Errorf("cannot rename non empty directory: %#v", source)
}
}
src := fs.svc.Bucket(fs.config.Bucket).Object(source)
@@ -266,7 +273,7 @@ func (fs *GCSFs) Remove(name string, isDir bool) error {
return err
}
if hasContents {
return fmt.Errorf("Cannot remove non empty directory: %#v", name)
return fmt.Errorf("cannot remove non empty directory: %#v", name)
}
}
ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(fs.ctxTimeout))
@@ -290,6 +297,11 @@ func (fs *GCSFs) Mkdir(name string) error {
return w.Close()
}
// MkdirAll does nothing, we don't have folder
func (*GCSFs) MkdirAll(name string, uid int, gid int) error {
return nil
}
// Symlink creates source as a symbolic link to target.
func (*GCSFs) Symlink(source, target string) error {
return ErrVfsUnsupported
@@ -441,7 +453,7 @@ func (*GCSFs) IsNotSupported(err error) bool {
// CheckRootPath creates the specified local root directory if it does not exists
func (fs *GCSFs) CheckRootPath(username string, uid int, gid int) bool {
// we need a local directory for temporary files
osFs := NewOsFs(fs.ConnectionID(), fs.localTempDir, nil)
osFs := NewOsFs(fs.ConnectionID(), fs.localTempDir, "")
return osFs.CheckRootPath(username, uid, gid)
}
@@ -510,6 +522,9 @@ func (fs *GCSFs) GetRelativePath(name string) string {
}
rel = path.Clean("/" + strings.TrimPrefix(rel, "/"+fs.config.KeyPrefix))
}
if fs.mountPath != "" {
rel = path.Join(fs.mountPath, rel)
}
return rel
}
@@ -578,6 +593,9 @@ func (GCSFs) HasVirtualFolders() bool {
// ResolvePath returns the matching filesystem path for the specified virtual path
func (fs *GCSFs) ResolvePath(virtualPath string) (string, error) {
if fs.mountPath != "" {
virtualPath = strings.TrimPrefix(virtualPath, fs.mountPath)
}
if !path.IsAbs(virtualPath) {
virtualPath = path.Clean("/" + virtualPath)
}