github.com/weaveworks/common@v0.0.0-20230728070032-dd9e68f319d5/tools/rebuild-image (about)

     1  #!/bin/bash
     2  # Rebuild a cached docker image if the input files have changed.
     3  # Usage: ./rebuild-image <image name> <image dir> <image files...>
     4  
     5  set -eux
     6  
     7  IMAGENAME=$1
     8  # shellcheck disable=SC2001
     9  SAVEDNAME=$(echo "$IMAGENAME" | sed "s/[\/\-]/\./g")
    10  IMAGEDIR=$2
    11  shift 2
    12  GIT_REVISION="$(git rev-parse HEAD)"
    13  
    14  INPUTFILES=("$@")
    15  CACHEDIR=$HOME/docker/
    16  
    17  # Rebuild the image
    18  rebuild() {
    19      mkdir -p "$CACHEDIR"
    20      rm "$CACHEDIR/$SAVEDNAME"* || true
    21      docker build --build-arg=revision="$GIT_REVISION" -t "$IMAGENAME" "$IMAGEDIR"
    22      docker save "$IMAGENAME:latest" | gzip - >"$CACHEDIR/$SAVEDNAME-$CIRCLE_SHA1.gz"
    23  }
    24  
    25  # Get the revision the cached image was build at
    26  cached_image_rev() {
    27      find "$CACHEDIR" -name "$SAVEDNAME-*" -type f | sed -n 's/^[^\-]*\-\([a-z0-9]*\).gz$/\1/p'
    28  }
    29  
    30  # Have there been any revision between $1 and $2
    31  has_changes() {
    32      local rev1=$1
    33      local rev2=$2
    34      local changes
    35      changes=$(git diff --oneline "$rev1..$rev2" -- "${INPUTFILES[@]}" | wc -l)
    36      [ "$changes" -gt 0 ]
    37  }
    38  
    39  commit_timestamp() {
    40      local rev=$1
    41      git show -s --format=%ct "$rev"
    42  }
    43  
    44  # Is the SHA1 actually present in the repo?
    45  # It could be it isn't, e.g. after a force push
    46  is_valid_commit() {
    47      local rev=$1
    48      git rev-parse --quiet --verify "$rev^{commit}" >/dev/null
    49  }
    50  
    51  cached_revision=$(cached_image_rev)
    52  if [ -z "$cached_revision" ]; then
    53      echo ">>> No cached image found; rebuilding"
    54      rebuild
    55      exit 0
    56  fi
    57  
    58  if ! is_valid_commit "$cached_revision"; then
    59      echo ">>> Git commit of cached image not found in repo; rebuilding"
    60      rebuild
    61      exit 0
    62  fi
    63  
    64  echo ">>> Found cached image rev $cached_revision"
    65  if has_changes "$cached_revision" "$CIRCLE_SHA1"; then
    66      echo ">>> Found changes, rebuilding"
    67      rebuild
    68      exit 0
    69  fi
    70  
    71  IMAGE_TIMEOUT="$((3 * 24 * 60 * 60))"
    72  if [ "$(commit_timestamp "$cached_revision")" -lt "${IMAGE_TIMEOUT}" ]; then
    73      echo ">>> Image is more the 24hrs old; rebuilding"
    74      rebuild
    75      exit 0
    76  fi
    77  
    78  # we didn't rebuild; import cached version
    79  echo ">>> No changes found, importing cached image"
    80  zcat "$CACHEDIR/$SAVEDNAME-$cached_revision.gz" | docker load