summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-09-06 22:46:20 +0800
committerGitHub <noreply@github.com>2021-09-06 16:46:20 +0200
commita807031a3093964387171a5bb07cc2c9181f0444 (patch)
tree01143ab519c89cb857c71f458be376558f9758c7 /modules
parent82da380af73cba733f15f12f12807a12f8efcc56 (diff)
downloadgitea-a807031a3093964387171a5bb07cc2c9181f0444.tar.gz
gitea-a807031a3093964387171a5bb07cc2c9181f0444.zip
Fix storage Iterate bug and Add storage doctor to delete garbage attachments (#16971)
* Fix storage Iterate bug and Add storage doctor to delete garbage attachments * Close object when used
Diffstat (limited to 'modules')
-rw-r--r--modules/doctor/storage.go76
-rw-r--r--modules/storage/minio.go4
2 files changed, 78 insertions, 2 deletions
diff --git a/modules/doctor/storage.go b/modules/doctor/storage.go
new file mode 100644
index 0000000000..cb06d66204
--- /dev/null
+++ b/modules/doctor/storage.go
@@ -0,0 +1,76 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package doctor
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/storage"
+)
+
+func checkAttachmentStorageFiles(logger log.Logger, autofix bool) error {
+ var total, garbageNum int
+ var deletePaths []string
+ if err := storage.Attachments.IterateObjects(func(p string, obj storage.Object) error {
+ defer obj.Close()
+
+ total++
+ stat, err := obj.Stat()
+ if err != nil {
+ return err
+ }
+ exist, err := models.ExistAttachmentsByUUID(stat.Name())
+ if err != nil {
+ return err
+ }
+ if !exist {
+ garbageNum++
+ if autofix {
+ deletePaths = append(deletePaths, p)
+ }
+ }
+ return nil
+ }); err != nil {
+ logger.Error("storage.Attachments.IterateObjects failed: %v", err)
+ return err
+ }
+
+ if garbageNum > 0 {
+ if autofix {
+ var deletedNum int
+ for _, p := range deletePaths {
+ if err := storage.Attachments.Delete(p); err != nil {
+ log.Error("Delete attachment %s failed: %v", p, err)
+ } else {
+ deletedNum++
+ }
+ }
+ logger.Info("%d missed information attachment detected, %d deleted.", garbageNum, deletedNum)
+ } else {
+ logger.Warn("Checked %d attachment, %d missed information.", total, garbageNum)
+ }
+ }
+ return nil
+}
+
+func checkStorageFiles(logger log.Logger, autofix bool) error {
+ if err := storage.Init(); err != nil {
+ logger.Error("storage.Init failed: %v", err)
+ return err
+ }
+ return checkAttachmentStorageFiles(logger, autofix)
+}
+
+func init() {
+ Register(&Check{
+ Title: "Check if there is garbage storage files",
+ Name: "storages",
+ IsDefault: false,
+ Run: checkStorageFiles,
+ AbortIfFailed: false,
+ SkipDatabaseInitialization: false,
+ Priority: 1,
+ })
+}
diff --git a/modules/storage/minio.go b/modules/storage/minio.go
index 724445c0ab..f78ba6aa27 100644
--- a/modules/storage/minio.go
+++ b/modules/storage/minio.go
@@ -151,7 +151,7 @@ type minioFileInfo struct {
}
func (m minioFileInfo) Name() string {
- return m.ObjectInfo.Key
+ return path.Base(m.ObjectInfo.Key)
}
func (m minioFileInfo) Size() int64 {
@@ -219,7 +219,7 @@ func (m *MinioStorage) IterateObjects(fn func(path string, obj Object) error) er
}
if err := func(object *minio.Object, fn func(path string, obj Object) error) error {
defer object.Close()
- return fn(strings.TrimPrefix(m.basePath, mObjInfo.Key), &minioObject{object})
+ return fn(strings.TrimPrefix(mObjInfo.Key, m.basePath), &minioObject{object})
}(object, fn); err != nil {
return convertMinioErr(err)
}