in helpers/ssh/ssh_command.go [134:179]
func (s *Client) Run(ctx context.Context, cmd Command) error {
if s.client == nil {
return errors.New("Not connected")
}
session, err := s.client.NewSession()
if err != nil {
return err
}
defer session.Close()
var envVariables bytes.Buffer
for _, keyValue := range cmd.Environment {
envVariables.WriteString("export " + helpers.ShellEscape(keyValue) + "\n")
}
session.Stdin = io.MultiReader(
&envVariables,
bytes.NewBufferString(cmd.Stdin),
)
session.Stdout = s.Stdout
session.Stderr = s.Stderr
err = session.Start(cmd.fullCommand())
if err != nil {
return err
}
waitCh := make(chan error)
go func() {
err := session.Wait()
if _, ok := err.(*ssh.ExitError); ok {
err = &ExitError{Inner: err}
}
waitCh <- err
}()
select {
case <-ctx.Done():
session.Signal(ssh.SIGKILL)
session.Close()
return <-waitCh
case err := <-waitCh:
return err
}
}