Add shell executable support
This commit is contained in:
parent
4ccb8fc93b
commit
b75ba32cc2
2 changed files with 62 additions and 2 deletions
19
modules.go
19
modules.go
|
|
@ -318,7 +318,7 @@ func (e *Executor) moduleShell(ctx context.Context, client sshExecutorClient, ar
|
||||||
cmd = prefixCommandStdin(cmd, stdin, getBoolArg(args, "stdin_add_newline", true))
|
cmd = prefixCommandStdin(cmd, stdin, getBoolArg(args, "stdin_add_newline", true))
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, stderr, rc, err := client.RunScript(ctx, cmd)
|
stdout, stderr, rc, err := runShellScriptCommand(ctx, client, cmd, getStringArg(args, "executable", ""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &TaskResult{Failed: true, Msg: err.Error(), Stdout: stdout, Stderr: stderr, RC: rc}, nil
|
return &TaskResult{Failed: true, Msg: err.Error(), Stdout: stdout, Stderr: stderr, RC: rc}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +508,7 @@ func (e *Executor) moduleScript(ctx context.Context, client sshExecutorClient, a
|
||||||
data = sprintf("cd %q && %s", chdir, data)
|
data = sprintf("cd %q && %s", chdir, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, stderr, rc, err := client.RunScript(ctx, data)
|
stdout, stderr, rc, err := runShellScriptCommand(ctx, client, data, getStringArg(args, "executable", ""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &TaskResult{Failed: true, Msg: err.Error()}, nil
|
return &TaskResult{Failed: true, Msg: err.Error()}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -522,6 +522,21 @@ func (e *Executor) moduleScript(ctx context.Context, client sshExecutorClient, a
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runShellScriptCommand executes a shell script using either the default
|
||||||
|
// heredoc path or a caller-specified executable.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// stdout, stderr, rc, err := runShellScriptCommand(ctx, client, "echo hi", "/bin/dash")
|
||||||
|
func runShellScriptCommand(ctx context.Context, client sshExecutorClient, script, executable string) (stdout, stderr string, exitCode int, err error) {
|
||||||
|
if executable == "" {
|
||||||
|
return client.RunScript(ctx, script)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := sprintf("%s -c %s", shellSingleQuote(executable), shellSingleQuote(script))
|
||||||
|
return client.Run(ctx, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
// --- File Modules ---
|
// --- File Modules ---
|
||||||
|
|
||||||
func (e *Executor) moduleCopy(ctx context.Context, client sshExecutorClient, args map[string]any, host string, task *Task) (*TaskResult, error) {
|
func (e *Executor) moduleCopy(ctx context.Context, client sshExecutorClient, args map[string]any, host string, task *Task) (*TaskResult, error) {
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,26 @@ func TestModulesCmd_ModuleShell_Good_WithChdir(t *testing.T) {
|
||||||
assert.Contains(t, last.Cmd, "npm install")
|
assert.Contains(t, last.Cmd, "npm install")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModulesCmd_ModuleShell_Good_ExecutableUsesRun(t *testing.T) {
|
||||||
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
|
mock.expectCommand(`/bin/dash.*echo test`, "test\n", "", 0)
|
||||||
|
|
||||||
|
result, err := e.moduleShell(context.Background(), mock, map[string]any{
|
||||||
|
"_raw_params": "echo test",
|
||||||
|
"executable": "/bin/dash",
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Changed)
|
||||||
|
|
||||||
|
last := mock.lastCommand()
|
||||||
|
require.NotNil(t, last)
|
||||||
|
assert.Equal(t, "Run", last.Method)
|
||||||
|
assert.Contains(t, last.Cmd, "/bin/dash")
|
||||||
|
assert.Contains(t, last.Cmd, "-c")
|
||||||
|
assert.Contains(t, last.Cmd, "echo test")
|
||||||
|
}
|
||||||
|
|
||||||
func TestModulesCmd_ModuleShell_Bad_NoCommand(t *testing.T) {
|
func TestModulesCmd_ModuleShell_Bad_NoCommand(t *testing.T) {
|
||||||
e, _ := newTestExecutorWithMock("host1")
|
e, _ := newTestExecutorWithMock("host1")
|
||||||
mock := NewMockSSHClient()
|
mock := NewMockSSHClient()
|
||||||
|
|
@ -642,6 +662,31 @@ func TestModulesCmd_ModuleScript_Good_ChdirPrefixesScript(t *testing.T) {
|
||||||
assert.Equal(t, `cd "/opt/app" && pwd`, last.Cmd)
|
assert.Equal(t, `cd "/opt/app" && pwd`, last.Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModulesCmd_ModuleScript_Good_ExecutableUsesRun(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
scriptPath := joinPath(tmpDir, "dash.sh")
|
||||||
|
require.NoError(t, writeTestFile(scriptPath, []byte("echo script works"), 0755))
|
||||||
|
|
||||||
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
|
mock.expectCommand(`/bin/dash.*echo script works`, "script works\n", "", 0)
|
||||||
|
|
||||||
|
result, err := e.moduleScript(context.Background(), mock, map[string]any{
|
||||||
|
"_raw_params": scriptPath,
|
||||||
|
"executable": "/bin/dash",
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, result)
|
||||||
|
assert.True(t, result.Changed)
|
||||||
|
|
||||||
|
last := mock.lastCommand()
|
||||||
|
require.NotNil(t, last)
|
||||||
|
assert.Equal(t, "Run", last.Method)
|
||||||
|
assert.Contains(t, last.Cmd, "/bin/dash")
|
||||||
|
assert.Contains(t, last.Cmd, "-c")
|
||||||
|
assert.Contains(t, last.Cmd, "echo script works")
|
||||||
|
}
|
||||||
|
|
||||||
func TestModulesCmd_ModuleScript_Bad_NoScript(t *testing.T) {
|
func TestModulesCmd_ModuleScript_Bad_NoScript(t *testing.T) {
|
||||||
e, _ := newTestExecutorWithMock("host1")
|
e, _ := newTestExecutorWithMock("host1")
|
||||||
mock := NewMockSSHClient()
|
mock := NewMockSSHClient()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue