github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/hostutil/host_status.go (about)

     1  package hostutil
     2  
     3  import (
     4  	"io/ioutil"
     5  	"time"
     6  
     7  	"github.com/evergreen-ci/evergreen/command"
     8  	"github.com/evergreen-ci/evergreen/model/host"
     9  	"github.com/evergreen-ci/evergreen/util"
    10  	"github.com/mongodb/grip"
    11  )
    12  
    13  const HostCheckTimeout = 10 * time.Second
    14  
    15  //CheckSSHResponse runs a test command over SSH to check whether or not the host
    16  //appears to be up and accepting ssh connections. Returns true/false if the check
    17  //passes or fails, or an error if the command cannot be attempted.
    18  func CheckSSHResponse(hostObject *host.Host, sshOptions []string) (bool, error) {
    19  	hostInfo, err := util.ParseSSHInfo(hostObject.Host)
    20  	if err != nil {
    21  		return false, err
    22  	}
    23  
    24  	if hostInfo.User == "" {
    25  		hostInfo.User = hostObject.User
    26  	}
    27  
    28  	// construct a command to check reachability
    29  	remoteCommand := &command.RemoteCommand{
    30  		CmdString:       "echo hi",
    31  		Stdout:          ioutil.Discard,
    32  		Stderr:          ioutil.Discard,
    33  		RemoteHostName:  hostInfo.Hostname,
    34  		User:            hostInfo.User,
    35  		Options:         append([]string{"-p", hostInfo.Port}, sshOptions...),
    36  		Background:      false,
    37  		LoggingDisabled: true,
    38  	}
    39  
    40  	done := make(chan error)
    41  	err = remoteCommand.Start()
    42  	if err != nil {
    43  		return false, err
    44  	}
    45  
    46  	go func() {
    47  		done <- remoteCommand.Wait()
    48  	}()
    49  
    50  	select {
    51  	case <-time.After(HostCheckTimeout):
    52  		grip.Warning(remoteCommand.Stop())
    53  		return false, nil
    54  	case err = <-done:
    55  		if err != nil {
    56  			return false, nil
    57  		}
    58  		return true, nil
    59  	}
    60  }