Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support uninstall cmd to destroy opengemini cluster #33

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion cmd/cluster/install2.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ func installCmd2() *cobra.Command {
return err
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
fmt.Println("install validate func args", args)
switch len(args) {
case 2:
return nil, cobra.ShellCompDirectiveDefault
Expand Down Expand Up @@ -155,3 +154,19 @@ func GetEnv(envVar string) (bool, string) {
return true, value
}
}

func ReadClusterOptionsByName(cmd *cobra.Command) (utils.ClusterOptions, error) {
var ops utils.ClusterOptions
var err error
if name, _ := cmd.Flags().GetString("name"); name == "" {
return ops, fmt.Errorf("the cluster name is required")
} else if !utils.CheckClusterNameExist(name) {
return ops, fmt.Errorf("the cluster name is not existed, please install the cluster first")
} else {
ops, err = utils.LoadClusterOptionsFromFile(filepath.Join(utils.ClusterInfoDir, name))
if err != nil {
return ops, err
}
}
return ops, err
}
66 changes: 45 additions & 21 deletions cmd/cluster/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,43 @@
package cluster

import (
"fmt"
"path/filepath"
"os"
"strings"

"github.com/fatih/color"
"github.com/openGemini/gemix/pkg/cluster/manager"
operator "github.com/openGemini/gemix/pkg/cluster/operation"
"github.com/openGemini/gemix/pkg/cluster/spec"
"github.com/openGemini/gemix/utils"
"github.com/openGemini/gemix/pkg/gui"
"github.com/openGemini/gemix/pkg/logger"
logprinter "github.com/openGemini/gemix/pkg/logger/printer"
"github.com/spf13/cobra"
"go.uber.org/zap"
)

var (
RootCmd *cobra.Command // represents the cluster command
ClusterCmd *cobra.Command // represents the cluster command
gOpt operator.Options
teleTopology string //lint:ignore U1000 keep this
skipConfirm bool
log = zap.NewNop() // init default logger
log = logprinter.NewLogger("") // init default logger
)

var openGeminiSpec *spec.SpecManager
var cm *manager.Manager

func init() {
RootCmd = &cobra.Command{
logger.InitGlobalLogger()

ClusterCmd = &cobra.Command{
Use: "cluster",
Short: "Deploy an openGemini cluster for production",
Long: `Deploy an openGemini cluster for production`,
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
log.SetDisplayModeFromString(gOpt.DisplayMode)

if err := spec.Initialize("cluster"); err != nil {
return err
}
Expand All @@ -54,7 +61,7 @@ func init() {
},
}

RootCmd.AddCommand(
ClusterCmd.AddCommand(
templateCmd(),
installCmd(),
installCmd2(),
Expand All @@ -63,25 +70,42 @@ func init() {
stopCmd(),
stopCmd2,
uninstallCmd,
newUninstallCmd(),
statusCmd,
upgradeCmd,
)

//RootCmd.PersistentFlags().BoolVarP(&skipConfirm, "yes", "y", false, "Skip all confirmations and assumes 'yes'")
//ClusterCmd.PersistentFlags().BoolVarP(&skipConfirm, "yes", "y", false, "Skip all confirmations and assumes 'yes'")
}

func ReadClusterOptionsByName(cmd *cobra.Command) (utils.ClusterOptions, error) {
var ops utils.ClusterOptions
var err error
if name, _ := cmd.Flags().GetString("name"); name == "" {
return ops, fmt.Errorf("the cluster name is required")
} else if !utils.CheckClusterNameExist(name) {
return ops, fmt.Errorf("the cluster name is not existed, please install the cluster first")
} else {
ops, err = utils.LoadClusterOptionsFromFile(filepath.Join(utils.ClusterInfoDir, name))
if err != nil {
return ops, err
}
// Execute executes the root command
func Execute() {
zap.L().Info("Execute command", zap.String("command", strings.Join(os.Args, " ")))
zap.L().Debug("Environment variables", zap.Strings("env", os.Environ()))

code := 0
err := ClusterCmd.Execute()
if err != nil {
code = 1
}

zap.L().Info("Execute command finished", zap.Int("code", code), zap.Error(err))

if err != nil {
gui.ColorErrorMsg.Fprintf(os.Stderr, "\nError: %s", err.Error())
}

logger.OutputDebugLog("gemix-cluster")

err = logger.OutputAuditLogIfEnabled()
if err != nil {
zap.L().Warn("Write audit log file failed", zap.Error(err))
code = 1
}

color.Unset()

if code != 0 {
os.Exit(code)
}
return ops, err
}
88 changes: 49 additions & 39 deletions cmd/cluster/uninstall.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 Huawei Cloud Computing Technologies Co., Ltd.
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -8,55 +8,65 @@
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cluster

import (
"fmt"

"github.com/openGemini/gemix/pkg/cluster/manager"
"github.com/openGemini/gemix/utils"
operator "github.com/openGemini/gemix/pkg/cluster/operation"
"github.com/openGemini/gemix/pkg/cluster/spec"
"github.com/openGemini/gemix/pkg/set"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

// uninstallCmd represents the uninstall command
var uninstallCmd = &cobra.Command{
Use: "uninstall",
Short: "uninstall cluster",
Long: `uninstall an openGemini cluster based on configuration files.`,
Run: func(cmd *cobra.Command, args []string) {
var ops utils.ClusterOptions
var err error
if ops, err = ReadClusterOptionsByName(cmd); err != nil {
fmt.Println(err)
fmt.Println(cmd.UsageString())
return
}

err = UninstallCluster(ops)
if err != nil {
fmt.Println(err)
}
},
}
func newUninstallCmd() *cobra.Command {
destroyOpt := operator.Options{}
cmd := &cobra.Command{
Use: "uninstall <cluster-name>",
Short: "Uninstall a specified cluster",
Long: `Uninstall a specified cluster, which will clean the deployment binaries and data.
`,
//You can retain some nodes and roles data when destroy cluster, see Example:
// Example: `
//$ gemix cluster uninstall <cluster-name> --retain-role-data grafana
//$ gemix cluster uninstall <cluster-name> --retain-node-data 172.16.13.11:3000
//$ gemix cluster uninstall <cluster-name> --retain-node-data 172.16.13.12
// `,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return cmd.Help()
}

func UninstallCluster(ops utils.ClusterOptions) error {
uninstaller := manager.NewGeminiUninstaller(ops)
defer uninstaller.Close()
clusterName := args[0]

if err := uninstaller.Prepare(); err != nil {
return err
}
if err := uninstaller.Run(); err != nil {
return err
// Validate the retained roles to prevent unexpected deleting data
if len(destroyOpt.RetainDataRoles) > 0 {
roles := set.NewStringSet(spec.AllComponentNames()...)
for _, role := range destroyOpt.RetainDataRoles {
if !roles.Exist(role) {
return errors.Errorf("role name `%s` invalid", role)
}
}
}

return cm.UninstallCluster(clusterName, gOpt, destroyOpt, skipConfirm)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
switch len(args) {
case 0:
return shellCompGetClusterName(cm, toComplete)
default:
return nil, cobra.ShellCompDirectiveNoFileComp
}
},
}
fmt.Printf("Successfully uninstalled the openGemini cluster with version : %s\n", ops.Version)
return nil
}

func init() {
uninstallCmd.Flags().StringP("name", "n", "", "cluster name")
//cmd.Flags().StringArrayVar(&destroyOpt.RetainDataNodes, "retain-node-data", nil, "Specify the nodes or hosts whose data will be retained")
//cmd.Flags().StringArrayVar(&destroyOpt.RetainDataRoles, "retain-role-data", nil, "Specify the roles whose data will be retained")
cmd.Flags().BoolVar(&destroyOpt.Force, "force", false, "Force will ignore remote error while destroy the cluster")

return cmd
}
62 changes: 62 additions & 0 deletions cmd/cluster/uninstall2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2023 Huawei Cloud Computing Technologies Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cluster

import (
"fmt"

"github.com/openGemini/gemix/pkg/cluster/manager"
"github.com/openGemini/gemix/utils"
"github.com/spf13/cobra"
)

// uninstallCmd represents the uninstall command
var uninstallCmd = &cobra.Command{
Use: "uninstall2",
Short: "uninstall cluster",
Long: `uninstall an openGemini cluster based on configuration files.`,
Run: func(cmd *cobra.Command, args []string) {
var ops utils.ClusterOptions
var err error
if ops, err = ReadClusterOptionsByName(cmd); err != nil {
fmt.Println(err)
fmt.Println(cmd.UsageString())
return
}

err = UninstallCluster(ops)
if err != nil {
fmt.Println(err)
}
},
}

func UninstallCluster(ops utils.ClusterOptions) error {
uninstaller := manager.NewGeminiUninstaller(ops)
defer uninstaller.Close()

if err := uninstaller.Prepare(); err != nil {
return err
}
if err := uninstaller.Run(); err != nil {
return err
}
fmt.Printf("Successfully uninstalled the openGemini cluster with version : %s\n", ops.Version)
return nil
}

func init() {
uninstallCmd.Flags().StringP("name", "n", "", "cluster name")
}
8 changes: 2 additions & 6 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package cmd

import (
"os"
"time"

"github.com/openGemini/gemix/cmd/cluster"
Expand All @@ -34,11 +33,8 @@ var RootCmd = &cobra.Command{
}

func Execute() {
RootCmd.AddCommand(cluster.RootCmd)
err := RootCmd.Execute()
if err != nil {
os.Exit(1)
}
RootCmd.AddCommand(cluster.ClusterCmd)
cluster.Execute()
}

var (
Expand Down
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ coverage:
status:
project:
default:
target: 70%
target: 10%
if_ci_failed: success
patch:
default:
Expand Down
8 changes: 4 additions & 4 deletions embed/examples/cluster/local.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ global:
{{- end }}

{{ if .TSMetaServers -}}
ts-meta-servers:
ts_meta_servers:
{{- range .TSMetaServers }}
- host: {{ . }}
{{- end }}
{{ end }}
{{ if .TSSqlServers -}}
ts-sql-servers:
ts_sql_servers:
{{- range .TSSqlServers }}
- host: {{ . }}
{{- end }}
{{ end }}
{{ if .TSStoreServers -}}
ts-store-servers:
ts_store_servers:
{{- range .TSStoreServers }}
- host: {{ . }}
{{- end }}
{{ end }}
{{ if .GrafanaServers -}}
grafana-servers:
grafana_servers:
{{- range .GrafanaServers }}
- host: {{ . }}
{{- end }}
Expand Down
Loading
Loading