Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/apis/serving/metadata_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
RevisionLastPinnedAnnotationKey,
RoutingStateModifiedAnnotationKey,
GroupNamePrefix+"forceUpgrade",
RevisionPreservedAnnotationKey,
)
)

Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/serving/metadata_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ func TestValidateObjectMetadata(t *testing.T) {
RevisionLastPinnedAnnotationKey: "pinned-val",
},
},
}, {
name: "valid preserve annotation label",
objectMeta: &metav1.ObjectMeta{
GenerateName: "some-name",
Annotations: map[string]string{
RevisionLastPinnedAnnotationKey: "true",
},
},
}, {
name: "invalid knative prefix annotation",
objectMeta: &metav1.ObjectMeta{
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/serving/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const (
// pinned a revision
RevisionLastPinnedAnnotationKey = GroupName + "/lastPinned"

// RevisionPreservedAnnotationKey is the annotation key used for preventing garbage collector
// from automatically deleting the revision.
RevisionPreservedAnnotationKey = GroupName + "/no-gc"

// RouteLabelKey is the label key attached to a Configuration indicating by
// which Route it is configured as traffic target.
// The key is also attached to Revision resources to indicate they are directly
Expand Down
4 changes: 4 additions & 0 deletions pkg/reconciler/gc/v2/gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v2
import (
"context"
"sort"
"strings"
"time"

"go.uber.org/zap"
Expand Down Expand Up @@ -61,6 +62,9 @@ func Collect(
})

for _, rev := range revs[gcSkipOffset:] {
if strings.EqualFold(rev.ObjectMeta.Annotations[serving.RevisionPreservedAnnotationKey], "true") {
continue
}
if isRevisionStale(ctx, rev, config) {
err := client.ServingV1().Revisions(rev.Namespace).Delete(rev.Name, &metav1.DeleteOptions{})
if err != nil {
Expand Down
37 changes: 37 additions & 0 deletions pkg/reconciler/gc/v2/gc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,43 @@ func TestCollect(t *testing.T) {
WithCreationTimestamp(oldest),
WithLastPinned(old)),
},
}, {
name: "keep oldest because of the preserve annotation",
cfg: cfg("keep-oldest", "foo", 5556,
WithLatestCreated("5556"),
WithLatestReady("5556"),
WithConfigObservedGen),
revs: []*v1.Revision{
Comment thread
MIBc marked this conversation as resolved.
rev("keep-oldest", "foo", 5554, MarkRevisionReady,
WithRevName("5554"),
WithCreationTimestamp(oldest),
WithLastPinned(oldest),
WithRevisionPreserveAnnotation()),
rev("keep-oldest", "foo", 5555, MarkRevisionReady,
WithRevName("5555"),
WithCreationTimestamp(older),
WithLastPinned(older)),
rev("keep-oldest", "foo", 5556, MarkRevisionReady,
WithRevName("5556"),
WithCreationTimestamp(old),
WithLastPinned(old)),
rev("keep-oldest", "foo", 5557, MarkRevisionReady,
WithRevName("5557"),
WithCreationTimestamp(tenMinutesAgo),
WithLastPinned(tenMinutesAgo)),
},
wantDeletes: []clientgotesting.DeleteActionImpl{{
ActionImpl: clientgotesting.ActionImpl{
Namespace: "foo",
Verb: "delete",
Resource: schema.GroupVersionResource{
Group: "serving.knative.dev",
Version: "v1",
Resource: "revisions",
},
},
Name: "5555",
}},
}}

cfgMap := &config.Config{
Expand Down
10 changes: 10 additions & 0 deletions pkg/testing/v1/revision.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ func WithLastPinned(t time.Time) RevisionOption {
}
}

// WithRevisionPreserveAnnotation updates the annotation with preserve key.
func WithRevisionPreserveAnnotation() RevisionOption {
return func(rev *v1.Revision) {
rev.Annotations = kmeta.UnionMaps(rev.Annotations,
map[string]string{
serving.RevisionPreservedAnnotationKey: "true",
})
}
}

// WithRoutingStateModified updates the annotation to the provided timestamp.
func WithRoutingStateModified(t time.Time) RevisionOption {
return func(rev *v1.Revision) {
Expand Down