Skip to content

Commit

Permalink
feat
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyelei committed Nov 12, 2024
1 parent a53757d commit c365b11
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 109 deletions.
4 changes: 2 additions & 2 deletions pkg/cmd/backuprepo/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ func (o *createOptions) validate(cmd *cobra.Command) error {
func (o *createOptions) createCredentialSecret() (*corev1.Secret, error) {
// if failed to get the namespace of KubeBlocks,
// then create the secret in the current namespace
namespace, err := util.GetKubeBlocksNamespace(o.client)
if err != nil {
namespace, err := util.GetKubeBlocksNamespace(o.client, "")

Check failure on line 349 in pkg/cmd/backuprepo/create.go

View workflow job for this annotation

GitHub Actions / make-test

ineffectual assignment to err (ineffassign)
if namespace == "" {
namespace, _, err = o.factory.ToRawKubeConfigLoader().Namespace()
if err != nil {
return nil, err
Expand Down
33 changes: 31 additions & 2 deletions pkg/cmd/kubeblocks/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package kubeblocks

import (
"context"
"fmt"
"strings"
"time"

Expand All @@ -32,6 +33,7 @@ import (
"k8s.io/kubectl/pkg/util/templates"

"github.com/apecloud/kbcli/pkg/printer"
"github.com/apecloud/kbcli/pkg/spinner"
"github.com/apecloud/kbcli/pkg/types"
"github.com/apecloud/kbcli/pkg/util"
"github.com/apecloud/kbcli/pkg/util/helm"
Expand Down Expand Up @@ -83,14 +85,40 @@ func NewConfigCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(o.Complete(f, cmd))
util.CheckErr(o.Upgrade())
util.CheckErr(configKBRelease(o))
util.CheckErr(markKubeBlocksPodsToLoadConfigMap(o.Client))
},
}
helm.AddValueOptionsFlags(cmd.Flags(), &o.ValueOpts)
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", "", "KubeBlocks namespace")
return cmd
}

func configKBRelease(o *InstallOptions) error {
kbRelease, err := o.getKBRelease()
if err != nil {
return err
}
if helm.ValueOptsIsEmpty(&o.ValueOpts) {
fmt.Fprint(o.Out, "--set should be specified.\n")
return nil
}
var kbVersion string
if kbRelease != nil && kbRelease.Chart != nil && kbRelease.Chart.Metadata != nil {
kbVersion = kbRelease.Chart.Metadata.Version
}
s := spinner.New(o.Out, spinnerMsg("Config KubeBlocks "+kbVersion))
defer s.Fail()
o.disableHelmPreHookJob()
// upgrade KubeBlocks chart
if err = o.upgradeChart(); err != nil {
return err
}
// successfully upgraded
s.Success()
return nil
}

func NewDescribeConfigCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
o := &InstallOptions{
Options: Options{
Expand All @@ -109,6 +137,7 @@ func NewDescribeConfigCmd(f cmdutil.Factory, streams genericiooptions.IOStreams)
},
}
printer.AddOutputFlag(cmd, &output)
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", "", "KubeBlocks namespace")
cmd.Flags().BoolVarP(&showAllConfig, "all", "A", false, "show all kubeblocks configs value")
cmd.Flags().StringVar(&filterConfig, "filter", "", "filter the desired kubeblocks configs, multiple filtered strings are comma separated")
return cmd
Expand All @@ -117,7 +146,7 @@ func NewDescribeConfigCmd(f cmdutil.Factory, streams genericiooptions.IOStreams)
// getHelmValues gets all kubeblocks values by helm and filter the addons values
func getHelmValues(release string, opt *Options) (map[string]interface{}, error) {
if len(opt.HelmCfg.Namespace()) == 0 {
namespace, err := util.GetKubeBlocksNamespace(opt.Client)
namespace, err := util.GetKubeBlocksNamespace(opt.Client, opt.Namespace)
if err != nil {
return nil, err
}
Expand Down
57 changes: 33 additions & 24 deletions pkg/cmd/kubeblocks/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/pkg/preflight"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"golang.org/x/exp/maps"
"helm.sh/helm/v3/pkg/cli/values"
Expand All @@ -54,6 +53,7 @@ import (
"github.com/apecloud/kbcli/pkg/types"
"github.com/apecloud/kbcli/pkg/util"
"github.com/apecloud/kbcli/pkg/util/helm"
"github.com/apecloud/kbcli/pkg/util/prompt"
"github.com/apecloud/kbcli/version"
)

Expand Down Expand Up @@ -155,6 +155,7 @@ func newInstallCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra
}

cmd.Flags().StringVar(&o.Version, "version", version.DefaultKubeBlocksVersion, "KubeBlocks version")
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", types.DefaultNamespace, "KubeBlocks namespace")
cmd.Flags().BoolVar(&o.CreateNamespace, "create-namespace", false, "Create the namespace if not present")
cmd.Flags().BoolVar(&o.Check, "check", true, "Check kubernetes environment before installation")
cmd.Flags().DurationVar(&o.Timeout, "timeout", 1800*time.Second, "Time to wait for installing KubeBlocks, such as --timeout=10m")
Expand All @@ -178,10 +179,6 @@ func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
fmt.Fprintf(o.Out, "Failed to enable the log file %s", err.Error())
}

if o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
return err
}

config, err := cmd.Flags().GetString("kubeconfig")
if err != nil {
return err
Expand All @@ -192,16 +189,7 @@ func (o *Options) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
return err
}

// check whether --namespace is specified, if not, KubeBlocks will be installed
// to the kb-system namespace
var targetNamespace string
cmd.Flags().Visit(func(flag *pflag.Flag) {
if flag.Name == "namespace" {
targetNamespace = o.Namespace
}
})

o.HelmCfg = helm.NewConfig(targetNamespace, config, ctx, klog.V(1).Enabled())
o.HelmCfg = helm.NewConfig(o.Namespace, config, ctx, klog.V(1).Enabled())
if o.Dynamic, err = f.DynamicClient(); err != nil {
return err
}
Expand All @@ -224,8 +212,24 @@ func (o *InstallOptions) PreCheckKBVersion() error {
if err != nil {
return err
}
o.checkUpgradeFrom09(v.KubeBlocks)
if !o.upgradeFrom09 {
o.upgradeFrom09 = o.checkUpgradeFrom09(v.KubeBlocks)
if o.upgradeFrom09 {
if o.upgradeFrom09 {
deploys, err := util.GetKubeBlocksDeploys(o.Client)
if err != nil {
return err
}
for _, deploy := range deploys {
if deploy.Namespace == o.HelmCfg.Namespace() {
return fmt.Errorf(`cannot install KubeBlocks in the same namespace "%s" with KubeBlocks 0.9`, o.HelmCfg.Namespace())
}
}
}
installWarn := fmt.Sprintf("You will Install KubeBlocks %s When existing KubeBlocks %s ", o.Version, v.KubeBlocks)
if err = prompt.Confirm(nil, o.In, installWarn, "Please type 'Yes/yes' to confirm your operation:"); err != nil {
return err
}
} else {
// check if KubeBlocks has been installed
if v.KubeBlocks != "" {
return fmt.Errorf("KubeBlocks %s already exists, repeated installation is not supported", v.KubeBlocks)
Expand Down Expand Up @@ -280,14 +284,14 @@ func (o *InstallOptions) CompleteInstallOptions() error {

func (o *InstallOptions) Install() error {
var err error
// create or update crds
s := spinner.New(o.Out, spinnerMsg("Create CRDs"))
defer s.Fail()
if o.upgradeFrom09 {
if err = o.preInstallWhenUpgradeFrom09(); err != nil {
return err
}
}
// create or update crds
s := spinner.New(o.Out, spinnerMsg("Create CRDs"))
defer s.Fail()
if err = createOrUpdateCRDS(o.Dynamic, o.Version); err != nil {
return fmt.Errorf("install crds failed: %s", err.Error())
}
Expand Down Expand Up @@ -380,6 +384,12 @@ You can check the KubeBlocks status by running "kbcli kubeblocks status"
fmt.Fprint(o.Out, msg)
o.printNotes()
}
if o.upgradeFrom09 {
fmt.Fprint(o.Out, "Start KubeBlocks 0.9")
if err = o.configKB09(); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -522,11 +532,10 @@ func (o *InstallOptions) checkVersion(v util.Version) error {
func (o *InstallOptions) checkNamespace() error {
// target namespace is not specified, use default namespace
if o.HelmCfg.Namespace() == "" {
o.HelmCfg.SetNamespace(types.DefaultNamespace)
o.HelmCfg.SetNamespace(o.Namespace)
o.CreateNamespace = true
fmt.Fprintf(o.Out, "KubeBlocks will be installed to namespace \"%s\"\n", o.HelmCfg.Namespace())
}

fmt.Fprintf(o.Out, "KubeBlocks will be installed to namespace \"%s\"\n", o.HelmCfg.Namespace())
// check if namespace exists
if !o.CreateNamespace {
_, err := o.Client.CoreV1().Namespaces().Get(context.TODO(), o.Namespace, metav1.GetOptions{})
Expand All @@ -540,7 +549,7 @@ func (o *InstallOptions) checkRemainedResource() error {
return nil
}

ns, _ := util.GetKubeBlocksNamespace(o.Client)
ns, _ := util.GetKubeBlocksNamespace(o.Client, o.Namespace)
if ns == "" {
ns = o.Namespace
}
Expand Down
52 changes: 43 additions & 9 deletions pkg/cmd/kubeblocks/install_1.0.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/apecloud/kubeblocks/pkg/constant"
"golang.org/x/mod/semver"
"helm.sh/helm/v3/pkg/cli/values"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -41,8 +42,9 @@ import (
)

const (
KBVersion092 = "v0.9.2"
KBVersion100 = "v1.0.0"
// TODO: tidy up the versions when 0.9.2 released
KBVersion092 = "v0.9.2-beta.16"
KBVersion100 = "v1.0.0-beta.1"
)

func (o *InstallOptions) checkUpgradeFrom09(kbVersions string) bool {
Expand Down Expand Up @@ -71,6 +73,8 @@ func (o *InstallOptions) checkUpgradeFrom09(kbVersions string) bool {
}

func (o *InstallOptions) preInstallWhenUpgradeFrom09() error {
// enable webhooks.conversionEnabled
o.ValueOpts.Values = append(o.ValueOpts.Values, "webhooks.conversionEnabled=true")
stopDeployments := func(getDeploys func(client kubernetes.Interface) ([]appsv1.Deployment, error), msgKey string) error {
kbDeploys, err := getDeploys(o.Client)
if err != nil {
Expand All @@ -86,18 +90,43 @@ func (o *InstallOptions) preInstallWhenUpgradeFrom09() error {
}
return nil
}
// 1. stop 0.9 KubeBlocks

// 1. update 092 chart values
if err := o.configKB09(); err != nil {
return err
}
// 2. stop 0.9 KubeBlocks
if err := stopDeployments(util.GetKubeBlocksDeploys, "KubeBlocks"); err != nil {
return err
}
// 2. stop 0.9 DataProtection
// 3. stop 0.9 DataProtection
if err := stopDeployments(util.GetDataProtectionDeploys, "DataProtection"); err != nil {
return err
}
// 3. Set global resources helm owner to 1.0 KB
// 4. Set global resources helm owner to 1.0 KB
return o.setGlobalResourcesHelmOwner()
}

func (o *InstallOptions) configKB09() error {
helmConfig := *o.HelmCfg
helmConfig.SetNamespace("")
configOpt := &InstallOptions{
Options: Options{
IOStreams: o.IOStreams,
Wait: true,
Dynamic: o.Dynamic,
Client: o.Client,
HelmCfg: &helmConfig,
},
ValueOpts: values.Options{
Values: []string{
"dualOperatorsMode=true",
},
},
}
return configKBRelease(configOpt)
}

func (o *InstallOptions) stopDeployment(s spinner.Interface, deploy *appsv1.Deployment) error {
defer s.Fail()
ctx := context.TODO()
Expand All @@ -111,12 +140,12 @@ func (o *InstallOptions) stopDeployment(s spinner.Interface, deploy *appsv1.Depl
metav1.PatchOptions{},
)
if err != nil {
return fmt.Errorf("failed to stop deployment %s/%s: %v",
return fmt.Errorf("failed to patch deployment %s/%s: %v",
deploy.Namespace, deploy.Name, err)
}
}
// wait for deployment to be stopped
return wait.PollUntilContextTimeout(context.Background(), 5*time.Second, 1*time.Minute, true,
if err := wait.PollUntilContextTimeout(context.Background(), 5*time.Second, 1*time.Minute, true,
func(_ context.Context) (bool, error) {
deployment, err := o.Client.AppsV1().Deployments(deploy.Namespace).Get(ctx, deploy.Name, metav1.GetOptions{})
if err != nil {
Expand All @@ -126,15 +155,18 @@ func (o *InstallOptions) stopDeployment(s spinner.Interface, deploy *appsv1.Depl
return true, nil
}
return false, err
})
}); err != nil {
return err
}
s.Success()
return nil
}

func (o *InstallOptions) setGlobalResourcesHelmOwner() error {
fmt.Fprintf(o.Out, "Change the release owner for the global resources\n")
setHelmOwner := func(gvr schema.GroupVersionResource, names []string) error {
patchOP := fmt.Sprintf(`[{"op": "replace", "path": "/metadata/annotations/meta.helm.sh~1release-name", "value": "%s"}`+
`,{"op": "replace", "path": "/metadata/annotations/meta.helm.sh~1release-namespace", "value": "%s"}]`, types.KubeBlocksChartName, o.Namespace)
`,{"op": "replace", "path": "/metadata/annotations/meta.helm.sh~1release-namespace", "value": "%s"}]`, types.KubeBlocksChartName, o.HelmCfg.Namespace())
for _, name := range names {
if _, err := o.Dynamic.Resource(gvr).Namespace("").Patch(context.TODO(), name,
k8stypes.JSONPatchType, []byte(patchOP), metav1.PatchOptions{}); client.IgnoreNotFound(err) != nil {
Expand Down Expand Up @@ -189,3 +221,5 @@ func (o *InstallOptions) setGlobalResourcesHelmOwner() error {
// update BackupRepo
return setHelmOwner(types.BackupRepoGVR(), []string{fmt.Sprintf("%s-backuprepo", types.KubeBlocksChartName)})
}

// TODO: uninstall KB
2 changes: 1 addition & 1 deletion pkg/cmd/kubeblocks/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (o *statusOptions) complete(f cmdutil.Factory) error {
return err
}

o.ns, _ = util.GetKubeBlocksNamespace(o.client)
o.ns, _ = util.GetKubeBlocksNamespace(o.client, "")
if o.ns == "" {
printer.Warning(o.Out, "Failed to find deployed KubeBlocks in any namespace\n")
printer.Warning(o.Out, "Will check all namespaces for KubeBlocks resources left behind\n")
Expand Down
Loading

0 comments on commit c365b11

Please sign in to comment.