aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--s3_fs.go46
1 files changed, 45 insertions, 1 deletions
diff --git a/s3_fs.go b/s3_fs.go
index 93ce8ac..f8983ef 100644
--- a/s3_fs.go
+++ b/s3_fs.go
@@ -95,7 +95,51 @@ func (s S3FS) RemoveAll(ctx context.Context, name string) error {
func (s S3FS) Rename(ctx context.Context, oldName, newName string) error {
s.ctx = ctx
- return errors.New("Not implemented Rename")
+
+ po := NewS3Path(oldName)
+ pn := NewS3Path(newName)
+ if po.class == ROOT || pn.class == ROOT {
+ return errors.New("Unable to rename root folder")
+ } else if po.class == BUCKET || pn.class == BUCKET {
+ log.Println("Moving a bucket is not implemented yet")
+ return nil
+ }
+
+ //Check that newName is not inside oldName
+ if len(newName) > len(oldName) && newName[:len(oldName)] == oldName {
+ return errors.New("Cannot move an entity inside itself (eg. moving /data in /data/test is impossible)")
+ }
+
+ //Gather all keys, copy the object, delete the original
+ objCh := s.mc.ListObjects(s.ctx, po.bucket, minio.ListObjectsOptions{Prefix: po.key, Recursive: true})
+ for obj := range objCh {
+ log.Println("found object", obj)
+ src := minio.CopySrcOptions{
+ Bucket: po.bucket,
+ Object: obj.Key,
+ }
+
+ dst := minio.CopyDestOptions{
+ Bucket: pn.bucket,
+ Object: path.Join(pn.key, obj.Key[len(po.key):]),
+ }
+
+ _, err := s.mc.CopyObject(s.ctx, dst, src)
+ log.Println("copy", obj)
+ if err != nil {
+ log.Println("copy err", err)
+ return err
+ }
+
+ log.Println("delete", obj)
+ err = s.mc.RemoveObject(s.ctx, po.bucket, obj.Key, minio.RemoveObjectOptions{})
+ if err != nil /*&& err.Code != 200*/ /* @FIXME workaround for garage's bug #98 */ {
+ log.Println("delete err", err)
+ return err
+ }
+ }
+
+ return nil
}
func (s S3FS) Stat(ctx context.Context, name string) (os.FileInfo, error) {