Browse Source

builder: fix wrong cache hits building from tars

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi 7 years ago
parent
commit
f6c8266afd
2 changed files with 70 additions and 1 deletions
  1. 69 0
      integration/build/build_test.go
  2. 1 1
      pkg/tarsum/tarsum.go

+ 69 - 0
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 {

+ 1 - 1
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
 			}