Skip to content

Commit 49982d4

Browse files
committed
storage: take lock files into consideration while garbage collecting
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
1 parent 9d77641 commit 49982d4

7 files changed

+33
-21
lines changed

controllers/bucket_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ func (r *BucketReconciler) garbageCollect(ctx context.Context, obj *sourcev1.Buc
690690
}
691691
if len(delFiles) > 0 {
692692
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
693-
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
693+
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)/2))
694694
return nil
695695
}
696696
}

controllers/gitrepository_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ func (r *GitRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourc
904904
}
905905
if len(delFiles) > 0 {
906906
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
907-
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
907+
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)/2))
908908
return nil
909909
}
910910
}

controllers/helmchart_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *sourcev1.
963963
}
964964
if len(delFiles) > 0 {
965965
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
966-
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
966+
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)/2))
967967
return nil
968968
}
969969
}

controllers/helmrepository_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ func (r *HelmRepositoryReconciler) garbageCollect(ctx context.Context, obj *sour
622622
}
623623
if len(delFiles) > 0 {
624624
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
625-
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
625+
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)/2))
626626
return nil
627627
}
628628
}

controllers/ocirepository_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ func (r *OCIRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourc
10691069
}
10701070
if len(delFiles) > 0 {
10711071
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
1072-
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
1072+
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)/2))
10731073
return nil
10741074
}
10751075
}

controllers/storage.go

+27-15
Original file line numberDiff line numberDiff line change
@@ -159,27 +159,26 @@ func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) ([]string, err
159159

160160
// getGarbageFiles returns all files that need to be garbage collected for the given artifact.
161161
// Garbage files are determined based on the below flow:
162-
// 1. collect all files with an expired ttl
162+
// 1. collect all artifact files with an expired ttl
163163
// 2. if we satisfy maxItemsToBeRetained, then return
164-
// 3. else, remove all files till the latest n files remain, where n=maxItemsToBeRetained
165-
func (s *Storage) getGarbageFiles(artifact sourcev1.Artifact, totalCountLimit, maxItemsToBeRetained int, ttl time.Duration) ([]string, error) {
164+
// 3. else, collect all artifact files till the latest n files remain, where n=maxItemsToBeRetained
165+
func (s *Storage) getGarbageFiles(artifact sourcev1.Artifact, totalCountLimit, maxItemsToBeRetained int, ttl time.Duration) (garbageFiles []string, _ error) {
166166
localPath := s.LocalPath(artifact)
167167
dir := filepath.Dir(localPath)
168-
garbageFiles := []string{}
169-
filesWithCreatedTs := make(map[time.Time]string)
168+
artifactFilesWithCreatedTs := make(map[time.Time]string)
170169
// sortedPaths contain all files sorted according to their created ts.
171170
sortedPaths := []string{}
172171
now := time.Now().UTC()
173-
totalFiles := 0
172+
totalArtifactFiles := 0
174173
var errors []string
175174
creationTimestamps := []time.Time{}
176175
_ = filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
177176
if err != nil {
178177
errors = append(errors, err.Error())
179178
return nil
180179
}
181-
if totalFiles >= totalCountLimit {
182-
return fmt.Errorf("reached file walking limit, already walked over: %d", totalFiles)
180+
if totalArtifactFiles >= totalCountLimit {
181+
return fmt.Errorf("reached file walking limit, already walked over: %d", totalArtifactFiles)
183182
}
184183
info, err := d.Info()
185184
if err != nil {
@@ -189,14 +188,16 @@ func (s *Storage) getGarbageFiles(artifact sourcev1.Artifact, totalCountLimit, m
189188
createdAt := info.ModTime().UTC()
190189
diff := now.Sub(createdAt)
191190
// Compare the time difference between now and the time at which the file was created
192-
// with the provided TTL. Delete if the difference is greater than the TTL.
191+
// with the provided TTL. Delete if the difference is greater than the TTL. Since the
192+
// below logic just deals with determining if an artifact needs to be garbage collected,
193+
// we avoid all lock files, adding them at the end to the list of garbage files.
193194
expired := diff > ttl
194-
if !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink {
195+
if !info.IsDir() && info.Mode()&os.ModeSymlink != os.ModeSymlink && filepath.Ext(path) != ".lock" {
195196
if path != localPath && expired {
196197
garbageFiles = append(garbageFiles, path)
197198
}
198-
totalFiles += 1
199-
filesWithCreatedTs[createdAt] = path
199+
totalArtifactFiles += 1
200+
artifactFilesWithCreatedTs[createdAt] = path
200201
creationTimestamps = append(creationTimestamps, createdAt)
201202
}
202203
return nil
@@ -208,14 +209,14 @@ func (s *Storage) getGarbageFiles(artifact sourcev1.Artifact, totalCountLimit, m
208209

209210
// We already collected enough garbage files to satisfy the no. of max
210211
// items that are supposed to be retained, so exit early.
211-
if totalFiles-len(garbageFiles) < maxItemsToBeRetained {
212+
if totalArtifactFiles-len(garbageFiles) < maxItemsToBeRetained {
212213
return garbageFiles, nil
213214
}
214215

215216
// sort all timestamps in an ascending order.
216217
sort.Slice(creationTimestamps, func(i, j int) bool { return creationTimestamps[i].Before(creationTimestamps[j]) })
217218
for _, ts := range creationTimestamps {
218-
path, ok := filesWithCreatedTs[ts]
219+
path, ok := artifactFilesWithCreatedTs[ts]
219220
if !ok {
220221
return garbageFiles, fmt.Errorf("failed to fetch file for created ts: %v", ts)
221222
}
@@ -225,7 +226,7 @@ func (s *Storage) getGarbageFiles(artifact sourcev1.Artifact, totalCountLimit, m
225226
var collected int
226227
noOfGarbageFiles := len(garbageFiles)
227228
for _, path := range sortedPaths {
228-
if path != localPath && !stringInSlice(path, garbageFiles) {
229+
if path != localPath && filepath.Ext(path) != ".lock" && !stringInSlice(path, garbageFiles) {
229230
// If we previously collected a few garbage files with an expired ttl, then take that into account
230231
// when checking whether we need to remove more files to satisfy the max no. of items allowed
231232
// in the filesystem, along with the no. of files already removed in this loop.
@@ -271,6 +272,17 @@ func (s *Storage) GarbageCollect(ctx context.Context, artifact sourcev1.Artifact
271272
} else {
272273
deleted = append(deleted, file)
273274
}
275+
// If a lock file exists for this garbage artifact, remove that too.
276+
lockFile := file + ".lock"
277+
if _, err = os.Lstat(lockFile); err == nil {
278+
err = os.Remove(lockFile)
279+
if err != nil {
280+
errors = append(errors, err)
281+
} else {
282+
deleted = append(deleted, lockFile)
283+
}
284+
285+
}
274286
}
275287
}
276288
if len(errors) > 0 {

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func main() {
135135
flag.StringSliceVar(&git.HostKeyAlgos, "ssh-hostkey-algos", []string{},
136136
"The list of hostkey algorithms to use for ssh connections, arranged from most preferred to the least.")
137137
flag.DurationVar(&artifactRetentionTTL, "artifact-retention-ttl", 60*time.Second,
138-
"The duration of time that artifacts will be kept in storage before being garbage collected.")
138+
"The duration of time that artifacts from previous reconcilations will be kept in storage before being garbage collected.")
139139
flag.IntVar(&artifactRetentionRecords, "artifact-retention-records", 2,
140140
"The maximum number of artifacts to be kept in storage after a garbage collection.")
141141

0 commit comments

Comments
 (0)