Skip to content

Commit

Permalink
feature flag and wait for resize
Browse files Browse the repository at this point in the history
  • Loading branch information
SidakM committed Dec 7, 2018
1 parent 57d1406 commit 0a2c2b0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
27 changes: 19 additions & 8 deletions pkg/apis/apps/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/apis/apps"
api "k8s.io/kubernetes/pkg/apis/core"
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/features"
)

// ValidateStatefulSetName can be used to check whether the given StatefulSet name is valid.
Expand Down Expand Up @@ -154,21 +156,30 @@ func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet *apps.StatefulSet) fi
statefulSet.Spec.UpdateStrategy = oldStatefulSet.Spec.UpdateStrategy

restoreVolumeClaimTemplates := make([]api.PersistentVolumeClaim, len(statefulSet.Spec.VolumeClaimTemplates))
volumeExpansionEnabled := utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes)
if len(oldStatefulSet.Spec.VolumeClaimTemplates) == len(statefulSet.Spec.VolumeClaimTemplates) {
for index, oldVolumeClaimTemplate := range oldStatefulSet.Spec.VolumeClaimTemplates {
oldStorageRequest := oldVolumeClaimTemplate.Spec.Resources.Requests[api.ResourceStorage]
newStorageRequest := statefulSet.Spec.VolumeClaimTemplates[index].Spec.Resources.Requests[api.ResourceStorage]
if newStorageRequest.Cmp(oldStorageRequest) < 0 {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "volumeClaimTemplates", fmt.Sprint(index), "spec", "resources", "requests", "storage"), "storage request can not be less than previous value"))
}

restoreVolumeClaimTemplates[index] = *statefulSet.Spec.VolumeClaimTemplates[index].DeepCopy()
statefulSet.Spec.VolumeClaimTemplates[index].Spec.Resources.Requests[api.ResourceStorage] = oldStorageRequest
if volumeExpansionEnabled {
oldStorageRequest := oldVolumeClaimTemplate.Spec.Resources.Requests[api.ResourceStorage]
newStorageRequest := statefulSet.Spec.VolumeClaimTemplates[index].Spec.Resources.Requests[api.ResourceStorage]
if newStorageRequest.Cmp(oldStorageRequest) < 0 {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "volumeClaimTemplates", fmt.Sprint(index), "spec", "resources", "requests", "storage"), "storage request can not be less than previous value"))
}
statefulSet.Spec.VolumeClaimTemplates[index].Spec.Resources.Requests[api.ResourceStorage] = oldStorageRequest
}
}
}

if !apiequality.Semantic.DeepEqual(statefulSet.Spec, oldStatefulSet.Spec) {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to statefulset spec for fields other than 'replicas', 'template' ,'updateStrategy' and 'volumeClaimTemplate.Spec.Resources.Requests[storage]' are forbidden"))
var errMsg string
if volumeExpansionEnabled {
errMsg = "updates to statefulset spec for fields other than 'replicas', 'template', 'updateStrategy' and 'volumeClaimTemplate.Spec.Resources.Requests[storage]' are forbidden"
} else {
errMsg = "updates to statefulset spec for fields other than 'replicas', 'template' and 'updateStrategy' are forbidden"
}

allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), errMsg))
}
statefulSet.Spec.Replicas = restoreReplicas
statefulSet.Spec.Template = restoreTemplate
Expand Down
9 changes: 6 additions & 3 deletions pkg/controller/statefulset/stateful_pod_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,17 @@ func (spc *realStatefulPodControl) updatePersistentVolumeClaims(set *apps.Statef

currentStorageRequest := currentClaim.Spec.Resources.Requests[v1.ResourceStorage]
updatedStorageRequest := updatedClaim.Spec.Resources.Requests[v1.ResourceStorage]
if updatedStorageRequest.Cmp(currentStorageRequest) != 0 {
if updatedStorageRequest.Cmp(currentStorageRequest) > 0 {
currentClaim.Spec.Resources.Requests[v1.ResourceStorage] = updatedStorageRequest
_, err = spc.client.CoreV1().PersistentVolumeClaims(currentClaim.Namespace).Update(currentClaim)
currentClaim, err = spc.client.CoreV1().PersistentVolumeClaims(currentClaim.Namespace).Update(currentClaim)
if err != nil {
errs = append(errs, fmt.Errorf("Failed to update PVC %s: %s", currentClaim.Name, err))
spc.recordClaimEvent("update", set, pod, currentClaim, err)
}
// Add wait for the FileSystemResizePending condition? So pods are restarted after underlying volume has expanded
}

if !resizePending(currentClaim) {
errs = append(errs, fmt.Errorf("Controller resize pending for PVC %s", currentClaim.Name))
}
}
return errorutils.NewAggregate(errs)
Expand Down
9 changes: 9 additions & 0 deletions pkg/controller/statefulset/stateful_set_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ func isHealthy(pod *v1.Pod) bool {
return isRunningAndReady(pod) && !isTerminating(pod)
}

func resizePending(pvc *v1.PersistentVolumeClaim) bool {
for _, condition := range pvc.Status.Conditions {
if condition.Type == v1.PersistentVolumeClaimFileSystemResizePending && condition.Status == v1.ConditionTrue {
return true
}
}
return false
}

// allowsBurst is true if the alpha burst annotation is set.
func allowsBurst(set *apps.StatefulSet) bool {
return set.Spec.PodManagementPolicy == apps.ParallelPodManagement
Expand Down

0 comments on commit 0a2c2b0

Please sign in to comment.