Browse code

Merge pull request #38871 from crosbymichael/exec-spec

Use original process spec for execs

Yong Tang authored on 2019/03/25 12:58:33
Showing 3 changed files
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"context"
5 5
 	"fmt"
6 6
 	"io"
7
+	"runtime"
7 8
 	"strings"
8 9
 	"time"
9 10
 
... ...
@@ -16,7 +17,7 @@ import (
16 16
 	"github.com/docker/docker/pkg/pools"
17 17
 	"github.com/docker/docker/pkg/signal"
18 18
 	"github.com/docker/docker/pkg/term"
19
-	specs "github.com/opencontainers/runtime-spec/specs-go"
19
+	"github.com/opencontainers/runtime-spec/specs-go"
20 20
 	"github.com/pkg/errors"
21 21
 	"github.com/sirupsen/logrus"
22 22
 )
... ...
@@ -217,12 +218,23 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
217 217
 		ec.StreamConfig.NewNopInputPipe()
218 218
 	}
219 219
 
220
-	p := &specs.Process{
221
-		Args:     append([]string{ec.Entrypoint}, ec.Args...),
222
-		Env:      ec.Env,
223
-		Terminal: ec.Tty,
224
-		Cwd:      ec.WorkingDir,
220
+	p := &specs.Process{}
221
+	if runtime.GOOS != "windows" {
222
+		container, err := d.containerdCli.LoadContainer(ctx, ec.ContainerID)
223
+		if err != nil {
224
+			return err
225
+		}
226
+		spec, err := container.Spec(ctx)
227
+		if err != nil {
228
+			return err
229
+		}
230
+		p = spec.Process
225 231
 	}
232
+	p.Args = append([]string{ec.Entrypoint}, ec.Args...)
233
+	p.Env = ec.Env
234
+	p.Cwd = ec.WorkingDir
235
+	p.Terminal = ec.Tty
236
+
226 237
 	if p.Cwd == "" {
227 238
 		p.Cwd = "/"
228 239
 	}
... ...
@@ -117,3 +117,18 @@ func TestExec(t *testing.T) {
117 117
 	assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory")
118 118
 	assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO")
119 119
 }
120
+
121
+func TestExecUser(t *testing.T) {
122
+	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
123
+	skip.If(t, testEnv.OSType == "windows", "FIXME. Probably needs to wait for container to be in running state.")
124
+	defer setupTest(t)()
125
+	ctx := context.Background()
126
+	client := testEnv.APIClient()
127
+
128
+	cID := container.Run(t, ctx, client, container.WithTty(true), container.WithUser("1:1"))
129
+
130
+	result, err := container.Exec(ctx, client, cID, []string{"id"})
131
+	assert.NilError(t, err)
132
+
133
+	assert.Assert(t, is.Contains(result.Stdout(), "uid=1(daemon) gid=1(daemon)"), "exec command not running as uid/gid 1")
134
+}
... ...
@@ -153,3 +153,10 @@ func WithRestartPolicy(policy string) func(c *TestContainerConfig) {
153 153
 		c.HostConfig.RestartPolicy.Name = policy
154 154
 	}
155 155
 }
156
+
157
+// WithUser sets the user
158
+func WithUser(user string) func(c *TestContainerConfig) {
159
+	return func(c *TestContainerConfig) {
160
+		c.Config.User = user
161
+	}
162
+}