Skip to content

Instantly share code, notes, and snippets.

@mostlygeek
Created July 15, 2016 16:14
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 mostlygeek/ced06ba017cb4834a4484123ee065574 to your computer and use it in GitHub Desktop.
Save mostlygeek/ced06ba017cb4834a4484123ee065574 to your computer and use it in GitHub Desktop.
shell script for verifying docker images with the digest hash
#!/usr/bin/env bash
# The docker registry has the canonical sha sum for verifying the
# image. The only way to get this (as of this coding) is the output from
# docker push/pull jobs. :|
#
# This script pulls the image and remembers the digest. Then that hash
# value is searched for in the build logs in circle or taskcluster
# if the sha256 hash value is found, the image is considered to be OK
if [ $# -ne 2 ]; then
echo "Usage $0 <source image> <destination image>"
exit 1
else
SOURCE=$1
DEST=$2
fi
echo "Pulling $SOURCE and Extracting Digest SHA"
TMPFILE=$(mktemp)
docker pull "$SOURCE" | tee -a "$TMPFILE"
DIGEST=$(awk '/Digest: / {print $2}' "$TMPFILE")
rm "$TMPFILE"
if [ "$DIGEST" == "" ]; then
echo "ERROR: Could not determine Digest"
exit 1
fi
# Extract BUILD_URL and start hunting for the docker push hash
BUILD_URL=$(docker run --rm --entrypoint="cat" "$SOURCE" /app/version.json | \
python -mjson.tool | \
grep '"build":' | grep -o 'https://[^"]*')
if [ "$BUILD_URL" == "" ]; then
echo "Error: Could not find image's build URL"
exit 1
fi
FOUND=""
echo
echo "Verifying digest: $DIGEST"
case "$BUILD_URL" in
https://circleci.com/*)
# get the artifact url
read BUILDNUM PROJ USER < <(echo "$BUILD_URL" | awk -F '/' '{print $NF, $(NF-1), $(NF-2)}')
BUILD_INFO="https://circleci.com/api/v1/project/$USER/$PROJ/$BUILDNUM"
# added security around circle, must be code from github.com/mozilla or github.com/mozilla-services
if [[ "$USER" != "mozilla" && "$USER" != "mozilla-services" ]]; then
echo "Circle source must be mozilla or mozilla-services"
exit 1
fi
# circleci puts output into separate files available on S3
# this extracts them from the build information, and reverse the order of the URLs with some
# sed magic. Reversing because the docker push is likely done during the Deployment step and not
# in the earlier stages
echo "CircleCI, hunting for build hash..."
for URL in $(curl -s "$BUILD_INFO" | grep output_url | grep -Eo 'https://[^"]+' | sed '1!G;h;$!d'); do
# gunzip since circle uploads all output compressed into S3
# and S3 doesn't do accept encoding detection...
echo " - $URL"
FOUND=$(curl -s "$URL" | gunzip | grep "$DIGEST")
if [ "$FOUND" != "" ]; then
break
fi
done
;;
https://tools.taskcluster.net/*)
JOB_KEY=$(echo "$BUILD_URL" | sed 's/^[^#]*#//')
# fetch the build log from taskcluster and look for the digest
LOG_URL="https://public-artifacts.taskcluster.net/$JOB_KEY/0/public/logs/live_backing.log"
# taskcluster also gzips first, smart people.
FOUND=$(curl -s "$LOG_URL" | gunzip | grep "$DIGEST")
;;
*)
echo "Error: Unsupported Image Builder"
exit 1
;;
esac
if [ -z "$FOUND" ]; then
echo "Could not find digest hash: $DIGEST in build output"
exit 1
fi
echo "Verified Image: $SOURCE ($DIGEST)"
docker tag -f "$SOURCE" "$DEST"
docker push "$DEST"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment