Skip to content

Commit fb79731

Browse files
committed
fix transaction
1 parent dcc6867 commit fb79731

File tree

1 file changed

+114
-95
lines changed

1 file changed

+114
-95
lines changed

services/packages/cleanup/cleanup.go

Lines changed: 114 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -32,115 +32,134 @@ func CleanupTask(ctx context.Context, olderThan time.Duration) error {
3232
return CleanupExpiredData(ctx, olderThan)
3333
}
3434

35-
func ExecuteCleanupRules(outerCtx context.Context) error {
36-
return packages_model.IterateEnabledCleanupRules(outerCtx, func(ctx context.Context, pcr *packages_model.PackageCleanupRule) error {
37-
select {
38-
case <-outerCtx.Done():
39-
return db.ErrCancelledf("While processing package cleanup rules")
40-
default:
35+
func executeCleanupOneRulePackage(ctx context.Context, pcr *packages_model.PackageCleanupRule, p *packages_model.Package) (err error, versionDeleted bool) {
36+
olderThan := time.Now().AddDate(0, 0, -pcr.RemoveDays)
37+
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
38+
PackageID: p.ID,
39+
IsInternal: optional.Some(false),
40+
Sort: packages_model.SortCreatedDesc,
41+
})
42+
if err != nil {
43+
return fmt.Errorf("CleanupRule [%d]: SearchVersions failed: %w", pcr.ID, err), false
44+
}
45+
if pcr.KeepCount > 0 {
46+
if pcr.KeepCount < len(pvs) {
47+
pvs = pvs[pcr.KeepCount:]
48+
} else {
49+
pvs = nil
4150
}
42-
43-
if err := pcr.CompiledPattern(); err != nil {
44-
return fmt.Errorf("CleanupRule [%d]: CompilePattern failed: %w", pcr.ID, err)
51+
}
52+
for _, pv := range pvs {
53+
if pcr.Type == packages_model.TypeContainer {
54+
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
55+
return fmt.Errorf("CleanupRule [%d]: container.ShouldBeSkipped failed: %w", pcr.ID, err), false
56+
} else if skip {
57+
log.Debug("Rule[%d]: keep '%s/%s' (container)", pcr.ID, p.Name, pv.Version)
58+
continue
59+
}
60+
}
61+
toMatch := pv.LowerVersion
62+
if pcr.MatchFullName {
63+
toMatch = p.LowerName + "/" + pv.LowerVersion
4564
}
65+
if pcr.KeepPatternMatcher != nil && pcr.KeepPatternMatcher.MatchString(toMatch) {
66+
log.Debug("Rule[%d]: keep '%s/%s' (keep pattern)", pcr.ID, p.Name, pv.Version)
67+
continue
68+
}
69+
if pv.CreatedUnix.AsLocalTime().After(olderThan) {
70+
log.Debug("Rule[%d]: keep '%s/%s' (remove days) %v", pcr.ID, p.Name, pv.Version, pv.CreatedUnix.FormatDate())
71+
continue
72+
}
73+
if pcr.RemovePatternMatcher != nil && !pcr.RemovePatternMatcher.MatchString(toMatch) {
74+
log.Debug("Rule[%d]: keep '%s/%s' (remove pattern)", pcr.ID, p.Name, pv.Version)
75+
continue
76+
}
77+
log.Debug("Rule[%d]: remove '%s/%s'", pcr.ID, p.Name, pv.Version)
78+
if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
79+
log.Error("CleanupRule [%d]: DeletePackageVersionAndReferences failed: %w", pcr.ID, err)
80+
continue
81+
}
82+
versionDeleted = true
83+
}
84+
return nil, versionDeleted
85+
}
4686

47-
olderThan := time.Now().AddDate(0, 0, -pcr.RemoveDays)
87+
func executeCleanupOneRule(ctx context.Context, pcr *packages_model.PackageCleanupRule) error {
88+
select {
89+
case <-ctx.Done():
90+
return db.ErrCancelledf("While processing package cleanup rules")
91+
default:
92+
}
93+
94+
if err := pcr.CompiledPattern(); err != nil {
95+
return fmt.Errorf("CleanupRule [%d]: CompilePattern failed: %w", pcr.ID, err)
96+
}
97+
98+
packages, err := packages_model.GetPackagesByType(ctx, pcr.OwnerID, pcr.Type)
99+
if err != nil {
100+
return fmt.Errorf("CleanupRule [%d]: GetPackagesByType failed: %w", pcr.ID, err)
101+
}
48102

49-
packages, err := packages_model.GetPackagesByType(ctx, pcr.OwnerID, pcr.Type)
103+
anyVersionDeleted := false
104+
for _, p := range packages {
105+
versionDeleted := false
106+
err = db.WithTx(ctx, func(ctx context.Context) (err error) {
107+
err, versionDeleted = executeCleanupOneRulePackage(ctx, pcr, p)
108+
return err
109+
})
50110
if err != nil {
51-
return fmt.Errorf("CleanupRule [%d]: GetPackagesByType failed: %w", pcr.ID, err)
111+
log.Error("CleanupRule [%d]: executeCleanupOneRulePackage(%d) failed: %v", pcr.ID, p.ID, err)
112+
continue
52113
}
53-
54-
anyVersionDeleted := false
55-
for _, p := range packages {
56-
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
57-
PackageID: p.ID,
58-
IsInternal: optional.Some(false),
59-
Sort: packages_model.SortCreatedDesc,
60-
})
61-
if err != nil {
62-
return fmt.Errorf("CleanupRule [%d]: SearchVersions failed: %w", pcr.ID, err)
63-
}
64-
if pcr.KeepCount > 0 {
65-
if pcr.KeepCount < len(pvs) {
66-
pvs = pvs[pcr.KeepCount:]
67-
} else {
68-
pvs = nil
69-
}
70-
}
71-
versionDeleted := false
72-
for _, pv := range pvs {
73-
if pcr.Type == packages_model.TypeContainer {
74-
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
75-
return fmt.Errorf("CleanupRule [%d]: container.ShouldBeSkipped failed: %w", pcr.ID, err)
76-
} else if skip {
77-
log.Debug("Rule[%d]: keep '%s/%s' (container)", pcr.ID, p.Name, pv.Version)
78-
continue
79-
}
80-
}
81-
toMatch := pv.LowerVersion
82-
if pcr.MatchFullName {
83-
toMatch = p.LowerName + "/" + pv.LowerVersion
84-
}
85-
if pcr.KeepPatternMatcher != nil && pcr.KeepPatternMatcher.MatchString(toMatch) {
86-
log.Debug("Rule[%d]: keep '%s/%s' (keep pattern)", pcr.ID, p.Name, pv.Version)
87-
continue
88-
}
89-
if pv.CreatedUnix.AsLocalTime().After(olderThan) {
90-
log.Debug("Rule[%d]: keep '%s/%s' (remove days) %v", pcr.ID, p.Name, pv.Version, pv.CreatedUnix.FormatDate())
91-
continue
92-
}
93-
if pcr.RemovePatternMatcher != nil && !pcr.RemovePatternMatcher.MatchString(toMatch) {
94-
log.Debug("Rule[%d]: keep '%s/%s' (remove pattern)", pcr.ID, p.Name, pv.Version)
95-
continue
96-
}
97-
log.Debug("Rule[%d]: remove '%s/%s'", pcr.ID, p.Name, pv.Version)
98-
if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
99-
log.Error("CleanupRule [%d]: DeletePackageVersionAndReferences failed: %w", pcr.ID, err)
100-
continue
114+
anyVersionDeleted = anyVersionDeleted || versionDeleted
115+
if versionDeleted {
116+
if pcr.Type == packages_model.TypeCargo {
117+
owner, err := user_model.GetUserByID(ctx, pcr.OwnerID)
118+
if err != nil {
119+
return fmt.Errorf("GetUserByID failed: %w", err)
101120
}
102-
versionDeleted = true
103-
anyVersionDeleted = true
104-
}
105-
if versionDeleted {
106-
if pcr.Type == packages_model.TypeCargo {
107-
owner, err := user_model.GetUserByID(ctx, pcr.OwnerID)
108-
if err != nil {
109-
return fmt.Errorf("GetUserByID failed: %w", err)
110-
}
111-
if err := cargo_service.UpdatePackageIndexIfExists(ctx, owner, owner, p.ID); err != nil {
112-
return fmt.Errorf("CleanupRule [%d]: cargo.UpdatePackageIndexIfExists failed: %w", pcr.ID, err)
113-
}
121+
if err := cargo_service.UpdatePackageIndexIfExists(ctx, owner, owner, p.ID); err != nil {
122+
return fmt.Errorf("CleanupRule [%d]: cargo.UpdatePackageIndexIfExists failed: %w", pcr.ID, err)
114123
}
115124
}
116125
}
126+
}
117127

118-
if anyVersionDeleted {
119-
switch pcr.Type {
120-
case packages_model.TypeDebian:
121-
if err := debian_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
122-
return fmt.Errorf("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
123-
}
124-
case packages_model.TypeAlpine:
125-
if err := alpine_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
126-
return fmt.Errorf("CleanupRule [%d]: alpine.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
127-
}
128-
case packages_model.TypeRpm:
129-
if err := rpm_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
130-
return fmt.Errorf("CleanupRule [%d]: rpm.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
131-
}
132-
case packages_model.TypeArch:
133-
release, err := arch_service.AquireRegistryLock(ctx, pcr.OwnerID)
134-
if err != nil {
135-
return err
136-
}
137-
defer release()
128+
if anyVersionDeleted {
129+
switch pcr.Type {
130+
case packages_model.TypeDebian:
131+
if err := debian_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
132+
return fmt.Errorf("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
133+
}
134+
case packages_model.TypeAlpine:
135+
if err := alpine_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
136+
return fmt.Errorf("CleanupRule [%d]: alpine.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
137+
}
138+
case packages_model.TypeRpm:
139+
if err := rpm_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
140+
return fmt.Errorf("CleanupRule [%d]: rpm.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
141+
}
142+
case packages_model.TypeArch:
143+
release, err := arch_service.AquireRegistryLock(ctx, pcr.OwnerID)
144+
if err != nil {
145+
return err
146+
}
147+
defer release()
138148

139-
if err := arch_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
140-
return fmt.Errorf("CleanupRule [%d]: arch.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
141-
}
149+
if err := arch_service.BuildAllRepositoryFiles(ctx, pcr.OwnerID); err != nil {
150+
return fmt.Errorf("CleanupRule [%d]: arch.BuildAllRepositoryFiles failed: %w", pcr.ID, err)
142151
}
143152
}
153+
}
154+
return nil
155+
}
156+
157+
func ExecuteCleanupRules(ctx context.Context) error {
158+
return packages_model.IterateEnabledCleanupRules(ctx, func(ctx context.Context, pcr *packages_model.PackageCleanupRule) error {
159+
err := executeCleanupOneRule(ctx, pcr)
160+
if err != nil {
161+
log.Error("CleanupRule [%d]: executeCleanupOneRule failed: %v", pcr.ID, err)
162+
}
144163
return nil
145164
})
146165
}

0 commit comments

Comments
 (0)