Skip to content

Commit a12d036

Browse files
GiteaBotZettat123
andauthored
Fix bugs in LFS meta garbage collection (go-gitea#26122) (go-gitea#26157)
Backport go-gitea#26122 by @Zettat123 This PR - Fix go-gitea#26093. Replace `time.Time` with `timeutil.TimeStamp` - Fix go-gitea#26135. Add missing `xorm:"extends"` to `CountLFSMetaObject` for LFS meta object query - Add a unit test for LFS meta object garbage collection Co-authored-by: Zettat123 <[email protected]>
1 parent 65d6bdf commit a12d036

File tree

3 files changed

+71
-7
lines changed

3 files changed

+71
-7
lines changed

models/git/lfs.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package git
66
import (
77
"context"
88
"fmt"
9-
"time"
109

1110
"code.gitea.io/gitea/models/db"
1211
"code.gitea.io/gitea/models/perm"
@@ -370,8 +369,8 @@ func IterateRepositoryIDsWithLFSMetaObjects(ctx context.Context, f func(ctx cont
370369

371370
// IterateLFSMetaObjectsForRepoOptions provides options for IterateLFSMetaObjectsForRepo
372371
type IterateLFSMetaObjectsForRepoOptions struct {
373-
OlderThan time.Time
374-
UpdatedLessRecentlyThan time.Time
372+
OlderThan timeutil.TimeStamp
373+
UpdatedLessRecentlyThan timeutil.TimeStamp
375374
OrderByUpdated bool
376375
LoopFunctionAlwaysUpdates bool
377376
}
@@ -382,8 +381,8 @@ func IterateLFSMetaObjectsForRepo(ctx context.Context, repoID int64, f func(cont
382381
batchSize := setting.Database.IterateBufferSize
383382
engine := db.GetEngine(ctx)
384383
type CountLFSMetaObject struct {
385-
Count int64
386-
LFSMetaObject
384+
Count int64
385+
LFSMetaObject `xorm:"extends"`
387386
}
388387

389388
id := int64(0)

services/repository/lfs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"code.gitea.io/gitea/modules/lfs"
1616
"code.gitea.io/gitea/modules/log"
1717
"code.gitea.io/gitea/modules/setting"
18+
"code.gitea.io/gitea/modules/timeutil"
1819
)
1920

2021
// GarbageCollectLFSMetaObjectsOptions provides options for GarbageCollectLFSMetaObjects function
@@ -122,8 +123,8 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R
122123
//
123124
// It is likely that a week is potentially excessive but it should definitely be enough that any
124125
// unassociated LFS object is genuinely unassociated.
125-
OlderThan: opts.OlderThan,
126-
UpdatedLessRecentlyThan: opts.UpdatedLessRecentlyThan,
126+
OlderThan: timeutil.TimeStamp(opts.OlderThan.Unix()),
127+
UpdatedLessRecentlyThan: timeutil.TimeStamp(opts.UpdatedLessRecentlyThan.Unix()),
127128
OrderByUpdated: true,
128129
LoopFunctionAlwaysUpdates: true,
129130
})

services/repository/lfs_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repository
5+
6+
import (
7+
"bytes"
8+
"context"
9+
"testing"
10+
"time"
11+
12+
"code.gitea.io/gitea/models/db"
13+
git_model "code.gitea.io/gitea/models/git"
14+
repo_model "code.gitea.io/gitea/models/repo"
15+
"code.gitea.io/gitea/models/unittest"
16+
"code.gitea.io/gitea/modules/lfs"
17+
"code.gitea.io/gitea/modules/setting"
18+
"code.gitea.io/gitea/modules/storage"
19+
20+
"github.com/stretchr/testify/assert"
21+
)
22+
23+
func TestGarbageCollectLFSMetaObjects(t *testing.T) {
24+
assert.NoError(t, unittest.PrepareTestDatabase())
25+
26+
setting.LFS.StartServer = true
27+
err := storage.Init()
28+
assert.NoError(t, err)
29+
30+
repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1")
31+
assert.NoError(t, err)
32+
33+
// add lfs object
34+
lfsContent := []byte("gitea1")
35+
lfsOid := storeObjectInRepo(t, repo.ID, &lfsContent)
36+
37+
// gc
38+
err = GarbageCollectLFSMetaObjects(context.Background(), GarbageCollectLFSMetaObjectsOptions{
39+
AutoFix: true,
40+
OlderThan: time.Now().Add(7 * 24 * time.Hour).Add(5 * 24 * time.Hour),
41+
UpdatedLessRecentlyThan: time.Now().Add(7 * 24 * time.Hour).Add(3 * 24 * time.Hour),
42+
})
43+
assert.NoError(t, err)
44+
45+
// lfs meta has been deleted
46+
_, err = git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, lfsOid)
47+
assert.ErrorIs(t, err, git_model.ErrLFSObjectNotExist)
48+
}
49+
50+
func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string {
51+
pointer, err := lfs.GeneratePointer(bytes.NewReader(*content))
52+
assert.NoError(t, err)
53+
54+
_, err = git_model.NewLFSMetaObject(db.DefaultContext, &git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID})
55+
assert.NoError(t, err)
56+
contentStore := lfs.NewContentStore()
57+
exist, err := contentStore.Exists(pointer)
58+
assert.NoError(t, err)
59+
if !exist {
60+
err := contentStore.Put(pointer, bytes.NewReader(*content))
61+
assert.NoError(t, err)
62+
}
63+
return pointer.Oid
64+
}

0 commit comments

Comments
 (0)