github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/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  	}
    38  
    39  	done := make(chan error)
    40  	err = remoteCommand.Start()
    41  	if err != nil {
    42  		return false, err
    43  	}
    44  
    45  	go func() {
    46  		done <- remoteCommand.Wait()
    47  	}()
    48  
    49  	select {
    50  	case <-time.After(HostCheckTimeout):
    51  		grip.Warning(remoteCommand.Stop())
    52  		return false, nil
    53  	case err = <-done:
    54  		if err != nil {
    55  			return false, nil
    56  		}
    57  		return true, nil
    58  	}
    59  }