diff --git a/command/agent/remote_exec.go b/command/agent/remote_exec.go index 64fec4599a..e5022df9e0 100644 --- a/command/agent/remote_exec.go +++ b/command/agent/remote_exec.go @@ -137,7 +137,7 @@ func (a *Agent) handleRemoteExec(msg *UserEvent) { // Ensure we write out an exit code exitCode := 0 - defer a.remoteExecWriteExitCode(&event, exitCode) + defer a.remoteExecWriteExitCode(&event, &exitCode) // Check if this is a script, we may need to spill to disk var script string @@ -190,7 +190,7 @@ func (a *Agent) handleRemoteExec(msg *UserEvent) { err := cmd.Wait() writer.Flush() close(writer.BufCh) - if err != nil { + if err == nil { exitCh <- 0 return } @@ -287,8 +287,8 @@ func (a *Agent) remoteExecWriteOutput(event *remoteExecEvent, num int, output [] } // remoteExecWriteExitCode is used to write an exit code -func (a *Agent) remoteExecWriteExitCode(event *remoteExecEvent, exitCode int) bool { - val := []byte(strconv.FormatInt(int64(exitCode), 10)) +func (a *Agent) remoteExecWriteExitCode(event *remoteExecEvent, exitCode *int) bool { + val := []byte(strconv.FormatInt(int64(*exitCode), 10)) if err := a.remoteExecWriteKey(event, remoteExecExitSuffix, val); err != nil { a.logger.Printf("[ERR] agent: failed to write exit code for remote exec job: %v", err) return false diff --git a/command/agent/remote_exec_test.go b/command/agent/remote_exec_test.go index d431b1f809..99722e6a02 100644 --- a/command/agent/remote_exec_test.go +++ b/command/agent/remote_exec_test.go @@ -140,7 +140,8 @@ func TestRemoteExecWrites(t *testing.T) { t.Fatalf("bad") } - if !agent.remoteExecWriteExitCode(event, 1) { + exitCode := 1 + if !agent.remoteExecWriteExitCode(event, &exitCode) { t.Fatalf("bad") } @@ -169,7 +170,9 @@ func TestRemoteExecWrites(t *testing.T) { } } -func TestHandleRemoteExec(t *testing.T) { + + +func testHandleRemoteExec(t *testing.T, command string, expectedSubstring string, expectedReturnCode string) { dir, agent := makeAgent(t, nextConfig()) defer os.RemoveAll(dir) defer agent.Shutdown() @@ -182,7 +185,7 @@ func TestHandleRemoteExec(t *testing.T) { defer destroySession(t, agent, event.Session) spec := &remoteExecSpec{ - Command: "uptime", + Command: command, Wait: time.Second, } buf, err := json.Marshal(spec) @@ -215,18 +218,26 @@ func TestHandleRemoteExec(t *testing.T) { key = "_rexec/" + event.Session + "/" + agent.config.NodeName + "/out/00000" d = getKV(t, agent, key) if d == nil || d.Session != event.Session || - !bytes.Contains(d.Value, []byte("load")) { + !bytes.Contains(d.Value, []byte(expectedSubstring)) { t.Fatalf("bad output: %#v", d) } // Verify we have an exit code key = "_rexec/" + event.Session + "/" + agent.config.NodeName + "/exit" d = getKV(t, agent, key) - if d == nil || d.Session != event.Session || string(d.Value) != "0" { + if d == nil || d.Session != event.Session || string(d.Value) != expectedReturnCode { t.Fatalf("bad output: %#v", d) } } +func TestHandleRemoteExec(t *testing.T) { + testHandleRemoteExec(t, "uptime", "load", "0") +} + +func TestHandleRemoteExecFailed(t *testing.T) { + testHandleRemoteExec(t, "echo failing;exit 2", "failing", "2") +} + func makeRexecSession(t *testing.T, agent *Agent) string { args := structs.SessionRequest{ Datacenter: agent.config.Datacenter,