Always add parent directories of files to snapshots.
During a snapshot, when a file changed and not its parent directories, the parent directories weren't added to the layer. This is inconsistent with Docker's behavior which always add parent directories to the layer. In some edge-cases, it could lead to problems with docker considering that parent directories where owned by root in forthcoming layers although they shouldn't (see #1163). Also, Docker seems to be POSIX compliant regarding the name of directories in the archive, which always have a slash appended. This commit also fixes this. Fixes #1163
This commit is contained in:
parent
54c2a7abf0
commit
e5585fded8
|
|
@ -226,10 +226,28 @@ func writeToTar(t util.Tar, files, whiteouts []string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
addedPaths := make(map[string]bool)
|
||||
for _, path := range files {
|
||||
if _, fileExists := addedPaths[path]; fileExists {
|
||||
continue
|
||||
}
|
||||
for _, parentPath := range util.ParentDirectories(path) {
|
||||
if parentPath == "/" {
|
||||
continue
|
||||
}
|
||||
if _, dirExists := addedPaths[parentPath]; dirExists {
|
||||
continue
|
||||
}
|
||||
if err := t.AddFileToTar(parentPath); err != nil {
|
||||
return err
|
||||
}
|
||||
addedPaths[parentPath] = true
|
||||
}
|
||||
if err := t.AddFileToTar(path); err != nil {
|
||||
return err
|
||||
}
|
||||
addedPaths[path] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@ func TestSnapshotFSFileChange(t *testing.T) {
|
|||
fooPath: "newbaz1",
|
||||
batPath: "baz",
|
||||
}
|
||||
for _, path := range util.ParentDirectoriesWithoutLeadingSlash(batPath) {
|
||||
if path == "/" {
|
||||
continue
|
||||
}
|
||||
snapshotFiles[path+"/"] = ""
|
||||
}
|
||||
|
||||
actualFiles := []string{}
|
||||
for {
|
||||
|
|
@ -76,6 +82,9 @@ func TestSnapshotFSFileChange(t *testing.T) {
|
|||
if _, isFile := snapshotFiles[hdr.Name]; !isFile {
|
||||
t.Fatalf("File %s unexpectedly in tar", hdr.Name)
|
||||
}
|
||||
if hdr.Typeflag == tar.TypeDir {
|
||||
continue
|
||||
}
|
||||
contents, _ := ioutil.ReadAll(tr)
|
||||
if string(contents) != snapshotFiles[hdr.Name] {
|
||||
t.Fatalf("Contents of %s incorrect, expected: %s, actual: %s", hdr.Name, snapshotFiles[hdr.Name], string(contents))
|
||||
|
|
@ -152,6 +161,12 @@ func TestSnapshotFSChangePermissions(t *testing.T) {
|
|||
snapshotFiles := map[string]string{
|
||||
batPathWithoutLeadingSlash: "baz2",
|
||||
}
|
||||
for _, path := range util.ParentDirectoriesWithoutLeadingSlash(batPathWithoutLeadingSlash) {
|
||||
if path == "/" {
|
||||
continue
|
||||
}
|
||||
snapshotFiles[path+"/"] = ""
|
||||
}
|
||||
|
||||
foundFiles := []string{}
|
||||
for {
|
||||
|
|
@ -164,6 +179,9 @@ func TestSnapshotFSChangePermissions(t *testing.T) {
|
|||
if _, isFile := snapshotFiles[hdr.Name]; !isFile {
|
||||
t.Fatalf("File %s unexpectedly in tar", hdr.Name)
|
||||
}
|
||||
if hdr.Typeflag == tar.TypeDir {
|
||||
continue
|
||||
}
|
||||
contents, _ := ioutil.ReadAll(tr)
|
||||
if string(contents) != snapshotFiles[hdr.Name] {
|
||||
t.Fatalf("Contents of %s incorrect, expected: %s, actual: %s", hdr.Name, snapshotFiles[hdr.Name], string(contents))
|
||||
|
|
@ -203,7 +221,9 @@ func TestSnapshotFiles(t *testing.T) {
|
|||
expectedFiles := []string{
|
||||
filepath.Join(testDirWithoutLeadingSlash, "foo"),
|
||||
}
|
||||
expectedFiles = append(expectedFiles, util.ParentDirectoriesWithoutLeadingSlash(filepath.Join(testDir, "foo"))...)
|
||||
for _, path := range util.ParentDirectoriesWithoutLeadingSlash(filepath.Join(testDir, "foo")) {
|
||||
expectedFiles = append(expectedFiles, strings.TrimRight(path, "/")+"/")
|
||||
}
|
||||
|
||||
f, err := os.Open(tarPath)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ func (t *Tar) AddFileToTar(p string) error {
|
|||
hdr.Name = p
|
||||
}
|
||||
|
||||
if hdr.Typeflag == tar.TypeDir && !strings.HasSuffix(hdr.Name, "/") {
|
||||
hdr.Name = hdr.Name + "/"
|
||||
}
|
||||
|
||||
// rootfs may not have been extracted when using cache, preventing uname/gname from resolving
|
||||
// this makes this layer unnecessarily differ from a cached layer which does contain this information
|
||||
hdr.Uname = ""
|
||||
|
|
|
|||
Loading…
Reference in New Issue