@@ -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