github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/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 24 "github.com/alibaba/sealer/common" 25 "github.com/alibaba/sealer/logger" 26 v1 "github.com/alibaba/sealer/types/api/v1" 27 v2 "github.com/alibaba/sealer/types/api/v2" 28 "github.com/alibaba/sealer/utils" 29 ) 30 31 type Interface interface { 32 // Copy local files to remote host 33 // scp -r /tmp root@192.168.0.2:/root/tmp => Copy("192.168.0.2","tmp","/root/tmp") 34 // need check md5sum 35 Copy(host, srcFilePath, dstFilePath string) error 36 // Fetch copy remote host files to localhost 37 Fetch(host, srcFilePath, dstFilePath string) error 38 // CmdAsync exec command on remote host, and asynchronous return logs 39 CmdAsync(host string, cmd ...string) error 40 // Cmd exec command on remote host, and return combined standard output and standard error 41 Cmd(host, cmd string) ([]byte, error) 42 // IsFileExist check remote file exist or not 43 IsFileExist(host, remoteFilePath string) (bool, error) 44 // RemoteDirExist Remote file existence returns true, nil 45 RemoteDirExist(host, remoteDirpath string) (bool, error) 46 // CmdToString exec command on remote host, and return spilt standard output and standard error 47 CmdToString(host, cmd, spilt string) (string, error) 48 // Platform Get remote platform 49 Platform(host string) (v1.Platform, error) 50 51 Ping(host string) error 52 } 53 54 type SSH struct { 55 IsStdout bool 56 Encrypted bool 57 User string 58 Password string 59 Port string 60 PkFile string 61 PkPassword string 62 Timeout *time.Duration 63 LocalAddress []net.Addr 64 } 65 66 func NewSSHClient(ssh *v1.SSH, isStdout bool) Interface { 67 if ssh.User == "" { 68 ssh.User = common.ROOT 69 } 70 address, err := utils.GetLocalHostAddresses() 71 if err != nil { 72 logger.Warn("failed to get local address, %v", err) 73 } 74 return &SSH{ 75 IsStdout: isStdout, 76 Encrypted: ssh.Encrypted, 77 User: ssh.User, 78 Password: ssh.Passwd, 79 Port: ssh.Port, 80 PkFile: ssh.Pk, 81 PkPassword: ssh.PkPasswd, 82 LocalAddress: address, 83 } 84 } 85 86 // GetHostSSHClient is used to executed bash command and no std out to be printed. 87 func GetHostSSHClient(hostIP string, cluster *v2.Cluster) (Interface, error) { 88 for _, host := range cluster.Spec.Hosts { 89 for _, ip := range host.IPS { 90 if hostIP == ip { 91 if err := mergo.Merge(&host.SSH, &cluster.Spec.SSH); err != nil { 92 return nil, err 93 } 94 return NewSSHClient(&host.SSH, false), nil 95 } 96 } 97 } 98 return nil, fmt.Errorf("get host ssh client failed, host ip %s not in hosts ip list", hostIP) 99 } 100 101 // NewStdoutSSHClient is used to show std out when execute bash command. 102 func NewStdoutSSHClient(hostIP string, cluster *v2.Cluster) (Interface, error) { 103 for _, host := range cluster.Spec.Hosts { 104 for _, ip := range host.IPS { 105 if hostIP == ip { 106 if err := mergo.Merge(&host.SSH, &cluster.Spec.SSH); err != nil { 107 return nil, err 108 } 109 return NewSSHClient(&host.SSH, true), nil 110 } 111 } 112 } 113 return nil, fmt.Errorf("get host ssh client failed, host ip %s not in hosts ip list", hostIP) 114 }