github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/utils/ssh/ssh.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ssh 16 17 import ( 18 "fmt" 19 "net" 20 "time" 21 22 "github.com/imdario/mergo" 23 "github.com/sirupsen/logrus" 24 25 "github.com/sealerio/sealer/common" 26 v1 "github.com/sealerio/sealer/types/api/v1" 27 v2 "github.com/sealerio/sealer/types/api/v2" 28 netUtils "github.com/sealerio/sealer/utils/net" 29 "github.com/sealerio/sealer/utils/os/fs" 30 ) 31 32 type Interface interface { 33 // Copy local files to remote host 34 // scp -r /tmp root@192.168.0.2:/root/tmp => Copy("192.168.0.2","tmp","/root/tmp") 35 // need check md5sum 36 Copy(host net.IP, srcFilePath, dstFilePath string) error 37 // CopyR copy remote host files to localhost 38 CopyR(host net.IP, srcFilePath, dstFilePath string) error 39 // CmdAsync exec command on remote host, and asynchronous return logs 40 CmdAsync(host net.IP, env map[string]string, cmd ...string) error 41 // Cmd exec command on remote host, and return combined standard output and standard error 42 Cmd(host net.IP, env map[string]string, cmd string) ([]byte, error) 43 // CmdToString exec command on remote host, and return spilt standard output and standard error 44 CmdToString(host net.IP, env map[string]string, cmd, spilt string) (string, error) 45 // IsFileExist check remote file exist or not 46 IsFileExist(host net.IP, remoteFilePath string) (bool, error) 47 // RemoteDirExist Remote file existence returns true, nil 48 RemoteDirExist(host net.IP, remoteDirpath string) (bool, error) 49 // GetPlatform Get remote platform 50 GetPlatform(host net.IP) (v1.Platform, error) 51 // Ping Ping remote host 52 Ping(host net.IP) error 53 } 54 55 type SSH struct { 56 AlsoToStdout bool 57 Encrypted bool 58 User string 59 Password string 60 Port string 61 PkFile string 62 PkPassword string 63 Timeout *time.Duration 64 LocalAddress []net.Addr 65 Fs fs.Interface 66 } 67 68 func NewSSHClient(ssh *v1.SSH, alsoToStdout bool) Interface { 69 if ssh.User == "" { 70 ssh.User = common.ROOT 71 } 72 address, err := netUtils.GetLocalHostAddresses() 73 if err != nil { 74 logrus.Warnf("failed to get local address: %v", err) 75 } 76 return &SSH{ 77 AlsoToStdout: alsoToStdout, 78 Encrypted: ssh.Encrypted, 79 User: ssh.User, 80 Password: ssh.Passwd, 81 Port: ssh.Port, 82 PkFile: ssh.Pk, 83 PkPassword: ssh.PkPasswd, 84 LocalAddress: address, 85 Fs: fs.NewFilesystem(), 86 } 87 } 88 89 // GetHostSSHClient is used to executed bash command and no std out to be printed. 90 func GetHostSSHClient(hostIP net.IP, cluster *v2.Cluster) (Interface, error) { 91 for i := range cluster.Spec.Hosts { 92 for _, ip := range cluster.Spec.Hosts[i].IPS { 93 if hostIP.Equal(ip) { 94 if err := mergo.Merge(&cluster.Spec.Hosts[i].SSH, &cluster.Spec.SSH); err != nil { 95 return nil, err 96 } 97 return NewSSHClient(&cluster.Spec.Hosts[i].SSH, false), nil 98 } 99 } 100 } 101 return nil, fmt.Errorf("failed to get host ssh client: host ip %s not in hosts ip list", hostIP) 102 } 103 104 // NewStdoutSSHClient is used to show std out when execute bash command. 105 func NewStdoutSSHClient(hostIP net.IP, cluster *v2.Cluster) (Interface, error) { 106 for i := range cluster.Spec.Hosts { 107 for _, ip := range cluster.Spec.Hosts[i].IPS { 108 if hostIP.Equal(ip) { 109 if err := mergo.Merge(&cluster.Spec.Hosts[i].SSH, &cluster.Spec.SSH); err != nil { 110 return nil, err 111 } 112 return NewSSHClient(&cluster.Spec.Hosts[i].SSH, true), nil 113 } 114 } 115 } 116 return nil, fmt.Errorf("failed to get host ssh client: host ip %s not in hosts ip list", hostIP) 117 }