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  }