@@ -32,127 +32,136 @@ func CleanupTask(ctx context.Context, olderThan time.Duration) error {
3232 return CleanupExpiredData (ctx , olderThan )
3333}
3434
35- func ExecuteCleanupRules (outerCtx context.Context ) error {
36- ctx , committer , err := db .TxContext (outerCtx )
35+ func executeCleanupOneRulePackage (ctx context.Context , pcr * packages_model.PackageCleanupRule , p * packages_model.Package ) (versionDeleted bool , err error ) {
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+ })
3742 if err != nil {
38- return err
43+ return false , fmt . Errorf ( "CleanupRule [%d]: SearchVersions failed: %w" , pcr . ID , err )
3944 }
40- defer committer .Close ()
41-
42- err = packages_model .IterateEnabledCleanupRules (ctx , func (ctx context.Context , pcr * packages_model.PackageCleanupRule ) error {
43- select {
44- case <- outerCtx .Done ():
45- return db .ErrCancelledf ("While processing package cleanup rules" )
46- default :
45+ if pcr .KeepCount > 0 {
46+ if pcr .KeepCount < len (pvs ) {
47+ pvs = pvs [pcr .KeepCount :]
48+ } else {
49+ pvs = nil
4750 }
48-
49- if err := pcr .CompiledPattern (); err != nil {
50- 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 false , fmt .Errorf ("CleanupRule [%d]: container.ShouldBeSkipped failed: %w" , pcr .ID , err )
56+ } else if skip {
57+ log .Debug ("Rule[%d]: keep '%s/%s' (container)" , pcr .ID , p .Name , pv .Version )
58+ continue
59+ }
5160 }
52-
53- olderThan := time .Now ().AddDate (0 , 0 , - pcr .RemoveDays )
54-
55- packages , err := packages_model .GetPackagesByType (ctx , pcr .OwnerID , pcr .Type )
56- if err != nil {
57- return fmt .Errorf ("CleanupRule [%d]: GetPackagesByType failed: %w" , pcr .ID , err )
61+ toMatch := pv .LowerVersion
62+ if pcr .MatchFullName {
63+ toMatch = p .LowerName + "/" + pv .LowerVersion
64+ }
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
5872 }
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: %v" , pcr .ID , err )
80+ continue
81+ }
82+ versionDeleted = true
83+ }
84+ return versionDeleted , nil
85+ }
5986
60- anyVersionDeleted := false
61- for _ , p := range packages {
62- pvs , _ , err := packages_model .SearchVersions (ctx , & packages_model.PackageSearchOptions {
63- PackageID : p .ID ,
64- IsInternal : optional .Some (false ),
65- Sort : packages_model .SortCreatedDesc ,
66- Paginator : db .NewAbsoluteListOptions (pcr .KeepCount , 200 ),
67- })
68- if err != nil {
69- return fmt .Errorf ("CleanupRule [%d]: SearchVersions failed: %w" , pcr .ID , err )
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- }
87+ func executeCleanupOneRule (ctx context.Context , pcr * packages_model.PackageCleanupRule ) error {
88+ if err := pcr .CompiledPattern (); err != nil {
89+ return fmt .Errorf ("CleanupRule [%d]: CompilePattern failed: %w" , pcr .ID , err )
90+ }
8191
82- toMatch := pv . LowerVersion
83- if pcr . MatchFullName {
84- toMatch = p . LowerName + "/" + pv . LowerVersion
85- }
92+ packages , err := packages_model . GetPackagesByType ( ctx , pcr . OwnerID , pcr . Type )
93+ if err != nil {
94+ return fmt . Errorf ( "CleanupRule [%d]: GetPackagesByType failed: %w" , pcr . ID , err )
95+ }
8696
87- if pcr .KeepPatternMatcher != nil && pcr .KeepPatternMatcher .MatchString (toMatch ) {
88- log .Debug ("Rule[%d]: keep '%s/%s' (keep pattern)" , pcr .ID , p .Name , pv .Version )
89- continue
90- }
91- if pv .CreatedUnix .AsLocalTime ().After (olderThan ) {
92- log .Debug ("Rule[%d]: keep '%s/%s' (remove days)" , pcr .ID , p .Name , pv .Version )
93- continue
94- }
95- if pcr .RemovePatternMatcher != nil && ! pcr .RemovePatternMatcher .MatchString (toMatch ) {
96- log .Debug ("Rule[%d]: keep '%s/%s' (remove pattern)" , pcr .ID , p .Name , pv .Version )
97- continue
97+ anyVersionDeleted := false
98+ for _ , p := range packages {
99+ versionDeleted := false
100+ err = db .WithTx (ctx , func (ctx context.Context ) (err error ) {
101+ versionDeleted , err = executeCleanupOneRulePackage (ctx , pcr , p )
102+ return err
103+ })
104+ if err != nil {
105+ log .Error ("CleanupRule [%d]: executeCleanupOneRulePackage(%d) failed: %v" , pcr .ID , p .ID , err )
106+ continue
107+ }
108+ anyVersionDeleted = anyVersionDeleted || versionDeleted
109+ if versionDeleted {
110+ if pcr .Type == packages_model .TypeCargo {
111+ owner , err := user_model .GetUserByID (ctx , pcr .OwnerID )
112+ if err != nil {
113+ return fmt .Errorf ("GetUserByID failed: %w" , err )
98114 }
99-
100- log .Debug ("Rule[%d]: remove '%s/%s'" , pcr .ID , p .Name , pv .Version )
101-
102- if err := packages_service .DeletePackageVersionAndReferences (ctx , pv ); err != nil {
103- return fmt .Errorf ("CleanupRule [%d]: DeletePackageVersionAndReferences failed: %w" , pcr .ID , err )
115+ if err := cargo_service .UpdatePackageIndexIfExists (ctx , owner , owner , p .ID ); err != nil {
116+ return fmt .Errorf ("CleanupRule [%d]: cargo.UpdatePackageIndexIfExists failed: %w" , pcr .ID , err )
104117 }
118+ }
119+ }
120+ }
105121
106- versionDeleted = true
107- anyVersionDeleted = true
122+ if anyVersionDeleted {
123+ switch pcr .Type {
124+ case packages_model .TypeDebian :
125+ if err := debian_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
126+ return fmt .Errorf ("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
127+ }
128+ case packages_model .TypeAlpine :
129+ if err := alpine_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
130+ return fmt .Errorf ("CleanupRule [%d]: alpine.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
108131 }
132+ case packages_model .TypeRpm :
133+ if err := rpm_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
134+ return fmt .Errorf ("CleanupRule [%d]: rpm.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
135+ }
136+ case packages_model .TypeArch :
137+ release , err := arch_service .AquireRegistryLock (ctx , pcr .OwnerID )
138+ if err != nil {
139+ return err
140+ }
141+ defer release ()
109142
110- if versionDeleted {
111- if pcr .Type == packages_model .TypeCargo {
112- owner , err := user_model .GetUserByID (ctx , pcr .OwnerID )
113- if err != nil {
114- return fmt .Errorf ("GetUserByID failed: %w" , err )
115- }
116- if err := cargo_service .UpdatePackageIndexIfExists (ctx , owner , owner , p .ID ); err != nil {
117- return fmt .Errorf ("CleanupRule [%d]: cargo.UpdatePackageIndexIfExists failed: %w" , pcr .ID , err )
118- }
119- }
143+ if err := arch_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
144+ return fmt .Errorf ("CleanupRule [%d]: arch.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
120145 }
121146 }
147+ }
148+ return nil
149+ }
122150
123- if anyVersionDeleted {
124- switch pcr .Type {
125- case packages_model .TypeDebian :
126- if err := debian_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
127- return fmt .Errorf ("CleanupRule [%d]: debian.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
128- }
129- case packages_model .TypeAlpine :
130- if err := alpine_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
131- return fmt .Errorf ("CleanupRule [%d]: alpine.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
132- }
133- case packages_model .TypeRpm :
134- if err := rpm_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
135- return fmt .Errorf ("CleanupRule [%d]: rpm.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
136- }
137- case packages_model .TypeArch :
138- release , err := arch_service .AquireRegistryLock (ctx , pcr .OwnerID )
139- if err != nil {
140- return err
141- }
142- defer release ()
151+ func ExecuteCleanupRules (ctx context.Context ) error {
152+ return packages_model .IterateEnabledCleanupRules (ctx , func (ctx context.Context , pcr * packages_model.PackageCleanupRule ) error {
153+ select {
154+ case <- ctx .Done ():
155+ return db .ErrCancelledf ("While processing package cleanup rules" )
156+ default :
157+ }
143158
144- if err := arch_service .BuildAllRepositoryFiles (ctx , pcr .OwnerID ); err != nil {
145- return fmt .Errorf ("CleanupRule [%d]: arch.BuildAllRepositoryFiles failed: %w" , pcr .ID , err )
146- }
147- }
159+ err := executeCleanupOneRule (ctx , pcr )
160+ if err != nil {
161+ log .Error ("CleanupRule [%d]: executeCleanupOneRule failed: %v" , pcr .ID , err )
148162 }
149163 return nil
150164 })
151- if err != nil {
152- return err
153- }
154-
155- return committer .Commit ()
156165}
157166
158167func CleanupExpiredData (outerCtx context.Context , olderThan time.Duration ) error {
0 commit comments