Skip to content

Commit f05cd7d

Browse files
committed
Updates garbage collection for orphaned ReleasePayloads to use coordinated deletion via remove__ prefixed tags in quay.io
1 parent a57aa87 commit f05cd7d

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

cmd/release-controller/sync_gc.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,29 @@ func (c *Controller) garbageCollectSync() error {
122122
}
123123
}
124124

125-
// all releasepayloads created for releases that no longer exist should be deleted
125+
// all releasepayloads created for releases that no longer exist should be garbage collected
126+
// Use coordinated deletion via remove__ prefixed tags in quay.io, allowing the pruner to handle tag deletion
126127
for _, payload := range payloads {
127128
if active.Has(payload.Name) {
128129
continue
129130
}
131+
132+
// Get the release config from the ImageStream to check if alternate repository is configured
133+
imageStream, err := c.releaseLister.ImageStreams(payload.Spec.PayloadCoordinates.Namespace).Get(payload.Spec.PayloadCoordinates.ImagestreamName)
134+
if err == nil {
135+
release, ok, err := releasecontroller.ReleaseDefinition(imageStream, c.parsedReleaseConfigCache, c.eventRecorder, *c.releaseLister)
136+
if err == nil && ok && len(release.Config.AlternateImageRepository) > 0 && len(release.Config.AlternateImageRepositorySecretName) > 0 {
137+
// Create a job to copy rc_payload__{version} to remove__rc_payload__{version}
138+
_, err := c.ensureRemoveTagJob(payload, release)
139+
if err != nil {
140+
klog.V(2).Infof("Failed to create remove tag job for releasepayload %s/%s: %v, proceeding with direct deletion", payload.Namespace, payload.Name, err)
141+
} else {
142+
klog.V(2).Infof("Created remove tag job for orphaned releasepayload %s/%s, pruner will handle quay.io tag deletion", payload.Namespace, payload.Name)
143+
}
144+
}
145+
}
146+
147+
// Delete the ReleasePayload
130148
klog.V(2).Infof("Removing orphaned releasepayload %s/%s", payload.Namespace, payload.Name)
131149
if err := c.releasePayloadClient.ReleasePayloads(payload.Namespace).Delete(context.TODO(), payload.Name, metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) {
132150
utilruntime.HandleError(fmt.Errorf("can't delete orphaned releasepayload %s/%s: %v", payload.Namespace, payload.Name, err))

cmd/release-controller/sync_release.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strconv"
77
"time"
88

9+
"github.com/openshift/release-controller/pkg/apis/release/v1alpha1"
910
releasecontroller "github.com/openshift/release-controller/pkg/release-controller"
1011

1112
batchv1 "k8s.io/api/batch/v1"
@@ -417,3 +418,44 @@ func (c *Controller) ensureReleaseMirrorJob(release *releasecontroller.Release,
417418
func releaseMirrorJobName(tagName string) string {
418419
return fmt.Sprintf("%s-alternate-mirror", tagName)
419420
}
421+
422+
// ensureRemoveTagJob creates a job to copy rc_payload__{version} to remove__rc_payload__{version} in quay.io
423+
func (c *Controller) ensureRemoveTagJob(payload *v1alpha1.ReleasePayload, release *releasecontroller.Release) (*batchv1.Job, error) {
424+
if len(release.Config.AlternateImageRepository) == 0 || len(release.Config.AlternateImageRepositorySecretName) == 0 {
425+
return nil, fmt.Errorf("alternate repository or secret not configured")
426+
}
427+
428+
jobName := fmt.Sprintf("%s-remove-tag", payload.Name)
429+
return c.ensureJob(jobName, nil, func() (*batchv1.Job, error) {
430+
// Get cli image from mirror or config
431+
cliImage := "registry.ci.openshift.org/ocp/4.16:cli"
432+
if mirror, err := c.releaseLister.ImageStreams(release.Target.Namespace).Get(release.Target.Name); err == nil {
433+
cliImage = fmt.Sprintf("%s:cli", mirror.Status.DockerImageRepository)
434+
}
435+
if len(release.Config.OverrideCLIImage) > 0 {
436+
cliImage = release.Config.OverrideCLIImage
437+
}
438+
439+
job, prefix := newReleaseJobBase(jobName, cliImage, release.Config.AlternateImageRepositorySecretName)
440+
441+
rcPayloadTag := fmt.Sprintf("rc_payload__%s", payload.Name)
442+
removeTag := fmt.Sprintf("remove__rc_payload__%s", payload.Name)
443+
fromImage := fmt.Sprintf("%s:%s", release.Config.AlternateImageRepository, rcPayloadTag)
444+
toImage := fmt.Sprintf("%s:%s", release.Config.AlternateImageRepository, removeTag)
445+
446+
job.Spec.Template.Spec.Containers[0].Command = []string{
447+
"/bin/bash", "-c",
448+
prefix + `
449+
oc image mirror --keep-manifest-list=true $1 $2
450+
`,
451+
"",
452+
fromImage, toImage,
453+
}
454+
455+
job.Annotations[releasecontroller.ReleaseAnnotationReleaseTag] = payload.Name
456+
job.Annotations[releasecontroller.ReleaseAnnotationTarget] = fmt.Sprintf("%s/%s", payload.Spec.PayloadCoordinates.Namespace, payload.Spec.PayloadCoordinates.ImagestreamName)
457+
458+
klog.V(2).Infof("Creating remove tag job %s/%s to copy %s to %s", c.jobNamespace, job.Name, fromImage, toImage)
459+
return job, nil
460+
})
461+
}

pkg/release-controller/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ type ReleaseConfig struct {
152152
// AlternateImageRepository is the full path to an external Image Repository where we
153153
// will mirror Accepted releases to.
154154
// For example:
155-
// "alternateImageRepository": "quay.io/openshift-release-dev/dev-release"
155+
// "alternateImageRepository": "quay.io/openshift/ci"
156156
AlternateImageRepository string `json:"alternateImageRepository"`
157157

158158
// AlternateImageRepositorySecret is the name of the secret containing credentials to the

0 commit comments

Comments
 (0)