diff --git a/builder/common/multistep_debug.go b/builder/common/multistep_debug.go index f0ac31029..2b5af804c 100644 --- a/builder/common/multistep_debug.go +++ b/builder/common/multistep_debug.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" + "log" "time" ) @@ -27,7 +28,12 @@ func MultistepDebugFn(ui packer.Ui) multistep.DebugPauseFn { result := make(chan string, 1) go func() { - result <- ui.Ask(message) + line, err := ui.Ask(message) + if err != nil { + log.Printf("Error asking for input: %s", err) + } + + result <- line }() for { diff --git a/packer/rpc/ui.go b/packer/rpc/ui.go index 5e7df0afe..6d69ca244 100644 --- a/packer/rpc/ui.go +++ b/packer/rpc/ui.go @@ -17,13 +17,9 @@ type UiServer struct { ui packer.Ui } -func (u *Ui) Ask(query string) string { - var result string - if err := u.client.Call("Ui.Ask", query, &result); err != nil { - panic(err) - } - - return result +func (u *Ui) Ask(query string) (result string, err error) { + err = u.client.Call("Ui.Ask", query, &result) + return } func (u *Ui) Error(message string) { @@ -44,9 +40,9 @@ func (u *Ui) Say(message string) { } } -func (u *UiServer) Ask(query string, reply *string) error { - *reply = u.ui.Ask(query) - return nil +func (u *UiServer) Ask(query string, reply *string) (err error) { + *reply, err = u.ui.Ask(query) + return } func (u *UiServer) Error(message *string, reply *interface{}) error { diff --git a/packer/rpc/ui_test.go b/packer/rpc/ui_test.go index f267bf512..78c203540 100644 --- a/packer/rpc/ui_test.go +++ b/packer/rpc/ui_test.go @@ -17,10 +17,10 @@ type testUi struct { sayMessage string } -func (u *testUi) Ask(query string) string { +func (u *testUi) Ask(query string) (string, error) { u.askCalled = true u.askQuery = query - return "foo" + return "foo", nil } func (u *testUi) Error(message string) { @@ -58,7 +58,8 @@ func TestUiRPC(t *testing.T) { uiClient := &Ui{client} // Basic error and say tests - result := uiClient.Ask("query") + result, err := uiClient.Ask("query") + assert.Nil(err, "should not error") assert.True(ui.askCalled, "ask should be called") assert.Equal(ui.askQuery, "query", "should be correct") assert.Equal(result, "foo", "should have correct result") diff --git a/packer/ui.go b/packer/ui.go index b8d5c11a9..5f4abcfc5 100644 --- a/packer/ui.go +++ b/packer/ui.go @@ -1,6 +1,7 @@ package packer import ( + "errors" "fmt" "io" "log" @@ -24,7 +25,7 @@ const ( // world. This sort of control allows us to strictly control how output // is formatted and various levels of output. type Ui interface { - Ask(string) string + Ask(string) (string, error) Say(string) Message(string) Error(string) @@ -53,7 +54,7 @@ type ReaderWriterUi struct { l sync.Mutex } -func (u *ColoredUi) Ask(query string) string { +func (u *ColoredUi) Ask(query string) (string, error) { return u.Ui.Ask(u.colorize(query, u.Color, true)) } @@ -83,7 +84,7 @@ func (u *ColoredUi) colorize(message string, color UiColor, bold bool) string { return fmt.Sprintf("\033[%d;%d;40m%s\033[0m", attr, color, message) } -func (u *PrefixedUi) Ask(query string) string { +func (u *PrefixedUi) Ask(query string) (string, error) { return u.Ui.Ask(fmt.Sprintf("%s: %s", u.SayPrefix, query)) } @@ -99,7 +100,7 @@ func (u *PrefixedUi) Error(message string) { u.Ui.Error(fmt.Sprintf("%s: %s", u.SayPrefix, message)) } -func (rw *ReaderWriterUi) Ask(query string) string { +func (rw *ReaderWriterUi) Ask(query string) (string, error) { rw.l.Lock() defer rw.l.Unlock() @@ -110,7 +111,7 @@ func (rw *ReaderWriterUi) Ask(query string) string { log.Printf("ui: ask: %s", query) if query != "" { if _, err := fmt.Fprint(rw.Writer, query+" "); err != nil { - panic(err) + return "", err } } @@ -124,18 +125,12 @@ func (rw *ReaderWriterUi) Ask(query string) string { result <- line }() - for { - select { - case line := <-result: - return line - case <-sigCh: - fmt.Fprint( - rw.Writer, - "\nInterrupts are blocked while waiting for input. Press enter.") - } + select { + case line := <-result: + return line, nil + case <-sigCh: + return "", errors.New("interrupted") } - - return "" } func (rw *ReaderWriterUi) Say(message string) {