From bc088692497a1589afd5421b2db40b9825112100 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 15 Feb 2018 18:00:39 -0800 Subject: [PATCH 1/2] builder: fix wrong cache hits building from tars Signed-off-by: Tonis Tiigi Upstream-commit: f6c8266afddcf24a2eb629af3b8e924e9c78ce73 Component: engine --- .../engine/integration/build/build_test.go | 69 +++++++++++++++++++ components/engine/pkg/tarsum/tarsum.go | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index 2a87204113..3f7b1dcf34 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -244,6 +244,75 @@ RUN cat somefile` assert.Contains(t, image.Config.Env, "bar=baz") } +// #35403 #36122 +func TestBuildUncleanTarFilenames(t *testing.T) { + ctx := context.TODO() + defer setupTest(t)() + + dockerfile := `FROM scratch +COPY foo / +FROM scratch +COPY bar /` + + buf := bytes.NewBuffer(nil) + w := tar.NewWriter(buf) + writeTarRecord(t, w, "Dockerfile", dockerfile) + writeTarRecord(t, w, "../foo", "foocontents0") + writeTarRecord(t, w, "/bar", "barcontents0") + err := w.Close() + require.NoError(t, err) + + apiclient := testEnv.APIClient() + resp, err := apiclient.ImageBuild(ctx, + buf, + types.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) + + out := bytes.NewBuffer(nil) + require.NoError(t, err) + _, err = io.Copy(out, resp.Body) + resp.Body.Close() + require.NoError(t, err) + + // repeat with changed data should not cause cache hits + + buf = bytes.NewBuffer(nil) + w = tar.NewWriter(buf) + writeTarRecord(t, w, "Dockerfile", dockerfile) + writeTarRecord(t, w, "../foo", "foocontents1") + writeTarRecord(t, w, "/bar", "barcontents1") + err = w.Close() + require.NoError(t, err) + + resp, err = apiclient.ImageBuild(ctx, + buf, + types.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) + + out = bytes.NewBuffer(nil) + require.NoError(t, err) + _, err = io.Copy(out, resp.Body) + resp.Body.Close() + require.NoError(t, err) + require.NotContains(t, out.String(), "Using cache") +} + +func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) { + err := w.WriteHeader(&tar.Header{ + Name: fn, + Mode: 0600, + Size: int64(len(contents)), + Typeflag: '0', + }) + require.NoError(t, err) + _, err = w.Write([]byte(contents)) + require.NoError(t, err) +} + type buildLine struct { Stream string Aux struct { diff --git a/components/engine/pkg/tarsum/tarsum.go b/components/engine/pkg/tarsum/tarsum.go index 6ad152a2ed..8c8478a455 100644 --- a/components/engine/pkg/tarsum/tarsum.go +++ b/components/engine/pkg/tarsum/tarsum.go @@ -236,7 +236,7 @@ func (ts *tarSum) Read(buf []byte) (int, error) { } return n, err } - ts.currentFile = path.Clean(currentHeader.Name) + ts.currentFile = path.Join(".", path.Join("/", currentHeader.Name)) if err := ts.encodeHeader(currentHeader); err != nil { return 0, err } From da22cbc58d33fdab49b28f3e7ddda473b0d1ec5d Mon Sep 17 00:00:00 2001 From: Boaz Shuster Date: Wed, 15 Nov 2017 16:44:49 +0200 Subject: [PATCH 2/2] Display a warn message when there is binding ports and net mode is host When a container is created if "--network" is set to "host" all the ports in the container are bound to the host. Thus, adding "-p" or "--publish" to the command-line is meaningless. Unlike "docker run" and "docker create", "docker service create" sends an error message when network mode is host and port bindings are given This patch however suggests to send a warning message to the client when such a case occurs. The warning message is added to "warnings" which are returned from "verifyPlatformContainerSettings". Signed-off-by: Boaz Shuster Upstream-commit: 6e78fdb790d2e1dbf95a1733cab9395b1b936622 Component: engine --- components/engine/daemon/container.go | 12 ++++- .../engine/daemon/container_unix_test.go | 44 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 components/engine/daemon/container_unix_test.go diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go index 26faedfdf9..6b65e829c1 100644 --- a/components/engine/daemon/container.go +++ b/components/engine/daemon/container.go @@ -333,6 +333,16 @@ func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *conta return nil, errors.Errorf("invalid isolation '%s' on %s", hostConfig.Isolation, runtime.GOOS) } + var ( + err error + warnings []string + ) // Now do platform-specific verification - return verifyPlatformContainerSettings(daemon, hostConfig, config, update) + if warnings, err = verifyPlatformContainerSettings(daemon, hostConfig, config, update); err != nil { + return warnings, err + } + if hostConfig.NetworkMode.IsHost() && len(hostConfig.PortBindings) > 0 { + warnings = append(warnings, "Published ports are discarded when using host network mode") + } + return warnings, err } diff --git a/components/engine/daemon/container_unix_test.go b/components/engine/daemon/container_unix_test.go new file mode 100644 index 0000000000..e102be6cdc --- /dev/null +++ b/components/engine/daemon/container_unix_test.go @@ -0,0 +1,44 @@ +// +build linux freebsd + +package daemon + +import ( + "testing" + + "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" + "github.com/docker/docker/daemon/config" + "github.com/docker/go-connections/nat" + "github.com/stretchr/testify/require" +) + +// TestContainerWarningHostAndPublishPorts that a warning is returned when setting network mode to host and specifying published ports. +// This should not be tested on Windows because Windows doesn't support "host" network mode. +func TestContainerWarningHostAndPublishPorts(t *testing.T) { + testCases := []struct { + ports nat.PortMap + warnings []string + }{ + {ports: nat.PortMap{}}, + {ports: nat.PortMap{ + "8080": []nat.PortBinding{{HostPort: "8989"}}, + }, warnings: []string{"Published ports are discarded when using host network mode"}}, + } + + for _, tc := range testCases { + hostConfig := &containertypes.HostConfig{ + Runtime: "runc", + NetworkMode: "host", + PortBindings: tc.ports, + } + cs := &config.Config{ + CommonUnixConfig: config.CommonUnixConfig{ + Runtimes: map[string]types.Runtime{"runc": {}}, + }, + } + d := &Daemon{configStore: cs} + wrns, err := d.verifyContainerSettings("", hostConfig, &containertypes.Config{}, false) + require.NoError(t, err) + require.Equal(t, tc.warnings, wrns) + } +}