From c915313ec9888e73cf2b61500ea13e1f27e05dcf Mon Sep 17 00:00:00 2001 From: Andy Hsu Date: Sun, 5 Mar 2023 15:36:12 +0800 Subject: [PATCH] feat: rename then delete if storage doesn't support overwrite upload (close #3643) --- drivers/aliyundrive_open/meta.go | 17 +++++++++-------- internal/driver/config.go | 21 +++++++++++---------- internal/op/fs.go | 29 ++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/drivers/aliyundrive_open/meta.go b/drivers/aliyundrive_open/meta.go index 48f3328c..d8680449 100644 --- a/drivers/aliyundrive_open/meta.go +++ b/drivers/aliyundrive_open/meta.go @@ -16,14 +16,15 @@ type Addition struct { } var config = driver.Config{ - Name: "AliyundriveOpen", - LocalSort: false, - OnlyLocal: false, - OnlyProxy: false, - NoCache: false, - NoUpload: false, - NeedMs: false, - DefaultRoot: "root", + Name: "AliyundriveOpen", + LocalSort: false, + OnlyLocal: false, + OnlyProxy: false, + NoCache: false, + NoUpload: false, + NeedMs: false, + DefaultRoot: "root", + NoOverwriteUpload: true, } func init() { diff --git a/internal/driver/config.go b/internal/driver/config.go index 53a3fdb6..35ff6e4f 100644 --- a/internal/driver/config.go +++ b/internal/driver/config.go @@ -1,16 +1,17 @@ package driver type Config struct { - Name string `json:"name"` - LocalSort bool `json:"local_sort"` - OnlyLocal bool `json:"only_local"` - OnlyProxy bool `json:"only_proxy"` - NoCache bool `json:"no_cache"` - NoUpload bool `json:"no_upload"` - NeedMs bool `json:"need_ms"` // if need get message from user, such as validate code - DefaultRoot string `json:"default_root"` - CheckStatus bool `json:"-"` - Alert string `json:"alert"` //info,success,warning,danger + Name string `json:"name"` + LocalSort bool `json:"local_sort"` + OnlyLocal bool `json:"only_local"` + OnlyProxy bool `json:"only_proxy"` + NoCache bool `json:"no_cache"` + NoUpload bool `json:"no_upload"` + NeedMs bool `json:"need_ms"` // if need get message from user, such as validate code + DefaultRoot string `json:"default_root"` + CheckStatus bool `json:"-"` + Alert string `json:"alert"` //info,success,warning,danger + NoOverwriteUpload bool `json:"-"` } func (c Config) MustProxy() bool { diff --git a/internal/op/fs.go b/internal/op/fs.go index 5dfe97f0..89ed3b3f 100644 --- a/internal/op/fs.go +++ b/internal/op/fs.go @@ -459,6 +459,7 @@ func Remove(ctx context.Context, storage driver.Driver, path string) error { if err != nil { // if object not found, it's ok if errs.IsObjectNotFound(err) { + log.Debugf("%s have been removed", path) return nil } return errors.WithMessage(err, "failed to get object") @@ -497,6 +498,8 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *mo // if file exist and size = 0, delete it dstDirPath = utils.FixAndCleanPath(dstDirPath) dstPath := stdpath.Join(dstDirPath, file.GetName()) + tempName := file.GetName() + ".alist_to_delete" + tempPath := stdpath.Join(dstDirPath, tempName) fi, err := GetUnwrap(ctx, storage, dstPath) if err == nil { if fi.GetSize() == 0 { @@ -504,6 +507,12 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *mo if err != nil { return errors.WithMessagef(err, "failed remove file that exist and have size 0") } + } else if storage.Config().NoOverwriteUpload { + // try to rename old obj + err = Rename(ctx, storage, dstPath, tempName) + if err != nil { + return err + } } else { file.Old = fi } @@ -542,10 +551,20 @@ func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file *mo return errs.NotImplement } log.Debugf("put file [%s] done", file.GetName()) - //if err == nil { - // //clear cache - // key := stdpath.Join(storage.GetStorage().MountPath, dstDirPath) - // listCache.Del(key) - //} + if storage.Config().NoOverwriteUpload && fi != nil && fi.GetSize() > 0 { + if err != nil { + // upload failed, recover old obj + err := Rename(ctx, storage, tempPath, file.GetName()) + if err != nil { + log.Errorf("failed recover old obj: %+v", err) + } + } else { + // upload success, remove old obj + err := Remove(ctx, storage, tempPath) + if err != nil { + return err + } + } + } return errors.WithStack(err) }