Add basic support for .wh..wh..opq
This fixes the case where directory is removed in aufs and then the same layer is imported to a different graphdriver. Currently when you do `rm -rf /foo && mkdir /foo` in a layer in aufs the files under `foo` would only be be hidden on aufs. The problems with this fix: 1) When a new diff is recreated from non-aufs driver the `opq` files would not be there. This should not mean layer differences for the user but still different content in the tar (one would have one `opq` file, the others would have `.wh.*` for every file inside that folder). This difference also only happens if the tar-split file isn’t stored for the layer. 2) New files that have the filenames before `.wh..wh..opq` when they are sorted do not get picked up by non-aufs graphdrivers. Fixing this would require a bigger refactoring that is planned in the future. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
parent
30ae8b046b
commit
4c53da8f9a
1 changed files with 21 additions and 4 deletions
|
@ -100,8 +100,11 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hdr.Name != ".wh..wh..opq" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
path := filepath.Join(dest, hdr.Name)
|
path := filepath.Join(dest, hdr.Name)
|
||||||
rel, err := filepath.Rel(dest, path)
|
rel, err := filepath.Rel(dest, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,10 +119,24 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
|
||||||
|
|
||||||
if strings.HasPrefix(base, ".wh.") {
|
if strings.HasPrefix(base, ".wh.") {
|
||||||
originalBase := base[len(".wh."):]
|
originalBase := base[len(".wh."):]
|
||||||
originalPath := filepath.Join(filepath.Dir(path), originalBase)
|
dir := filepath.Dir(path)
|
||||||
|
if originalBase == ".wh..opq" {
|
||||||
|
fi, err := os.Lstat(dir)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(dir); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if err := os.Mkdir(dir, fi.Mode()&os.ModePerm); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
originalPath := filepath.Join(dir, originalBase)
|
||||||
if err := os.RemoveAll(originalPath); err != nil {
|
if err := os.RemoveAll(originalPath); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If path exits we almost always just want to remove and replace it.
|
// If path exits we almost always just want to remove and replace it.
|
||||||
// The only exception is when it is a directory *and* the file from
|
// The only exception is when it is a directory *and* the file from
|
||||||
|
|
Loading…
Reference in a new issue