Skip to content

Commit

Permalink
fix: playground does not output error message when kubernetes cluster…
Browse files Browse the repository at this point in the history
… is not ready (apecloud#2391)
  • Loading branch information
ldming authored Apr 4, 2023
1 parent 9466d38 commit 912c31a
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 69 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ kbcli-doc: generate ## generate CLI command reference manual.
$(GO) run ./hack/docgen/cli/main.go ./docs/user_docs/cli



##@ Operator Controller Manager

.PHONY: manager
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/cloudprovider/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type Interface interface {
Name() string

// CreateK8sCluster creates a kubernetes cluster
CreateK8sCluster(clusterInfo *K8sClusterInfo, init bool) error
CreateK8sCluster(clusterInfo *K8sClusterInfo) error

// DeleteK8sCluster deletes the created kubernetes cluster
DeleteK8sCluster(clusterInfo *K8sClusterInfo) error
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/cloudprovider/k3d.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (p *localCloudProvider) Name() string {
}

// CreateK8sCluster create a local kubernetes cluster using k3d
func (p *localCloudProvider) CreateK8sCluster(clusterInfo *K8sClusterInfo, init bool) error {
func (p *localCloudProvider) CreateK8sCluster(clusterInfo *K8sClusterInfo) error {
var err error

if p.cfg, err = buildClusterRunConfig(clusterInfo.ClusterName); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/cli/cloudprovider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (p *cloudProvider) Name() string {
}

// CreateK8sCluster create a kubernetes cluster
func (p *cloudProvider) CreateK8sCluster(clusterInfo *K8sClusterInfo, init bool) error {
func (p *cloudProvider) CreateK8sCluster(clusterInfo *K8sClusterInfo) error {
// init terraform
fmt.Fprintf(p.stdout, "Check and install terraform... \n")
if err := initTerraform(); err != nil {
Expand All @@ -66,7 +66,7 @@ func (p *cloudProvider) CreateK8sCluster(clusterInfo *K8sClusterInfo, init bool)

// create cluster
fmt.Fprintf(p.stdout, "\nInit and apply %s in %s\n", K8sService(p.name), p.tfPath)
return tfInitAndApply(p.tfPath, init, p.stdout, p.stderr, clusterInfo.buildApplyOpts()...)
return tfInitAndApply(p.tfPath, p.stdout, p.stderr, clusterInfo.buildApplyOpts()...)
}

func (p *cloudProvider) DeleteK8sCluster(clusterInfo *K8sClusterInfo) error {
Expand All @@ -85,7 +85,7 @@ func (p *cloudProvider) DeleteK8sCluster(clusterInfo *K8sClusterInfo) error {

// destroy cluster
fmt.Fprintf(p.stdout, "\nDestroy %s cluster in %s\n", K8sService(p.name), p.tfPath)
return tfDestroy(p.tfPath, p.stdout, p.stderr, clusterInfo.buildDestroyOpts()...)
return tfInitAndDestroy(p.tfPath, p.stdout, p.stderr, clusterInfo.buildDestroyOpts()...)
}

func (p *cloudProvider) GetClusterInfo() (*K8sClusterInfo, error) {
Expand Down
15 changes: 9 additions & 6 deletions internal/cli/cloudprovider/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,15 @@ func initTerraform() error {
return nil
}

func tfInitAndApply(workingDir string, init bool, stdout, stderr io.Writer, opts ...tfexec.ApplyOption) error {
func tfInitAndApply(workingDir string, stdout, stderr io.Writer, opts ...tfexec.ApplyOption) error {
ctx := context.Background()
tf, err := newTerraform(workingDir, stdout, stderr)
if err != nil {
return err
}

if init {
if err = tf.Init(ctx, tfexec.Upgrade(true)); err != nil {
return err
}
if err = tf.Init(ctx, tfexec.Upgrade(false)); err != nil {
return err
}

if err = tf.Apply(ctx, opts...); err != nil {
Expand All @@ -96,12 +94,17 @@ func tfInitAndApply(workingDir string, init bool, stdout, stderr io.Writer, opts
return nil
}

func tfDestroy(workingDir string, stdout, stderr io.Writer, opts ...tfexec.DestroyOption) error {
func tfInitAndDestroy(workingDir string, stdout, stderr io.Writer, opts ...tfexec.DestroyOption) error {
ctx := context.Background()
tf, err := newTerraform(workingDir, stdout, stderr)
if err != nil {
return err
}

if err = tf.Init(ctx, tfexec.Upgrade(false)); err != nil {
return err
}

return tf.Destroy(ctx, opts...)
}

Expand Down
5 changes: 2 additions & 3 deletions internal/cli/cmd/playground/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,9 @@ func (o *destroyOptions) destroyCloud() error {
}

func (o *destroyOptions) removeKubeConfig() error {
configPath := util.ConfigPath("config")
spinner := printer.Spinner(o.Out, "Remove kubeconfig from %s", configPath)
spinner := printer.Spinner(o.Out, "Remove kubeconfig from %s", defaultKubeConfigPath)
defer spinner(false)
if err := kubeConfigRemove(o.prevCluster.KubeConfig, configPath); err != nil {
if err := kubeConfigRemove(o.prevCluster.KubeConfig, defaultKubeConfigPath); err != nil {
return err
}
spinner(true)
Expand Down
117 changes: 64 additions & 53 deletions internal/cli/cmd/playground/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
Expand Down Expand Up @@ -156,7 +157,7 @@ func (o *initOptions) local() error {
// create a local kubernetes cluster (k3d cluster) to deploy KubeBlocks
spinner := printer.Spinner(o.Out, "%-40s", "Create k3d cluster: "+clusterInfo.ClusterName)
defer spinner(false)
if err = provider.CreateK8sCluster(clusterInfo, true); err != nil {
if err = provider.CreateK8sCluster(clusterInfo); err != nil {
return errors.Wrap(err, "failed to set up k3d cluster")
}
spinner(true)
Expand All @@ -169,52 +170,6 @@ func (o *initOptions) local() error {
return o.installKBAndCluster(clusterInfo.ClusterName)
}

func (o *initOptions) installKBAndCluster(k8sClusterName string) error {
var err error

// playground always use the default kubeconfig at ~/.kube/config
configPath := util.ConfigPath("config")
if err = util.SetKubeConfig(configPath); err != nil {
return err
}

// create helm config
o.helmCfg = helm.NewConfig("", configPath, "", klog.V(1).Enabled())

// Install KubeBlocks
if err = o.installKubeBlocks(k8sClusterName); err != nil {
return errors.Wrap(err, "failed to install KubeBlocks")
}

// Install database cluster
clusterInfo := "ClusterDefinition: " + o.clusterDef
if o.clusterVersion != "" {
clusterInfo += ", ClusterVersion: " + o.clusterVersion
}
spinner := printer.Spinner(o.Out, "Create cluster %s (%s)", kbClusterName, clusterInfo)
defer spinner(false)
if err = o.createCluster(); err != nil {
return errors.Wrapf(err, "failed to create cluster %s", kbClusterName)
}
spinner(true)

// Print guide information
fmt.Fprintf(os.Stdout, "\nKubeBlocks playground init SUCCESSFULLY!\n\n")
if k8sClusterName != "" {
fmt.Fprintf(os.Stdout, "Kubernetes cluster \"%s\" has been created.\n", k8sClusterName)
}
fmt.Fprintf(os.Stdout, "Cluster \"%s\" has been created.\n", kbClusterName)

// output elapsed time
if !o.startTime.IsZero() {
fmt.Fprintf(o.Out, "Elapsed time: %s\n", time.Since(o.startTime).Truncate(time.Second))
}

printGuide()

return nil
}

// bootstraps a playground in the remote cloud
func (o *initOptions) cloud() error {
cpPath, err := cloudProviderRepoDir()
Expand Down Expand Up @@ -268,11 +223,13 @@ func (o *initOptions) cloud() error {
return err
}

if err = provider.CreateK8sCluster(clusterInfo, true); err != nil {
// create a kubernetes cluster in the cloud
if err = provider.CreateK8sCluster(clusterInfo); err != nil {
return err
}
printer.PrintBlankLine(o.Out)

// write cluster kubeconfig to local kubeconfig file and switch current context to it
if err = o.setKubeConfig(provider); err != nil {
return err
}
Expand All @@ -289,7 +246,8 @@ func (o *initOptions) confirmToContinue() error {
fmt.Fprintf(o.Out, "\nPlayground init cancelled, please destroy the old cluster first.\n")
return cmdutil.ErrExit
}
fmt.Fprintf(o.Out, "Continue to initialize %s %s cluster %s... \n", o.cloudProvider, cp.K8sService(o.cloudProvider), clusterName)
fmt.Fprintf(o.Out, "Continue to initialize %s %s cluster %s... \n",
o.cloudProvider, cp.K8sService(o.cloudProvider), clusterName)
return nil
}

Expand Down Expand Up @@ -328,14 +286,15 @@ func (o *initOptions) setKubeConfig(provider cp.Interface) error {
return errors.New("failed to get kubernetes cluster kubeconfig")
}
if err = writeClusterInfoToFile(o.stateFilePath, clusterInfo); err != nil {
return errors.Wrapf(err, "failed to write kubernetes cluster info to state file %s:\n %v", o.stateFilePath, clusterInfo)
return errors.Wrapf(err, "failed to write kubernetes cluster info to state file %s:\n %v",
o.stateFilePath, clusterInfo)
}

// merge created kubernetes cluster kubeconfig to ~/.kube/config and set it as default
configPath := util.ConfigPath("config")
spinner := printer.Spinner(o.Out, "Write kubeconfig to %s", configPath)
spinner := printer.Spinner(o.Out, "Write kubeconfig to %s", defaultKubeConfigPath)
defer spinner(false)
if err = kubeConfigWrite(clusterInfo.KubeConfig, configPath, writeKubeConfigOptions{UpdateExisting: true, UpdateCurrentContext: true}); err != nil {
if err = kubeConfigWrite(clusterInfo.KubeConfig, defaultKubeConfigPath,
writeKubeConfigOptions{UpdateExisting: true, UpdateCurrentContext: true}); err != nil {
return errors.Wrapf(err, "failed to write cluster %s kubeconfig", clusterInfo.ClusterName)
}
spinner(true)
Expand All @@ -351,6 +310,58 @@ func (o *initOptions) setKubeConfig(provider cp.Interface) error {
return nil
}

func (o *initOptions) installKBAndCluster(k8sClusterName string) error {
var err error

// when the kubernetes cluster is not ready, the runtime will output the error
// message like "couldn't get resource list for", we ignore it
runtime.ErrorHandlers[0] = func(err error) {
if klog.V(1).Enabled() {
klog.ErrorDepth(2, err)
}
}

// playground always use the default kubeconfig at ~/.kube/config
if err = util.SetKubeConfig(defaultKubeConfigPath); err != nil {
return err
}

// create helm config
o.helmCfg = helm.NewConfig("", defaultKubeConfigPath, "", klog.V(1).Enabled())

// Install KubeBlocks
if err = o.installKubeBlocks(k8sClusterName); err != nil {
return errors.Wrap(err, "failed to install KubeBlocks")
}

// Install database cluster
clusterInfo := "ClusterDefinition: " + o.clusterDef
if o.clusterVersion != "" {
clusterInfo += ", ClusterVersion: " + o.clusterVersion
}
spinner := printer.Spinner(o.Out, "Create cluster %s (%s)", kbClusterName, clusterInfo)
defer spinner(false)
if err = o.createCluster(); err != nil {
return errors.Wrapf(err, "failed to create cluster %s", kbClusterName)
}
spinner(true)

// Print guide information
fmt.Fprintf(os.Stdout, "\nKubeBlocks playground init SUCCESSFULLY!\n\n")
if k8sClusterName != "" {
fmt.Fprintf(os.Stdout, "Kubernetes cluster \"%s\" has been created.\n", k8sClusterName)
}
fmt.Fprintf(os.Stdout, "Cluster \"%s\" has been created.\n", kbClusterName)

// output elapsed time
if !o.startTime.IsZero() {
fmt.Fprintf(o.Out, "Elapsed time: %s\n", time.Since(o.startTime).Truncate(time.Second))
}

printGuide()
return nil
}

func (o *initOptions) installKubeBlocks(k8sClusterName string) error {
f := util.NewFactory()
client, err := f.KubernetesClientSet()
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/cmd/playground/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var _ = Describe("playground", func() {
clusterVersion: clitesting.ClusterVersionName,
IOStreams: streams,
cloudProvider: defaultCloudProvider,
helmCfg: helm.NewConfig("", util.ConfigPath("config"), "", false),
helmCfg: helm.NewConfig("", util.ConfigPath("config_kb_test"), "", false),
}
Expect(o.validate()).Should(Succeed())
Expect(o.run()).Should(HaveOccurred())
Expand Down
4 changes: 4 additions & 0 deletions internal/cli/cmd/playground/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package playground

import (
"github.com/apecloud/kubeblocks/internal/cli/cloudprovider"
"github.com/apecloud/kubeblocks/internal/cli/util"
)

const (
Expand All @@ -41,6 +42,9 @@ const (
var (
// kbClusterName is the playground cluster name that created by KubeBlocks
kbClusterName = "mycluster"

// defaultKubeConfigPath is the default kubeconfig path, it is ~/.kube/config
defaultKubeConfigPath = util.ConfigPath("config")
)

var guideStr = `
Expand Down

0 comments on commit 912c31a

Please sign in to comment.