Skip to content

Commit

Permalink
refactor: create the etcd cluster (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
daviderli614 committed Dec 7, 2022
1 parent 79d140d commit dfd8f67
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Flags:
Use "gtctl [command] --help" for more information about a command.
```

Create your own GreptimeDB cluster:
Create your own GreptimeDB cluster and etcd cluster:

```console
gtctl cluster create mydb -n default
Expand Down
45 changes: 37 additions & 8 deletions cmd/app/cluster/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,19 @@ import (
)

type createClusterCliOptions struct {
Namespace string
OperatorNamespace string
StorageClassName string
StorageSize string
StorageRetainPolicy string
GreptimeDBVersion string
OperatorVersion string
Registry string
Namespace string
OperatorNamespace string
EtcdNamespace string
StorageClassName string
StorageSize string
StorageRetainPolicy string
GreptimeDBVersion string
OperatorVersion string
Registry string
EtcdEndpoint string
EtcdChartsVersion string
EtcdStorageClassName string
EtcdStorageSize string

DryRun bool
Timeout int
Expand Down Expand Up @@ -66,6 +71,7 @@ func NewCreateClusterCommand(l log.Logger) *cobra.Command {

var (
clusterName = args[0]
etcdSvcName = fmt.Sprintf("%s-etcd-svc", args[0])

// TODO(zyy17): should use timeout context.
ctx = context.TODO()
Expand All @@ -80,6 +86,24 @@ func NewCreateClusterCommand(l log.Logger) *cobra.Command {
}
l.Infof("🎉 Finish to create greptimedb-operator.\n")

l.Infof("☕️ Start to create etcd cluster...\n")
createEtcdOptions := &manager.CreateEtcdOptions{
Name: args[0] + "-etcd",
Namespace: options.EtcdNamespace,
Timeout: time.Duration(options.Timeout) * time.Second,
DryRun: options.DryRun,
Registry: options.Registry,
EtcdChartsVersion: options.EtcdChartsVersion,
EtcdStorageClassName: options.EtcdStorageClassName,
EtcdStorageSize: options.EtcdStorageSize,
}
if err := log.StartSpinning("Creating etcd cluster...", func() error {
return m.CreateEtcdCluster(ctx, createEtcdOptions)
}); err != nil {
return err
}
l.Infof("🎉 Finish to create etcd cluster.\n")

l.Infof("☕️ Start to create GreptimeDB cluster...\n")
createClusterOptions := &manager.CreateClusterOptions{
ClusterName: args[0],
Expand All @@ -91,6 +115,7 @@ func NewCreateClusterCommand(l log.Logger) *cobra.Command {
DryRun: options.DryRun,
GreptimeDBVersion: options.GreptimeDBVersion,
Registry: options.Registry,
EtcdEndPoint: fmt.Sprintf("%s.%s:2379", etcdSvcName, options.EtcdNamespace),
}

if err := log.StartSpinning("Creating GreptimeDB cluster", func() error {
Expand Down Expand Up @@ -119,6 +144,10 @@ func NewCreateClusterCommand(l log.Logger) *cobra.Command {
cmd.Flags().StringVar(&options.GreptimeDBVersion, "version", manager.DefaultGreptimeDBChartVersion, "The GreptimeDB version.")
cmd.Flags().StringVar(&options.OperatorVersion, "operator-version", manager.DefaultGreptimeDBOperatorChartVersion, "The greptimedb-operator version.")
cmd.Flags().StringVar(&options.Registry, "registry", "", "The image registry")
cmd.Flags().StringVar(&options.EtcdChartsVersion, "etcd-chart-version", manager.DefaultEtcdChartVersion, "The greptimedb-etcd helm chart version")
cmd.Flags().StringVar(&options.EtcdNamespace, "etcd-namespace", "default", "The namespace of etcd cluster.")
cmd.Flags().StringVar(&options.EtcdStorageClassName, "etcd-storage-class-name", "standard", "The etcd storage class name.")
cmd.Flags().StringVar(&options.EtcdStorageSize, "etcd-storage-size", "10Gi", "the etcd persistent volume size.")

return cmd
}
28 changes: 28 additions & 0 deletions pkg/kube/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@ func (c *Client) WaitForClusterReady(name, namespace string, timeout time.Durati
}
}

func (c *Client) WaitForEtcdReady(name, namespace string, timeout time.Duration) error {
conditionFunc := func() (bool, error) {
return c.IsStatefulSetReady(context.TODO(), name, namespace)
}

if int(timeout) < 0 {
return wait.PollInfinite(time.Second, conditionFunc)
} else {
return wait.PollImmediate(time.Second, timeout, conditionFunc)
}
}

func (c *Client) isDeploymentReady(ctx context.Context, name, namespace string) (bool, error) {
deployment, err := c.kubeClient.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
Expand Down Expand Up @@ -275,6 +287,22 @@ func (c *Client) isClusterReady(ctx context.Context, name, namespace string) (bo
return false, nil
}

func (c *Client) IsStatefulSetReady(ctx context.Context, name, namespace string) (bool, error) {
statefulSet, err := c.kubeClient.AppsV1().StatefulSets(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return false, err
}
if statefulSet == nil {
return false, nil
}

if statefulSet.Status.ReadyReplicas == *statefulSet.Spec.Replicas {
return true, nil
}

return false, nil
}

// FIXME(zyy17): Generate clientset for Greptime CRDs.

func (c *Client) getCluster(ctx context.Context, name, namespace string) (*greptimev1alpha1.GreptimeDBCluster, error) {
Expand Down
1 change: 1 addition & 0 deletions pkg/manager/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ const (
defaultOperatorReleaseName = "greptimedb-operator"
defaultOperatorHelmPackageName = "greptimedb-operator"
defaultGreptimeDBHelmPackageName = "greptimedb"
defaultEtcdHelmPackageName = "greptimedb-etcd"
)
84 changes: 82 additions & 2 deletions pkg/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ import (

const (
defaultChartsURL = "https://github.com/GreptimeTeam/helm-charts/releases/download"
DefaultGreptimeDBChartVersion = "0.1.0-alpha-20221116"
DefaultGreptimeDBOperatorChartVersion = "0.1.0-alpha.5"
DefaultGreptimeDBChartVersion = "0.1.1-alpha.2"
DefaultGreptimeDBOperatorChartVersion = "0.1.1-alpha.2"
DefaultEtcdChartVersion = "0.1.1-alpha.1"
)

// Manager manage the cluster resources.
Expand All @@ -42,6 +43,7 @@ type Manager interface {
UpdateCluster(ctx context.Context, options *UpdateClusterOptions) error
DeleteCluster(ctx context.Context, options *DeleteClusterOption) error
CreateOperator(ctx context.Context, options *CreateOperatorOptions) error
CreateEtcdCluster(ctx context.Context, options *CreateEtcdOptions) error
}

type GetClusterOptions struct {
Expand All @@ -59,6 +61,19 @@ type CreateClusterOptions struct {
StorageRetainPolicy string
GreptimeDBVersion string
Registry string
EtcdEndPoint string

Timeout time.Duration
DryRun bool
}

type CreateEtcdOptions struct {
Name string
Namespace string
Registry string
EtcdChartsVersion string
EtcdStorageClassName string
EtcdStorageSize string

Timeout time.Duration
DryRun bool
Expand Down Expand Up @@ -220,6 +235,42 @@ func (m *manager) CreateOperator(ctx context.Context, options *CreateOperatorOpt
return nil
}

func (m *manager) CreateEtcdCluster(ctx context.Context, options *CreateEtcdOptions) error {
values, err := m.generateEtcdValues(options)
if err != nil {
return err
}

// The download URL example: https://github.com/GreptimeTeam/helm-charts/releases/download/greptimedb-etcd-0.1.0/greptimedb-etcd-0.1.0.tgz
chartName := defaultEtcdHelmPackageName + "-" + options.EtcdChartsVersion
downloadURL := fmt.Sprintf("%s/%s/%s.tgz", defaultChartsURL, chartName, chartName)

chart, err := m.render.LoadChartFromRemoteCharts(downloadURL)
if err != nil {
return err
}

manifests, err := m.render.GenerateManifests(options.Name, options.Namespace, chart, values)
if err != nil {
return err
}

if options.DryRun {
m.l.Infof(string(manifests))
return nil
}

if err := m.client.Apply(manifests); err != nil {
return err
}

if err := m.client.WaitForEtcdReady(options.Name, options.Namespace, options.Timeout); err != nil {
return err
}

return nil
}

func (m *manager) generateClusterValues(options *CreateClusterOptions) (map[string]interface{}, error) {
var rawArgs []string

Expand All @@ -240,6 +291,10 @@ func (m *manager) generateClusterValues(options *CreateClusterOptions) (map[stri
rawArgs = append(rawArgs, fmt.Sprintf("datanode.storage.storageRetainPolicy=%s", options.StorageRetainPolicy))
}

if len(options.EtcdEndPoint) > 0 {
rawArgs = append(rawArgs, fmt.Sprintf("etcdEndpoints=%s", options.EtcdEndPoint))
}

if len(rawArgs) > 0 {
values, err := m.generateHelmValues(strings.Join(rawArgs, ","))
if err != nil {
Expand Down Expand Up @@ -271,3 +326,28 @@ func (m *manager) generateHelmValues(args string) (map[string]interface{}, error
}
return values, nil
}

func (m *manager) generateEtcdValues(options *CreateEtcdOptions) (map[string]interface{}, error) {
var rawArgs []string
if len(options.Registry) > 0 {
rawArgs = append(rawArgs, fmt.Sprintf("image.registry=%s", options.Registry))
}

if len(options.EtcdStorageClassName) > 0 {
rawArgs = append(rawArgs, fmt.Sprintf("storage.storageClassName=%s", options.EtcdStorageClassName))
}

if len(options.EtcdStorageSize) > 0 {
rawArgs = append(rawArgs, fmt.Sprintf("storage.volumeSize=%s", options.EtcdStorageSize))
}

if len(rawArgs) > 0 {
values, err := m.generateHelmValues(strings.Join(rawArgs, ","))
if err != nil {
return nil, err
}
return values, nil
}

return nil, nil
}

0 comments on commit dfd8f67

Please sign in to comment.