Skip to content

Instantly share code, notes, and snippets.

@neersighted
Last active November 7, 2022 19:27
Show Gist options
  • Save neersighted/077b067a8a0e1c37c5e7fab5e5b94e82 to your computer and use it in GitHub Desktop.
Save neersighted/077b067a8a0e1c37c5e7fab5e5b94e82 to your computer and use it in GitHub Desktop.
Exploring 'implied directories' in Moby layer diffs

Exploring 'implied directories' in layers

Notably, all directories are present, even when a change is only to a file or is a whiteout.

To run locally:

$ sh explore.sh

The output will look like the following:

--------------------------------------------------------------------------
4436d46c103e44302f721ddced90aa0657ecc9f68714e63de2a0d2522519e98c/layer.tar (RUN /bin/sh -c mkdir /qux # buildkit)
--------------------------------------------------------------------------
etc/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
--------------------------------------------------------------------------
b17faed57831ba8ef03c3670d10c7452a179d46ee045fd5c58f3301e9b9c09e5/layer.tar (WORKDIR /qux)
--------------------------------------------------------------------------
--------------------------------------------------------------------------
69e16878951fd7cb44c30814717425cbd5a74f68a0aacbdac44fec7d0f2dff1d/layer.tar (RUN /bin/sh -c touch foo # buildkit)
--------------------------------------------------------------------------
etc/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/foo:
	Type: regular file
	Mode: 0100644
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
--------------------------------------------------------------------------
8637760c70e1dc8955b1282c7338a1c07bfc41697429ea82fbdfd2003af17878/layer.tar (RUN /bin/sh -c echo bar > foo # buildkit)
--------------------------------------------------------------------------
etc/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/foo:
	Type: regular file
	Mode: 0100644
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 4
--------------------------------------------------------------------------
d8adc6ae8d990e2fcf26be6352daf20f5817a559ec55241c56e2958cd6ee81f2/layer.tar (RUN /bin/sh -c rm foo # buildkit)
--------------------------------------------------------------------------
etc/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/:
	Type: directory
	Mode: 040755
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
qux/.wh.foo:
	Type: regular file
	Mode: 0600
	User: 0
	Group: 0
	Username: 
	Groupname: 
	Size: 0
FROM alpine:latest
RUN mkdir /qux
WORKDIR /qux
RUN touch foo
RUN echo bar > foo
RUN rm foo
#!/bin/sh
if ! command -v yq >/dev/null; then
go install github.com/mikefarah/yq/v4@latest
fi
if ! command -v metatar >/dev/null; then
go install github.com/xyproto/metatar@latest
fi
tmpdir=$(mktemp -d)
image=$(docker build -q .)
trap 'rm -rf "$tmpdir"; docker rmi -f "$image" >/dev/null' EXIT
docker save "$image" | tar -x -C "$tmpdir"
config=$(yq '.[0].Config' <"$tmpdir/manifest.json")
layers=$(yq '.[0].Layers | .[1:] | .[]' -P <"$tmpdir/manifest.json")
nlayers=$(echo "$layers" | wc -l)
history=$(yq '.history | map(select(.empty_layer != true)) | .[].created_by' < "$tmpdir/$config" | tail -n"$nlayers")
i=1
for layer_tar in $layers; do
echo "--------------------------------------------------------------------------"
printf "$layer_tar (%s)\n" "$(echo "$history" | sed -n "${i}p")"
echo "--------------------------------------------------------------------------"
metatar --list "$tmpdir/$layer_tar"
i=$((i+1))
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment