047683d12c
Introduce a new --no-use-released-parent option to `build-docker-image` that allows specifying whether the parent image uses the same tag as the one that's currently build or the release tag. Default is to use the release tag for parent image, however `build-all-docker-images` script forces it to be the current tag. Change to Dockerfile is coming next. Change-Id: Ief11c9abb722c181ca85f38ee11800dbf4332a5f
187 lines
4.5 KiB
Bash
Executable File
187 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Depends on bash 4 and gawk
|
|
|
|
TOPDIR=$(git rev-parse --show-toplevel)
|
|
# Work in a temp dir so that developers can continue working while a build is
|
|
# in progress
|
|
WORKDIR=$(mktemp -d /tmp/kolla-workdir.XXXXXXXXXX)
|
|
# Remove $WORKDIR otherwise $TOPDIR is copied *inside* of it
|
|
rm -rf $WORKDIR
|
|
cp -aL "$TOPDIR" $WORKDIR
|
|
DOCKERDIR="$WORKDIR/docker"
|
|
|
|
declare -A dependency
|
|
declare -A img_dirs
|
|
declare -A status
|
|
|
|
function info {
|
|
[[ -n $1 ]] && printf "%s\n" "$1"
|
|
}
|
|
|
|
function success {
|
|
[[ -n $1 ]] && printf "\033[00;32m%s\033[00m\n" "$1"
|
|
}
|
|
|
|
function warn {
|
|
[[ -n $1 ]] && printf "\033[00;31m%s\033[00m\n" "$1"
|
|
}
|
|
|
|
function set_defaults {
|
|
PREFIX=centos-rdo-
|
|
NAMESPACE=kollaglue
|
|
}
|
|
|
|
function has_changed {
|
|
local image=$1
|
|
# Rebuild everything unless given git revision
|
|
# We don't really care about the order of the $FROM and $TO parameters, all
|
|
# we need is the list of changed files between the revisions, or HEAD if
|
|
# only one of them is specified
|
|
[[ -z $FROM && -z $TO ]] || git diff --name-only $FROM $TO | grep -q "${img_dirs[$image]#$WORKDIR/}"
|
|
}
|
|
|
|
function requires_build {
|
|
local image=$1
|
|
local dep=${dependency[$image]}
|
|
# An image requires a built if it meets the following conditions:
|
|
# - it has instructions to build the image
|
|
# - it hasn't been processed yet
|
|
# - its dependency was rebuilt or its build instruction was modified
|
|
[[ ${img_dirs[$image]} && -z ${status[$image]} ]] && \
|
|
([[ ${status[$dep]} == "rebuilt" ]] || has_changed $image)
|
|
}
|
|
|
|
function build_image {
|
|
local dir=$1
|
|
if [ -x "$dir/build" ]; then
|
|
printf "\n"
|
|
info "Building image in $dir"
|
|
if $dir/build $ARGS --no-use-released-parent; then
|
|
success "Successfully built image in $dir"
|
|
status[$image]="rebuilt"
|
|
else
|
|
warn "Failed to build image in $dir"
|
|
status[$image]="fail"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function init_image {
|
|
local img_dir=$1
|
|
|
|
set_defaults
|
|
[ -f $WORKDIR/.buildconf ] && . $WORKDIR/.buildconf
|
|
[ -f $img_dir/.buildconf ] && . $img_dir/.buildconf
|
|
[ -n "$FORCE_NAMESPACE" ] && NAMESPACE=$FORCE_NAMESPACE
|
|
|
|
local image="${NAMESPACE:+${NAMESPACE}/}${PREFIX}${img_dir##*/}"
|
|
local base_image=$(cat $img_dir/Dockerfile | gawk 'match($0, /^\s*FROM\s+(\S+)/, matches) {print matches[1]}' )
|
|
base_image=${base_image//%%KOLLA_NAMESPACE%%/$NAMESPACE}
|
|
base_image=${base_image//%%KOLLA_PREFIX%%/$PREFIX}
|
|
base_image=${base_image//:%%KOLLA_TAG%%/}
|
|
|
|
img_dirs[$image]=$img_dir
|
|
dependency[$image]=$base_image
|
|
|
|
# Restore defaults to minimize risk of side effects
|
|
set_defaults
|
|
}
|
|
|
|
function process_image {
|
|
local image=$1
|
|
if [ -n "${dependency[$image]}" ]; then
|
|
process_image ${dependency[$image]}
|
|
fi
|
|
if requires_build $image; then
|
|
build_image ${img_dirs[$image]}
|
|
fi
|
|
if [ -z "${status[$image]}" ]; then
|
|
status[$image]="up-to-date"
|
|
fi
|
|
}
|
|
|
|
function print_summary {
|
|
printf "\nSummary\n=======\n"
|
|
for image in "${!status[@]}"; do
|
|
case "${status[$image]}" in
|
|
("fail") warn "Failed to process $image" ;;
|
|
("rebuilt") success "Rebuilt $image" ;;
|
|
(*) info "$image: ${status[$image]}" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function interrupted {
|
|
info "Interrupted..."
|
|
print_summary
|
|
rm -rf $WORKDIR
|
|
exit 1
|
|
}
|
|
|
|
function usage () {
|
|
read -r -d '' HELP <<EOF
|
|
A wrapper to build-docker-image that build all images in order.
|
|
|
|
Options:
|
|
|
|
--from <git-revision>
|
|
--to <git-revision>
|
|
|
|
$($WORKDIR/tools/build-docker-image --help)
|
|
EOF
|
|
printf "%s\n" "${HELP/$WORKDIR\/tools\/build-docker-image/$0}"
|
|
}
|
|
|
|
trap 'interrupted' INT
|
|
|
|
|
|
ARGS=$@
|
|
PARSED_ARGS=$(getopt -q -o hn: -l help,namespace:,from:,to: -- "$@")
|
|
|
|
eval set -- "$PARSED_ARGS"
|
|
|
|
while :; do
|
|
case "$1" in
|
|
|
|
(--help|-h) usage
|
|
exit 0
|
|
;;
|
|
|
|
(--namespace|-n)
|
|
shift
|
|
FORCE_NAMESPACE="$1"
|
|
;;
|
|
|
|
(--from)
|
|
shift
|
|
FROM="$1"
|
|
ARGS=${ARGS/\-\-from*$FROM/}
|
|
;;
|
|
|
|
(--to)
|
|
shift
|
|
TO="$1"
|
|
ARGS=${ARGS/\-\-to*$TO/}
|
|
;;
|
|
|
|
(--) break
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
done
|
|
|
|
# Do a first pass to find images to build and their dependencies
|
|
for dockerfile in $(find $DOCKERDIR -name Dockerfile); do
|
|
init_image $(dirname $dockerfile)
|
|
done
|
|
|
|
# Process all images
|
|
for image in "${!img_dirs[@]}"; do
|
|
process_image $image
|
|
done
|
|
|
|
print_summary
|
|
rm -rf $WORKDIR
|