Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Symlink, Lstat and ReadLink function for the Driver interface #229

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type Driver interface {
MkdirAll(path string) error
// Create creates the named file
Create(path string) (err error)
// Symlink create a symbolic link
Symlink(oldname, newname string) error
// Remove removes the specified file or directory
Remove(path string) error
// Rename renames a file
Expand All @@ -27,10 +29,14 @@ type Driver interface {
WalkDir(root string, fn fs.WalkDirFunc) error
// Open opens the named file for reading
Open(path string) (f http.File, err error)
// Stat returns the os.FileInfo describing the named file
// Stat returns the os.FileInfo describing the named file, if path is a symbolic link, read the real file
Stat(path string) (fi os.FileInfo, err error)
// Lstat returns the os.FileInfo describing the named file, if path is a symbolic link, read the symbolic link info
Lstat(path string) (fi os.FileInfo, err error)
// GetFileTime get the creation time, last access time, last modify time of the path
GetFileTime(path string) (cTime time.Time, aTime time.Time, mTime time.Time, err error)
// Write write src file to dest file
Write(src string, dest string) error
// ReadLink returns the destination of the named symbolic link
ReadLink(path string) (string, error)
}
21 changes: 21 additions & 0 deletions driver/minio/minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7/pkg/s3utils"
"github.com/no-src/gofs/driver"
nsfs "github.com/no-src/gofs/fs"
"github.com/no-src/gofs/internal/rate"
"github.com/no-src/gofs/retry"
"github.com/no-src/log"
Expand Down Expand Up @@ -144,6 +145,18 @@ func (c *minIODriver) Create(path string) (err error) {
return err
}

func (c *minIODriver) Symlink(oldname, newname string) (err error) {
if err = c.Remove(newname); err != nil {
return err
}
err = c.reconnectIfLost(func() error {
content := nsfs.SymlinkText(oldname)
_, err = c.client.PutObject(c.ctx, c.bucketName, newname, bytes.NewReader([]byte(content)), int64(len(content)), minio.PutObjectOptions{})
return err
})
return err
}

func (c *minIODriver) Remove(path string) (err error) {
return c.reconnectIfLost(func() error {
infoChan := c.client.ListObjects(c.ctx, c.bucketName, minio.ListObjectsOptions{
Expand Down Expand Up @@ -250,6 +263,10 @@ func (c *minIODriver) Stat(path string) (fi os.FileInfo, err error) {
return fi, err
}

func (c *minIODriver) Lstat(path string) (fi os.FileInfo, err error) {
return c.Stat(path)
}

func (c *minIODriver) GetFileTime(path string) (cTime time.Time, aTime time.Time, mTime time.Time, err error) {
err = c.reconnectIfLost(func() error {
var info minio.ObjectInfo
Expand Down Expand Up @@ -288,6 +305,10 @@ func (c *minIODriver) Client() *minio.Client {
return c.client
}

func (c *minIODriver) ReadLink(path string) (string, error) {
return path, nil
}

// fPutObject - Create an object in a bucket, with contents from file at filePath. Allows request cancellation.
// Keep up to date with the minio.Client.FPutObject.
func (c *minIODriver) fPutObject(ctx context.Context, bucketName, objectName, filePath string, opts minio.PutObjectOptions) (info minio.UploadInfo, err error) {
Expand Down
29 changes: 27 additions & 2 deletions driver/sftp/sftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,18 @@ func (sc *sftpDriver) Create(path string) (err error) {
return err
}

func (sc *sftpDriver) Symlink(oldname, newname string) error {
if err := sc.Remove(newname); err != nil {
return err
}
return sc.reconnectIfLost(func() error {
return sc.client.Symlink(oldname, newname)
})
}

func (sc *sftpDriver) Remove(path string) error {
return sc.reconnectIfLost(func() error {
f, err := sc.client.Stat(path)
f, err := sc.client.Lstat(path)
if os.IsNotExist(err) {
return nil
}
Expand Down Expand Up @@ -260,10 +269,18 @@ func (sc *sftpDriver) Stat(path string) (fi os.FileInfo, err error) {
return fi, err
}

func (sc *sftpDriver) Lstat(path string) (fi os.FileInfo, err error) {
err = sc.reconnectIfLost(func() error {
fi, err = sc.client.Lstat(path)
return err
})
return fi, err
}

func (sc *sftpDriver) GetFileTime(path string) (cTime time.Time, aTime time.Time, mTime time.Time, err error) {
err = sc.reconnectIfLost(func() error {
var fi os.FileInfo
fi, err = sc.client.Stat(path)
fi, err = sc.client.Lstat(path)
if err != nil {
return err
}
Expand Down Expand Up @@ -315,6 +332,14 @@ func (sc *sftpDriver) Write(src string, dest string) (err error) {
return err
}

func (sc *sftpDriver) ReadLink(path string) (realPath string, err error) {
err = sc.reconnectIfLost(func() error {
realPath, err = sc.client.ReadLink(path)
return err
})
return realPath, err
}

type statDirEntry struct {
info fs.FileInfo
}
Expand Down