Skip to content

Commit 01adf75

Browse files
Merge pull request #186 from jstuever/bz1665011
Bug 1665011: updatepayload: prune older jobs to maintain limit.
2 parents 4ad2ea5 + 28df8fa commit 01adf75

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

pkg/cvo/updatepayload.go

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@ import (
77
"fmt"
88
"os"
99
"path/filepath"
10+
"sort"
1011
"strings"
1112

13+
"github.com/pkg/errors"
14+
1215
batchv1 "k8s.io/api/batch/v1"
1316
corev1 "k8s.io/api/core/v1"
1417
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1519
randutil "k8s.io/apimachinery/pkg/util/rand"
1620
"k8s.io/client-go/kubernetes"
21+
"k8s.io/klog"
1722
"k8s.io/utils/pointer"
1823

19-
"k8s.io/klog"
2024
configv1 "github.com/openshift/api/config/v1"
21-
2225
"github.com/openshift/cluster-version-operator/lib/resourcebuilder"
2326
"github.com/openshift/cluster-version-operator/pkg/payload"
2427
"github.com/openshift/cluster-version-operator/pkg/verify"
@@ -189,13 +192,76 @@ func (r *payloadRetriever) fetchUpdatePayloadToDir(ctx context.Context, dir stri
189192
},
190193
}
191194

192-
_, err := r.kubeClient.BatchV1().Jobs(job.Namespace).Create(job)
195+
// Prune older jobs while gracefully handling errors.
196+
err := r.pruneJobs(2)
197+
if err != nil {
198+
klog.Warningf("failed to prune jobs: %v", err)
199+
}
200+
201+
_, err = r.kubeClient.BatchV1().Jobs(job.Namespace).Create(job)
193202
if err != nil {
194203
return err
195204
}
196205
return resourcebuilder.WaitForJobCompletion(ctx, r.kubeClient.BatchV1(), job)
197206
}
198207

208+
// pruneJobs deletes the older, finished jobs in the namespace.
209+
// retain - the number of newest jobs to keep.
210+
func (r *payloadRetriever) pruneJobs(retain int) error {
211+
jobs, err := r.kubeClient.BatchV1().Jobs(r.namespace).List(metav1.ListOptions{})
212+
if err != nil {
213+
return err
214+
}
215+
if len(jobs.Items) <= retain {
216+
return nil
217+
}
218+
219+
// Select jobs to be deleted
220+
var deleteJobs []batchv1.Job
221+
for _, job := range jobs.Items {
222+
switch {
223+
// Ignore jobs not begining with operatorName
224+
case !strings.HasPrefix(job.Name, r.operatorName+"-"):
225+
break
226+
// Ignore jobs that have not yet started
227+
case job.Status.StartTime == nil:
228+
break
229+
// Ignore jobs that are still active
230+
case job.Status.Active == 1:
231+
break
232+
default:
233+
deleteJobs = append(deleteJobs, job)
234+
}
235+
}
236+
if len(deleteJobs) <= retain {
237+
return nil
238+
}
239+
240+
// Sort jobs by StartTime to determine the newest. nil StartTime is assumed newest.
241+
sort.Slice(deleteJobs, func(i, j int) bool {
242+
if deleteJobs[i].Status.StartTime == nil {
243+
return false
244+
}
245+
if deleteJobs[j].Status.StartTime == nil {
246+
return true
247+
}
248+
return deleteJobs[i].Status.StartTime.Before(deleteJobs[j].Status.StartTime)
249+
})
250+
251+
var errs []error
252+
for _, job := range deleteJobs[:len(deleteJobs)-retain] {
253+
err := r.kubeClient.BatchV1().Jobs(r.namespace).Delete(job.Name, &metav1.DeleteOptions{})
254+
if err != nil {
255+
errs = append(errs, errors.Wrapf(err, "failed to delete job %v", job.Name))
256+
}
257+
}
258+
agg := utilerrors.NewAggregate(errs)
259+
if agg != nil {
260+
return fmt.Errorf("error deleting jobs: %v", agg.Error())
261+
}
262+
return nil
263+
}
264+
199265
// copyPayloadCmd returns command that copies cvo and release manifests from deafult location
200266
// to the target dir.
201267
// It is made up of 2 commands:

0 commit comments

Comments
 (0)