Skip to content
This repository has been archived by the owner on Jun 4, 2021. It is now read-only.

Commit

Permalink
Fix opqaue whiteout handling in flattener.
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshRosen committed Sep 22, 2018
1 parent 7a9a2c4 commit 496d266
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions client/v2_2/docker_image_.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,18 +798,19 @@ def __exit__(self, unused_type, unused_value, unused_traceback):
pass


def _in_whiteout_dir(fs, name):
def _in_whiteout_dir(fs, opaque_whiteouts, name):
while name:
dirname = os.path.dirname(name)
if name == dirname:
break
if fs.get(dirname):
if fs.get(dirname) or dirname in opaque_whiteouts:
return True
name = dirname
return False


_WHITEOUT_PREFIX = '.wh.'
_OPAQUE_WHITEOUT_FILENAME = '.wh..wh..opq'


def extract(image, tar):
Expand All @@ -823,17 +824,24 @@ def extract(image, tar):
# to whether they are a tombstone or not.
fs = {}

opaque_whiteouts_in_higher_layers = set()

# Walk the layers, topmost first and add files. If we've seen them in a
# higher layer then we skip them
for layer in image.diff_ids():
buf = io.BytesIO(image.uncompressed_layer(layer))
with tarfile.open(mode='r:', fileobj=buf) as layer_tar:
opaque_whiteouts_in_this_layer = []
for tarinfo in layer_tar:
# If we see a whiteout file, then don't add anything to the tarball
# but ensure that any lower layers don't add a file with the whited
# out name.
basename = os.path.basename(tarinfo.name)
dirname = os.path.dirname(tarinfo.name)

if basename == _OPAQUE_WHITEOUT_FILENAME:
opaque_whiteouts_in_this_layer.append(dirname)

tombstone = basename.startswith(_WHITEOUT_PREFIX)
if tombstone:
basename = basename[len(_WHITEOUT_PREFIX):]
Expand All @@ -845,7 +853,7 @@ def extract(image, tar):
continue

# Check for a whited out parent directory
if _in_whiteout_dir(fs, name):
if _in_whiteout_dir(fs, opaque_whiteouts_in_higher_layers, name):
continue

# Mark this file as handled by adding its name.
Expand All @@ -857,3 +865,4 @@ def extract(image, tar):
tar.addfile(tarinfo, fileobj=layer_tar.extractfile(tarinfo))
else:
tar.addfile(tarinfo, fileobj=None)
opaque_whiteouts_in_higher_layers.update(opaque_whiteouts_in_this_layer)

0 comments on commit 496d266

Please sign in to comment.