diff --git a/pkg/registry/apps/rest/storage_apps.go b/pkg/registry/apps/rest/storage_apps.go index 9b1b96dcbe0..c667c3048e9 100644 --- a/pkg/registry/apps/rest/storage_apps.go +++ b/pkg/registry/apps/rest/storage_apps.go @@ -102,6 +102,10 @@ func (p RESTStorageProvider) v1beta2Storage(apiResourceConfigSource serverstorag storage["replicasets/status"] = replicaSetStorage.Status storage["replicasets/scale"] = replicaSetStorage.Scale } + if apiResourceConfigSource.ResourceEnabled(version.WithResource("controllerrevisions")) { + historyStorage := controllerrevisionsstore.NewREST(restOptionsGetter) + storage["controllerrevisions"] = historyStorage + } return storage } diff --git a/staging/src/k8s.io/api/apps/v1beta2/register.go b/staging/src/k8s.io/api/apps/v1beta2/register.go index d5f7816ffe7..e207c7dc5a9 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/register.go +++ b/staging/src/k8s.io/api/apps/v1beta2/register.go @@ -53,6 +53,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &DaemonSetList{}, &ReplicaSet{}, &ReplicaSetList{}, + &ControllerRevision{}, + &ControllerRevisionList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/staging/src/k8s.io/api/apps/v1beta2/types.go b/staging/src/k8s.io/api/apps/v1beta2/types.go index 2d96df373c3..d040d3de2a0 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types.go @@ -19,6 +19,7 @@ package v1beta2 import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -778,3 +779,43 @@ type ReplicaSetCondition struct { // +optional Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ControllerRevision implements an immutable snapshot of state data. Clients +// are responsible for serializing and deserializing the objects that contain +// their internal state. +// Once a ControllerRevision has been successfully created, it can not be updated. +// The API Server will fail validation of all requests that attempt to mutate +// the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both +// the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However, +// it may be subject to name and representation changes in future releases, and clients should not +// depend on its stability. It is primarily for internal use by controllers. +type ControllerRevision struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Data is the serialized representation of the state. + Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` + + // Revision indicates the revision of the state represented by Data. + Revision int64 `json:"revision" protobuf:"varint,3,opt,name=revision"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ControllerRevisionList is a resource containing a list of ControllerRevision objects. +type ControllerRevisionList struct { + metav1.TypeMeta `json:",inline"` + + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of ControllerRevisions + Items []ControllerRevision `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 8eaae85fea8..b3462acdb0d 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -168,6 +168,11 @@ var etcdStorageData = map[schema.GroupVersionResource]struct { expectedEtcdPath: "/registry/replicasets/etcdstoragepathtestnamespace/rs2", expectedGVK: gvkP("extensions", "v1beta1", "ReplicaSet"), }, + gvr("apps", "v1beta2", "controllerrevisions"): { + stub: `{"metadata":{"name":"crs2"},"data":{"name":"abc","namespace":"default","creationTimestamp":null,"Spec":{"Replicas":0,"Selector":{"matchLabels":{"foo":"bar"}},"Template":{"creationTimestamp":null,"labels":{"foo":"bar"},"Spec":{"Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status":{"ObservedGeneration":null,"Replicas":0}},"revision":0}`, + expectedEtcdPath: "/registry/controllerrevisions/etcdstoragepathtestnamespace/crs2", + expectedGVK: gvkP("apps", "v1beta1", "ControllerRevision"), + }, // -- // k8s.io/kubernetes/pkg/apis/autoscaling/v1