Skip to content

Commit

Permalink
Bubble up errors, disable TTY for upload
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVitek committed Jul 18, 2016
1 parent eddc347 commit d32fd08
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 29 deletions.
2 changes: 1 addition & 1 deletion cmd/sup/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"errors"
"flag"
"fmt"
"os"
Expand All @@ -10,6 +9,7 @@ import (
"text/tabwriter"
"time"

"github.com/pkg/errors"
"github.com/pressly/sup"
)

Expand Down
20 changes: 11 additions & 9 deletions ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,17 @@ func (c *SSHClient) Run(task *Task) error {
return err
}

// Set up terminal modes
modes := ssh.TerminalModes{
ssh.ECHO: 0, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := sess.RequestPty("xterm", 80, 40, modes); err != nil {
return ErrTask{task, fmt.Sprintf("request for pseudo terminal failed: %s", err)}
if task.TTY {
// Set up terminal modes
modes := ssh.TerminalModes{
ssh.ECHO: 0, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := sess.RequestPty("xterm", 80, 40, modes); err != nil {
return ErrTask{task, fmt.Sprintf("request for pseudo terminal failed: %s", err)}
}
}

// Start the remote command.
Expand Down
28 changes: 14 additions & 14 deletions sup.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package sup

import (
"errors"
"fmt"
"io"
"os"
Expand All @@ -10,6 +9,7 @@ import (
"sync"

"github.com/goware/prefixer"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
)

Expand Down Expand Up @@ -45,7 +45,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
if network.Bastion != "" {
bastion = &SSHClient{}
if err := bastion.Connect(network.Bastion); err != nil {
return err
return errors.Wrap(err, "connecting to bastion failed")
}
}

Expand All @@ -64,7 +64,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
env: env + `export SUP_HOST="` + host + `";`,
}
if err := local.Connect(host); err != nil {
errCh <- err
errCh <- errors.Wrap(err, "connecting to localhost failed")
return
}
clientCh <- local
Expand All @@ -79,12 +79,12 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {

if bastion != nil {
if err := remote.ConnectWith(host, bastion.DialThrough); err != nil {
errCh <- err
errCh <- errors.Wrap(err, "connecting to remote host through bastion failed")
return
}
} else {
if err := remote.Connect(host); err != nil {
errCh <- err
errCh <- errors.Wrap(err, "connecting to remote host failed")
return
}
}
Expand All @@ -108,15 +108,15 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
clients = append(clients, client)
}
for err := range errCh {
return err
return errors.Wrap(err, "connecting to clients failed")
}

// Run command or run multiple commands defined by target sequentially.
for _, cmd := range commands {
// Translate command into task(s).
tasks, err := CreateTasks(cmd, clients, env)
if err != nil {
return fmt.Errorf("CreateTasks(): %s", err)
return errors.Wrap(err, "creating task failed")
}

// Run tasks sequentially.
Expand All @@ -133,7 +133,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {

err := c.Run(task)
if err != nil {
return fmt.Errorf("%s%v", prefix, err)
return errors.Wrap(err, prefix+"task failed")
}

// Copy over tasks's STDOUT.
Expand All @@ -144,7 +144,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
if err != nil && err != io.EOF {
// TODO: io.Copy() should not return io.EOF at all.
// Upstream bug? Or prefixer.WriteTo() bug?
fmt.Fprintf(os.Stderr, "%sSTDOUT: %v", prefix, err)
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, prefix+"reading STDOUT failed"))
}
}(c)

Expand All @@ -154,7 +154,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
defer wg.Done()
_, err := io.Copy(os.Stderr, prefixer.New(c.Stderr(), prefix))
if err != nil && err != io.EOF {
fmt.Fprintf(os.Stderr, "%sSTDERR: %v", prefix, err)
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, prefix+"reading STDERR failed"))
}
}(c)

