Skip to content

Instantly share code, notes, and snippets.

@serious-angel
Last active December 6, 2024 17:29
Show Gist options
  • Save serious-angel/3fe877d9afeaf8e09d61060647017a1f to your computer and use it in GitHub Desktop.
Save serious-angel/3fe877d9afeaf8e09d61060647017a1f to your computer and use it in GitHub Desktop.
Docker image layer data preview quick experimental Bash script
# /usr/bin/env bash
_totalSize=0;
_Fmt() ( numfmt --from=iec --to=iec --suffix B --format='%0.2f' -- "${1}K"; );
_DirSize() ( sudo -- bash -c 'if [[ -d "$1" ]]; then du -ks -- "$1" | cut -f1; else printf ?; fi;' - "$1"; );
_TreePath() ( sudo -- tree -avr --charset=ascii --dirsfirst --du -- "$1"; );
_PreviewLayers()
{
declare resultFilepart="$1";
shift;
declare layers=( "$@" );
shift $#;
declare layersCount="${#layers[@]}";
declare indexPadding="${#layersCount}";
declare i;
for (( i=0; i < layersCount; i++ ));
do
declare layerDirpath="${layers[i]}";
declare layerId="${layerDirpath%/*}";
declare layerId="${layerId##*/}";
declare layerSize="$( _DirSize "$layerDirpath"; )" || return $?;
declare _totalSize="$(( _totalSize + layerSize ))";
declare message;
printf -v message -- $" [%${indexPadding}s] Layer '%s' ~ %10s B (%10s) -> %10s B (%10s)\n" \
"$i" \
"$layerDirpath" \
"$layerSize" "$( _Fmt "$layerSize"; )" \
"$_totalSize" "$( _Fmt "$_totalSize"; )";
printf '%s' "$message";
(
printf '%s\n' "$message";
_TreePath "$layerDirpath" || return $?;
) \
&> "${resultFilepart}_${i}-${layersCount}_${layerId:0:16}.txt";
done
}
_Main() (
declare imageName="$1";
shift;
docker images -- "$imageName" || return $?;
printf '\n';
declare imageId="$( docker images -q -- "$imageName"; )" || return $?;
declare currentDirpath; currentDirpath="$( pwd -P; )";
declare time; time="$( date -u -- '+%F_%H_%M_%S_Z'; )";
declare layerDataDirpart="${currentDirpath}/${time}";
printf '# LowerDir\n\n';
declare lowerDirLayers=();
readarray -td ':' -- lowerDirLayers < <(
docker image inspect --format '{{json .GraphDriver.Data}}' "$imageId" \
| jq '.LowerDir' \
| perl -pe 's/["\n]//g';
) \
|| return $?;
_PreviewLayers "${layerDataDirpart}_lower" "${lowerDirLayers[@]}";
printf '\n# UpperDir\n\n';
declare upperDirLayers=();
readarray -td ':' -- upperDirLayers < <(
docker image inspect --format '{{json .GraphDriver.Data}}' "$imageId" \
| jq '.UpperDir' \
| perl -pe 's/["\n]//g';
) \
|| return $?;
_PreviewLayers "${layerDataDirpart}_upper" "${upperDirLayers[@]}";
printf '\nTotal: %s B (%s)\n\n' "$_totalSize" "$( _Fmt "$_totalSize"; )";
printf $'Hurray! Please check layer contents in files:\n\n';
ls -la -- "$layerDataDirpart"*;
printf '\n';
)
_Main "$@";
$ ./image_layers.sh node;
REPOSITORY TAG IMAGE ID CREATED SIZE
node latest e15446acc41f 2 weeks ago 1.12GB
# LowerDir
[0] Layer '/var/lib/docker/overlay2/a875f17bdc2dd04a2439457ed0b5aec4f740432a3661f08a2e6eca59d57661e3/diff' ~ 5280 B ( 5.16MB) -> 5280 B ( 5.16MB)
[1] Layer '/var/lib/docker/overlay2/222440f39327db7c3f0e4c94ec8aacffe536e600981771e823a750f254c8a7f0/diff' ~ 198816 B ( 194.16MB) -> 204096 B ( 199.32MB)
[2] Layer '/var/lib/docker/overlay2/eff01b43d034758d03ed0e49fcc166a16d244bae463eeaf26f004dbfe6e5dbd4/diff' ~ 68 B ( 68.00KB) -> 204164 B ( 199.38MB)
[3] Layer '/var/lib/docker/overlay2/1936ff5cba642f1888f3069ec3223826a0f43ece29a123a3027f83eef6e25bd7/diff' ~ 603888 B ( 589.74MB) -> 808052 B ( 789.12MB)
[4] Layer '/var/lib/docker/overlay2/538f0145f18bd799cdb53c2b315f10ca4adc4ff0645a2ce62bc111bcb73a6c3d/diff' ~ 189060 B ( 184.63MB) -> 997112 B ( 973.75MB)
[5] Layer '/var/lib/docker/overlay2/59a261372580a2be1a0ea6d2bdf36ff43da1928102a6e51c4050da6822da45c4/diff' ~ 51040 B ( 49.85MB) -> 1048152 B ( 1023.59MB)
[6] Layer '/var/lib/docker/overlay2/4eb4ac9cfa5e72a81fdad84a78e03ffaab0b47a187573f696bc4c8112290d70f/diff' ~ 129640 B ( 126.61MB) -> 1177792 B ( 1.13GB)
# UpperDir
[0] Layer '/var/lib/docker/overlay2/7dd3b1e349edda701561d44cfdc6b0af308e9bdc86758f6d10b010dcf7d54e45/diff' ~ 20 B ( 20.00KB) -> 20 B ( 20.00KB)
Total: 0 B (0.00B)
Hurray! Please check layer contents in files:
-rw-rw-r-- 1 user user 1113 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_0-7_a875f17bdc2dd04a.txt
-rw-rw-r-- 1 user user 391294 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_1-7_222440f39327db7c.txt
-rw-rw-r-- 1 user user 881 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_2-7_eff01b43d034758d.txt
-rw-rw-r-- 1 user user 696494 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_3-7_1936ff5cba642f18.txt
-rw-rw-r-- 1 user user 347925 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_4-7_538f0145f18bd799.txt
-rw-rw-r-- 1 user user 104948 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_5-7_59a261372580a2be.txt
-rw-rw-r-- 1 user user 325745 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_lower_6-7_4eb4ac9cfa5e72a8.txt
-rw-rw-r-- 1 user user 462 Dec 6 17:26 /home/user/temp/2024-12-06_17_26_46_Z_upper_0-1_7dd3b1e349edda70.txt
[0] Layer '/var/lib/docker/overlay2/a875f17bdc2dd04a2439457ed0b5aec4f740432a3661f08a2e6eca59d57661e3/diff' ~ 5280 B ( 5.16MB) -> 5280 B ( 5.16MB)
[ 5373312] /var/lib/docker/overlay2/a875f17bdc2dd04a2439457ed0b5aec4f740432a3661f08a2e6eca59d57661e3/diff
|-- [ 12345] usr
| `-- [ 8249] local
| `-- [ 4153] bin
| |-- [ 30] yarnpkg -> /opt/yarn-v1.22.22/bin/yarnpkg
| `-- [ 27] yarn -> /opt/yarn-v1.22.22/bin/yarn
`-- [ 5356871] opt
`-- [ 5352775] yarn-v1.22.22
|-- [ 5334753] lib
| |-- [ 9910] v8-compile-cache.js
| `-- [ 5320747] cli.js
|-- [ 6242] bin
| |-- [ 30] yarnpkg.cmd
| |-- [ 42] yarnpkg
| |-- [ 1015] yarn.js
| |-- [ 34] yarn.cmd
| `-- [ 1025] yarn
|-- [ 2342] preinstall.js
|-- [ 634] package.json
|-- [ 3353] README.md
`-- [ 1355] LICENSE
21415932 bytes used in 8 directories, 13 files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment