Skip to content

Commit c772934

Browse files
zeripathlunny
andauthored
Adjust gitea doctor --run storages to check all storage types (#21785)
The doctor check `storages` currently only checks the attachment storage. This PR adds some basic garbage collection functionality for the other types of storage. Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
1 parent de6dfb7 commit c772934

File tree

10 files changed

+296
-31
lines changed

10 files changed

+296
-31
lines changed

models/git/lfs.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,9 @@ func LFSObjectAccessible(user *user_model.User, oid string) (bool, error) {
235235
return count > 0, err
236236
}
237237

238-
// LFSObjectIsAssociated checks if a provided Oid is associated
239-
func LFSObjectIsAssociated(oid string) (bool, error) {
240-
return db.GetEngine(db.DefaultContext).Exist(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
238+
// ExistsLFSObject checks if a provided Oid exists within the DB
239+
func ExistsLFSObject(ctx context.Context, oid string) (bool, error) {
240+
return db.GetEngine(ctx).Exist(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
241241
}
242242

243243
// LFSAutoAssociate auto associates accessible LFSMetaObjects

models/packages/package_blob.go

+7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ func GetBlobByID(ctx context.Context, blobID int64) (*PackageBlob, error) {
6262
return pb, nil
6363
}
6464

65+
// ExistPackageBlobWithSHA returns if a package blob exists with the provided sha
66+
func ExistPackageBlobWithSHA(ctx context.Context, blobSha256 string) (bool, error) {
67+
return db.GetEngine(ctx).Exist(&PackageBlob{
68+
HashSHA256: blobSha256,
69+
})
70+
}
71+
6572
// FindExpiredUnreferencedBlobs gets all blobs without associated files older than the specific duration
6673
func FindExpiredUnreferencedBlobs(ctx context.Context, olderThan time.Duration) ([]*PackageBlob, error) {
6774
pbs := make([]*PackageBlob, 0, 10)

models/repo/archiver.go

+36
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ package repo
77
import (
88
"context"
99
"fmt"
10+
"strconv"
11+
"strings"
1012
"time"
1113

1214
"code.gitea.io/gitea/models/db"
1315
"code.gitea.io/gitea/modules/git"
1416
"code.gitea.io/gitea/modules/timeutil"
17+
"code.gitea.io/gitea/modules/util"
1518

1619
"xorm.io/builder"
1720
)
@@ -44,6 +47,28 @@ func (archiver *RepoArchiver) RelativePath() string {
4447
return fmt.Sprintf("%d/%s/%s.%s", archiver.RepoID, archiver.CommitID[:2], archiver.CommitID, archiver.Type.String())
4548
}
4649

50+
// repoArchiverForRelativePath takes a relativePath created from (archiver *RepoArchiver) RelativePath() and creates a shell repoArchiver struct representing it
51+
func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) {
52+
parts := strings.SplitN(relativePath, "/", 3)
53+
if len(parts) != 3 {
54+
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
55+
}
56+
repoID, err := strconv.ParseInt(parts[0], 10, 64)
57+
if err != nil {
58+
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
59+
}
60+
nameExts := strings.SplitN(parts[2], ".", 2)
61+
if len(nameExts) != 2 {
62+
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
63+
}
64+
65+
return &RepoArchiver{
66+
RepoID: repoID,
67+
CommitID: parts[1] + nameExts[0],
68+
Type: git.ToArchiveType(nameExts[1]),
69+
}, nil
70+
}
71+
4772
var delRepoArchiver = new(RepoArchiver)
4873

4974
// DeleteRepoArchiver delete archiver
@@ -65,6 +90,17 @@ func GetRepoArchiver(ctx context.Context, repoID int64, tp git.ArchiveType, comm
6590
return nil, nil
6691
}
6792

93+
// ExistsRepoArchiverWithStoragePath checks if there is a RepoArchiver for a given storage path
94+
func ExistsRepoArchiverWithStoragePath(ctx context.Context, storagePath string) (bool, error) {
95+
// We need to invert the path provided func (archiver *RepoArchiver) RelativePath() above
96+
archiver, err := repoArchiverForRelativePath(storagePath)
97+
if err != nil {
98+
return false, err
99+
}
100+
101+
return db.GetEngine(ctx).Exist(archiver)
102+
}
103+
68104
// AddRepoArchiver adds an archiver
69105
func AddRepoArchiver(ctx context.Context, archiver *RepoArchiver) error {
70106
_, err := db.GetEngine(ctx).Insert(archiver)

models/repo/attachment.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ func GetAttachmentsByUUIDs(ctx context.Context, uuids []string) ([]*Attachment,
122122
return attachments, db.GetEngine(ctx).In("uuid", uuids).Find(&attachments)
123123
}
124124

125-
// ExistAttachmentsByUUID returns true if attachment is exist by given UUID
126-
func ExistAttachmentsByUUID(uuid string) (bool, error) {
127-
return db.GetEngine(db.DefaultContext).Where("`uuid`=?", uuid).Exist(new(Attachment))
125+
// ExistAttachmentsByUUID returns true if attachment exists with the given UUID
126+
func ExistAttachmentsByUUID(ctx context.Context, uuid string) (bool, error) {
127+
return db.GetEngine(ctx).Where("`uuid`=?", uuid).Exist(new(Attachment))
128128
}
129129

130130
// GetAttachmentsByIssueID returns all attachments of an issue.

models/repo/avatar.go

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ func (repo *Repository) CustomAvatarRelativePath() string {
2424
return repo.Avatar
2525
}
2626

27+
// ExistsWithAvatarAtStoragePath returns true if there is a user with this Avatar
28+
func ExistsWithAvatarAtStoragePath(ctx context.Context, storagePath string) (bool, error) {
29+
// See func (repo *Repository) CustomAvatarRelativePath()
30+
// repo.Avatar is used directly as the storage path - therefore we can check for existence directly using the path
31+
return db.GetEngine(ctx).Where("`avatar`=?", storagePath).Exist(new(Repository))
32+
}
33+
2734
// RelAvatarLink returns a relative link to the repository's avatar.
2835
func (repo *Repository) RelAvatarLink() string {
2936
return repo.relAvatarLink(db.DefaultContext)

models/user/avatar.go

+7
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,10 @@ func (u *User) IsUploadAvatarChanged(data []byte) bool {
111111
avatarID := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d-%x", u.ID, md5.Sum(data)))))
112112
return u.Avatar != avatarID
113113
}
114+
115+
// ExistsWithAvatarAtStoragePath returns true if there is a user with this Avatar
116+
func ExistsWithAvatarAtStoragePath(ctx context.Context, storagePath string) (bool, error) {
117+
// See func (u *User) CustomAvatarRelativePath()
118+
// u.Avatar is used directly as the storage path - therefore we can check for existence directly using the path
119+
return db.GetEngine(ctx).Where("`avatar`=?", storagePath).Exist(new(User))
120+
}

0 commit comments

Comments
 (0)