Commit 9219a19f authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer/plugin: Better error handling around command exit cases

parent ff23b679
...@@ -2,6 +2,7 @@ package plugin ...@@ -2,6 +2,7 @@ package plugin
import ( import (
"bytes" "bytes"
"errors"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"net/rpc" "net/rpc"
"os/exec" "os/exec"
...@@ -24,17 +25,27 @@ func Command(cmd *exec.Cmd) (result packer.Command, err error) { ...@@ -24,17 +25,27 @@ func Command(cmd *exec.Cmd) (result packer.Command, err error) {
return return
} }
// TODO: timeout cmdExited := make(chan bool)
// TODO: check that command is even running go func() {
address := "" cmd.Wait()
for { cmdExited <- true
line, err := out.ReadBytes('\n') }()
if err == nil {
address = strings.TrimSpace(string(line)) var address string
break for done := false; !done; {
} select {
case <-cmdExited:
err = errors.New("plugin exited before we could connect")
return
case <-time.After(10 * time.Millisecond):
if line, err := out.ReadBytes('\n'); err == nil {
address = strings.TrimSpace(string(line))
done = true
}
time.Sleep(10 * time.Millisecond) // Make sure to reset err to nil
err = nil
}
} }
client, err := rpc.Dial("tcp", address) client, err := rpc.Dial("tcp", address)
......
...@@ -22,3 +22,10 @@ func TestCommand_Good(t *testing.T) { ...@@ -22,3 +22,10 @@ func TestCommand_Good(t *testing.T) {
result := command.Synopsis() result := command.Synopsis()
assert.Equal(result, "1", "should return result") assert.Equal(result, "1", "should return result")
} }
func TestCommand_CommandExited(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
_, err := Command(helperProcess("im-a-command-that-doesnt-work"))
assert.NotNil(err, "should have an error")
}
package plugin package plugin
import ( import (
"fmt"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"os" "os"
"os/exec" "os/exec"
"testing" "testing"
"time"
) )
type helperCommand byte type helperCommand byte
...@@ -38,5 +40,30 @@ func TestHelperProcess(*testing.T) { ...@@ -38,5 +40,30 @@ func TestHelperProcess(*testing.T) {
return return
} }
ServeCommand(new(helperCommand)) args := os.Args
for len(args) > 0 {
if args[0] == "--" {
args = args[1:]
break
}
args = args[1:]
}
if len(args) == 0 {
fmt.Fprintf(os.Stderr, "No command\n")
os.Exit(2)
}
cmd, args := args[0], args[1:]
switch cmd {
case "command":
ServeCommand(new(helperCommand))
case "start-timeout":
time.Sleep(1 * time.Minute)
os.Exit(1)
default:
fmt.Fprintf(os.Stderr, "Unknown command: %q\n", cmd)
os.Exit(2)
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment