github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/contrib/imgprune/entrypoint.sh (about) 1 #!/bin/bash 2 3 set -e 4 5 source /usr/local/bin/lib_entrypoint.sh 6 7 req_env_var GCPJSON GCPNAME GCPPROJECT IMGNAMES 8 9 unset BASE_IMAGES 10 # When executing under Cirrus-CI, script have access to current source 11 LIB="$CIRRUS_WORKING_DIR/$SCRIPT_BASE/lib.sh" 12 if [[ "$CI" == "true" ]] && [[ -r "$LIB" ]] 13 then 14 # Avoid importing anything that might conflict 15 for env in $(sed -ne 's/^[^#]\+_BASE_IMAGE=/img=/p' "$LIB") 16 do 17 eval $env 18 BASE_IMAGES="$BASE_IMAGES $img" 19 done 20 else 21 # metadata labeling may have broken for some reason in the future 22 echo "Warning: Running outside of Cirrus-CI, very minor-risk of base-image deletion." 23 fi 24 25 gcloud_init 26 27 # For safety's sake + limit nr background processes 28 PRUNE_LIMIT=5 29 THEFUTURE=$(date --date='+1 hour' +%s) 30 TOO_OLD='30 days ago' 31 THRESHOLD=$(date --date="$TOO_OLD" +%s) 32 # Format Ref: https://cloud.google.com/sdk/gcloud/reference/topic/formats 33 FORMAT='value[quote](name,selfLink,creationTimestamp,labels)' 34 PROJRE="/v1/projects/$GCPPROJECT/global/" 35 RECENTLY=$(date --date='3 days ago' --iso-8601=date) 36 # Filter Ref: https://cloud.google.com/sdk/gcloud/reference/topic/filters 37 FILTER="selfLink~$PROJRE AND creationTimestamp<$RECENTLY AND NOT name=($IMGNAMES $BASE_IMAGES)" 38 TODELETE=$(mktemp -p '' todelete.XXXXXX) 39 IMGCOUNT=$(mktemp -p '' imgcount.XXXXXX) 40 41 # Search-loop runs in a sub-process, must store count in file 42 echo "0" > "$IMGCOUNT" 43 count_image() { 44 local count 45 count=$(<"$IMGCOUNT") 46 let 'count+=1' 47 echo "$count" > "$IMGCOUNT" 48 } 49 50 echo "Using filter: $FILTER" 51 echo "Searching images for pruning candidates older than $TOO_OLD ($(date --date="$TOO_OLD" --iso-8601=date)):" 52 $GCLOUD compute images list --format="$FORMAT" --filter="$FILTER" | \ 53 while read name selfLink creationTimestamp labels 54 do 55 count_image 56 created_ymd=$(date --date=$creationTimestamp --iso-8601=date) 57 last_used=$(egrep --only-matching --max-count=1 'last-used=[[:digit:]]+' <<< $labels || true) 58 markmsgpfx="Marking $name (created $created_ymd) for deletion" 59 if [[ -z "$last_used" ]] 60 then # image pre-dates addition of tracking labels 61 echo "$markmsgpfx: Missing 'last-used' metadata, labels: '$labels'" 62 echo "$name" >> $TODELETE 63 continue 64 fi 65 66 last_used_timestamp=$(date --date=@$(cut -d= -f2 <<< $last_used || true) +%s || true) 67 last_used_ymd=$(date --date=@$last_used_timestamp --iso-8601=date) 68 if [[ -z "$last_used_timestamp" ]] || [[ "$last_used_timestamp" -ge "$THEFUTURE" ]] 69 then 70 echo "$markmsgpfx: Missing or invalid last-used timestamp: '$last_used_timestamp'" 71 echo "$name" >> $TODELETE 72 continue 73 fi 74 75 if [[ "$last_used_timestamp" -le "$THRESHOLD" ]] 76 then 77 echo "$markmsgpfx: Used over $TOO_OLD on $last_used_ymd" 78 echo "$name" >> $TODELETE 79 continue 80 fi 81 done 82 83 COUNT=$(<"$IMGCOUNT") 84 echo "########################################################################" 85 echo "Deleting up to $PRUNE_LIMIT images marked ($(wc -l < $TODELETE)) of all searched ($COUNT):" 86 87 # Require a minimum number of images to exist 88 NEED="$[$PRUNE_LIMIT*2]" 89 if [[ "$COUNT" -lt "$NEED" ]] 90 then 91 die 0 Safety-net Insufficient images \($COUNT\) to process deletions \($NEED\) 92 exit 0 93 fi 94 95 for image_name in $(sort --random-sort $TODELETE | tail -$PRUNE_LIMIT) 96 do 97 if echo "$IMGNAMES $BASE_IMAGES" | grep -q "$image_name" 98 then 99 # double-verify in-use images were filtered out in search loop above 100 die 8 FATAL ATTEMPT TO DELETE IN-USE IMAGE \'$image_name\' - THIS SHOULD NEVER HAPPEN 101 fi 102 echo "Deleting $image_name in parallel..." 103 $GCLOUD compute images delete $image_name & 104 done 105 106 wait || true # Nothing to delete: No background jobs