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

refactor: reimplement delete cmd for cluster delete #179

Merged
merged 2 commits into from
Nov 1, 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
4 changes: 1 addition & 3 deletions cmd/gtctl/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/spf13/cobra"

"github.com/GreptimeTeam/gtctl/pkg/cmd/gtctl/cluster/delete"
"github.com/GreptimeTeam/gtctl/pkg/logger"
)

Expand All @@ -38,9 +37,8 @@ func NewClusterCommand(l logger.Logger) *cobra.Command {
},
}

// TODO(sh2): will refactor them in the following PR.
cmd.AddCommand(NewCreateClusterCommand(l))
cmd.AddCommand(delete.NewDeleteClusterCommand(l))
cmd.AddCommand(NewDeleteClusterCommand(l))
cmd.AddCommand(NewScaleClusterCommand(l))
cmd.AddCommand(NewGetClusterCommand(l))
cmd.AddCommand(NewListClustersCommand(l))
Expand Down
81 changes: 6 additions & 75 deletions cmd/gtctl/cluster_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand All @@ -34,13 +33,6 @@ import (
"github.com/GreptimeTeam/gtctl/pkg/status"
)

const (
// Various of support config type
configOperator = "operator"
configCluster = "cluster"
configEtcd = "etcd"
)

type clusterCreateCliOptions struct {
// The options for deploying GreptimeDBCluster in K8s.
Namespace string
Expand Down Expand Up @@ -72,74 +64,13 @@ type clusterCreateCliOptions struct {
// Common options.
Timeout int
DryRun bool
Set configValues
Set config.SetValues

// If UseGreptimeCNArtifacts is true, the creation will download the artifacts(charts and binaries) from 'downloads.greptime.cn'.
// Also, it will use ACR registry for charts images.
UseGreptimeCNArtifacts bool
}

type configValues struct {
rawConfig []string

operatorConfig string
clusterConfig string
etcdConfig string
}

// parseConfig parse raw config values and classify it to different
// categories of config type by its prefix.
func (c *configValues) parseConfig() error {
var (
operatorConfig []string
clusterConfig []string
etcdConfig []string
)

for _, raw := range c.rawConfig {
if len(raw) == 0 {
return fmt.Errorf("cannot parse empty config values")
}

var configPrefix, configValue string
values := strings.Split(raw, ",")

for _, value := range values {
value = strings.Trim(value, " ")
cfg := strings.SplitN(value, ".", 2)
configPrefix = cfg[0]
if len(cfg) == 2 {
configValue = cfg[1]
} else {
configValue = configPrefix
}

switch configPrefix {
case configOperator:
operatorConfig = append(operatorConfig, configValue)
case configCluster:
clusterConfig = append(clusterConfig, configValue)
case configEtcd:
etcdConfig = append(etcdConfig, configValue)
default:
clusterConfig = append(clusterConfig, value)
}
}
}

if len(operatorConfig) > 0 {
c.operatorConfig = strings.Join(operatorConfig, ",")
}
if len(clusterConfig) > 0 {
c.clusterConfig = strings.Join(clusterConfig, ",")
}
if len(etcdConfig) > 0 {
c.etcdConfig = strings.Join(etcdConfig, ",")
}

return nil
}

func NewCreateClusterCommand(l logger.Logger) *cobra.Command {
var options clusterCreateCliOptions

Expand All @@ -159,7 +90,7 @@ func NewCreateClusterCommand(l logger.Logger) *cobra.Command {
cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "default", "Namespace of GreptimeDB cluster.")
cmd.Flags().BoolVar(&options.DryRun, "dry-run", false, "Output the manifests without applying them.")
cmd.Flags().IntVar(&options.Timeout, "timeout", 600, "Timeout in seconds for the command to complete, -1 means no timeout, default is 10 min.")
cmd.Flags().StringArrayVar(&options.Set.rawConfig, "set", []string{}, "set values on the command line for greptimedb cluster, etcd and operator (can specify multiple or separate values with commas: eg. cluster.key1=val1,etcd.key2=val2).")
cmd.Flags().StringArrayVar(&options.Set.RawConfig, "set", []string{}, "set values on the command line for greptimedb cluster, etcd and operator (can specify multiple or separate values with commas: eg. cluster.key1=val1,etcd.key2=val2).")
cmd.Flags().StringVar(&options.GreptimeDBChartVersion, "greptimedb-chart-version", "", "The greptimedb helm chart version, use latest version if not specified.")
cmd.Flags().StringVar(&options.GreptimeDBOperatorChartVersion, "greptimedb-operator-chart-version", "", "The greptimedb-operator helm chart version, use latest version if not specified.")
cmd.Flags().StringVar(&options.EtcdChartVersion, "etcd-chart-version", "", "The greptimedb-etcd helm chart version, use latest version if not specified.")
Expand Down Expand Up @@ -205,7 +136,7 @@ func NewCluster(args []string, options *clusterCreateCliOptions, l logger.Logger
}

// Parse config values that set in command line.
if err = options.Set.parseConfig(); err != nil {
if err = options.Set.Parse(); err != nil {
return err
}

Expand All @@ -218,14 +149,14 @@ func NewCluster(args []string, options *clusterCreateCliOptions, l logger.Logger
EtcdStorageClassName: options.EtcdStorageClassName,
EtcdStorageSize: options.EtcdStorageSize,
EtcdClusterSize: options.EtcdClusterSize,
ConfigValues: options.Set.etcdConfig,
ConfigValues: options.Set.EtcdConfig,
UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts,
ValuesFile: options.EtcdClusterValuesFile,
},
Operator: &opt.CreateOperatorOptions{
GreptimeDBOperatorChartVersion: options.GreptimeDBOperatorChartVersion,
ImageRegistry: options.ImageRegistry,
ConfigValues: options.Set.operatorConfig,
ConfigValues: options.Set.OperatorConfig,
UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts,
ValuesFile: options.GreptimeDBOperatorValuesFile,
},
Expand All @@ -237,7 +168,7 @@ func NewCluster(args []string, options *clusterCreateCliOptions, l logger.Logger
DatanodeStorageSize: options.StorageSize,
DatanodeStorageRetainPolicy: options.StorageRetainPolicy,
EtcdEndPoints: fmt.Sprintf("%s.%s:2379", kubernetes.EtcdClusterName(clusterName), options.EtcdNamespace),
ConfigValues: options.Set.clusterConfig,
ConfigValues: options.Set.ClusterConfig,
UseGreptimeCNArtifacts: options.UseGreptimeCNArtifacts,
ValuesFile: options.GreptimeDBClusterValuesFile,
},
Expand Down
78 changes: 78 additions & 0 deletions cmd/gtctl/cluster_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2023 Greptime Team
//
// 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 main

import (
"context"
"fmt"

"github.com/spf13/cobra"

opt "github.com/GreptimeTeam/gtctl/pkg/cluster"
"github.com/GreptimeTeam/gtctl/pkg/cluster/baremetal"
"github.com/GreptimeTeam/gtctl/pkg/cluster/kubernetes"
"github.com/GreptimeTeam/gtctl/pkg/logger"
)

type clusterDeleteOptions struct {
Namespace string
TearDownEtcd bool

// The options for deleting GreptimeDB cluster in bare-metal.
BareMetal bool
}

func NewDeleteClusterCommand(l logger.Logger) *cobra.Command {
var options clusterDeleteOptions

cmd := &cobra.Command{
Use: "delete",
Short: "Delete a GreptimeDB cluster",
Long: `Delete a GreptimeDB cluster`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("cluster name should be set")
}

clusterName := args[0]
var (
cluster opt.Operations
err error
ctx = context.TODO()
)

if options.BareMetal {
cluster, err = baremetal.NewCluster(l, clusterName, baremetal.WithCreateNoDirs())
} else {
cluster, err = kubernetes.NewCluster(l)
}
if err != nil {
return err
}

deleteOptions := &opt.DeleteOptions{
Namespace: options.Namespace,
Name: clusterName,
}
return cluster.Delete(ctx, deleteOptions)
},
}

cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "default", "Namespace of GreptimeDB cluster.")
cmd.Flags().BoolVar(&options.TearDownEtcd, "tear-down-etcd", false, "Tear down etcd cluster.")
cmd.Flags().BoolVar(&options.BareMetal, "bare-metal", false, "Get the greptimedb cluster on bare-metal environment.")

return cmd
}
4 changes: 2 additions & 2 deletions cmd/gtctl/cluster_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
type clusterGetCliOptions struct {
Namespace string

// The options for getting GreptimeDBCluster in bare-metal.
// The options for getting GreptimeDB cluster in bare-metal.
BareMetal bool
}

Expand All @@ -57,7 +57,7 @@ func NewGetClusterCommand(l logger.Logger) *cobra.Command {
)

if options.BareMetal {
cluster, err = baremetal.NewCluster(l, clusterName) // TODO(sh2): call baremetal.WithCreateNoDirs()
cluster, err = baremetal.NewCluster(l, clusterName, baremetal.WithCreateNoDirs())
} else {
cluster, err = kubernetes.NewCluster(l)
}
Expand Down
33 changes: 19 additions & 14 deletions pkg/cluster/baremetal/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,26 @@ type Option func(cluster *Cluster)

// WithReplaceConfig replaces current cluster config with given config.
func WithReplaceConfig(cfg *config.BareMetalClusterConfig) Option {
return func(d *Cluster) {
d.config = cfg
return func(c *Cluster) {
c.config = cfg
}
}

func WithGreptimeVersion(version string) Option {
return func(d *Cluster) {
d.config.Cluster.Artifact.Version = version
return func(c *Cluster) {
c.config.Cluster.Artifact.Version = version
}
}

func WithEnableCache(enableCache bool) Option {
return func(d *Cluster) {
d.enableCache = enableCache
return func(c *Cluster) {
c.enableCache = enableCache
}
}

func WithCreateNoDirs() Option {
return func(c *Cluster) {
c.createNoDirs = true
}
}

Expand Down Expand Up @@ -117,19 +123,18 @@ func NewCluster(l logger.Logger, clusterName string, opts ...Option) (cluster.Op
c.am = am

// Configure Cluster Components.
mm.AllocateClusterScopeDirs(clusterName)
if !c.createNoDirs {
mm.AllocateClusterScopeDirs(clusterName)
if err = mm.CreateClusterScopeDirs(c.config); err != nil {
return nil, err
}

csd := mm.GetClusterScopeDirs()
c.cc = NewClusterComponents(c.config.Cluster, components.WorkingDirs{
DataDir: csd.DataDir,
LogsDir: csd.LogsDir,
PidsDir: csd.PidsDir,
}, &c.wg, c.logger)
}
csd := mm.GetClusterScopeDirs()
c.cc = NewClusterComponents(c.config.Cluster, components.WorkingDirs{
DataDir: csd.DataDir,
LogsDir: csd.LogsDir,
PidsDir: csd.PidsDir,
}, &c.wg, c.logger)

return c, nil
}
68 changes: 68 additions & 0 deletions pkg/cluster/baremetal/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2023 Greptime Team
//
// 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 baremetal

import (
"context"
"fmt"
"os"
"syscall"

opt "github.com/GreptimeTeam/gtctl/pkg/cluster"
fileutils "github.com/GreptimeTeam/gtctl/pkg/utils/file"
)

func (c *Cluster) Delete(ctx context.Context, options *opt.DeleteOptions) error {
cluster, err := c.get(ctx, &opt.GetOptions{Name: options.Name})
if err != nil {
return err
}

running, ferr, serr := c.isClusterRunning(cluster.ForegroundPid)
if ferr != nil {
return fmt.Errorf("error checking whether cluster '%s' is running: %v", options.Name, ferr)
}
if running || serr == nil {
return fmt.Errorf("cluster '%s' is running, please stop it before deleting", options.Name)
}

csd := c.mm.GetClusterScopeDirs()
c.logger.V(0).Infof("Deleting cluster configurations and runtime directories in %s", csd.BaseDir)
if err = c.delete(ctx, csd.BaseDir); err != nil {
return err
}
c.logger.V(0).Info("Deleted!")

return nil
}

func (c *Cluster) delete(_ context.Context, baseDir string) error {
return fileutils.DeleteDirIfExists(baseDir)
}

// isClusterRunning checks the current status of cluster by sending signal to process.
func (c *Cluster) isClusterRunning(pid int) (runs bool, f error, s error) {
p, f := os.FindProcess(pid)
if f != nil {
return false, f, nil
}

s = p.Signal(syscall.Signal(0))
if s != nil {
return false, nil, s
}

return true, nil, nil
}
1 change: 0 additions & 1 deletion pkg/cluster/baremetal/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ func collectClusterInfoFromBareMetal(data *cfg.BareMetalClusterMetadata) (
rows(string(greptimedbclusterv1alpha1.DatanodeComponentKind), data.Config.Cluster.Datanode.Replicas)
rows(string(greptimedbclusterv1alpha1.MetaComponentKind), data.Config.Cluster.MetaSrv.Replicas)

// TODO(sh2): make "etcd" a const?
bulk = append(bulk, []string{"etcd", pidsMap["etcd"]})

config, err := yaml.Marshal(data.Config)
Expand Down
Loading
Loading