diff --git a/README.md b/README.md index bec0dc4..6f25346 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ ## Documentation -- [English](https://docs.opengemini.org/guide/reference/gemix/gemix_documentation_guide.html) -- [简体中文](https://docs.opengemini.org/zh/guide/reference/gemix/gemix_documentation_guide) +- [English]() +- [简体中文](https://docs.opengemini.org/zh/guide/reference/gemix_manual.html) ## Installation @@ -32,6 +32,11 @@ gemix playground gemix cluster insall opengemini_demo v1.1.1 ./topology.yaml --skip-create-user -p ``` +Tips: + +> If there are network issues with the automatic download of the installation package, +> please place the installation package under `~/.gemix/storage/cluster/packages/` + ## Usage After installing `gemix`, you can use it to install binaries of openGemini components and create clusters. diff --git a/pkg/cluster/operation/download.go b/pkg/cluster/operation/download.go index bb8da23..4a99c85 100644 --- a/pkg/cluster/operation/download.go +++ b/pkg/cluster/operation/download.go @@ -45,7 +45,10 @@ func Download(prefix, component, nodeOS, arch, version string) error { if component == spec.ComponentGrafana { // FIXME: download from opengemini.org - fileName = fmt.Sprintf("%s-%s.%s-%s.tar.gz", component, ver.GrafanaVersion, nodeOS, arch) + if nodeOS == "darwin" { + arch = "amd64" + } + fileName = fmt.Sprintf("%s-enterprise-%s.%s-%s.tar.gz", component, ver.GrafanaVersion, nodeOS, arch) componentUrl = strings.Join([]string{"https://dl.grafana.com/oss/release", fileName}, "/") } dstPath := spec.ProfilePath(spec.OpenGeminiPackageCacheDir, fileName) @@ -55,9 +58,8 @@ func Download(prefix, component, nodeOS, arch, version string) error { if utils2.IsExist(dstPath) { if component == spec.ComponentOpenGemini { - if err := repository.VerifyComponent(version, dstPath); err != nil { - _ = os.Remove(dstPath) // nolint - } + // TODO: do not remote package + _ = repository.VerifyComponent(version, dstPath) // nolint } } diff --git a/pkg/repository/repo.go b/pkg/repository/repo.go index 6bc8b7f..ef8c8b8 100644 --- a/pkg/repository/repo.go +++ b/pkg/repository/repo.go @@ -61,7 +61,8 @@ func VerifyComponent(version, target string) error { checksums := spec.ProfilePath(spec.OpenGeminiPackageCacheDir, CHECKSUMS) if utils.IsNotExist(checksums) { if err := tryToDownloadCheckSumsFile(version); err != nil { - return errors.WithStack(err) + // FIXME: assume that the user downloaded the component without problems + return nil } } diff --git a/util/clusterInfo.go b/util/clusterInfo.go deleted file mode 100644 index a6f8139..0000000 --- a/util/clusterInfo.go +++ /dev/null @@ -1,91 +0,0 @@ -// 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 util - -import ( - "encoding/json" - "fmt" - "os" -) - -type StartOptions struct { - User string - SkipCreateUser bool -} - -type ClusterOptions struct { - Name string - Version string - User string - Key string - Password string - SshType SSHType - YamlPath string -} - -func SaveClusterOptionsToFile(filename string, cluster ClusterOptions) error { - data, err := json.Marshal(cluster) - if err != nil { - return err - } - - err = os.WriteFile(filename, data, 0750) - return err -} - -func LoadClusterOptionsFromFile(filename string) (ClusterOptions, error) { - data, err := os.ReadFile(filename) - if err != nil { - return ClusterOptions{}, err - } - - var cluster ClusterOptions - err = json.Unmarshal(data, &cluster) - if err != nil { - return ClusterOptions{}, err - } - - return cluster, nil -} - -func CheckClusterNameValid(name string) bool { - files, err := os.ReadDir(ClusterInfoDir) - if err != nil { - fmt.Println("Error reading directory:", err) - return false - } - - for _, file := range files { - if file.Name() == name { - return false - } - } - return true -} - -func CheckClusterNameExist(name string) bool { - files, err := os.ReadDir(ClusterInfoDir) - if err != nil { - fmt.Println("Error reading directory:", err) - return false - } - - for _, file := range files { - if file.Name() == name { - return true - } - } - return false -} diff --git a/util/connect.go b/util/connect.go deleted file mode 100644 index 417c9fc..0000000 --- a/util/connect.go +++ /dev/null @@ -1,144 +0,0 @@ -// 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 util - -import ( - "fmt" - "net" - "os" - "path" - "time" - - "github.com/pkg/sftp" - "golang.org/x/crypto/ssh" -) - -type SSHType int32 - -const ( - SSH_UNKNOW SSHType = 0 - SSH_PW SSHType = 1 - SSH_KEY SSHType = 2 -) - -func NewSSH_PW(user, password, host string, port int) (*ssh.Client, error) { - var ( - auth []ssh.AuthMethod - addr string - clientConfig *ssh.ClientConfig - sshClient *ssh.Client - err error - ) - auth = make([]ssh.AuthMethod, 0) - auth = append(auth, ssh.Password(password)) - clientConfig = &ssh.ClientConfig{ - User: user, - Auth: auth, - Timeout: 30 * time.Second, - HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { - return nil - }, - } - addr = fmt.Sprintf("%s:%d", host, port) - if sshClient, err = ssh.Dial("tcp", addr, clientConfig); err != nil { - return nil, err - } - return sshClient, err -} - -func NewSSH_Key(user, privateKeyPath, host string, port int) (*ssh.Client, error) { - var ( - auth []ssh.AuthMethod - addr string - clientConfig *ssh.ClientConfig - sshClient *ssh.Client - err error - ) - - privateKeyBytes, err := os.ReadFile(privateKeyPath) - if err != nil { - return nil, err - } - - key, err := ssh.ParsePrivateKey(privateKeyBytes) - if err != nil { - return nil, err - } - - auth = make([]ssh.AuthMethod, 0) - auth = append(auth, ssh.PublicKeys(key)) - - clientConfig = &ssh.ClientConfig{ - User: user, - Auth: auth, - Timeout: 30 * time.Second, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - } - - addr = fmt.Sprintf("%s:%d", host, port) - if sshClient, err = ssh.Dial("tcp", addr, clientConfig); err != nil { - return nil, err - } - - return sshClient, nil -} - -func NewSftpClient(sshClient *ssh.Client) (*sftp.Client, error) { - var ( - sftpClient *sftp.Client - err error - ) - if sftpClient, err = sftp.NewClient(sshClient); err != nil { - return nil, err - } - return sftpClient, nil -} - -func UploadFile(ip string, localFilePath string, remoteDir string, sftpClient *sftp.Client) error { - if sftpClient == nil { - return ErrNoSftpSession - } - srcFile, err := os.Open(localFilePath) - if err != nil { - fmt.Printf("open %s failed! %v\n", localFilePath, err) - return err - } - defer srcFile.Close() - // create target file on remote host - var remoteFileName = path.Base(localFilePath) - dstFile, err := sftpClient.Create(path.Join(remoteDir, remoteFileName)) - if err != nil { - fmt.Printf("create %s:%s failed! %v\n", ip, path.Join(remoteDir, remoteFileName), err) - return err - } - defer dstFile.Close() - if _, err = dstFile.ReadFrom(srcFile); err != nil { - fmt.Printf("%s:%s read from %s failed! %v\n", ip, path.Join(remoteDir, remoteFileName), localFilePath, err) - return err - } - fmt.Printf("upload %s to %s:%s \n", localFilePath, ip, remoteDir) - return nil -} - -func NewSshSession(sshClient *ssh.Client) (*ssh.Session, error) { - var ( - sshSession *ssh.Session - err error - ) - if sshSession, err = sshClient.NewSession(); err != nil { - return nil, err - } - return sshSession, nil -} diff --git a/util/const.go b/util/const.go deleted file mode 100644 index ec49bbb..0000000 --- a/util/const.go +++ /dev/null @@ -1,107 +0,0 @@ -// 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 util - -import ( - "fmt" - "os" - "os/user" - "path/filepath" - "time" -) - -var DownloadDst string -var InstallScriptPath string -var ClusterInfoDir string - -func init() { - execPath, _ := os.Getwd() - currentUser, err := user.Current() - if err != nil { - fmt.Println(err) - } - homeDirectory := currentUser.HomeDir - DownloadDst = filepath.Join(homeDirectory, ".gemix", "download") - InstallScriptPath = filepath.Join(execPath, "scripts/install.sh") - ClusterInfoDir = filepath.Join(homeDirectory, ".gemix", "cluster-info") - - if err = os.MkdirAll(DownloadDst, 0750); err != nil { - fmt.Println(err) - } - - if err = os.MkdirAll(ClusterInfoDir, 0750); err != nil { - fmt.Println(err) - } -} - -// env -const ( - SshEnvUser = "OPENGEMINI_SSH_USER" - SshEnvKey = "OPENGEMINI_SSH_KEY" - SshEnvPW = "OPENGEMINI_SSH_PW" -) - -// downloader -const ( - DownloadWeb = "https://github.com/openGemini/openGemini/releases/download" - DownloadFillChar = "openGemini-" - DownloadPkgSuffix = ".tar.gz" - - // fixed values - DownloadTimeout = 2 * time.Minute - - // default values - DownloadLatestUrl = "https://github.com/openGemini/openGemini/releases/latest" - DownloadDefaultOs = "linux" - DownloadDefaultArch = "amd64" -) - -// local -const ( - LocalBinRelPath = "usr/bin" - LocalEtcRelPath = "etc" - LocalConfName = "openGemini.conf" -) - -// config -const ( - RemoteMetaConfName = "openGemini-meta.conf" - RemoteSqlConfName = "openGemini-sql.conf" - RemoteStoreConfName = "openGemini-store.conf" -) - -// file name -const ( - TsMeta = "ts-meta" // process name & bin file name - TsSql = "ts-sql" - TsStore = "ts-store" - InstallScript = "install.sh" -) - -// remote -const ( - // gemix - RemoteBinRelPath = "bin" - RemoteEtcRelPath = "etc" - - // openGemini - RemotePidPath = "pid" - RemotePidSuffix = ".pid" - RemoteLogSuffix = ".log" - - MetaExtraLog = "meta_extra" - SqlExtraLog = "sql_extra" - StoreExtraLog = "store_extra" -) diff --git a/util/error.go b/util/error.go deleted file mode 100644 index 2fb1d66..0000000 --- a/util/error.go +++ /dev/null @@ -1,26 +0,0 @@ -// 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 util - -import "errors" - -var ( - ErrUnexpectedNil = errors.New("unexpected nil value") - - ErrNoSshClient = errors.New("no ssh client") - ErrNoSftpSession = errors.New("no sftp session") - - ErrUnknowSSHType = errors.New("unknow ssh type") -) diff --git a/util/version.go b/util/version.go deleted file mode 100644 index e535e6a..0000000 --- a/util/version.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 util - -import ( - "fmt" - "net/url" - "os/exec" - "path" - "regexp" - "strings" -) - -func GetLatestVerFromCurl() (string, error) { - cmd := exec.Command("curl", "-i", "-k", DownloadLatestUrl) - output, err := cmd.Output() - if err != nil { - return "", err - } - response := string(output) - - re := regexp.MustCompile(`location:\s*(.*?)\n`) - matches := re.FindStringSubmatch(response) - - if len(matches) < 2 { - return "", fmt.Errorf("location header not found") - } - locationValue := strings.TrimSpace(matches[1]) - - parsedURL, err := url.Parse(locationValue) - if err != nil { - return "", err - } - urlPath := parsedURL.Path - lastSegment := path.Base(urlPath) - - return lastSegment, nil -}