Переглянути джерело

Use original process spec for execs

Fixes #38865

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
(cherry picked from commit 7603c22c7365d7d7150597fe396e0707d6e561da)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Michael Crosby 6 роки тому
батько
коміт
3d3d757071

+ 18 - 6
daemon/exec.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
+	"runtime"
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
@@ -16,7 +17,7 @@ import (
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
-	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
@@ -217,12 +218,23 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
 		ec.StreamConfig.NewNopInputPipe()
 		ec.StreamConfig.NewNopInputPipe()
 	}
 	}
 
 
-	p := &specs.Process{
-		Args:     append([]string{ec.Entrypoint}, ec.Args...),
-		Env:      ec.Env,
-		Terminal: ec.Tty,
-		Cwd:      ec.WorkingDir,
+	p := &specs.Process{}
+	if runtime.GOOS != "windows" {
+		container, err := d.containerdCli.LoadContainer(ctx, ec.ContainerID)
+		if err != nil {
+			return err
+		}
+		spec, err := container.Spec(ctx)
+		if err != nil {
+			return err
+		}
+		p = spec.Process
 	}
 	}
+	p.Args = append([]string{ec.Entrypoint}, ec.Args...)
+	p.Env = ec.Env
+	p.Cwd = ec.WorkingDir
+	p.Terminal = ec.Tty
+
 	if p.Cwd == "" {
 	if p.Cwd == "" {
 		p.Cwd = "/"
 		p.Cwd = "/"
 	}
 	}

+ 15 - 0
integration/container/exec_test.go

@@ -118,3 +118,18 @@ func TestExec(t *testing.T) {
 	assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory")
 	assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory")
 	assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
 	assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
 }
 }
+
+func TestExecUser(t *testing.T) {
+	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
+	skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
+	defer setupTest(t)()
+	ctx := context.Background()
+	client := testEnv.APIClient()
+
+	cID := container.Run(t, ctx, client, container.WithTty(true), container.WithUser("1:1"))
+
+	result, err := container.Exec(ctx, client, cID, []string{"id"})
+	assert.NilError(t, err)
+
+	assert.Assert(t, is.Contains(result.Stdout(), "uid=1(daemon) gid=1(daemon)"), "exec command not running as uid/gid 1")
+}

+ 7 - 0
integration/internal/container/ops.go

@@ -134,3 +134,10 @@ func WithAutoRemove(c *TestContainerConfig) {
 	}
 	}
 	c.HostConfig.AutoRemove = true
 	c.HostConfig.AutoRemove = true
 }
 }
+
+// WithUser sets the user
+func WithUser(user string) func(c *TestContainerConfig) {
+	return func(c *TestContainerConfig) {
+		c.Config.User = user
+	}
+}