Skip to content

Commit

Permalink
feat: add cluster status monitoring and improve error handling
Browse files Browse the repository at this point in the history
Signed-off-by: Benevor <2647311844@qq.com>
  • Loading branch information
Benevor committed Oct 11, 2023
1 parent b5f6fde commit 4344a91
Show file tree
Hide file tree
Showing 52 changed files with 2,576 additions and 1,560 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022 Huawei Cloud Computing Technologies Co., Ltd.
# 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.
Expand Down
2 changes: 1 addition & 1 deletion Makefile.common
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022 Huawei Cloud Computing Technologies Co., Ltd.
# 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.
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# openGemini-UP
# Gemix

Cluster deployment and upgrade tool.

Expand All @@ -20,28 +20,28 @@ The following table describes some commonly used basic commands.

| command | description | parameter | example |
| --- | --- | --- | --- |
| `version` | display version number of openGemini-UP | no para | `./openGemini-UP version` |
| `list` | display the version information of all components currently downloaded | no para | `./openGemini-UP list` |
| `install` | install database components | --version | `./openGemini-UP install --version v1.0.0` |
| `cluster` | deploying and managing openGemini clusters | have subcommand | |
| `version` | display version number of gemix | no para | `./gemix version` |
| `list` | display the version information of all components currently downloaded | no para | `./gemix list` |
| `cluster` | deploying and managing openGemini clusters | have subcommand | |

The following table describes the subcommands of the `cluster` command.

