Skip to content

Commit

Permalink
Merge pull request #52557 from enisoc/automated-cherry-pick-of-#51199…
Browse files Browse the repository at this point in the history
…-upstream-release-1.6

Automatic merge from submit-queue.

Automated cherry pick of #51199

Cherry pick of #51199 on release-1.6.

This allows users to completely avoid any disruption due to #48327, by first upgrading to a 1.6.x release containing this patch, before upgrading to 1.7.x.

#51199: Makes Hostname and Subdomain fields of v1.PodSpec settable
  • Loading branch information
Kubernetes Submit Queue committed Sep 16, 2017
2 parents ee58d3a + c0f58c1 commit 6091610
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 13 deletions.
10 changes: 10 additions & 0 deletions pkg/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2476,6 +2476,16 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) field.ErrorList {

// handle updateable fields by munging those fields prior to deep equal comparison.
mungedPod := *newPod

// allow hostname and subdomain to be updated if they are empty. This allows for migration between the beta
// annotations and the GA field when upgrading between Kubernetes 1.6.x and 1.7.x.
if oldPod.Spec.Hostname == "" {
mungedPod.Spec.Hostname = oldPod.Spec.Hostname
}
if oldPod.Spec.Subdomain == "" {
mungedPod.Spec.Subdomain = oldPod.Spec.Subdomain
}

// munge containers[*].image
var newContainers []api.Container
for ix, container := range mungedPod.Spec.Containers {
Expand Down
48 changes: 48 additions & 0 deletions pkg/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4836,6 +4836,54 @@ func TestValidatePodUpdate(t *testing.T) {
false,
"added invalid new toleration to existing tolerations in pod spec updates",
},
{
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Hostname: "bar"},
},
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Hostname: ""},
},
true,
"update empty hostname",
},
{
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Subdomain: "bar"},
},
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Subdomain: ""},
},
true,
"update empty subdomain",
},
{
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Hostname: "bar"},
},
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Hostname: "baz"},
},
false,
"update hostname",
},
{
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Subdomain: "bar"},
},
api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{Subdomain: "baz"},
},
false,
"update subdomain",
},
}

for _, test := range tests {
Expand Down
28 changes: 15 additions & 13 deletions pkg/controller/statefulset/stateful_set_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,21 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
set.Name, replicas[i].Name)
return nil
}
// Enforce the StatefulSet invariants - we do this without respect to the Pod's readiness so that the endpoints
// controller can be notified of identity changes if a Pod becomes unready due to a DNS inconsistency with respect
// to the Pods identity.
if !identityMatches(set, replicas[i]) || !storageMatches(set, replicas[i]) {
// Make a deep copy so we don't mutate the shared cache
copy, err := api.Scheme.DeepCopy(replicas[i])
if err != nil {
return err
}
replica := copy.(*v1.Pod)
if err := ssc.podControl.UpdateStatefulPod(set, replica); err != nil {
return err
}
}

// If we have a Pod that has been created but is not running and ready we can not make progress.
// We must ensure that all for each Pod, when we create it, all of its predecessors, with respect to its
// ordinal, are Running and Ready.
Expand All @@ -147,19 +162,6 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
set.Name, replicas[i].Name)
return nil
}
// Enforce the StatefulSet invariants
if identityMatches(set, replicas[i]) && storageMatches(set, replicas[i]) {
continue
}
// Make a deep copy so we don't mutate the shared cache
copy, err := api.Scheme.DeepCopy(replicas[i])
if err != nil {
return err
}
replica := copy.(*v1.Pod)
if err := ssc.podControl.UpdateStatefulPod(set, replica); err != nil {
return err
}
}

// At this point, all of the current Replicas are Running and Ready, we can consider termination.
Expand Down
6 changes: 6 additions & 0 deletions pkg/controller/statefulset/stateful_set_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ func updateStorage(set *apps.StatefulSet, pod *v1.Pod) {
func updateIdentity(set *apps.StatefulSet, pod *v1.Pod) {
pod.Name = getPodName(set, getOrdinal(pod))
pod.Namespace = set.Namespace
if pod.Spec.Hostname == "" {
pod.Spec.Hostname = pod.Name
}
if pod.Spec.Subdomain == "" {
pod.Spec.Subdomain = set.Spec.ServiceName
}
if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/controller/statefulset/stateful_set_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,22 @@ func TestUpdateIdentity(t *testing.T) {
if !identityMatches(set, pod) {
t.Error("updateIdentity failed to update the Pods namespace")
}
pod.Spec.Hostname = ""
pod.Spec.Subdomain = ""
updateIdentity(set, pod)
if pod.Spec.Hostname != pod.Name || pod.Spec.Subdomain != set.Spec.ServiceName {
t.Errorf("want hostame=%s subdomain=%s got hostname=%s subdomain=%s",
pod.Name,
set.Spec.ServiceName,
pod.Spec.Hostname,
set.Spec.ServiceName)
}
pod.Spec.Hostname = "foo"
pod.Spec.Subdomain = "bar"
updateIdentity(set, pod)
if pod.Spec.Hostname != "foo" || pod.Spec.Subdomain != "bar" {
t.Errorf("want hostame=foo subdomain=bar got hostname=%s subdomain=%s", pod.Spec.Hostname, set.Spec.ServiceName)
}
pod = newStatefulSetPod(set, 1)
delete(pod.Annotations, podapi.PodHostnameAnnotation)
pod.Spec.Hostname = ""
Expand Down

0 comments on commit 6091610

Please sign in to comment.