Skip to content

Commit

Permalink
Use existing "VerifyInstallation" to wait for completion of KUDO init (
Browse files Browse the repository at this point in the history
…#1662)

Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
  • Loading branch information
ANeumann82 committed Aug 27, 2020
1 parent ad70978 commit 8358371
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 28 deletions.
6 changes: 6 additions & 0 deletions pkg/engine/health/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ func IsHealthy(obj runtime.Object) error {
}
return fmt.Errorf("pod %q is not running yet: %s", obj.Name, obj.Status.Phase)

case *corev1.Namespace:
if obj.Status.Phase == corev1.NamespaceActive {
return nil
}
return fmt.Errorf("namespace %s is not active: %s", obj.Name, obj.Status.Phase)

// unless we build logic for what a healthy object is, assume it's healthy when created.
default:
log.Printf("HealthUtil: Unknown type %s is marked healthy by default", reflect.TypeOf(obj))
Expand Down
11 changes: 5 additions & 6 deletions pkg/kudoctl/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (initCmd *initCmd) run() error {

if initCmd.wait {
clog.Printf("⌛Waiting for KUDO controller to be ready in your cluster...")
err := setup.WatchKUDOUntilReady(initCmd.client.KubeClient, opts, initCmd.timeout)
err := setup.WatchKUDOUntilReady(installer, initCmd.client, initCmd.timeout)
if err != nil {
return errors.New("watch timed out, readiness uncertain")
}
Expand Down Expand Up @@ -287,13 +287,12 @@ func (initCmd *initCmd) runYamlOutput(installer kudoinit.Artifacter) error {
// verifyExistingInstallation checks if the current installation is valid and as expected
func (initCmd *initCmd) verifyExistingInstallation(v kudoinit.InstallVerifier) error {
clog.V(4).Printf("verify existing installation")
result := verifier.NewResult()
if err := v.VerifyInstallation(initCmd.client, &result); err != nil {
ok, err := setup.VerifyExistingInstallation(v, initCmd.client, initCmd.out)
if err != nil {
return err
}
result.PrintWarnings(initCmd.out)
if !result.IsValid() {
result.PrintErrors(initCmd.out)
if !ok {
return fmt.Errorf("KUDO installation is not valid")
}
return nil
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/kudoctl/kudoinit/crd/crds.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/yaml"

"github.com/kudobuilder/kudo/pkg/engine/health"
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/kube"
"github.com/kudobuilder/kudo/pkg/kudoctl/kudoinit"
Expand Down Expand Up @@ -121,6 +122,10 @@ func (c Initializer) verifyInstallation(client v1beta1.CustomResourceDefinitions
result.AddErrors(fmt.Sprintf("Installed CRD %s has invalid version %s, expected %s", crd.Name, existingCrd.Spec.Version, crd.Spec.Version))
return nil
}
if err := health.IsHealthy(existingCrd); err != nil {
result.AddErrors(fmt.Sprintf("Installed CRD %s is not healthy: %v", crd.Name, err))
return nil
}
clog.V(2).Printf("CRD %s is installed with version %s", crd.Name, existingCrd.Spec.Versions[0].Name)
return nil
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/kudoctl/kudoinit/prereq/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"

"github.com/kudobuilder/kudo/pkg/engine/health"
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
"github.com/kudobuilder/kudo/pkg/kudoctl/kube"
"github.com/kudobuilder/kudo/pkg/kudoctl/kudoinit"
Expand Down Expand Up @@ -64,14 +65,17 @@ func (o KudoNamespace) PreUpgradeVerify(client *kube.Client, result *verifier.Re
}

func (o KudoNamespace) VerifyInstallation(client *kube.Client, result *verifier.Result) error {
_, err := client.KubeClient.CoreV1().Namespaces().Get(context.TODO(), o.opts.Namespace, metav1.GetOptions{})
ns, err := client.KubeClient.CoreV1().Namespaces().Get(context.TODO(), o.opts.Namespace, metav1.GetOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
result.AddErrors(fmt.Sprintf("namespace %s does not exist", o.opts.Namespace))
return nil
}
return err
}
if err := health.IsHealthy(ns); err != nil {
result.AddErrors(fmt.Sprintf("namespace %s is not healthy: %v", o.opts.Namespace, err))
}
return nil
}

Expand Down
20 changes: 20 additions & 0 deletions pkg/kudoctl/kudoinit/setup/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package setup

import (
"fmt"
"io"

"k8s.io/apimachinery/pkg/runtime"

Expand Down Expand Up @@ -167,3 +168,22 @@ func (i *Installer) Resources() []runtime.Object {

return allManifests
}

// verifyExistingInstallation checks if the current installation is valid and as expected
func VerifyExistingInstallation(v kudoinit.InstallVerifier, client *kube.Client, out io.Writer) (bool, error) {
clog.V(4).Printf("verify existing installation")
result := verifier.NewResult()
if err := v.VerifyInstallation(client, &result); err != nil {
return false, err
}
if out != nil {
result.PrintWarnings(out)
}
if !result.IsValid() {
if out != nil {
result.PrintErrors(out)
}
return false, nil
}
return true, nil
}
28 changes: 7 additions & 21 deletions pkg/kudoctl/kudoinit/setup/wait.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
package setup

import (
"context"
"time"

"github.com/kudobuilder/kudo/pkg/engine/health"
"github.com/kudobuilder/kudo/pkg/kudoctl/kube"

"k8s.io/apimachinery/pkg/util/wait"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
appsv1 "k8s.io/client-go/kubernetes/typed/apps/v1"

"github.com/kudobuilder/kudo/pkg/kudoctl/kudoinit"
)

// WatchKUDOUntilReady waits for the KUDO pod to become available.
// WatchKUDOUntilReady waits for the KUDO installation to become available.
//
// Returns no error if it exists. If the timeout was reached and it could not find the pod, it returns error.
func WatchKUDOUntilReady(client kubernetes.Interface, opts kudoinit.Options, timeout int64) error {
func WatchKUDOUntilReady(v kudoinit.InstallVerifier, client *kube.Client, timeout int64) error {
return wait.PollImmediate(500*time.Millisecond, time.Duration(timeout)*time.Second,
func() (bool, error) { return verifyKudoStatefulset(client.AppsV1(), opts.Namespace) })
}

func verifyKudoStatefulset(client appsv1.StatefulSetsGetter, namespace string) (bool, error) {
ss, err := client.StatefulSets(namespace).Get(context.TODO(), kudoinit.DefaultManagerName, metav1.GetOptions{})
if err != nil || ss == nil {
return false, err
}
err = health.IsHealthy(ss)
if err != nil {
return false, nil
}
return true, nil
func() (bool, error) {
return VerifyExistingInstallation(v, client, nil)
},
)
}

0 comments on commit 8358371

Please sign in to comment.