@@ -32,127 +32,136 @@ func CleanupTask(ctx context.Context, olderThan time.Duration) error {
32
32
return CleanupExpiredData (ctx , olderThan )
33
33
}
34
34
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
+ })
37
42
if err != nil {
38
- return err
43
+ return false , fmt . Errorf ( "CleanupRule [%d]: SearchVersions failed: %w" , pcr . ID , err )
39
44
}
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
47
50
}
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
+ }
51
60
}
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
58
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: %v" , pcr .ID , err )
80
+ continue
81
+ }
82
+ versionDeleted = true
83
+ }
84
+ return versionDeleted , nil
85
+ }
59
86
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
+ }
81
91
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
+ }
86
96
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 )
98
114
}
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 )
104
117
}
118
+ }
119
+ }
120
+ }
105
121
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 )
108
131
}
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 ()
109
142
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 )
120
145
}
121
146
}
147
+ }
148
+ return nil
149
+ }
122
150
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
+ }
143
158
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 )
148
162
}
149
163
return nil
150
164
})
151
- if err != nil {
152
- return err
153
- }
154
-
155
- return committer .Commit ()
156
165
}
157
166
158
167
func CleanupExpiredData (outerCtx context.Context , olderThan time.Duration ) error {
0 commit comments