The building machinery was being handed an uninitialized container
Config. This changes it to use the target container's Config.
Resolves #30538
Signed-off-by: Anthony Sottile <asottile@umich.edu>
... | ... |
@@ -13,7 +13,6 @@ import ( |
13 | 13 |
"github.com/docker/docker/api/server/httputils" |
14 | 14 |
"github.com/docker/docker/api/types" |
15 | 15 |
"github.com/docker/docker/api/types/backend" |
16 |
- "github.com/docker/docker/api/types/container" |
|
17 | 16 |
"github.com/docker/docker/api/types/filters" |
18 | 17 |
"github.com/docker/docker/api/types/versions" |
19 | 18 |
"github.com/docker/docker/pkg/ioutils" |
... | ... |
@@ -46,9 +45,6 @@ func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r * |
46 | 46 |
if err != nil && err != io.EOF { //Do not fail if body is empty. |
47 | 47 |
return err |
48 | 48 |
} |
49 |
- if c == nil { |
|
50 |
- c = &container.Config{} |
|
51 |
- } |
|
52 | 49 |
|
53 | 50 |
commitCfg := &backend.ContainerCommitConfig{ |
54 | 51 |
ContainerCommitConfig: types.ContainerCommitConfig{ |
... | ... |
@@ -396,7 +396,8 @@ func BuildFromConfig(config *container.Config, changes []string) (*container.Con |
396 | 396 |
} |
397 | 397 |
|
398 | 398 |
dispatchRequest := newDispatchRequest(b, dockerfile.EscapeToken, nil, newBuildArgs(b.options.BuildArgs), newStagesBuildResults()) |
399 |
- dispatchRequest.state.runConfig = config |
|
399 |
+ // We make mutations to the configuration, ensure we have a copy |
|
400 |
+ dispatchRequest.state.runConfig = copyRunConfig(config) |
|
400 | 401 |
dispatchRequest.state.imageID = config.Image |
401 | 402 |
for _, cmd := range commands { |
402 | 403 |
err := dispatch(dispatchRequest, cmd) |
... | ... |
@@ -149,6 +149,10 @@ func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (str |
149 | 149 |
defer daemon.containerUnpause(container) |
150 | 150 |
} |
151 | 151 |
|
152 |
+ if c.MergeConfigs && c.Config == nil { |
|
153 |
+ c.Config = container.Config |
|
154 |
+ } |
|
155 |
+ |
|
152 | 156 |
newConfig, err := dockerfile.BuildFromConfig(c.Config, c.Changes) |
153 | 157 |
if err != nil { |
154 | 158 |
return "", err |
... | ... |
@@ -121,11 +121,19 @@ func (s *DockerSuite) TestCommitChange(c *check.C) { |
121 | 121 |
"test", "test-commit") |
122 | 122 |
imageID = strings.TrimSpace(imageID) |
123 | 123 |
|
124 |
+ // The ordering here is due to `PATH` being overridden from the container's |
|
125 |
+ // ENV. On windows, the container doesn't have a `PATH` ENV variable so |
|
126 |
+ // the ordering is the same as the cli. |
|
127 |
+ expectedEnv := "[PATH=/foo DEBUG=true test=1]" |
|
128 |
+ if testEnv.DaemonPlatform() == "windows" { |
|
129 |
+ expectedEnv = "[DEBUG=true test=1 PATH=/foo]" |
|
130 |
+ } |
|
131 |
+ |
|
124 | 132 |
prefix, slash := getPrefixAndSlashFromDaemonPlatform() |
125 | 133 |
prefix = strings.ToUpper(prefix) // Force C: as that's how WORKDIR is normalized on Windows |
126 | 134 |
expected := map[string]string{ |
127 | 135 |
"Config.ExposedPorts": "map[8080/tcp:{}]", |
128 |
- "Config.Env": "[DEBUG=true test=1 PATH=/foo]", |
|
136 |
+ "Config.Env": expectedEnv, |
|
129 | 137 |
"Config.Labels": "map[foo:bar]", |
130 | 138 |
"Config.Cmd": "[/bin/sh]", |
131 | 139 |
"Config.WorkingDir": prefix + slash + "opt", |
132 | 140 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,47 @@ |
0 |
+package image |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "context" |
|
4 |
+ "testing" |
|
5 |
+ |
|
6 |
+ "github.com/docker/docker/api/types" |
|
7 |
+ "github.com/docker/docker/api/types/container" |
|
8 |
+ "github.com/docker/docker/integration/util/request" |
|
9 |
+ "github.com/stretchr/testify/assert" |
|
10 |
+ "github.com/stretchr/testify/require" |
|
11 |
+) |
|
12 |
+ |
|
13 |
+func TestCommitInheritsEnv(t *testing.T) { |
|
14 |
+ defer setupTest(t)() |
|
15 |
+ client := request.NewAPIClient(t) |
|
16 |
+ ctx := context.Background() |
|
17 |
+ |
|
18 |
+ createResp1, err := client.ContainerCreate(ctx, &container.Config{Image: "busybox"}, nil, nil, "") |
|
19 |
+ require.NoError(t, err) |
|
20 |
+ |
|
21 |
+ commitResp1, err := client.ContainerCommit(ctx, createResp1.ID, types.ContainerCommitOptions{ |
|
22 |
+ Changes: []string{"ENV PATH=/bin"}, |
|
23 |
+ Reference: "test-commit-image", |
|
24 |
+ }) |
|
25 |
+ require.NoError(t, err) |
|
26 |
+ |
|
27 |
+ image1, _, err := client.ImageInspectWithRaw(ctx, commitResp1.ID) |
|
28 |
+ require.NoError(t, err) |
|
29 |
+ |
|
30 |
+ expectedEnv1 := []string{"PATH=/bin"} |
|
31 |
+ assert.Equal(t, expectedEnv1, image1.Config.Env) |
|
32 |
+ |
|
33 |
+ createResp2, err := client.ContainerCreate(ctx, &container.Config{Image: image1.ID}, nil, nil, "") |
|
34 |
+ require.NoError(t, err) |
|
35 |
+ |
|
36 |
+ commitResp2, err := client.ContainerCommit(ctx, createResp2.ID, types.ContainerCommitOptions{ |
|
37 |
+ Changes: []string{"ENV PATH=/usr/bin:$PATH"}, |
|
38 |
+ Reference: "test-commit-image", |
|
39 |
+ }) |
|
40 |
+ require.NoError(t, err) |
|
41 |
+ |
|
42 |
+ image2, _, err := client.ImageInspectWithRaw(ctx, commitResp2.ID) |
|
43 |
+ require.NoError(t, err) |
|
44 |
+ expectedEnv2 := []string{"PATH=/usr/bin:/bin"} |
|
45 |
+ assert.Equal(t, expectedEnv2, image2.Config.Env) |
|
46 |
+} |