Merge branch 'master' into add-logical-backup

This commit is contained in:
Sergey Dudoladov
2019-04-01 13:52:18 +02:00
19 changed files with 502 additions and 50 deletions
+20 -21
View File
@@ -327,14 +327,10 @@ func (c *Cluster) compareStatefulSetWith(statefulSet *v1beta1.StatefulSet) *comp
match = false
reasons = append(reasons, "new statefulset's annotations doesn't match the current one")
}
if len(c.Statefulset.Spec.Template.Spec.Containers) != len(statefulSet.Spec.Template.Spec.Containers) {
needsRollUpdate = true
reasons = append(reasons, "new statefulset's container specification doesn't match the current one")
} else {
var containerReasons []string
needsRollUpdate, containerReasons = c.compareContainers(c.Statefulset, statefulSet)
reasons = append(reasons, containerReasons...)
}
needsRollUpdate, reasons = c.compareContainers("initContainers", c.Statefulset.Spec.Template.Spec.InitContainers, statefulSet.Spec.Template.Spec.InitContainers, needsRollUpdate, reasons)
needsRollUpdate, reasons = c.compareContainers("containers", c.Statefulset.Spec.Template.Spec.Containers, statefulSet.Spec.Template.Spec.Containers, needsRollUpdate, reasons)
if len(c.Statefulset.Spec.Template.Spec.Containers) == 0 {
c.logger.Warningf("statefulset %q has no container", util.NameFromMeta(c.Statefulset.ObjectMeta))
return &compareStatefulsetResult{}
@@ -425,34 +421,37 @@ func newCheck(msg string, cond containerCondition) containerCheck {
return containerCheck{reason: msg, condition: cond}
}
// compareContainers: compare containers from two stateful sets
// compareContainers: compare two list of Containers
// and return:
// * whether or not a rolling update is needed
// * a list of reasons in a human readable format
func (c *Cluster) compareContainers(setA, setB *v1beta1.StatefulSet) (bool, []string) {
reasons := make([]string, 0)
needsRollUpdate := false
func (c *Cluster) compareContainers(description string, setA, setB []v1.Container, needsRollUpdate bool, reasons []string) (bool, []string) {
if len(setA) != len(setB) {
return true, append(reasons, fmt.Sprintf("new statefulset %s's length does not match the current ones", description))
}
checks := []containerCheck{
newCheck("new statefulset's container %s (index %d) name doesn't match the current one",
newCheck("new statefulset %s's %s (index %d) name doesn't match the current one",
func(a, b v1.Container) bool { return a.Name != b.Name }),
newCheck("new statefulset's container %s (index %d) image doesn't match the current one",
newCheck("new statefulset %s's %s (index %d) image doesn't match the current one",
func(a, b v1.Container) bool { return a.Image != b.Image }),
newCheck("new statefulset's container %s (index %d) ports don't match the current one",
newCheck("new statefulset %s's %s (index %d) ports don't match the current one",
func(a, b v1.Container) bool { return !reflect.DeepEqual(a.Ports, b.Ports) }),
newCheck("new statefulset's container %s (index %d) resources don't match the current ones",
newCheck("new statefulset %s's %s (index %d) resources don't match the current ones",
func(a, b v1.Container) bool { return !compareResources(&a.Resources, &b.Resources) }),
newCheck("new statefulset's container %s (index %d) environment doesn't match the current one",
newCheck("new statefulset %s's %s (index %d) environment doesn't match the current one",
func(a, b v1.Container) bool { return !reflect.DeepEqual(a.Env, b.Env) }),
newCheck("new statefulset's container %s (index %d) environment sources don't match the current one",
newCheck("new statefulset %s's %s (index %d) environment sources don't match the current one",
func(a, b v1.Container) bool { return !reflect.DeepEqual(a.EnvFrom, b.EnvFrom) }),
}
for index, containerA := range setA.Spec.Template.Spec.Containers {
containerB := setB.Spec.Template.Spec.Containers[index]
for index, containerA := range setA {
containerB := setB[index]
for _, check := range checks {
if check.condition(containerA, containerB) {
needsRollUpdate = true
reasons = append(reasons, fmt.Sprintf(check.reason, containerA.Name, index))
reasons = append(reasons, fmt.Sprintf(check.reason, description, containerA.Name, index))
}
}
}
+16
View File
@@ -861,6 +861,20 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State
numberOfInstances := c.getNumberOfInstances(spec)
// the operator has domain-specific logic on how to do rolling updates of PG clusters
// so we do not use default rolling updates implemented by stateful sets
// that leaves the legacy "OnDelete" update strategy as the only option
updateStrategy := v1beta1.StatefulSetUpdateStrategy{Type: v1beta1.OnDeleteStatefulSetStrategyType}
var podManagementPolicy v1beta1.PodManagementPolicyType
if c.OpConfig.PodManagementPolicy == "ordered_ready" {
podManagementPolicy = v1beta1.OrderedReadyPodManagement
} else if c.OpConfig.PodManagementPolicy == "parallel" {
podManagementPolicy = v1beta1.ParallelPodManagement
} else {
return nil, fmt.Errorf("could not set the pod management policy to the unknown value: %v", c.OpConfig.PodManagementPolicy)
}
statefulSet := &v1beta1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: c.statefulSetName(),
@@ -874,6 +888,8 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State
ServiceName: c.serviceName(Master),
Template: *podTemplate,
VolumeClaimTemplates: []v1.PersistentVolumeClaim{*volumeClaimTemplate},
UpdateStrategy: updateStrategy,
PodManagementPolicy: podManagementPolicy,
},
}