#!/bin/bash # Bring in the variables from SOLUTION file, supporting # nested substitution . SOLUTION . MANIFEST VARS=($(sed -nE "s,(^[^#][^=]*).*$,\1,pg" SOLUTION)) VARS+=($(sed -nE "s,(^[^#][^=]*).*$,\1,pg" MANIFEST)) for var in ${VARS[@]}; do export ${var} done [[ -d "templates/${OS_DISTRO}" ]] || { echo "Unrecognized OS_DISTRO: '${OS_DISTRO}'" exit -1 } if [[ -e "Dockerfile.solution.${OS_DISTRO}-${OS_RELEASE}" ]]; then SOLUTION_SUFFIX=".${OS_DISTRO}-${OS_RELEASE}" elif [[ -e "Dockerfile.solution.${OS_DISTRO}" ]]; then SOLUTION_SUFFIX=".${OS_DISTRO}" else SOLUTION_SUFFIX="" fi [[ "${SOLUTION_SUFFIX}" == "" ]] && { cat << EOF The following Dockerfile.solutions were checked, but do not exist: * Dockerfile.solution.${OS_DISTRO} * Dockerfile.solution.${OS_DISTRO}-${OS_RELEASE} Using 'Dockerfile.solution' as default. EOF } export DOCKERFILE="Dockerfile${SOLUTION_SUFFIX}" export SOLUTION="Dockerfile.solution${SOLUTION_SUFFIX}" VARS+=("DOCKERFILE") VARS+=("SOLUTION") cat << EOF Using: ${SOLUTION} To generate: ${DOCKERFILE} EOF # Build a SHELL-FORMAT value to pass to envsubst. # Only those variables matched in SHELL-FORMAT will # be escaped by envsubst. ENV='' for var in ${VARS[@]}; do ENV=${ENV}'$'${var} done # Remove the Dockerfile if it exists; should check # if it is clean first, and abort if not. # [ -e ${DOCKERFILE} ] && rm ${DOCKERFILE} cat << EOM > ${DOCKERFILE} # # DO NOT EDIT THIS DOCKERFILE # # This file is auto-generated via scripts/build-dockerfile # by using environment substitution while concatenating the # contents of templates/*, and then adding the contents # of ${SOLUTION} # # Most solution specific changes should be isolated in # ${SOLUTION}. After making changes, you can then re-run # scripts/build-dockerfile # EOM SNIPPETS=() # Create a list of all the templates for this distro for snippet in templates/${OS_DISTRO}/??-*.in; do SNIPPETS+=($snippet) done # Add in the list of templates from the release sub-directory # removing from the base distro if a name conflict [[ -d templates/${OS_DISTRO}/${OS_RELEASE} ]] && { for snippet in templates/${OS_DISTRO}/${OS_RELEASE}/??-*.in; do SNIPPETS=(${SNIPPETS[@]%%*$(basename ${snippet})}) SNIPPETS+=($snippet) done } # Sort the entries by the filename by rewriting # the entries as FILENAME DIRNAME # Then read the sorted information back out and # re-create the filepath, storing the results in # the TEMPLATES array TEMPLATES=($(for snippet in ${SNIPPETS[@]}; do echo $(basename $snippet) $(dirname $snippet) done | sort | while read base dir; do echo ${dir}/${base} done)) for snippet in ${TEMPLATES[@]}; do cat << EOM >> ${DOCKERFILE} # # Template from ${snippet} # EOM envsubst ${ENV} < $snippet >> ${DOCKERFILE} done cat << EOM >> ${DOCKERFILE} # # Solution begins here (from ${SOLUTION}) # EOM envsubst ${ENV} < ${SOLUTION} >> ${DOCKERFILE} cat << EOM >> ${DOCKERFILE} # # Standard ending begins here (from templates/ending.in) # EOM envsubst ${ENV} < templates/ending.in >> ${DOCKERFILE} cat << EOM ${DOCKERFILE} has been updated. To build the image, you can run: OS_DISTRO=${OS_DISTRO} OS_RELEASE=${OS_RELEASE} scripts/build-image.sh EOM