diff --git a/pkg/api/pod/BUILD b/pkg/api/pod/BUILD index 316c6a7819..71c3c3db22 100644 --- a/pkg/api/pod/BUILD +++ b/pkg/api/pod/BUILD @@ -11,7 +11,9 @@ go_library( srcs = ["util.go"], deps = [ "//pkg/api:go_default_library", + "//pkg/features:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index 9dc4fa68ee..fbc785ab3f 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -18,7 +18,9 @@ package pod import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/features" ) // Visitor is called with each object name, and returns true if visiting should continue @@ -225,3 +227,20 @@ func UpdatePodCondition(status *api.PodStatus, condition *api.PodCondition) bool // Return true if one of the fields have changed. return !isEqual } + +// DropDisabledAlphaFields removes disabled fields from the pod spec. +// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pod spec. +func DropDisabledAlphaFields(podSpec *api.PodSpec) { + if !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) { + podSpec.Priority = nil + podSpec.PriorityClassName = "" + } + + if !utilfeature.DefaultFeatureGate.Enabled(features.LocalStorageCapacityIsolation) { + for i := range podSpec.Volumes { + if podSpec.Volumes[i].EmptyDir != nil { + podSpec.Volumes[i].EmptyDir.SizeLimit = nil + } + } + } +} diff --git a/pkg/registry/apps/statefulset/BUILD b/pkg/registry/apps/statefulset/BUILD index d57cf94861..253542236c 100644 --- a/pkg/registry/apps/statefulset/BUILD +++ b/pkg/registry/apps/statefulset/BUILD @@ -15,6 +15,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/apps:go_default_library", "//pkg/apis/apps/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", diff --git a/pkg/registry/apps/statefulset/strategy.go b/pkg/registry/apps/statefulset/strategy.go index 9a737e8cfd..c070619c4c 100644 --- a/pkg/registry/apps/statefulset/strategy.go +++ b/pkg/registry/apps/statefulset/strategy.go @@ -24,6 +24,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps/validation" ) @@ -55,6 +56,8 @@ func (statefulSetStrategy) PrepareForCreate(ctx genericapirequest.Context, obj r statefulSet.Status = apps.StatefulSetStatus{} statefulSet.Generation = 1 + + pod.DropDisabledAlphaFields(&statefulSet.Spec.Template.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -64,6 +67,9 @@ func (statefulSetStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, // Update is not allowed to set status newStatefulSet.Status = oldStatefulSet.Status + pod.DropDisabledAlphaFields(&newStatefulSet.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldStatefulSet.Spec.Template.Spec) + // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. // See metav1.ObjectMeta description for more information on Generation. diff --git a/pkg/registry/batch/cronjob/BUILD b/pkg/registry/batch/cronjob/BUILD index efcde00737..0910d4e396 100644 --- a/pkg/registry/batch/cronjob/BUILD +++ b/pkg/registry/batch/cronjob/BUILD @@ -14,6 +14,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/batch:go_default_library", "//pkg/apis/batch/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/registry/batch/cronjob/strategy.go b/pkg/registry/batch/cronjob/strategy.go index 1da7c50724..5b8b35ba0f 100644 --- a/pkg/registry/batch/cronjob/strategy.go +++ b/pkg/registry/batch/cronjob/strategy.go @@ -23,6 +23,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch/validation" ) @@ -51,6 +52,8 @@ func (cronJobStrategy) NamespaceScoped() bool { func (cronJobStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { cronJob := obj.(*batch.CronJob) cronJob.Status = batch.CronJobStatus{} + + pod.DropDisabledAlphaFields(&cronJob.Spec.JobTemplate.Spec.Template.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -58,6 +61,9 @@ func (cronJobStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old newCronJob := obj.(*batch.CronJob) oldCronJob := old.(*batch.CronJob) newCronJob.Status = oldCronJob.Status + + pod.DropDisabledAlphaFields(&newCronJob.Spec.JobTemplate.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldCronJob.Spec.JobTemplate.Spec.Template.Spec) } // Validate validates a new scheduled job. diff --git a/pkg/registry/batch/job/BUILD b/pkg/registry/batch/job/BUILD index 1361d89b64..76f4aaeb9c 100644 --- a/pkg/registry/batch/job/BUILD +++ b/pkg/registry/batch/job/BUILD @@ -14,6 +14,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/batch:go_default_library", "//pkg/apis/batch/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/registry/batch/job/strategy.go b/pkg/registry/batch/job/strategy.go index d019270016..b3f6ae3300 100644 --- a/pkg/registry/batch/job/strategy.go +++ b/pkg/registry/batch/job/strategy.go @@ -31,6 +31,7 @@ import ( "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch/validation" ) @@ -59,6 +60,8 @@ func (jobStrategy) NamespaceScoped() bool { func (jobStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { job := obj.(*batch.Job) job.Status = batch.JobStatus{} + + pod.DropDisabledAlphaFields(&job.Spec.Template.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -66,6 +69,9 @@ func (jobStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runt newJob := obj.(*batch.Job) oldJob := old.(*batch.Job) newJob.Status = oldJob.Status + + pod.DropDisabledAlphaFields(&newJob.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldJob.Spec.Template.Spec) } // Validate validates a new job. diff --git a/pkg/registry/core/node/BUILD b/pkg/registry/core/node/BUILD index 2cfe69090f..40a4110eea 100644 --- a/pkg/registry/core/node/BUILD +++ b/pkg/registry/core/node/BUILD @@ -16,6 +16,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/validation:go_default_library", + "//pkg/features:go_default_library", "//pkg/kubelet/client:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", @@ -32,6 +33,7 @@ go_library( "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) diff --git a/pkg/registry/core/node/strategy.go b/pkg/registry/core/node/strategy.go index 16eea39e8e..9b959bb7ba 100644 --- a/pkg/registry/core/node/strategy.go +++ b/pkg/registry/core/node/strategy.go @@ -34,8 +34,10 @@ import ( "k8s.io/apiserver/pkg/registry/generic" pkgstorage "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/client" ) @@ -61,8 +63,12 @@ func (nodeStrategy) AllowCreateOnUpdate() bool { // PrepareForCreate clears fields that are not allowed to be set by end users on creation. func (nodeStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { - _ = obj.(*api.Node) + node := obj.(*api.Node) // Nodes allow *all* fields, including status, to be set on create. + + if !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) { + node.Spec.ConfigSource = nil + } } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -70,6 +76,11 @@ func (nodeStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old run newNode := obj.(*api.Node) oldNode := old.(*api.Node) newNode.Status = oldNode.Status + + if !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) { + newNode.Spec.ConfigSource = nil + oldNode.Spec.ConfigSource = nil + } } // Validate validates a new node. diff --git a/pkg/registry/core/pod/BUILD b/pkg/registry/core/pod/BUILD index 36a4b049f6..1105959241 100644 --- a/pkg/registry/core/pod/BUILD +++ b/pkg/registry/core/pod/BUILD @@ -15,6 +15,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/helper/qos:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/kubelet/client:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", diff --git a/pkg/registry/core/pod/strategy.go b/pkg/registry/core/pod/strategy.go index 2c6bbf5237..a3d19438c7 100644 --- a/pkg/registry/core/pod/strategy.go +++ b/pkg/registry/core/pod/strategy.go @@ -39,6 +39,7 @@ import ( "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/helper/qos" + podutil "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/kubelet/client" ) @@ -65,6 +66,8 @@ func (podStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.O Phase: api.PodPending, QOSClass: qos.GetPodQOS(pod), } + + podutil.DropDisabledAlphaFields(&pod.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -72,6 +75,9 @@ func (podStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runt newPod := obj.(*api.Pod) oldPod := old.(*api.Pod) newPod.Status = oldPod.Status + + podutil.DropDisabledAlphaFields(&newPod.Spec) + podutil.DropDisabledAlphaFields(&oldPod.Spec) } // Validate validates a new pod. diff --git a/pkg/registry/core/podtemplate/BUILD b/pkg/registry/core/podtemplate/BUILD index 56c64540e2..9f13517597 100644 --- a/pkg/registry/core/podtemplate/BUILD +++ b/pkg/registry/core/podtemplate/BUILD @@ -13,6 +13,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/api/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", diff --git a/pkg/registry/core/podtemplate/strategy.go b/pkg/registry/core/podtemplate/strategy.go index 77a1dee56a..30ff599550 100644 --- a/pkg/registry/core/podtemplate/strategy.go +++ b/pkg/registry/core/podtemplate/strategy.go @@ -22,6 +22,7 @@ import ( genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/api/validation" ) @@ -42,7 +43,9 @@ func (podTemplateStrategy) NamespaceScoped() bool { // PrepareForCreate clears fields that are not allowed to be set by end users on creation. func (podTemplateStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { - _ = obj.(*api.PodTemplate) + template := obj.(*api.PodTemplate) + + pod.DropDisabledAlphaFields(&template.Template.Spec) } // Validate validates a new pod template. @@ -62,7 +65,11 @@ func (podTemplateStrategy) AllowCreateOnUpdate() bool { // PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (podTemplateStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { - _ = obj.(*api.PodTemplate) + newTemplate := obj.(*api.PodTemplate) + oldTemplate := old.(*api.PodTemplate) + + pod.DropDisabledAlphaFields(&newTemplate.Template.Spec) + pod.DropDisabledAlphaFields(&oldTemplate.Template.Spec) } // ValidateUpdate is the default update validation for an end user. diff --git a/pkg/registry/core/replicationcontroller/BUILD b/pkg/registry/core/replicationcontroller/BUILD index 6f3f74e28e..cbe1d65d18 100644 --- a/pkg/registry/core/replicationcontroller/BUILD +++ b/pkg/registry/core/replicationcontroller/BUILD @@ -16,6 +16,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/helper:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/api/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", diff --git a/pkg/registry/core/replicationcontroller/strategy.go b/pkg/registry/core/replicationcontroller/strategy.go index fd19c5d49a..2047afb6d3 100644 --- a/pkg/registry/core/replicationcontroller/strategy.go +++ b/pkg/registry/core/replicationcontroller/strategy.go @@ -35,6 +35,7 @@ import ( "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/helper" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/api/validation" ) @@ -64,6 +65,10 @@ func (rcStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Ob controller.Status = api.ReplicationControllerStatus{} controller.Generation = 1 + + if controller.Spec.Template != nil { + pod.DropDisabledAlphaFields(&controller.Spec.Template.Spec) + } } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -73,6 +78,13 @@ func (rcStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runti // update is not allowed to set status newController.Status = oldController.Status + if oldController.Spec.Template != nil { + pod.DropDisabledAlphaFields(&oldController.Spec.Template.Spec) + } + if newController.Spec.Template != nil { + pod.DropDisabledAlphaFields(&newController.Spec.Template.Spec) + } + // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. We push // the burden of managing the status onto the clients because we can't (in general) diff --git a/pkg/registry/extensions/daemonset/BUILD b/pkg/registry/extensions/daemonset/BUILD index 6865c0cdac..f658faf630 100644 --- a/pkg/registry/extensions/daemonset/BUILD +++ b/pkg/registry/extensions/daemonset/BUILD @@ -14,6 +14,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/validation:go_default_library", "//vendor/k8s.io/api/apps/v1beta2:go_default_library", diff --git a/pkg/registry/extensions/daemonset/strategy.go b/pkg/registry/extensions/daemonset/strategy.go index 7afdf9b284..0b42f3a967 100644 --- a/pkg/registry/extensions/daemonset/strategy.go +++ b/pkg/registry/extensions/daemonset/strategy.go @@ -30,6 +30,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions/validation" ) @@ -63,6 +64,8 @@ func (daemonSetStrategy) PrepareForCreate(ctx genericapirequest.Context, obj run if daemonSet.Spec.TemplateGeneration < 1 { daemonSet.Spec.TemplateGeneration = 1 } + + pod.DropDisabledAlphaFields(&daemonSet.Spec.Template.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -70,6 +73,9 @@ func (daemonSetStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, ol newDaemonSet := obj.(*extensions.DaemonSet) oldDaemonSet := old.(*extensions.DaemonSet) + pod.DropDisabledAlphaFields(&newDaemonSet.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldDaemonSet.Spec.Template.Spec) + // update is not allowed to set status newDaemonSet.Status = oldDaemonSet.Status diff --git a/pkg/registry/extensions/deployment/BUILD b/pkg/registry/extensions/deployment/BUILD index 4f80dbf7f2..63476b6d2e 100644 --- a/pkg/registry/extensions/deployment/BUILD +++ b/pkg/registry/extensions/deployment/BUILD @@ -15,6 +15,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/validation:go_default_library", "//vendor/k8s.io/api/apps/v1beta1:go_default_library", diff --git a/pkg/registry/extensions/deployment/strategy.go b/pkg/registry/extensions/deployment/strategy.go index 349f606ca5..0b898fcc04 100644 --- a/pkg/registry/extensions/deployment/strategy.go +++ b/pkg/registry/extensions/deployment/strategy.go @@ -31,6 +31,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions/validation" ) @@ -61,6 +62,8 @@ func (deploymentStrategy) PrepareForCreate(ctx genericapirequest.Context, obj ru deployment := obj.(*extensions.Deployment) deployment.Status = extensions.DeploymentStatus{} deployment.Generation = 1 + + pod.DropDisabledAlphaFields(&deployment.Spec.Template.Spec) } // Validate validates a new deployment. @@ -84,6 +87,9 @@ func (deploymentStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, o oldDeployment := old.(*extensions.Deployment) newDeployment.Status = oldDeployment.Status + pod.DropDisabledAlphaFields(&newDeployment.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldDeployment.Spec.Template.Spec) + // Spec updates bump the generation so that we can distinguish between // scaling events and template changes, annotation updates bump the generation // because annotations are copied from deployments to their replica sets. diff --git a/pkg/registry/extensions/replicaset/BUILD b/pkg/registry/extensions/replicaset/BUILD index 01bb4a781d..6935e70003 100644 --- a/pkg/registry/extensions/replicaset/BUILD +++ b/pkg/registry/extensions/replicaset/BUILD @@ -15,6 +15,7 @@ go_library( ], deps = [ "//pkg/api:go_default_library", + "//pkg/api/pod:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/validation:go_default_library", "//vendor/k8s.io/api/apps/v1beta2:go_default_library", diff --git a/pkg/registry/extensions/replicaset/strategy.go b/pkg/registry/extensions/replicaset/strategy.go index f432f3403c..1bd5bf5181 100644 --- a/pkg/registry/extensions/replicaset/strategy.go +++ b/pkg/registry/extensions/replicaset/strategy.go @@ -37,6 +37,7 @@ import ( apistorage "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions/validation" ) @@ -67,6 +68,8 @@ func (rsStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Ob rs.Status = extensions.ReplicaSetStatus{} rs.Generation = 1 + + pod.DropDisabledAlphaFields(&rs.Spec.Template.Spec) } // PrepareForUpdate clears fields that are not allowed to be set by end users on update. @@ -76,6 +79,9 @@ func (rsStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runti // update is not allowed to set status newRS.Status = oldRS.Status + pod.DropDisabledAlphaFields(&newRS.Spec.Template.Spec) + pod.DropDisabledAlphaFields(&oldRS.Spec.Template.Spec) + // Any changes to the spec increment the generation number, any changes to the // status should reflect the generation number of the corresponding object. We push // the burden of managing the status onto the clients because we can't (in general)