Skip to content

Commit

Permalink
fix: use overlay whiteouts when extracting tar layers (#577)
Browse files Browse the repository at this point in the history
If a tar layer has a deleted file, a whiteout entry is created. However,
when extracting tar and overlay whiteouts are incompatible.

Signed-off-by: Ramkumar Chinchani <[email protected]>
  • Loading branch information
rchincha authored Dec 13, 2023
1 parent ec24577 commit b6996fd
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pkg/overlay/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,9 @@ func unpackOne(l ispec.Descriptor, ociDir string, extractDir string) error {
return err
}

err = layer.UnpackLayer(extractDir, uncompressed, nil)
// always unpack with Overlay whiteout mode to prevent ignoring whiteouts in tar layers
// see test/publish.bats: "building from published images with whiteouts" for more details
err = layer.UnpackLayer(extractDir, uncompressed, &layer.UnpackOptions{WhiteoutMode: layer.OverlayFSWhiteout})
if err != nil {
if rmErr := os.RemoveAll(extractDir); rmErr != nil {
log.Errorf("Failed to remove dir '%s' after failed extraction: %v", extractDir, rmErr)
Expand Down
3 changes: 3 additions & 0 deletions test/empty-layers.bats
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ EOF
}

@test "a real-world docker image with empty/filler layer" {
if [ "$PRIVILEGE_LEVEL" != "priv" ]; then
skip "requires privileges"
fi
cat > stacker.yaml <<EOF
image:
from:
Expand Down
32 changes: 32 additions & 0 deletions test/publish.bats
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,35 @@ published:
EOF

}

@test "building from published images with whiteouts" {
# This tests the case where an image is published after deleting some entries
# We expect that the published image can now be used to build another image,
# while respecting the whiteouts (due to deletion)
if [ -z "${REGISTRY_URL}" ]; then
skip "skipping test because no registry found in REGISTRY_URL env variable"
fi

cat > stacker.yaml <<EOF
parent:
from:
type: docker
url: docker://ghcr.io/project-stacker/alpine:edge
run: |
rm -rf /etc/apk/repositories
EOF
stacker build
stacker publish --skip-tls --url docker://${REGISTRY_URL} --tag latest
stacker clean

cat > stacker.yaml <<EOF
child:
from:
type: docker
url: docker://${REGISTRY_URL}/parent:latest
insecure: true
run: |
[ ! -f /etc/apk/repositories ]
EOF
stacker build
}

0 comments on commit b6996fd

Please sign in to comment.