diff --git a/cmd/sealos/cmd/exec.go b/cmd/sealos/cmd/exec.go index 847c7688d15..e4a464b0677 100644 --- a/cmd/sealos/cmd/exec.go +++ b/cmd/sealos/cmd/exec.go @@ -17,7 +17,9 @@ limitations under the License. package cmd import ( - "github.com/labring/sealos/pkg/ssh" + "github.com/labring/sealos/pkg/clusterfile" + "github.com/labring/sealos/pkg/types/v1beta1" + "github.com/labring/sealos/pkg/utils/ssh" "github.com/spf13/cobra" ) @@ -26,6 +28,7 @@ var clusterName string var ips []string func newExecCmd() *cobra.Command { + var cluster *v1beta1.Cluster var cmd = &cobra.Command{ Use: "exec", Short: "exec a shell command or script on all node.", @@ -42,18 +45,26 @@ set ips to exec cmd: Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(ips) > 0 { - execCmd, err := ssh.NewExecCmdFromIPs(clusterName, ips) + execCmd, err := ssh.NewExecCmdFromIPs(cluster, ips) if err != nil { return err } return execCmd.RunCmd(args[0]) } - execCmd, err := ssh.NewExecCmdFromRoles(clusterName, roles) + execCmd, err := ssh.NewExecCmdFromRoles(cluster, roles) if err != nil { return err } return execCmd.RunCmd(args[0]) }, + PreRunE: func(cmd *cobra.Command, args []string) error { + cls, err := clusterfile.GetClusterFromName(clusterName) + if err != nil { + return err + } + cluster = cls + return nil + }, } cmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "default", "submit one cluster name") cmd.Flags().StringVarP(&roles, "roles", "r", "", "set role label to roles") diff --git a/cmd/sealos/cmd/scp.go b/cmd/sealos/cmd/scp.go index 4355819f386..1c63ca41458 100644 --- a/cmd/sealos/cmd/scp.go +++ b/cmd/sealos/cmd/scp.go @@ -17,7 +17,9 @@ limitations under the License. package cmd import ( - "github.com/labring/sealos/pkg/ssh" + "github.com/labring/sealos/pkg/clusterfile" + "github.com/labring/sealos/pkg/types/v1beta1" + "github.com/labring/sealos/pkg/utils/ssh" "github.com/spf13/cobra" ) @@ -27,6 +29,7 @@ import ( // var ips []string func newScpCmd() *cobra.Command { + var cluster *v1beta1.Cluster var cmd = &cobra.Command{ Use: "scp", // Aliases: []string{"cp"}, @@ -44,18 +47,26 @@ set ips to copy file: Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { if len(ips) > 0 { - sshCmd, err := ssh.NewExecCmdFromIPs(clusterName, ips) + sshCmd, err := ssh.NewExecCmdFromIPs(cluster, ips) if err != nil { return err } return sshCmd.RunCopy(args[0], args[1]) } - sshCmd, err := ssh.NewExecCmdFromRoles(clusterName, roles) + sshCmd, err := ssh.NewExecCmdFromRoles(cluster, roles) if err != nil { return err } return sshCmd.RunCopy(args[0], args[1]) }, + PreRunE: func(cmd *cobra.Command, args []string) error { + cls, err := clusterfile.GetClusterFromName(clusterName) + if err != nil { + return err + } + cluster = cls + return nil + }, } cmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "default", "submit one cluster name") cmd.Flags().StringVarP(&roles, "roles", "r", "", "set role label to roles") diff --git a/pkg/clusterfile/util.go b/pkg/clusterfile/util.go index 35b514872f5..8da8cc48ff0 100644 --- a/pkg/clusterfile/util.go +++ b/pkg/clusterfile/util.go @@ -50,7 +50,17 @@ func GetDefaultClusterName() (string, error) { return "", ErrClusterNotExist } - +func GetClusterFromName(clusterName string) (cluster *v2.Cluster, err error) { + if clusterName == "" { + clusterName, err = GetDefaultClusterName() + if err != nil { + return nil, err + } + } + clusterFile := contants.Clusterfile(clusterName) + cluster, err = GetClusterFromFile(clusterFile) + return +} func GetClusterFromFile(filepath string) (cluster *v2.Cluster, err error) { cluster = &v2.Cluster{} if err = yaml2.UnmarshalYamlFromFile(filepath, cluster); err != nil { diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go deleted file mode 100644 index fd1ef7f9019..00000000000 --- a/pkg/ssh/ssh.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright © 2021 Alibaba Group Holding 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 ssh - -import ( - "context" - "fmt" - "strings" - - "github.com/labring/sealos/pkg/clusterfile" - v2 "github.com/labring/sealos/pkg/types/v1beta1" - "github.com/labring/sealos/pkg/utils/contants" - "github.com/labring/sealos/pkg/utils/logger" - "github.com/labring/sealos/pkg/utils/ssh" - - "golang.org/x/sync/errgroup" -) - -type Exec struct { - cluster *v2.Cluster - ipList []string -} - -func NewExecCmdFromRoles(clusterName string, roles string) (Exec, error) { - if clusterName == "" { - var err error - clusterName, err = clusterfile.GetDefaultClusterName() - if err != nil { - return Exec{}, err - } - } - clusterFile := contants.Clusterfile(clusterName) - cluster, err := clusterfile.GetClusterFromFile(clusterFile) - if err != nil { - return Exec{}, err - } - var ipList []string - if roles == "" { - ipList = append(cluster.GetMasterIPList(), cluster.GetNodeIPList()...) - } else { - roles := strings.Split(roles, ",") - for _, role := range roles { - ipList = append(ipList, cluster.GetIPSByRole(role)...) - } - if len(ipList) == 0 { - return Exec{}, fmt.Errorf("failed to get ipList, please check your roles label") - } - } - return Exec{cluster: cluster, ipList: ipList}, nil -} - -func NewExecCmdFromIPs(clusterName string, ips []string) (Exec, error) { - if clusterName == "" { - var err error - clusterName, err = clusterfile.GetDefaultClusterName() - if err != nil { - return Exec{}, err - } - } - clusterFile := contants.Clusterfile(clusterName) - cluster, err := clusterfile.GetClusterFromFile(clusterFile) - if err != nil { - return Exec{}, err - } - return Exec{cluster: cluster, ipList: ips}, nil -} - -func (e *Exec) RunCmd(cmd string) error { - eg, _ := errgroup.WithContext(context.Background()) - for _, ipAddr := range e.ipList { - ip := ipAddr - eg.Go(func() error { - sshClient, sshErr := ssh.NewSSHByCluster(e.cluster, true) - if sshErr != nil { - return sshErr - } - err := sshClient.CmdAsync(ip, cmd) - if err != nil { - return err - } - return nil - }) - } - if err := eg.Wait(); err != nil { - return fmt.Errorf("failed to sealos exec command, err: %v", err) - } - return nil -} - -func (e *Exec) RunCopy(srcFilePath, dstFilePath string) error { - eg, _ := errgroup.WithContext(context.Background()) - for _, ipAddr := range e.ipList { - ip := ipAddr - eg.Go(func() error { - sshClient, sshErr := ssh.NewSSHByCluster(e.cluster, true) - if sshErr != nil { - return sshErr - } - err := sshClient.Copy(ip, srcFilePath, dstFilePath) - if err != nil { - return err - } - return nil - }) - } - if err := eg.Wait(); err != nil { - return fmt.Errorf("failed to sealos copy command, err: %v", err) - } - logger.Info("transfers files success") - return nil -} diff --git a/pkg/utils/ssh/exec.go b/pkg/utils/ssh/exec.go new file mode 100644 index 00000000000..6cd01c77a88 --- /dev/null +++ b/pkg/utils/ssh/exec.go @@ -0,0 +1,97 @@ +/* +Copyright 2022 cuisongliu@qq.com. + +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 ssh + +import ( + "context" + "fmt" + "strings" + + v2 "github.com/labring/sealos/pkg/types/v1beta1" + "github.com/labring/sealos/pkg/utils/logger" + "golang.org/x/sync/errgroup" +) + +type Exec struct { + cluster *v2.Cluster + ipList []string +} + +func NewExecCmdFromRoles(cluster *v2.Cluster, roles string) (Exec, error) { + var ipList []string + if roles == "" { + ipList = append(cluster.GetMasterIPList(), cluster.GetNodeIPList()...) + } else { + roleList := strings.Split(roles, ",") + for _, role := range roleList { + ipList = append(ipList, cluster.GetIPSByRole(role)...) + } + if len(ipList) == 0 { + return Exec{}, fmt.Errorf("failed to get ipList, please check your roles label") + } + } + return Exec{cluster: cluster, ipList: ipList}, nil +} + +func NewExecCmdFromIPs(cluster *v2.Cluster, ips []string) (Exec, error) { + return Exec{cluster: cluster, ipList: ips}, nil +} + +func (e *Exec) RunCmd(cmd string) error { + eg, _ := errgroup.WithContext(context.Background()) + for _, ipAddr := range e.ipList { + ip := ipAddr + eg.Go(func() error { + sshClient, sshErr := NewSSHByCluster(e.cluster, true) + if sshErr != nil { + return sshErr + } + err := sshClient.CmdAsync(ip, cmd) + if err != nil { + return err + } + return nil + }) + } + if err := eg.Wait(); err != nil { + return fmt.Errorf("failed to exec command, err: %v", err) + } + return nil +} + +func (e *Exec) RunCopy(srcFilePath, dstFilePath string) error { + eg, _ := errgroup.WithContext(context.Background()) + for _, ipAddr := range e.ipList { + ip := ipAddr + eg.Go(func() error { + sshClient, sshErr := NewSSHByCluster(e.cluster, true) + if sshErr != nil { + return sshErr + } + err := sshClient.Copy(ip, srcFilePath, dstFilePath) + if err != nil { + return err + } + return nil + }) + } + if err := eg.Wait(); err != nil { + return fmt.Errorf("failed to copy command, err: %v", err) + } + logger.Info("transfers files success") + return nil +}