diff --git a/go.sum b/go.sum index fb11fdbc4..629d466c2 100644 --- a/go.sum +++ b/go.sum @@ -25,12 +25,8 @@ github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e h1:eb0Pzkt15Bm github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.0.1 h1:2kKm5lb7dKVrt5TYUiAavE6oFc1cFT0057UVGT+JqLk= -github.com/Masterminds/semver/v3 v3.0.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.0.0 h1:KSQz7Nb08/3VU9E4ns29dDxcczhOD1q7O1UfM4G3t3g= -github.com/Masterminds/sprig/v3 v3.0.0/go.mod h1:NEUY/Qq8Gdm2xgYA+NwJM6wmfdRV9xkh8h/Rld20R0U= github.com/Masterminds/sprig/v3 v3.0.2 h1:wz22D0CiSctrliXiI9ZO3HoNApweeRGftyDN+BQa3B8= github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA= diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 96179d19d..e3d3afb14 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -26,6 +26,7 @@ import ( "sync" "time" + "github.com/Masterminds/semver/v3" jsonpatch "github.com/evanphx/json-patch" "github.com/pkg/errors" batch "k8s.io/api/batch/v1" @@ -52,8 +53,9 @@ var ErrNoObjectsVisited = errors.New("no objects visited") // Client represents a client capable of communicating with the Kubernetes API. type Client struct { - Factory Factory - Log func(string, ...interface{}) + Factory Factory + Log func(string, ...interface{}) + serverVersion *semver.Version } // New creates a new Client. @@ -77,10 +79,18 @@ var nopLogger = func(_ string, _ ...interface{}) {} // IsReachable tests connectivity to the cluster func (c *Client) IsReachable() error { client, _ := c.Factory.KubernetesClientSet() - _, err := client.ServerVersion() + sv, err := client.ServerVersion() if err != nil { return errors.New("Kubernetes cluster unreachable") } + + version, err := semver.NewVersion(sv.GitVersion) + if err != nil { + return fmt.Errorf("illegal server version %s", version) + } + + c.serverVersion = version + return nil } @@ -99,10 +109,12 @@ func (c *Client) Wait(resources ResourceList, timeout time.Duration) error { if err != nil { return err } + w := waiter{ - c: cs, - log: c.Log, - timeout: timeout, + c: cs, + log: c.Log, + timeout: timeout, + serverVersion: c.serverVersion, } return w.waitForResources(resources) } diff --git a/pkg/kube/wait.go b/pkg/kube/wait.go index 7198917c4..5502cb9bc 100644 --- a/pkg/kube/wait.go +++ b/pkg/kube/wait.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + "github.com/Masterminds/semver/v3" "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" appsv1beta1 "k8s.io/api/apps/v1beta1" @@ -40,9 +41,10 @@ import ( ) type waiter struct { - c kubernetes.Interface - timeout time.Duration - log func(string, ...interface{}) + c kubernetes.Interface + timeout time.Duration + log func(string, ...interface{}) + serverVersion *semver.Version } // waitForResources polls to get the current status of all pods, PVCs, and Services @@ -249,6 +251,8 @@ func (w *waiter) crdReady(crd apiextv1beta1.CustomResourceDefinition) bool { return false } +var V112 = semver.MustParse("v1.12.0") + func (w *waiter) statefulSetReady(sts *appsv1.StatefulSet) bool { // If the update strategy is not a rolling update, there will be nothing to wait for if sts.Spec.UpdateStrategy.Type != appsv1.RollingUpdateStatefulSetStrategyType { @@ -275,10 +279,15 @@ func (w *waiter) statefulSetReady(sts *appsv1.StatefulSet) bool { // updated expectedReplicas := replicas - partition - // Make sure all the updated pods have been scheduled - if int(sts.Status.UpdatedReplicas) != expectedReplicas { - w.log("StatefulSet is not ready: %s/%s. %d out of %d expected pods have been scheduled", sts.Namespace, sts.Name, sts.Status.UpdatedReplicas, expectedReplicas) - return false + // https://github.com/kubernetes/kubernetes/issues/52653 + if w.serverVersion != nil && w.serverVersion.LessThan(V112) { + // do nothing + } else { + // Make sure all the updated pods have been scheduled + if int(sts.Status.UpdatedReplicas) != expectedReplicas { + w.log("StatefulSet is not ready: %s/%s. %d out of %d expected pods have been scheduled", sts.Namespace, sts.Name, sts.Status.UpdatedReplicas, expectedReplicas) + return false + } } if int(sts.Status.ReadyReplicas) != replicas {