diff --git a/frontend/gateway/forwarder/forward.go b/frontend/gateway/forwarder/forward.go index 4b8fa2612744..9294fed7699b 100644 --- a/frontend/gateway/forwarder/forward.go +++ b/frontend/gateway/forwarder/forward.go @@ -264,6 +264,7 @@ func (c *BridgeClient) NewContainer(ctx context.Context, req client.NewContainer NetMode: req.NetMode, Hostname: req.Hostname, Mounts: make([]container.Mount, len(req.Mounts)), + Platform: req.Platform, } eg, ctx := errgroup.WithContext(ctx) diff --git a/frontend/gateway/forwarder/forward_test.go b/frontend/gateway/forwarder/forward_test.go new file mode 100644 index 000000000000..d8e27cfe015b --- /dev/null +++ b/frontend/gateway/forwarder/forward_test.go @@ -0,0 +1,64 @@ +package forwarder + +import ( + "context" + "runtime" + "testing" + + "github.com/moby/buildkit/cache" + buildkitclient "github.com/moby/buildkit/client" + "github.com/moby/buildkit/executor" + resourcestypes "github.com/moby/buildkit/executor/resources/types" + gwclient "github.com/moby/buildkit/frontend/gateway/client" + "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/util/system" + "github.com/stretchr/testify/require" +) + +func TestNewContainerPreservesPlatform(t *testing.T) { + exec := &recordingExecutor{process: make(chan executor.ProcessInfo, 1)} + c := &BridgeClient{ + workers: emptyWorkerInfos{}, + executor: exec, + } + targetOS := "windows" + if runtime.GOOS == targetOS { + targetOS = "linux" + } + ctx := t.Context() + + ctr, err := c.NewContainer(ctx, gwclient.NewContainerRequest{ + Platform: &pb.Platform{OS: targetOS, Architecture: "amd64"}, + }) + require.NoError(t, err) + + proc, err := ctr.Start(ctx, gwclient.StartRequest{}) + require.NoError(t, err) + require.Contains(t, (<-exec.process).Meta.Env, "PATH="+system.DefaultPathEnv(targetOS)) + require.NoError(t, proc.Wait()) + require.NoError(t, ctr.Release(ctx)) +} + +type emptyWorkerInfos struct{} + +func (emptyWorkerInfos) DefaultCacheManager() (cache.Manager, error) { + return nil, nil +} + +func (emptyWorkerInfos) WorkerInfos() []buildkitclient.WorkerInfo { + return nil +} + +type recordingExecutor struct { + process chan executor.ProcessInfo +} + +func (e *recordingExecutor) Run(_ context.Context, _ string, _ executor.Mount, _ []executor.Mount, process executor.ProcessInfo, started chan<- struct{}) (resourcestypes.Recorder, error) { + e.process <- process + close(started) + return nil, nil +} + +func (e *recordingExecutor) Exec(context.Context, string, executor.ProcessInfo) error { + return nil +}