Skip to content

Instantly share code, notes, and snippets.

@digulla
Created January 30, 2020 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digulla/2971f04a1171217b124e740b61e69cee to your computer and use it in GitHub Desktop.
Save digulla/2971f04a1171217b124e740b61e69cee to your computer and use it in GitHub Desktop.
#!/bin/bash
set -o pipefail
archive="$1"
fromImage="$2"
outputName=$(basename "$archive" ".tar.gz")-partial.tar
echo "Result will be in ${outputName}.gz"
if [[ -e "${outputName}" || -e "${outputName}.gz" ]]; then
# gzip later will complain, so stop early
echo "ERROR Result already exists. Please delete it and run the script again."
exit 1
fi
layerCount=$(docker image inspect --format "{{len .RootFS.Layers}}" "$fromImage" || exit 1)
echo "The FROM image $fromImage has $layerCount layers"
echo "Getting layers from image..."
tar xvzf "$archive" manifest.json
toDelete=( $(jq ".[0].Layers[0:$layerCount]" manifest.json | \
sed -e 's/\[//' -e 's/\]//' -e 's/,$//' -e 's/"//g' -e 's:/layer.tar::')
)
echo "Layers to delete: ${toDelete[*]}"
echo "Creating new manifest.json"
mv manifest.json manifest.json.orig
jq "del(.[0].Layers[0:$layerCount])" manifest.json.orig > manifest.json
members=()
for layer in "${toDelete[@]}"; do
members+=("$layer/layer.tar")
members+=("$layer/VERSION")
members+=("$layer/json")
done
set -x
zcat "$archive" | tar --delete "${members[@]}" manifest.json | pv > "$outputName"
# Note: --owner=0 --group=0 were necessary on my system because my GID is > 2'097'151
tar --append --owner=0 --group=0 -f "$outputName" manifest.json || exit 0
gzip -v9 "$outputName"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment