1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Add constants for AUFS whiteout files

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2015-09-29 10:18:28 -07:00
parent 00e3277107
commit 2fb5d0c323
4 changed files with 35 additions and 12 deletions

View file

@ -322,7 +322,7 @@ func (a *Driver) Diff(id, parent string) (archive.Archive, error) {
// AUFS doesn't need the parent layer to produce a diff. // AUFS doesn't need the parent layer to produce a diff.
return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{
Compression: archive.Uncompressed, Compression: archive.Uncompressed,
ExcludePatterns: []string{".wh..wh.*", "!.wh..wh..opq"}, ExcludePatterns: []string{archive.WhiteoutMetaPrefix + "*", "!" + archive.WhiteoutOpaqueDir},
}) })
} }

View file

@ -102,7 +102,7 @@ func Changes(layers []string, rw string) ([]Change, error) {
} }
// Skip AUFS metadata // Skip AUFS metadata
if matched, err := filepath.Match(string(os.PathSeparator)+".wh..wh.*", path); err != nil || matched { if matched, err := filepath.Match(string(os.PathSeparator)+WhiteoutMetaPrefix+"*", path); err != nil || matched {
return err return err
} }
@ -113,8 +113,8 @@ func Changes(layers []string, rw string) ([]Change, error) {
// Find out what kind of modification happened // Find out what kind of modification happened
file := filepath.Base(path) file := filepath.Base(path)
// If there is a whiteout, then the file was removed // If there is a whiteout, then the file was removed
if strings.HasPrefix(file, ".wh.") { if strings.HasPrefix(file, WhiteoutPrefix) {
originalFile := file[len(".wh."):] originalFile := file[len(WhiteoutPrefix):]
change.Path = filepath.Join(filepath.Dir(path), originalFile) change.Path = filepath.Join(filepath.Dir(path), originalFile)
change.Kind = ChangeDelete change.Kind = ChangeDelete
} else { } else {
@ -362,7 +362,7 @@ func ExportChanges(dir string, changes []Change) (Archive, error) {
if change.Kind == ChangeDelete { if change.Kind == ChangeDelete {
whiteOutDir := filepath.Dir(change.Path) whiteOutDir := filepath.Dir(change.Path)
whiteOutBase := filepath.Base(change.Path) whiteOutBase := filepath.Base(change.Path)
whiteOut := filepath.Join(whiteOutDir, ".wh."+whiteOutBase) whiteOut := filepath.Join(whiteOutDir, WhiteoutPrefix+whiteOutBase)
timestamp := time.Now() timestamp := time.Now()
hdr := &tar.Header{ hdr := &tar.Header{
Name: whiteOut[1:], Name: whiteOut[1:],

View file

@ -83,11 +83,11 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
} }
// Skip AUFS metadata dirs // Skip AUFS metadata dirs
if strings.HasPrefix(hdr.Name, ".wh..wh.") { if strings.HasPrefix(hdr.Name, WhiteoutMetaPrefix) {
// Regular files inside /.wh..wh.plnk can be used as hardlink targets // Regular files inside /.wh..wh.plnk can be used as hardlink targets
// We don't want this directory, but we need the files in them so that // We don't want this directory, but we need the files in them so that
// such hardlinks can be resolved. // such hardlinks can be resolved.
if strings.HasPrefix(hdr.Name, ".wh..wh.plnk") && hdr.Typeflag == tar.TypeReg { if strings.HasPrefix(hdr.Name, WhiteoutLinkDir) && hdr.Typeflag == tar.TypeReg {
basename := filepath.Base(hdr.Name) basename := filepath.Base(hdr.Name)
aufsHardlinks[basename] = hdr aufsHardlinks[basename] = hdr
if aufsTempdir == "" { if aufsTempdir == "" {
@ -101,7 +101,7 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
} }
} }
if hdr.Name != ".wh..wh..opq" { if hdr.Name != WhiteoutOpaqueDir {
continue continue
} }
} }
@ -117,10 +117,9 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
} }
base := filepath.Base(path) base := filepath.Base(path)
if strings.HasPrefix(base, ".wh.") { if strings.HasPrefix(base, WhiteoutPrefix) {
originalBase := base[len(".wh."):]
dir := filepath.Dir(path) dir := filepath.Dir(path)
if originalBase == ".wh..opq" { if base == WhiteoutOpaqueDir {
fi, err := os.Lstat(dir) fi, err := os.Lstat(dir)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return 0, err return 0, err
@ -132,6 +131,7 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
return 0, err return 0, err
} }
} else { } else {
originalBase := base[len(WhiteoutPrefix):]
originalPath := filepath.Join(dir, originalBase) 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
@ -156,7 +156,7 @@ func UnpackLayer(dest string, layer Reader) (size int64, err error) {
// Hard links into /.wh..wh.plnk don't work, as we don't extract that directory, so // Hard links into /.wh..wh.plnk don't work, as we don't extract that directory, so
// we manually retarget these into the temporary files we extracted them into // we manually retarget these into the temporary files we extracted them into
if hdr.Typeflag == tar.TypeLink && strings.HasPrefix(filepath.Clean(hdr.Linkname), ".wh..wh.plnk") { if hdr.Typeflag == tar.TypeLink && strings.HasPrefix(filepath.Clean(hdr.Linkname), WhiteoutLinkDir) {
linkBasename := filepath.Base(hdr.Linkname) linkBasename := filepath.Base(hdr.Linkname)
srcHdr = aufsHardlinks[linkBasename] srcHdr = aufsHardlinks[linkBasename]
if srcHdr == nil { if srcHdr == nil {

23
pkg/archive/whiteouts.go Normal file
View file

@ -0,0 +1,23 @@
package archive
// Whiteouts are files with a special meaning for the layered filesystem.
// Docker uses AUFS whiteout files inside exported archives. In other
// filesystems these files are generated/handled on tar creation/extraction.
// WhiteoutPrefix prefix means file is a whiteout. If this is followed by a
// filename this means that file has been removed from the base layer.
const WhiteoutPrefix = ".wh."
// WhiteoutMetaPrefix prefix means whiteout has a special meaning and is not
// for remoing an actaul file. Normally these files are excluded from exported
// archives.
const WhiteoutMetaPrefix = WhiteoutPrefix + WhiteoutPrefix
// WhiteoutLinkDir is a directory AUFS uses for storing hardlink links to other
// layers. Normally these should not go into exported archives and all changed
// hardlinks should be copied to the top layer.
const WhiteoutLinkDir = WhiteoutMetaPrefix + "plnk"
// WhiteoutOpaqueDir file means directory has been made opaque - meaning
// readdir calls to this directory do not follow to lower layers.
const WhiteoutOpaqueDir = WhiteoutMetaPrefix + ".opq"