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 }