root/build-tools/build-docker-images/build-stx-images.sh
Don Penney b864e153dd Support source patches for building images
The build-stx-images.sh allows for building images using a git repo as
the source, which is cloned into the workspace as part of the build
procedure. In some cases, there may be source changes required for
fixes or enhancements that have not yet merged into the referenced
repo. This update adds support in build-stx-images to allow the
designer to specify patches in the image directives file, which will
be applied after cloning.

Designer workflow:
* clone git repo (may need to apply any existing git patches from
previous fixes)
* make changes
* commit, with a beautiful and admirable commit message
* git format-patch
* copy source patch to stx repo, somewhere alongside the docker_image
directives file (ie. a docker_patches dir)
* update docker_image directives file to add DOCKER_REPO_PATCHES or
SOURCE_PATCHES, as appropriate, with DOCKER_REF or SOURCE_REF set to
the current upstream SHA used as the base for the patch

Story: 2006711
Task: 38499
Change-Id: Icac2b4dc2ebeb32946de6e5adcbf59a10c56a30c
Signed-off-by: Don Penney <don.penney@windriver.com>
2020-01-28 10:51:07 -05:00

824 lines
23 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2018-2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This utility builds the StarlingX container images
#
MY_SCRIPT_DIR=$(dirname $(readlink -f $0))
source ${MY_SCRIPT_DIR}/../build-wheels/utils.sh
# Required env vars
if [ -z "${MY_WORKSPACE}" -o -z "${MY_REPO}" ]; then
echo "Environment not setup for builds" >&2
exit 1
fi
source ${MY_REPO}/build-tools/git-utils.sh
SUPPORTED_OS_ARGS=('centos' 'distroless')
OS=centos
BUILD_STREAM=stable
IMAGE_VERSION=$(date --utc '+%Y.%m.%d.%H.%M') # Default version, using timestamp
PREFIX=dev
LATEST_PREFIX=""
PUSH=no
PROXY=""
DOCKER_USER=${USER}
DOCKER_REGISTRY=
BASE=
WHEELS=
CLEAN=no
TAG_LATEST=no
TAG_LIST_FILE=
TAG_LIST_LATEST_FILE=
declare -a ONLY
declare -a SKIP
declare -i MAX_ATTEMPTS=1
function usage {
cat >&2 <<EOF
Usage:
$(basename $0)
Options:
--os: Specify base OS (valid options: ${SUPPORTED_OS_ARGS[@]})
--version: Specify version for output image
--stream: Build stream, stable or dev (default: stable)
--base: Specify base docker image (required option)
--wheels: Specify path to wheels tarball or image, URL or docker tag (required option)
--push: Push to docker repo
--proxy: Set proxy <URL>:<PORT>
--user: Docker repo userid
--registry: Docker registry
--prefix: Prefix on the image tag (default: dev)
--latest: Add a 'latest' tag when pushing
--latest-prefix: Alternative prefix on the latest image tag
--clean: Remove image(s) from local registry
--only <image> : Only build the specified image(s). Multiple images
can be specified with a comma-separated list, or with
multiple --only arguments.
--skip <image> : Skip building the specified image(s). Multiple images
can be specified with a comma-separated list, or with
multiple --skip arguments.
--attempts: Max attempts, in case of failure (default: 1)
EOF
}
function is_in {
local search=$1
shift
for v in $*; do
if [ "${search}" = "${v}" ]; then
return 0
fi
done
return 1
}
function is_empty {
test $# -eq 0
}
#
# get_git: Clones a git into a subdirectory of ${WORKDIR}, and
# leaves you in that directory. On error the directory
# is undefined.
#
function get_git {
local git_repo=${1}
local git_ref=${2}
local git_patches=${@:3} # Take remaining args as patch list
local git_name
git_name=$(basename ${git_repo} | sed 's/[.]git$//')
if [ -z ${git_name} ] || \
[ "${git_name}" == "." ] || \
[ "${git_name}" == ".." ] || \
[ "${git_name}" == "*" ]; then
echo "git repo appears to be invalid: ${git_repo}. Aborting..." >&2
return 1
fi
if [ ! -d ${WORKDIR}/${git_name} ]; then
cd ${WORKDIR}
git clone --recursive ${git_repo}
if [ $? -ne 0 ]; then
echo "Failed to clone ${git_repo}. Aborting..." >&2
return 1
fi
cd $git_name
git checkout ${git_ref}
if [ $? -ne 0 ]; then
echo "Failed to checkout '${git_name}' base ref: ${git_ref}" >&2
echo "Aborting..." >&2
return 1
fi
# Apply any patches
for p in ${git_patches}; do
git am ${p}
if [ $? -ne 0 ]; then
echo "Failed to apply ${p} in ${git_name}" >&2
echo "Aborting..." >&2
return 1
fi
done
else
cd ${WORKDIR}/${git_name}
git fetch
if [ $? -ne 0 ]; then
echo "Failed to fetch '${git_name}'. Aborting..." >&2
return 1
fi
git checkout ${git_ref}
if [ $? -ne 0 ]; then
echo "Failed to checkout '${git_name}' base ref: ${git_ref}" >&2
echo "Aborting..." >&2
return 1
fi
# Apply any patches
for p in ${git_patches}; do
git am ${p}
if [ $? -ne 0 ]; then
echo "Failed to apply ${p} in ${git_name}" >&2
echo "Aborting..." >&2
return 1
fi
done
fi
return 0
}
function get_loci {
# Use a specific HEAD of loci, to provide a stable builder
local LOCI_REF="432503259f5e624afdabd9dacc9d9b367dd95e96"
local LOCI_REPO="https://github.com/openstack/loci.git"
local ORIGWD=${PWD}
get_git ${LOCI_REPO} ${LOCI_REF}
if [ $? -ne 0 ]; then
echo "Failed to clone or update loci. Aborting..." >&2
cd ${ORIGWD}
return 1
fi
cd ${ORIGWD}
return 0
}
function update_image_record {
# Update the image record file with a new/updated entry
local LABEL=$1
local TAG=$2
local FILE=$3
grep -q "/${LABEL}:" ${FILE}
if [ $? -eq 0 ]; then
# Update the existing record
sed -i "s#.*/${LABEL}:.*#${TAG}#" ${FILE}
else
# Add a new record
echo "${TAG}" >> ${FILE}
fi
}
function post_build {
#
# Common utility function called from image build functions to run post-build steps.
#
local image_build_file=$1
local LABEL=$2
local build_image_name=$3
# Get additional supported args
#
# To avoid polluting the environment and impacting
# other builds, we're going to explicitly grab specific
# variables from the directives file. While this does
# mean the file is sourced repeatedly, it ensures we
# don't get junk.
local CUSTOMIZATION
CUSTOMIZATION=$(source ${image_build_file} && echo ${CUSTOMIZATION})
# Default IMAGE_UPDATE_VER to 0, if not set
local -i IMAGE_UPDATE_VER
IMAGE_UPDATE_VER=$(source ${image_build_file} && echo ${IMAGE_UPDATE_VER:-0})
local IMAGE_TAG_VERSIONED="${IMAGE_TAG}.${IMAGE_UPDATE_VER}"
if [ -n "${CUSTOMIZATION}" ]; then
docker run --entrypoint /bin/bash --name ${USER}_update_img ${build_image_name} -c "${CUSTOMIZATION}"
if [ $? -ne 0 ]; then
echo "Failed to add customization for ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
docker rm ${USER}_update_img
return 1
fi
docker commit --change='CMD ["bash"]' ${USER}_update_img ${build_image_name}
if [ $? -ne 0 ]; then
echo "Failed to commit customization for ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
docker rm ${USER}_update_img
return 1
fi
docker rm ${USER}_update_img
fi
if [ "${OS}" = "centos" ]; then
# Record python modules and packages
docker run --entrypoint /bin/bash --rm ${build_image_name} -c 'rpm -qa | sort' \
> ${WORKDIR}/${LABEL}-${OS}-${BUILD_STREAM}.rpmlst
docker run --entrypoint /bin/bash --rm ${build_image_name} -c 'pip freeze 2>/dev/null | sort' \
> ${WORKDIR}/${LABEL}-${OS}-${BUILD_STREAM}.piplst
fi
RESULTS_BUILT+=(${build_image_name})
if [ "${PUSH}" = "yes" ]; then
local push_tag="${DOCKER_REGISTRY}${DOCKER_USER}/${LABEL}:${IMAGE_TAG_VERSIONED}"
docker tag ${build_image_name} ${push_tag}
docker push ${push_tag}
RESULTS_PUSHED+=(${push_tag})
update_image_record ${LABEL} ${push_tag} ${TAG_LIST_FILE}
if [ "$TAG_LATEST" = "yes" ]; then
local latest_tag="${DOCKER_REGISTRY}${DOCKER_USER}/${LABEL}:${IMAGE_TAG_LATEST}"
docker tag ${push_tag} ${latest_tag}
docker push ${latest_tag}
RESULTS_PUSHED+=(${latest_tag})
update_image_record ${LABEL} ${latest_tag} ${TAG_LIST_LATEST_FILE}
fi
fi
}
function cleanup_loci_failure {
# When loci fails, it leaves behind a stopped container and a none:none image.
# This function looks for those stopped containers to clean up after a failure.
local container
local image
local extra_fields
docker ps --no-trunc -f status=exited | grep /opt/loci/scripts/install.sh \
| while read container image extra_fields; do
echo "Cleaning loci build container and image: ${container} ${image}"
docker rm ${container}
docker image rm ${image}
done
}
function build_image_loci {
local image_build_file=$1
# Get the supported args
#
# To avoid polluting the environment and impacting
# other builds, we're going to explicitly grab specific
# variables from the directives file. While this does
# mean the file is sourced repeatedly, it ensures we
# don't get junk.
local LABEL
LABEL=$(source ${image_build_file} && echo ${LABEL})
local PROJECT
PROJECT=$(source ${image_build_file} && echo ${PROJECT})
local PROJECT_REPO
PROJECT_REPO=$(source ${image_build_file} && echo ${PROJECT_REPO})
local PROJECT_REF
PROJECT_REF=$(source ${image_build_file} && echo ${PROJECT_REF})
local PIP_PACKAGES
PIP_PACKAGES=$(source ${image_build_file} && echo ${PIP_PACKAGES})
local DIST_PACKAGES
DIST_PACKAGES=$(source ${image_build_file} && echo ${DIST_PACKAGES})
local PROFILES
PROFILES=$(source ${image_build_file} && echo ${PROFILES})
if is_in ${PROJECT} ${SKIP[@]} || is_in ${LABEL} ${SKIP[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
if ! is_empty ${ONLY[@]} && ! is_in ${PROJECT} ${ONLY[@]} && ! is_in ${LABEL} ${ONLY[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
echo "Building ${LABEL}"
local -a BUILD_ARGS=
BUILD_ARGS=(--build-arg PROJECT=${PROJECT})
BUILD_ARGS+=(--build-arg PROJECT_REPO=${PROJECT_REPO})
BUILD_ARGS+=(--build-arg FROM=${BASE})
BUILD_ARGS+=(--build-arg WHEELS=${WHEELS})
if [ ! -z "$PROXY" ]; then
BUILD_ARGS+=(--build-arg http_proxy=$PROXY)
fi
if [ -n "${PROJECT_REF}" ]; then
BUILD_ARGS+=(--build-arg PROJECT_REF=${PROJECT_REF})
fi
if [ -n "${PIP_PACKAGES}" ]; then
BUILD_ARGS+=(--build-arg PIP_PACKAGES="${PIP_PACKAGES}")
fi
if [ -n "${DIST_PACKAGES}" ]; then
BUILD_ARGS+=(--build-arg DIST_PACKAGES="${DIST_PACKAGES}")
fi
if [ -n "${PROFILES}" ]; then
BUILD_ARGS+=(--build-arg PROFILES="${PROFILES}")
fi
local build_image_name="${USER}/${LABEL}:${IMAGE_TAG_BUILD}"
with_retries ${MAX_ATTEMPTS} docker build ${WORKDIR}/loci --no-cache \
"${BUILD_ARGS[@]}" \
--tag ${build_image_name} 2>&1 | tee ${WORKDIR}/docker-${LABEL}-${OS}-${BUILD_STREAM}.log
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "Failed to build ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
cleanup_loci_failure
return 1
fi
if [ ${OS} = "centos" ]; then
# For images with apache, we need a workaround for paths
echo "${PROFILES}" | grep -q apache
if [ $? -eq 0 ]; then
docker run --entrypoint /bin/bash --name ${USER}_update_img ${build_image_name} -c '\
ln -s /var/log/httpd /var/log/apache2 && \
ln -s /var/run/httpd /var/run/apache2 && \
ln -s /etc/httpd /etc/apache2 && \
ln -s /etc/httpd/conf.d /etc/apache2/conf-enabled && \
ln -s /etc/httpd/conf.modules.d /etc/apache2/mods-available && \
ln -s /usr/sbin/httpd /usr/sbin/apache2 && \
ln -s /etc/httpd/conf.d /etc/apache2/sites-enabled \
'
if [ $? -ne 0 ]; then
echo "Failed to add apache workaround for ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
docker rm ${USER}_update_img
return 1
fi
docker commit --change='CMD ["bash"]' ${USER}_update_img ${build_image_name}
if [ $? -ne 0 ]; then
echo "Failed to commit apache workaround for ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
docker rm ${USER}_update_img
return 1
fi
docker rm ${USER}_update_img
fi
fi
post_build ${image_build_file} ${LABEL} ${build_image_name}
}
function build_image_docker {
local image_build_file=$1
# Get the supported args
#
local LABEL
LABEL=$(source ${image_build_file} && echo ${LABEL})
local DOCKER_REPO
DOCKER_REPO=$(source ${image_build_file} && echo ${DOCKER_REPO})
local DOCKER_REF
DOCKER_REF=$(source ${image_build_file} && echo ${DOCKER_REF:-master})
# DOCKER_PATCHES is a list of patch files, relative to the local dir
local DOCKER_PATCHES
DOCKER_PATCHES=$(source ${image_build_file} && for p in ${DOCKER_PATCHES}; do echo $(dirname ${image_build_file})/${p}; done)
if is_in ${PROJECT} ${SKIP[@]} || is_in ${LABEL} ${SKIP[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
if ! is_empty ${ONLY[@]} && ! is_in ${PROJECT} ${ONLY[@]} && ! is_in ${LABEL} ${ONLY[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
echo "Building ${LABEL}"
local docker_src
if [ -z "${DOCKER_REPO}" ]; then
docker_src=$(dirname ${image_build_file})/docker
else
local ORIGWD=${PWD}
echo "get_git '${DOCKER_REPO}' '${DOCKER_REF}' '${DOCKER_PATCHES}'"
get_git "${DOCKER_REPO}" "${DOCKER_REF}" "${DOCKER_PATCHES}"
if [ $? -ne 0 ]; then
echo "Failed to clone or update ${DOCKER_REPO}. Aborting..." >&2
cd ${ORIGWD}
return 1
fi
local DOCKER_FILE="${PWD}/Dockerfile"
if [ ! -f ${DOCKER_FILE} ]; then
DOCKER_FILE=$(find ${PWD} -type f -name Dockerfile | head -n 1)
fi
docker_src=$(dirname ${DOCKER_FILE})
cd ${ORIGWD}
fi
# Check for a Dockerfile
if [ ! -f ${docker_src}/Dockerfile ]; then
echo "${docker_src}/Dockerfile not found" >&2
RESULTS_FAILED+=(${LABEL})
return 1
fi
# Possible design option: Make a copy of the docker_src dir in BUILDDIR
local build_image_name="${USER}/${LABEL}:${IMAGE_TAG_BUILD}"
local -a BASE_BUILD_ARGS
BASE_BUILD_ARGS+=(${docker_src} --no-cache)
BASE_BUILD_ARGS+=(--build-arg "BASE=${BASE}")
if [ ! -z "$PROXY" ]; then
BASE_BUILD_ARGS+=(--build-arg http_proxy=$PROXY)
fi
BASE_BUILD_ARGS+=(--tag ${build_image_name})
with_retries ${MAX_ATTEMPTS} docker build ${BASE_BUILD_ARGS[@]} 2>&1 | tee ${WORKDIR}/docker-${LABEL}-${OS}-${BUILD_STREAM}.log
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "Failed to build ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
return 1
fi
post_build ${image_build_file} ${LABEL} ${build_image_name}
}
function build_image_script {
local image_build_file=$1
# Get the supported args
#
local LABEL
LABEL=$(source ${image_build_file} && echo ${LABEL})
local SOURCE_REPO
SOURCE_REPO=$(source ${image_build_file} && echo ${SOURCE_REPO})
local SOURCE_REF
SOURCE_REF=$(source ${image_build_file} && echo ${SOURCE_REF:-master})
local COMMAND
COMMAND=$(source ${image_build_file} && echo ${COMMAND})
local SCRIPT
SCRIPT=$(source ${image_build_file} && echo ${SCRIPT})
local ARGS
ARGS=$(source ${image_build_file} && echo ${ARGS})
# SOURCE_PATCHES is a list of patch files, relative to the local dir
local SOURCE_PATCHES
SOURCE_PATCHES=$(source ${image_build_file} && for p in ${SOURCE_PATCHES}; do echo $(dirname ${image_build_file})/${p}; done)
if is_in ${PROJECT} ${SKIP[@]} || is_in ${LABEL} ${SKIP[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
if ! is_empty ${ONLY[@]} && ! is_in ${PROJECT} ${ONLY[@]} && ! is_in ${LABEL} ${ONLY[@]}; then
echo "Skipping ${LABEL}"
return 0
fi
# Validate the COMMAND option
SUPPORTED_COMMAND_ARGS=('bash')
local VALID_COMMAND=1
for supported_command in ${SUPPORTED_COMMAND_ARGS[@]}; do
if [ "$COMMAND" = "${supported_command}" ]; then
VALID_COMMAND=0
break
fi
done
if [ ${VALID_COMMAND} -ne 0 ]; then
echo "Unsupported build command specified: ${COMMAND}" >&2
echo "Supported command options: ${SUPPORTED_COMMAND_ARGS[@]}" >&2
RESULTS_FAILED+=(${LABEL})
return 1
fi
# Validate the SCRIPT file existed
if [ ! -f $(dirname ${image_build_file})/${SCRIPT} ]; then
echo "${SCRIPT} not found" >&2
RESULTS_FAILED+=(${LABEL})
return 1
fi
echo "Building ${LABEL}"
local ORIGWD=${PWD}
echo "get_git '${SOURCE_REPO}' '${SOURCE_REF}' '${SOURCE_PATCHES}'"
get_git "${SOURCE_REPO}" "${SOURCE_REF}" "${SOURCE_PATCHES}"
if [ $? -ne 0 ]; then
echo "Failed to clone or update ${SOURCE_REPO}. Aborting..." >&2
cd ${ORIGWD}
return 1
fi
cp $(dirname ${image_build_file})/${SCRIPT} ${SCRIPT}
local build_image_name="${USER}/${LABEL}:${IMAGE_TAG_BUILD}"
with_retries ${MAX_ATTEMPTS} ${COMMAND} ${SCRIPT} ${ARGS} ${build_image_name} $PROXY 2>&1 | tee ${WORKDIR}/docker-${LABEL}-${OS}-${BUILD_STREAM}.log
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "Failed to build ${LABEL}... Aborting"
RESULTS_FAILED+=(${LABEL})
return 1
fi
# check docker image
cd ${ORIGWD}
post_build ${image_build_file} ${LABEL} ${build_image_name}
}
function build_image {
local image_build_file=$1
# Get the builder
local BUILDER
BUILDER=$(source ${image_build_file} && echo ${BUILDER})
case ${BUILDER} in
loci)
build_image_loci ${image_build_file}
return $?
;;
docker)
build_image_docker ${image_build_file}
return $?
;;
script)
build_image_script ${image_build_file}
return $?
;;
*)
echo "Unsupported BUILDER in ${image_build_file}: ${BUILDER}" >&2
return 1
;;
esac
}
OPTS=$(getopt -o h -l help,os:,version:,release:,stream:,push,proxy:,user:,registry:,base:,wheels:,only:,skip:,prefix:,latest,latest-prefix:,clean,attempts: -- "$@")
if [ $? -ne 0 ]; then
usage
exit 1
fi
eval set -- "${OPTS}"
while true; do
case $1 in
--)
# End of getopt arguments
shift
break
;;
--base)
BASE=$2
shift 2
;;
--os)
OS=$2
shift 2
;;
--wheels)
WHEELS=$2
shift 2
;;
--version)
IMAGE_VERSION=$2
shift 2
;;
--stream)
BUILD_STREAM=$2
shift 2
;;
--release) # Temporarily keep --release support as an alias for --stream
BUILD_STREAM=$2
shift 2
;;
--prefix)
PREFIX=$2
shift 2
;;
--latest-prefix)
LATEST_PREFIX=$2
shift 2
;;
--push)
PUSH=yes
shift
;;
--proxy)
PROXY=$2
shift 2
;;
--user)
DOCKER_USER=$2
shift 2
;;
--registry)
# Add a trailing / if needed
DOCKER_REGISTRY="${2%/}/"
shift 2
;;
--clean)
CLEAN=yes
shift
;;
--only)
# Read comma-separated values into array
ONLY+=(${2//,/ })
shift 2
;;
--skip)
# Read comma-separated values into array
SKIP+=(${2//,/ })
shift 2
;;
--latest)
TAG_LATEST=yes
shift
;;
--attempts)
MAX_ATTEMPTS=$2
shift 2
;;
-h | --help )
usage
exit 1
;;
*)
usage
exit 1
;;
esac
done
# Validate the OS option
VALID_OS=1
for supported_os in ${SUPPORTED_OS_ARGS[@]}; do
if [ "$OS" = "${supported_os}" ]; then
VALID_OS=0
break
fi
done
if [ ${VALID_OS} -ne 0 ]; then
echo "Unsupported OS specified: ${OS}" >&2
echo "Supported OS options: ${SUPPORTED_OS_ARGS[@]}" >&2
exit 1
fi
if [ -z "${WHEELS}" ]; then
echo "Path to wheels tarball must be specified with --wheels option." >&2
exit 1
fi
if [ -z "${BASE}" ]; then
echo "Base image must be specified with --base option." >&2
exit 1
fi
IMAGE_TAG="${OS}-${BUILD_STREAM}"
IMAGE_TAG_LATEST="${IMAGE_TAG}-latest"
if [ -n "${LATEST_PREFIX}" ]; then
IMAGE_TAG_LATEST="${LATEST_PREFIX}-${IMAGE_TAG_LATEST}"
elif [ -n "${PREFIX}" ]; then
IMAGE_TAG_LATEST="${PREFIX}-${IMAGE_TAG_LATEST}"
fi
if [ -n "${PREFIX}" ]; then
IMAGE_TAG="${PREFIX}-${IMAGE_TAG}"
fi
IMAGE_TAG_BUILD="${IMAGE_TAG}-build"
if [ -n "${IMAGE_VERSION}" ]; then
IMAGE_TAG="${IMAGE_TAG}-${IMAGE_VERSION}"
fi
WORKDIR=${MY_WORKSPACE}/std/build-images
mkdir -p ${WORKDIR}
if [ $? -ne 0 ]; then
echo "Failed to create ${WORKDIR}" >&2
exit 1
fi
TAG_LIST_FILE=${WORKDIR}/images-${OS}-${BUILD_STREAM}-versioned.lst
TAG_LIST_LATEST_FILE=${WORKDIR}/images-${OS}-${BUILD_STREAM}-latest.lst
if [ "${PUSH}" = "yes" ]; then
if is_empty ${ONLY[@]} && is_empty ${SKIP[@]}; then
# Reset image record files, since we're building everything
echo -n > ${TAG_LIST_FILE}
if [ "$TAG_LATEST" = "yes" ]; then
echo -n > ${TAG_LIST_LATEST_FILE}
fi
fi
fi
# Check to see if the BASE image is already pulled
docker images --format '{{.Repository}}:{{.Tag}}' ${BASE} | grep -q "^${BASE}$"
BASE_IMAGE_PRESENT=$?
# Pull the image anyway, to ensure it's up to date
docker pull ${BASE}
# Download loci, if needed.
get_loci
if [ $? -ne 0 ]; then
# Error is reported by the function already
exit 1
fi
# Find the directives files
for image_build_inc_file in $(find ${GIT_LIST} -maxdepth 1 -name "${OS}_${BUILD_STREAM}_docker_images.inc"); do
basedir=$(dirname ${image_build_inc_file})
for image_build_dir in $(sed -e 's/#.*//' ${image_build_inc_file} | sort -u); do
for image_build_file in ${basedir}/${image_build_dir}/${OS}/*.${BUILD_STREAM}_docker_image; do
# Failures are reported by the build functions
build_image ${image_build_file}
done
done
done
if [ "${CLEAN}" = "yes" -a ${#RESULTS_BUILT[@]} -gt 0 ]; then
# Delete the images
echo "Deleting images"
docker image rm ${RESULTS_BUILT[@]} ${RESULTS_PUSHED[@]}
if [ $? -ne 0 ]; then
# We don't want to fail the overall build for this, so just log it
echo "Failed to clean up images" >&2
fi
if [ ${BASE_IMAGE_PRESENT} -ne 0 ]; then
# The base image was not already present, so delete it
echo "Removing docker image ${BASE}"
docker image rm ${BASE}
if [ $? -ne 0 ]; then
echo "Failed to delete base image from docker" >&2
fi
fi
fi
RC=0
if [ ${#RESULTS_BUILT[@]} -gt 0 ]; then
echo "#######################################"
echo
echo "The following images were built:"
for i in ${RESULTS_BUILT[@]}; do
echo $i
done | sort
if [ ${#RESULTS_PUSHED[@]} -gt 0 ]; then
echo
echo "The following tags were pushed:"
for i in ${RESULTS_PUSHED[@]}; do
echo $i
done | sort
fi
fi
if [ ${#RESULTS_FAILED[@]} -gt 0 ]; then
echo
echo "#######################################"
echo
echo "There were ${#RESULTS_FAILED[@]} failures:"
for i in ${RESULTS_FAILED[@]}; do
echo $i
done | sort
RC=1
fi
exit ${RC}