Merge pull request #3474 from creack/fix_add_cache_issue
Fix ADD caching issue with . prefixed path
diff --git a/buildfile.go b/buildfile.go
index 09b1f80..ef4b95c 100644
--- a/buildfile.go
+++ b/buildfile.go
@@ -407,6 +407,15 @@
hash string
sums = b.context.GetSums()
)
+
+ // Has tarsum strips the '.' and './', we put it back for comparaison.
+ for file, sum := range sums {
+ if len(file) == 0 || file[0] != '.' && file[0] != '/' {
+ delete(sums, file)
+ sums["./"+file] = sum
+ }
+ }
+
if fi, err := os.Stat(path.Join(b.contextPath, origPath)); err != nil {
return err
} else if fi.IsDir() {
@@ -428,7 +437,8 @@
if err != nil {
return err
}
- if hit {
+ // If we do not have a hash, never use the cache
+ if hit && hash != "" {
return nil
}
}
diff --git a/graphdriver/vfs/driver.go b/graphdriver/vfs/driver.go
index fab9d06..12230f4 100644
--- a/graphdriver/vfs/driver.go
+++ b/graphdriver/vfs/driver.go
@@ -36,9 +36,8 @@
}
func copyDir(src, dst string) error {
- cmd := exec.Command("cp", "-aT", "--reflink=auto", src, dst)
- if err := cmd.Run(); err != nil {
- return err
+ if output, err := exec.Command("cp", "-aT", "--reflink=auto", src, dst).CombinedOutput(); err != nil {
+ return fmt.Errorf("Error VFS copying directory: %s (%s)", err, output)
}
return nil
}
diff --git a/integration/buildfile_test.go b/integration/buildfile_test.go
index def63d2..ef51777 100644
--- a/integration/buildfile_test.go
+++ b/integration/buildfile_test.go
@@ -457,7 +457,7 @@
}
}
-func checkCacheBehavior(t *testing.T, template testContextTemplate, expectHit bool) {
+func checkCacheBehavior(t *testing.T, template testContextTemplate, expectHit bool) (imageId string) {
eng := NewTestEngine(t)
defer nuke(mkRuntimeFromEngine(eng, t))
@@ -466,20 +466,36 @@
t.Fatal(err)
}
- imageId := img.ID
+ imageId = img.ID
- img = nil
img, err = buildImage(template, t, eng, expectHit)
if err != nil {
t.Fatal(err)
}
- hit := imageId == img.ID
- if hit != expectHit {
- t.Logf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)",
- hit, expectHit, imageId, img.ID)
- t.Fail()
+ if hit := imageId == img.ID; hit != expectHit {
+ t.Fatalf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)", hit, expectHit, imageId, img.ID)
}
+ return
+}
+
+func checkCacheBehaviorFromEngime(t *testing.T, template testContextTemplate, expectHit bool, eng *engine.Engine) (imageId string) {
+ img, err := buildImage(template, t, eng, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ imageId = img.ID
+
+ img, err = buildImage(template, t, eng, expectHit)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if hit := imageId == img.ID; hit != expectHit {
+ t.Fatalf("Cache misbehavior, got hit=%t, expected hit=%t: (first: %s, second %s)", hit, expectHit, imageId, img.ID)
+ }
+ return
}
func TestBuildImageWithCache(t *testing.T) {
@@ -506,11 +522,61 @@
maintainer dockerio
run echo "first"
add foo /usr/lib/bla/bar
+ run [ "$(cat /usr/lib/bla/bar)" = "hello" ]
run echo "second"
+ add . /src/
+ run [ "$(cat /src/foo)" = "hello" ]
`,
- [][2]string{{"foo", "hello"}},
+ [][2]string{
+ {"foo", "hello"},
+ },
nil}
- checkCacheBehavior(t, template, true)
+ eng := NewTestEngine(t)
+ defer nuke(mkRuntimeFromEngine(eng, t))
+
+ id1 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ template.files = append(template.files, [2]string{"bar", "hello2"})
+ id2 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id1 == id2 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
+ id3 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id2 != id3 {
+ t.Fatal("The cache should have been used but hasn't.")
+ }
+ template.files[1][1] = "hello3"
+ id4 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id3 == id4 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
+ template.dockerfile += `
+ add ./bar /src2/
+ run ls /src2/bar
+ `
+ id5 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id4 == id5 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
+ template.files[1][1] = "hello4"
+ id6 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id5 == id6 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
+
+ template.dockerfile += `
+ add bar /src2/bar2
+ add /bar /src2/bar3
+ run ls /src2/bar2 /src2/bar3
+ `
+ id7 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id6 == id7 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
+ template.files[1][1] = "hello5"
+ id8 := checkCacheBehaviorFromEngime(t, template, true, eng)
+ if id7 == id8 {
+ t.Fatal("The cache should have been invalided but hasn't.")
+ }
}
func TestBuildADDLocalFileWithoutCache(t *testing.T) {