diff --git a/mock_ssh_test.go b/mock_ssh_test.go index 5cadc15..a8e9f78 100644 --- a/mock_ssh_test.go +++ b/mock_ssh_test.go @@ -626,14 +626,22 @@ func moduleCopyWithClient(e *Executor, client sshFileRunner, args map[string]any return nil, mockError("moduleCopyWithClient", "copy: dest required") } force := getBoolArg(args, "force", true) + remoteSrc := getBoolArg(args, "remote_src", false) var content []byte var err error if src := getStringArg(args, "src", ""); src != "" { - content, err = readTestFile(src) - if err != nil { - return nil, mockWrap("moduleCopyWithClient", "read src", err) + if remoteSrc { + content, err = client.Download(context.Background(), src) + if err != nil { + return nil, mockWrap("moduleCopyWithClient", "download src", err) + } + } else { + content, err = readTestFile(src) + if err != nil { + return nil, mockWrap("moduleCopyWithClient", "read src", err) + } } } else if c := getStringArg(args, "content", ""); c != "" { content = []byte(c) diff --git a/modules.go b/modules.go index d18a287..7a4c1ab 100644 --- a/modules.go +++ b/modules.go @@ -434,15 +434,25 @@ func (e *Executor) moduleCopy(ctx context.Context, client sshExecutorClient, arg return nil, coreerr.E("Executor.moduleCopy", "dest required", nil) } force := getBoolArg(args, "force", true) + remoteSrc := getBoolArg(args, "remote_src", false) var content string var err error if src := getStringArg(args, "src", ""); src != "" { - src = e.resolveLocalPath(src) - content, err = coreio.Local.Read(src) - if err != nil { - return nil, coreerr.E("Executor.moduleCopy", "read src", err) + if remoteSrc { + var data []byte + data, err = client.Download(ctx, src) + if err != nil { + return nil, coreerr.E("Executor.moduleCopy", "download src", err) + } + content = string(data) + } else { + src = e.resolveLocalPath(src) + content, err = coreio.Local.Read(src) + if err != nil { + return nil, coreerr.E("Executor.moduleCopy", "read src", err) + } } } else if c := getStringArg(args, "content", ""); c != "" { content = c diff --git a/modules_file_test.go b/modules_file_test.go index ab47d94..8489d6e 100644 --- a/modules_file_test.go +++ b/modules_file_test.go @@ -57,6 +57,25 @@ func TestModulesFile_ModuleCopy_Good_SrcFile(t *testing.T) { assert.Equal(t, []byte("worker_processes auto;"), up.Content) } +func TestModulesFile_ModuleCopy_Good_RemoteSrc(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + mock.addFile("/tmp/remote-source.txt", []byte("remote payload")) + + result, err := e.moduleCopy(context.Background(), mock, map[string]any{ + "src": "/tmp/remote-source.txt", + "dest": "/etc/app/remote.txt", + "remote_src": true, + }, "host1", &Task{}) + + require.NoError(t, err) + assert.True(t, result.Changed) + + up := mock.lastUpload() + require.NotNil(t, up) + assert.Equal(t, "/etc/app/remote.txt", up.Remote) + assert.Equal(t, []byte("remote payload"), up.Content) +} + func TestModulesFile_ModuleCopy_Good_OwnerGroup(t *testing.T) { e, mock := newTestExecutorWithMock("host1")