Skip to content

Commit

Permalink
pass correct working directory to RunPlugin (#17763)
Browse files Browse the repository at this point in the history
RunPlugin expects the working directory of the program to be passed in
in the plugin request. This was the case until
#15191. In that PR we switched from
passing pwd (which is the same as `ctx.Pwd` a layer above) to
minfo.GetProgramDirectory(), which is the path from which the plugin is
executed. Fix this by passing in `info.WorkingDirectory`, which a layer
above is `ctx.Pwd`.

Add a test for this as well to make sure we're not regressing this
again.

Likely nobody noticed this, because most plugins probably don't rely on
this path, and most providers are not being run using `RunPlugin`.
  • Loading branch information
tgummerer authored Nov 14, 2024
1 parent 04c4912 commit 9a50879
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
changes:
- type: fix
scope: engine
description: Pass correct working directory to RunPlugin
2 changes: 1 addition & 1 deletion sdk/go/common/resource/plugin/langruntime_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ func (h *langhost) RunPlugin(info RunPluginInfo) (io.Reader, io.Reader, context.
ctx, kill := context.WithCancel(h.ctx.Request())

resp, err := h.client.RunPlugin(ctx, &pulumirpc.RunPluginRequest{
Pwd: minfo.GetProgramDirectory(),
Pwd: info.WorkingDirectory,
Args: info.Args,
Env: info.Env,
Info: minfo,
Expand Down
113 changes: 113 additions & 0 deletions sdk/go/common/resource/plugin/langruntime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@
package plugin

import (
"context"
"errors"
"testing"

pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
"github.com/stretchr/testify/require"

"google.golang.org/protobuf/types/known/emptypb"

grpc "google.golang.org/grpc"
)

func TestMakeExecutablePromptChoices(t *testing.T) {
Expand All @@ -42,3 +49,109 @@ func TestMakeExecutablePromptChoices(t *testing.T) {
require.Equal(t, choices[3].StringValue, "aaa_does_not_exist")
require.Equal(t, choices[3].DisplayName, "aaa_does_not_exist [not found]")
}

type MockLanguageRuntimeClient struct {
RunPluginF (func(ctx context.Context, info *pulumirpc.RunPluginRequest,
) (pulumirpc.LanguageRuntime_RunPluginClient, error))
}

func (m *MockLanguageRuntimeClient) RunPlugin(
ctx context.Context, info *pulumirpc.RunPluginRequest, _ ...grpc.CallOption,
) (pulumirpc.LanguageRuntime_RunPluginClient, error) {
return m.RunPluginF(ctx, info)
}

func (m *MockLanguageRuntimeClient) GetRequiredPlugins(
ctx context.Context, in *pulumirpc.GetRequiredPluginsRequest, opts ...grpc.CallOption,
) (*pulumirpc.GetRequiredPluginsResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) Run(
ctx context.Context, in *pulumirpc.RunRequest, opts ...grpc.CallOption,
) (*pulumirpc.RunResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) GetPluginInfo(
ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption,
) (*pulumirpc.PluginInfo, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) InstallDependencies(
ctx context.Context, in *pulumirpc.InstallDependenciesRequest, opts ...grpc.CallOption,
) (pulumirpc.LanguageRuntime_InstallDependenciesClient, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) RuntimeOptionsPrompts(
ctx context.Context, in *pulumirpc.RuntimeOptionsRequest, opts ...grpc.CallOption,
) (*pulumirpc.RuntimeOptionsResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) About(
ctx context.Context, in *pulumirpc.AboutRequest, opts ...grpc.CallOption,
) (*pulumirpc.AboutResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) GetProgramDependencies(
ctx context.Context, in *pulumirpc.GetProgramDependenciesRequest, opts ...grpc.CallOption,
) (*pulumirpc.GetProgramDependenciesResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) GenerateProgram(
ctx context.Context, in *pulumirpc.GenerateProgramRequest, opts ...grpc.CallOption,
) (*pulumirpc.GenerateProgramResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) GenerateProject(
ctx context.Context, in *pulumirpc.GenerateProjectRequest, opts ...grpc.CallOption,
) (*pulumirpc.GenerateProjectResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) GeneratePackage(
ctx context.Context, in *pulumirpc.GeneratePackageRequest, opts ...grpc.CallOption,
) (*pulumirpc.GeneratePackageResponse, error) {
panic("not implemented")
}

func (m *MockLanguageRuntimeClient) Pack(
ctx context.Context, in *pulumirpc.PackRequest, opts ...grpc.CallOption,
) (*pulumirpc.PackResponse, error) {
panic("not implemented")
}

func TestRunPluginPassesCorrectPwd(t *testing.T) {
t.Parallel()

returnErr := errors.New("erroring so we don't need to implement the whole thing")
mockLanguageRuntime := &MockLanguageRuntimeClient{
RunPluginF: func(
ctx context.Context, info *pulumirpc.RunPluginRequest,
) (pulumirpc.LanguageRuntime_RunPluginClient, error) {
require.Equal(t, "/tmp", info.Pwd)
return nil, returnErr
},
}

pCtx, err := NewContext(nil, nil, nil, nil, "", nil, false, nil)
require.NoError(t, err)
host := &langhost{
ctx: pCtx,
runtime: "go",
plug: nil,
client: mockLanguageRuntime,
}

// Test that the plugin is run with the correct working directory.
_, _, _, err = host.RunPlugin(RunPluginInfo{
WorkingDirectory: "/tmp",
})
require.Equal(t, returnErr, err)
}

0 comments on commit 9a50879

Please sign in to comment.