| command | description | parameter | example |
| --- | --- | --- | --- |
| `deploy` | deploy an openGemini cluster| --version<br />--yaml<br />--user<br />--key<br />--password | `./openGemini-UP cluster deploy --version v1.0.0 --yaml ./topology.example.yaml --user root --key ~/.ssh/id_rsa` |
| `stop` | stop an openGemini cluster | --yaml<br />--user<br />--key<br />--password | `./openGemini-UP cluster stop --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `start` | start an openGemini cluster which is stopped | --yaml<br />--user<br />--key<br />--password | `./openGemini-UP cluster start --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `destroy` | destroy an openGemini cluster which means stopping services and clearing data| --yaml<br />--user<br />--key<br />--password | `./openGemini-UP cluster destroy --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `upgrade` | upgrade an openGemini cluster to the specified version | --version<br />--yaml<br />--user<br />--key<br />--password | `./openGemini-UP cluster upgrade --version v1.0.0 --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `install` | install an openGemini cluster | --version<br />--yaml<br />--user<br />--key<br />--password | `./gemix cluster install --version v1.0.0 --yaml ./topology.example.yaml --user root --key ~/.ssh/id_rsa` |
| `start` | start an openGemini cluster and check the running status after startup | --version<br />--yaml<br />--user<br />--key<br />--password | `./gemix cluster start --version v1.0.0 --yaml ./topology.example.yaml --user root --key ~/.ssh/id_rsa` |
| `stop` | stop an openGemini cluster | --yaml<br />--user<br />--key<br />--password | `./gemix cluster stop --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `uninstall` | uninstall an openGemini cluster which means clearing data | --version<br />--yaml<br />--user<br />--key<br />--password | `./gemix cluster uninstall --version v1.0.0 --yaml ./topology.example.yaml --user root --password xxxxxx` |
| `status` | Check the running status of the openGemini cluster, including port occupancy, disk capacity, etc | --yaml<br />--user<br />--key<br />--password | `./gemix cluster status --yaml ./topology.example.yaml --user liujibo --key ~/.ssh/id_rsa` |
| `upgrade` | upgrade an openGemini cluster to the specified version and uninstall the old one | --version<br />--old_version<br />--yaml<br />--user<br />--key<br />--password | `./gemix cluster upgrade --old_version v1.0.0 --version v1.0.1 --yaml ./topology.example.yaml --user root --password xxxxxx` |

## topology.example.yaml

The `topology.example.yaml` is written by the user and contains the necessary information for deploying the openGemini cluster. You can modify the content of the file according to the template.

The meaning of each part is as follows:

* `global`: Default values for some options.
* `global`: Default values for some options. These options are mandatory.
* `ts-meta`: Deployment information for `ts-meta`, users can modify some options in `openGemini.conf` here.
* `ts-sql`: Deployment information for `ts-sql`, users can modify some options in `openGemini.conf` here.
* `ts-store`: Deployment information for `ts-store`, users can modify some options in `openGemini.conf` here.
Expand All @@ -56,7 +56,7 @@ global:
log_dir: "/gemini-deploy/logs"
# Storage directory for cluster deployment files, startup scripts, and configuration files.
deploy_dir: "/gemini-deploy"
# operating system, linux/darwin/windows.
# operating system, linux/darwin.
os: "linux"
# Supported values: "amd64", "arm64" (default: "amd64").
arch: "amd64"
Expand Down
59 changes: 0 additions & 59 deletions cmd/cluster.go

This file was deleted.

101 changes: 101 additions & 0 deletions cmd/cluster/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// 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"
"os"

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

// clusterCmd represents the cluster command
var ClusterCmd = &cobra.Command{
Use: "cluster",
Short: "manage cluster",
Long: `Manage openGemini cluster, including install, stop, uninstall, status, etc.`,
Run: func(cmd *cobra.Command, args []string) {},
}

func getClusterOptions(cmd *cobra.Command) (manager.ClusterOptions, error) {
var ops manager.ClusterOptions
if version, _ := cmd.Flags().GetString("version"); version == "" {
latestVer, err := util.GetLatestVerFromCurl()
if err != nil {
return ops, err
} else {
ops.Version = latestVer
}
} else {
ops.Version = version
}
if user, _ := cmd.Flags().GetString("user"); user == "" {
has, value := GetEnv(util.SshEnvUser)
if has {
ops.User = value
} else {
return ops, fmt.Errorf("the user is required")
}
} else {
ops.User = user
}
password, _ := cmd.Flags().GetString("password")
key, _ := cmd.Flags().GetString("key")
if password == "" && key == "" {
hasKey, key := GetEnv(util.SshEnvKey)
if hasKey {
ops.Key = key
ops.SshType = config.SSH_KEY
} else {
hasPW, pw := GetEnv(util.SshEnvPW)
if hasPW {
ops.Password = pw
ops.SshType = config.SSH_PW
} else {
return ops, fmt.Errorf("the password and key need at least one")
}
}

} else if password != "" && key != "" {
return ops, fmt.Errorf("the password and key need only one")
} else {
ops.Key = key
ops.Password = password
if key != "" {
ops.SshType = config.SSH_KEY
} else {
ops.SshType = config.SSH_PW
}
}

if yPath, _ := cmd.Flags().GetString("yaml"); yPath == "" {
return ops, fmt.Errorf("the path of cluster configuration file must be specified")
} else {
ops.YamlPath = yPath
}
return ops, nil
}

func GetEnv(envVar string) (bool, string) {
value := os.Getenv(envVar)
if value == "" {
return false, value
} else {
return true, value
}
}
64 changes: 64 additions & 0 deletions cmd/cluster/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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/spf13/cobra"
)

// installCmd represents the install command
var installCmd = &cobra.Command{
Use: "install",
Short: "install cluster",
Long: `Install an openGemini cluster based on configuration files and version numbers.`,
Run: func(cmd *cobra.Command, args []string) {
ops, err := getClusterOptions(cmd)
if err != nil {
fmt.Println(err)
return
}

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

func InstallCluster(ops manager.ClusterOptions) error {
installer := manager.NewGeminiInstaller(ops)
defer installer.Close()

if err := installer.PrepareForInstall(); err != nil {
return err
}
if err := installer.Install(); err != nil {
return err
}
fmt.Printf("Successfully installed the openGemini cluster with version : %s\n", ops.Version)
return nil
}

func init() {
ClusterCmd.AddCommand(installCmd)
installCmd.Flags().StringP("version", "v", "", "component version")
installCmd.Flags().StringP("yaml", "y", "", "The path to cluster topology yaml file")
installCmd.Flags().StringP("user", "u", "", "The user name to login via SSH. The user must has root (or sudo) privilege.")
installCmd.Flags().StringP("key", "k", "", "The path of the SSH identity file. If specified, public key authentication will be used.")
installCmd.Flags().StringP("password", "p", "", "The password of target hosts. If specified, password authentication will be used.")
}
71 changes: 71 additions & 0 deletions cmd/cluster/start.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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/spf13/cobra"
)

// startCmd represents the start command
var startCmd = &cobra.Command{
Use: "start",
Short: "start cluster",
Long: `Start an openGemini cluster based on configuration files and version numbers.`,
Run: func(cmd *cobra.Command, args []string) {
ops, err := getClusterOptions(cmd)
if err != nil {
fmt.Println(err)
return
}

err = StartCluster(ops)
if err != nil {
fmt.Println(err)
return
}

fmt.Printf("\nCheck the status of openGemini cluster\n")
err = PatrolCluster(ops)
if err != nil {
fmt.Println(err)
}
},
}

func StartCluster(ops manager.ClusterOptions) error {
starter := manager.NewGeminiStarter(ops)
defer starter.Close()

if err := starter.PrepareForStart(); err != nil {
return err
}
if err := starter.Start(); err != nil {
return err
}
fmt.Printf("Successfully started the openGemini cluster with version : %s\n", ops.Version)
return nil
}

func init() {
ClusterCmd.AddCommand(startCmd)
startCmd.Flags().StringP("version", "v", "", "component version")
startCmd.Flags().StringP("yaml", "y", "", "The path to cluster topology yaml file")
startCmd.Flags().StringP("user", "u", "", "The user name to login via SSH. The user must has root (or sudo) privilege.")
startCmd.Flags().StringP("key", "k", "", "The path of the SSH identity file. If specified, public key authentication will be used.")
startCmd.Flags().StringP("password", "p", "", "The password of target hosts. If specified, password authentication will be used.")
}
Loading

0 comments on commit 4344a91

Please sign in to comment.