github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/utils/ssh/utils.go (about) 1 // Copyright © 2022 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 "bufio" 19 "context" 20 "fmt" 21 "io" 22 "net" 23 "os" 24 "sync" 25 "time" 26 27 "github.com/sirupsen/logrus" 28 "golang.org/x/sync/errgroup" 29 30 "github.com/sealerio/sealer/utils/hash" 31 ) 32 33 //func displayInit() { 34 // reader, writer = io.Pipe() 35 // writeFlusher = dockerioutils.NewWriteFlusher(writer) 36 // defer func() { 37 // _ = reader.Close() 38 // _ = writer.Close() 39 // _ = writeFlusher.Close() 40 // }() 41 // progressChanOut = streamformatter.NewJSONProgressOutput(writeFlusher, false) 42 // err := dockerjsonmessage.DisplayJSONMessagesToStream(reader, dockerstreams.NewOut(common.StdOut), nil) 43 // if err != nil && err != io.ErrClosedPipe { 44 // logrus.Warnf("error occurs in display progressing, err: %s", err) 45 // } 46 //} 47 48 func localMd5Sum(localPath string) string { 49 md5, err := hash.FileMD5(localPath) 50 if err != nil { 51 logrus.Errorf("failed to get file md5: %v", err) 52 return "" 53 } 54 return md5 55 } 56 57 func fileExist(path string) bool { 58 _, err := os.Stat(path) 59 return err == nil || os.IsExist(err) 60 } 61 62 func ReadPipe(stdout, stderr io.Reader, alsoToStdout bool) { 63 var combineSlice []string 64 var combineLock sync.Mutex 65 doneout := make(chan error, 1) 66 doneerr := make(chan error, 1) 67 go func() { 68 doneerr <- readPipe(stderr, &combineSlice, &combineLock, alsoToStdout) 69 }() 70 go func() { 71 doneout <- readPipe(stdout, &combineSlice, &combineLock, alsoToStdout) 72 }() 73 <-doneerr 74 <-doneout 75 } 76 77 func readPipe(pipe io.Reader, combineSlice *[]string, combineLock *sync.Mutex, alsoToStdout bool) error { 78 r := bufio.NewReader(pipe) 79 for { 80 line, _, err := r.ReadLine() 81 if err != nil { 82 return err 83 } 84 85 combineLock.Lock() 86 *combineSlice = append(*combineSlice, string(line)) 87 logrus.Tracef("command execution result is: %s", line) 88 if alsoToStdout { 89 fmt.Println(string(line)) 90 } 91 combineLock.Unlock() 92 } 93 } 94 95 func WaitSSHReady(ssh Interface, tryTimes int, hosts ...net.IP) error { 96 var err error 97 eg, _ := errgroup.WithContext(context.Background()) 98 for _, h := range hosts { 99 host := h 100 eg.Go(func() error { 101 for i := 0; i < tryTimes; i++ { 102 err = ssh.Ping(host) 103 if err == nil { 104 return nil 105 } 106 time.Sleep(time.Duration(i) * time.Second) 107 } 108 return fmt.Errorf("wait for [%s] ssh ready timeout: %v, ensure that the IP address or password is correct", host, err) 109 }) 110 } 111 return eg.Wait() 112 }