Expand All @@ -167,7 +167,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
writer := io.MultiWriter(writers...)
_, err := io.Copy(writer, task.Input)
if err != nil && err != io.EOF {
fmt.Fprintf(os.Stderr, "STDIN: %v", err)
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, "copying STDIN failed"))
}
// TODO: Use MultiWriteCloser (not in Stdlib), so we can writer.Close() instead?
for _, c := range clients {
Expand All @@ -189,7 +189,7 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
for _, c := range task.Clients {
err := c.Signal(sig)
if err != nil {
fmt.Printf("sending signal failed: %v", err)
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, "sending signal failed"))
}
}
}
Expand All @@ -211,10 +211,10 @@ func (sup *Stackup) Run(network *Network, commands ...*Command) error {
}
if e, ok := err.(*ssh.ExitError); ok && e.ExitStatus() != 15 {
// TODO: Store all the errors, and print them after Wait().
fmt.Fprintf(os.Stderr, "%sexit %v\n", prefix, e.ExitStatus())
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(e, prefix))
os.Exit(e.ExitStatus())
}
fmt.Fprintf(os.Stderr, "%s%v\n", prefix, err)
fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, prefix))
os.Exit(1)
}
}(c)
Expand Down
4 changes: 2 additions & 2 deletions tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ func NewTarStreamReader(cwd, path, exclude string) (io.Reader, error) {
cmd.Dir = cwd
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, errors.Wrap(err, "creating stdout pipe failed")
return nil, errors.Wrap(err, "tar: stdout pipe failed")
}

if err := cmd.Start(); err != nil {
return nil, errors.Wrap(err, "starting cmd failed")
return nil, errors.Wrap(err, "tar: starting cmd failed")
}

return stdout, nil
Expand Down
27 changes: 24 additions & 3 deletions task.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,41 @@ import (
"io"
"io/ioutil"
"os"

"github.com/pkg/errors"
)

// Task represents a set of commands to be run.
type Task struct {
Run string
Input io.Reader
Clients []Client
TTY bool
}

func CreateTasks(cmd *Command, clients []Client, env string) ([]*Task, error) {
var tasks []*Task

cwd, err := os.Getwd()
if err != nil {
return nil, errors.Wrap(err, "resolving CWD failed")
}

// Anything to upload?
for _, upload := range cmd.Upload {
uploadFile, err := ResolveLocalPath(cwd, upload.Src, env)
if err != nil {
return nil, errors.Wrap(err, "upload: "+upload.Src)
}
uploadTarReader, err := NewTarStreamReader(cwd, uploadFile, upload.Exc)
if err != nil {
return nil, errors.Wrap(err, "upload: "+upload.Src)
}

task := Task{
Run: RemoteTarCommand(upload.Dst),
Input: NewTarStreamReader(upload.Src, upload.Exc, env),
Input: uploadTarReader,
TTY: false,
}

if cmd.Once {
Expand All @@ -48,15 +66,16 @@ func CreateTasks(cmd *Command, clients []Client, env string) ([]*Task, error) {
if cmd.Script != "" {
f, err := os.Open(cmd.Script)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "can't open script")
}
data, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "can't read script")
}

task := Task{
Run: string(data),
TTY: true,
}
if cmd.Stdin {
task.Input = os.Stdin
Expand Down Expand Up @@ -90,6 +109,7 @@ func CreateTasks(cmd *Command, clients []Client, env string) ([]*Task, error) {
task := &Task{
Run: cmd.Local,
Clients: []Client{local},
TTY: true,
}
if cmd.Stdin {
task.Input = os.Stdin
Expand All @@ -101,6 +121,7 @@ func CreateTasks(cmd *Command, clients []Client, env string) ([]*Task, error) {
if cmd.Run != "" {
task := Task{
Run: cmd.Run,
TTY: true,
}
if cmd.Stdin {
task.Input = os.Stdin
Expand Down

0 comments on commit d32fd08

Please sign in to comment.