-
-
Save svenXY/1ff698a2053938f0629b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# forked from shepmaster/trace-images.sh | |
# added some logic and made it cron-able (as little output as possible) | |
hash jq 2>/dev/null || { echo >&2 "jq is required but was not found. Please run make sure it is in the path"; exit 1;} | |
shopt -s nullglob | |
# Reset all variables that might be set | |
interactive=0 | |
verbose=0 | |
dryrun=0 | |
while [ "$#" -gt 0 ]; do | |
case $1 in | |
-h|-\?|--help) | |
show_help | |
exit | |
;; | |
-r|--registry) | |
if [ "$#" -gt 1 ]; then | |
base_dir=$2 | |
shift 2 | |
continue | |
else | |
echo 'ERROR: Please specify the path to the registry with -r|-registry.' >&2 | |
exit 1 | |
fi | |
;; | |
--registry=?*) | |
base_dir=${1#*=} | |
;; | |
-v|--verbose) | |
verbose=1 | |
;; | |
-n|--dry-run) | |
dryrun=1 | |
verbose=1 | |
;; | |
-i|--interactive) | |
interactive=1 | |
verbose=1 | |
;; | |
*) # Default case: If no more options then break out of the loop. | |
break | |
esac | |
shift | |
done | |
if [ -z "$base_dir" ] ; then | |
# should never happen, but anyway... | |
echo 'ERROR: Please specify the path to the registry with -r|-registry.' >&2 | |
exit; | |
fi | |
readonly output_dir=$(mktemp -d -t cleanup_docker_images-XXXX) | |
readonly jq=$(which jq) | |
readonly repository_dir=$base_dir/repositories | |
readonly image_dir=$base_dir/images | |
readonly all_images=$output_dir/all | |
readonly used_images=$output_dir/used | |
readonly unused_images=$output_dir/unused | |
function cleanup() { | |
[ $verbose -eq 1 ] && echo "Cleaning up $output_dir" | |
rm -rf $output_dir | |
} | |
trap cleanup EXIT ERR INT | |
function image_history() { | |
local readonly image_hash=$1 | |
$jq '.[]' $image_dir/$image_hash/ancestry | tr -d '"' | |
} | |
[ $verbose -eq 1 ] && echo "Collecting orphan images at $repository_dir" | |
for library in $repository_dir/*; do | |
[ $verbose -eq 1 ] && echo "Library $(basename $library)" >&2 | |
for repo in $library/*; do | |
[ $verbose -eq 1 ] && echo " Repo $(basename $repo)" >&2 | |
for tag in $repo/tag_*; do | |
[ $verbose -eq 1 ] && echo " Tag $(basename $tag)" >&2 | |
tagged_image=$(cat $tag) | |
image_history $tagged_image | |
done | |
done | |
done | sort | uniq > $used_images | |
[ $verbose -eq 1 ] && echo -n "used_images: " && cat $used_images | wc -l | |
ls $image_dir > $all_images | |
[ $verbose -eq 1 ] && echo -n "all_images: " && cat $all_images | wc -l | |
# | |
grep -v -F -f $used_images $all_images > $unused_images || true | |
readonly all_image_count=$(wc -l $all_images | awk '{print $1}') | |
readonly used_image_count=$(wc -l $used_images | awk '{print $1}') | |
readonly unused_image_count=$(wc -l $unused_images | awk '{print $1}') | |
readonly unused_image_size=$( if [ $unused_image_count -gt 0 ] ; then \ | |
cd $image_dir; du -hc $(cat $unused_images) | tail -n1 | cut -f1; \ | |
else echo 0; fi | |
) | |
if [ $unused_image_count -le 0 ] ; then | |
[ $verbose -eq 1 ] && echo "no unused images."; | |
exit; | |
fi | |
[ $verbose -eq 1 ] && echo -e "\nTrimming _index_images..." | |
readonly unused_images_flatten=$output_dir/unused.flatten | |
cat $unused_images | sed -e 's/\(.*\)/\"\1\" /' | tr -d "\n" > $unused_images_flatten | |
for library in $repository_dir/*; do | |
echo "Library $(basename $library)" >&2 | |
for repo in $library/*; do | |
[ $verbose -eq 1 ] && echo " Repo $(basename $repo)" >&2 | |
mkdir -p "$output_dir/$(basename $repo)" | |
$jq '.' "$repo/_index_images" > "$output_dir/$(basename $repo)/_index_images.old" | |
$jq -s '.[0] - [ .[1:][] | {id: .} ]' "$repo/_index_images" $unused_images_flatten > "$output_dir/$(basename $repo)/_index_images" | |
if [ $dryrun -eq 1 ]; then | |
echo "Dryrun - not overwriting $repo/_index_images" | |
else | |
cp "$output_dir/$(basename $repo)/_index_images" "$repo/_index_images" | |
fi | |
done | |
done | |
[ $verbose -eq 1 ] && echo "these are unused images:" | |
[ $verbose -eq 1 ] && cat $unused_images | |
[ $verbose -eq 1 ] && echo "${all_image_count} images, ${used_image_count} used, ${unused_image_count} unused" | |
[ $verbose -eq 1 ] && echo "Unused images consume ${unused_image_size}" | |
ok="N"; | |
if [ $interactive -eq 1 ]; then | |
echo -e "\nRemove images,are you sure?[Y=yes]" | |
read ok; | |
else | |
ok='Y' | |
fi | |
if [ "$ok" = "Y" ] ; then | |
[ $verbose -eq 1 ] && echo "before cleanup:" && du -sm $base_dir | |
if [ $dryrun -eq 1 ]; then | |
echo "Dryrun - not deleting anything" | |
cat $unused_images | xargs -I{} echo rm -rf $image_dir/{} | |
else | |
cat $unused_images | xargs -I{} rm -rf $image_dir/{} | |
fi | |
[ $verbose -eq 1 ] && echo "after cleanup:" && du -sm $base_dir | |
else | |
[ $verbose -eq 1 ] && echo "do nothing" | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment