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