Skip to content

Instantly share code, notes, and snippets.

@tsibley
Created June 5, 2023 21:27
Show Gist options
  • Save tsibley/4007da244db936750262f05ef329469e to your computer and use it in GitHub Desktop.
Save tsibley/4007da244db936750262f05ef329469e to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Downloads the latest images, extracts their caching keys, and provides them
# into the environment so local images may be built using downloaded cached
# layers.
#
# This is necessary because usually local builds only use other locally built
# layers, so you must pay the cost of a full build at the beginning.
#
set -euo pipefail
: "${TAG:=latest}"
main() {
pushd "$(dirname "$0")/.." >/dev/null
pull-nextstrain-images
pull-base-image
export-build-args
popd >/dev/null
log "Running your command now…"
exec "$@"
}
pull-nextstrain-images() {
log "Pulling latest Nextstrain images (tagged $TAG)"
./devel/pull "$TAG"
}
pull-base-image() {
local image="$(base-image)"
log "Pulling latest $image base image (tagged $TAG)"
docker image pull "$image"
if ! has-layer nextstrain/base:"$TAG" "$(final-layer "$image")"; then
die "nextstrain/base:$TAG is built with a version of $image that I can't find."
fi
}
export-build-args() {
build_args="$(build-args)"
log "Exporting build args $build_args"
export $build_args
}
build-args() {
list-values nextstrain/base-builder:"$TAG" .ContainerConfig.Cmd \
| awk '/^CACHE_DATE=(.*)/ { print }'
}
base-image() {
awk '/^FROM/ { print $2; exit }' Dockerfile
}
final-layer() {
local image="$1"
local layer_count=$(inspect "$image" "{{len .RootFS.Layers}}")
inspect "$image" "{{index .RootFS.Layers $(($layer_count - 1))}}"
}
has-layer() {
local image="$1"
local layer="$2"
list-layers "$image" | grep -qF "$layer" 2>/dev/null
}
list-layers() {
list-values "$1" .RootFS.Layers
}
list-values() {
local image="$1"
local field="$2"
inspect "$image" "{{range $field}}{{.}}"$'\n'"{{end}}"
}
inspect() {
local image="$1"
local format="$2"
docker image inspect "$image" --format "$format"
}
log() {
echo "==> $*" >&2
}
die() {
echo "==> $*" >&2
exit 1
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment