github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/command/remote_command.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os/exec"
     7  	"strings"
     8  
     9  	"github.com/mongodb/grip"
    10  )
    11  
    12  type RemoteCommand struct {
    13  	Id        string
    14  	CmdString string
    15  
    16  	Stdout io.Writer
    17  	Stderr io.Writer
    18  
    19  	// info necessary for sshing into the remote host
    20  	RemoteHostName string
    21  	User           string
    22  	Options        []string
    23  	Background     bool
    24  
    25  	// optional flag for hiding sensitive commands from log output
    26  	LoggingDisabled bool
    27  
    28  	// set after the command is started
    29  	Cmd *exec.Cmd
    30  }
    31  
    32  func (rc *RemoteCommand) Run() error {
    33  	grip.Debugf("RemoteCommand(%s) beginning Run()", rc.Id)
    34  	err := rc.Start()
    35  	if err != nil {
    36  		return err
    37  	}
    38  	if rc.Cmd != nil && rc.Cmd.Process != nil {
    39  		grip.Debugf("RemoteCommand(%s) started process %d", rc.Id, rc.Cmd.Process.Pid)
    40  	} else {
    41  		grip.Debugf("RemoteCommand(%s) has nil Cmd or Cmd.Process in Run()", rc.Id)
    42  	}
    43  	return rc.Cmd.Wait()
    44  }
    45  
    46  func (rc *RemoteCommand) Wait() error {
    47  	return rc.Cmd.Wait()
    48  }
    49  
    50  func (rc *RemoteCommand) Start() error {
    51  
    52  	// build the remote connection, in user@host format
    53  	remote := rc.RemoteHostName
    54  	if rc.User != "" {
    55  		remote = fmt.Sprintf("%v@%v", rc.User, remote)
    56  	}
    57  
    58  	// build the command
    59  	cmdArray := append(rc.Options, remote)
    60  
    61  	// set to the background, if necessary
    62  	cmdString := rc.CmdString
    63  	if rc.Background {
    64  		cmdString = fmt.Sprintf("nohup %v > /tmp/start 2>&1 &", cmdString)
    65  	}
    66  	cmdArray = append(cmdArray, cmdString)
    67  
    68  	grip.InfoWhenf(!rc.LoggingDisabled, "Remote command executing: '%s'",
    69  		strings.Join(cmdArray, " "))
    70  
    71  	// set up execution
    72  	cmd := exec.Command("ssh", cmdArray...)
    73  	cmd.Stdout = rc.Stdout
    74  	cmd.Stderr = rc.Stderr
    75  
    76  	// cache the command running
    77  	rc.Cmd = cmd
    78  	return cmd.Start()
    79  }
    80  
    81  func (rc *RemoteCommand) Stop() error {
    82  	if rc.Cmd != nil && rc.Cmd.Process != nil {
    83  		grip.Debugf("RemoteCommand(%s) killing process %d", rc.Id, rc.Cmd.Process.Pid)
    84  		return rc.Cmd.Process.Kill()
    85  	}
    86  	grip.Warningf("RemoteCommand(%s) Trying to stop command but Cmd / Process was nil", rc.Id)
    87  	return nil
    88  }