Skip to content

Commit a290aab

Browse files
authored
Fix debian package clean up (#32351) (#32590)
Partially backport #32351
1 parent 8f6cc95 commit a290aab

File tree

3 files changed

+56
-19
lines changed

3 files changed

+56
-19
lines changed

models/packages/debian/search.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,26 +75,27 @@ func ExistPackages(ctx context.Context, opts *PackageSearchOptions) (bool, error
7575
}
7676

7777
// SearchPackages gets the packages matching the search options
78-
func SearchPackages(ctx context.Context, opts *PackageSearchOptions, iter func(*packages.PackageFileDescriptor)) error {
79-
return db.GetEngine(ctx).
78+
func SearchPackages(ctx context.Context, opts *PackageSearchOptions) ([]*packages.PackageFileDescriptor, error) {
79+
var pkgFiles []*packages.PackageFile
80+
err := db.GetEngine(ctx).
8081
Table("package_file").
8182
Select("package_file.*").
8283
Join("INNER", "package_version", "package_version.id = package_file.version_id").
8384
Join("INNER", "package", "package.id = package_version.package_id").
8485
Where(opts.toCond()).
85-
Asc("package.lower_name", "package_version.created_unix").
86-
Iterate(new(packages.PackageFile), func(_ int, bean any) error {
87-
pf := bean.(*packages.PackageFile)
88-
89-
pfd, err := packages.GetPackageFileDescriptor(ctx, pf)
90-
if err != nil {
91-
return err
92-
}
93-
94-
iter(pfd)
95-
96-
return nil
97-
})
86+
Asc("package.lower_name", "package_version.created_unix").Find(&pkgFiles)
87+
if err != nil {
88+
return nil, err
89+
}
90+
pfds := make([]*packages.PackageFileDescriptor, 0, len(pkgFiles))
91+
for _, pf := range pkgFiles {
92+
pfd, err := packages.GetPackageFileDescriptor(ctx, pf)
93+
if err != nil {
94+
return nil, err
95+
}
96+
pfds = append(pfds, pfd)
97+
}
98+
return pfds, nil
9899
}
99100

100101
// GetDistributions gets all available distributions

services/packages/debian/repository.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,11 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa
206206
w := io.MultiWriter(packagesContent, gzw, xzw)
207207

208208
addSeparator := false
209-
if err := debian_model.SearchPackages(ctx, opts, func(pfd *packages_model.PackageFileDescriptor) {
209+
pfds, err := debian_model.SearchPackages(ctx, opts)
210+
if err != nil {
211+
return err
212+
}
213+
for _, pfd := range pfds {
210214
if addSeparator {
211215
fmt.Fprintln(w)
212216
}
@@ -220,10 +224,7 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa
220224
fmt.Fprintf(w, "SHA1: %s\n", pfd.Blob.HashSHA1)
221225
fmt.Fprintf(w, "SHA256: %s\n", pfd.Blob.HashSHA256)
222226
fmt.Fprintf(w, "SHA512: %s\n", pfd.Blob.HashSHA512)
223-
}); err != nil {
224-
return err
225227
}
226-
227228
gzw.Close()
228229
xzw.Close()
229230

tests/integration/api_packages_debian_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"fmt"
1111
"io"
1212
"net/http"
13+
"strconv"
1314
"strings"
1415
"testing"
1516

@@ -19,6 +20,7 @@ import (
1920
user_model "code.gitea.io/gitea/models/user"
2021
"code.gitea.io/gitea/modules/base"
2122
debian_module "code.gitea.io/gitea/modules/packages/debian"
23+
packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
2224
"code.gitea.io/gitea/tests"
2325

2426
"github.com/blakesmith/ar"
@@ -263,4 +265,37 @@ func TestPackageDebian(t *testing.T) {
263265
assert.Contains(t, body, "Components: "+strings.Join(components, " ")+"\n")
264266
assert.Contains(t, body, "Architectures: "+architectures[1]+"\n")
265267
})
268+
269+
t.Run("Cleanup", func(t *testing.T) {
270+
defer tests.PrintCurrentTest(t)()
271+
272+
rule := &packages.PackageCleanupRule{
273+
Enabled: true,
274+
RemovePattern: `.*`,
275+
MatchFullName: true,
276+
OwnerID: user.ID,
277+
Type: packages.TypeDebian,
278+
}
279+
280+
_, err := packages.InsertCleanupRule(db.DefaultContext, rule)
281+
assert.NoError(t, err)
282+
283+
// When there were a lot of packages (> 50 or 100) and the code used "Iterate" to get all packages, it ever caused bugs,
284+
// because "Iterate" keeps a dangling SQL session but the callback function still uses the same session to execute statements.
285+
// The "Iterate" problem has been checked by TestContextSafety now, so here we only need to check the cleanup logic with a small number
286+
packagesCount := 2
287+
for i := 0; i < packagesCount; i++ {
288+
uploadURL := fmt.Sprintf("%s/pool/%s/%s/upload", rootURL, "test", "main")
289+
req := NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, "1.0."+strconv.Itoa(i), "all")).AddBasicAuth(user.Name)
290+
MakeRequest(t, req, http.StatusCreated)
291+
}
292+
req := NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, "test"))
293+
MakeRequest(t, req, http.StatusOK)
294+
295+
err = packages_cleanup_service.CleanupTask(db.DefaultContext, 0)
296+
assert.NoError(t, err)
297+
298+
req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/Release", rootURL, "test"))
299+
MakeRequest(t, req, http.StatusNotFound)
300+
})
266301
}

0 commit comments

Comments
 (0)