#!/bin/bash # Bring in the variables from SOLUTION file, supporting # nested substitution . SOLUTION VARS=($(sed -nE "s,(^[^#][^=]*).*$,\1,pg" SOLUTION)) 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} EOF } REGISTRY_OS_AMR=amr-registry.caas.intel.com/vtt-osgc/os/ export REGISTRY_OS=${REGISTRY_OS:-${REGISTRY_OS_AMR}} if [[ "${REGISTRY_OS}" == "external" ]]; then export REGISTRY_OS= fi export DOCKERFILE="Dockerfile${SOLUTION_SUFFIX}" export SOLUTION="Dockerfile.solution${SOLUTION_SUFFIX}" export PACKAGE_DISTRO VARS+=(DOCKERFILE SOLUTION BUILD REGISTRY_OS PACKAGE_DISTRO) if [[ "${BUILD}" != "" ]] && [[ "${BUILD}" != "N/A" ]]; then # Override PACKAGE_REPOSITORY as it won't be used -- instead a file # repository will be configured PACKAGE_REPOSITORY=file:///repos/${BUILD} PACKAGE_STREAM="N/A" # ARTIFACTORY_PATH is set by scripts/build-dockerfile.sh based on the value of # BUILD. For example, agama-ci-releases_20.4 becomes agama-ci-releases/20.4 # # sh (the shell interpreter of Docker) does not support subsitution so # this can't be done within the Dockerfile itself. # ARTIFACTORY_PATH=${BUILD%-*} # Prune off -405 ARTIFACTORY_PATH=${ARTIFACTORY_PATH#agama-ci-} # Prune of agama-ci- ARTIFACTORY_PATH=${ARTIFACTORY_PATH//_/\/} # releases_20.4 => releases/20.4 # Since we're already making special variables, scripts/build-dockerfile.sh # will also set ARTIFACTORY_RELEASE based on the OS_RELEASE name if Ubuntu # is being used (eg., 20.04 for focal, etc) case ${OS_RELEASE} in focal) ARTIFACTORY_RELEASE=20.04 ;; # Focal Fossa groovy) ARTIFACTORY_RELEASE=20.10 ;; # Groovy Gorilla esac ARTIFACTORY_RELEASE=${ARTIFACTORY_RELEASE:-${OS_RELEASE}} VARS+=(ARTIFACTORY_PATH ARTIFACTORY_RELEASE) export ARTIFACTORY_RELEASE export ARTIFACTORY_PATH TAG_SUFFIX=${BUILD} else TAG_SUFFIX=${PACKAGE_STREAM} fi cat << EOF Using: ${SOLUTION} To generate: ${DOCKERFILE} Values used: 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 echo " ${var} = ${!var}" ENV=${ENV}'$'${var} done SNIPPETS=() # Create a list of all the templates for this distro for snippet in templates/??-*.in templates/${OS_DISTRO}/??-*.in; do if [[ "${TEMPLATE_IGNORE}" != "" ]] && [[ ${snippet} =~ ${TEMPLATE_IGNORE} ]]; then continue fi SNIPPETS+=($snippet) done # Add in the list of templates from the release sub-directory # removing from the base distro if a name conflict if [[ -d templates/${OS_DISTRO}/${OS_RELEASE} ]]; then for snippet in templates/${OS_DISTRO}/${OS_RELEASE}/??-*.in; do if [[ "${TEMPLATE_IGNORE}" != "" ]] && [[ ${snippet} =~ ${TEMPLATE_IGNORE} ]]; then continue fi SNIPPETS=(${SNIPPETS[@]%%*$(basename ${snippet})}) SNIPPETS+=(${snippet}) done fi # Filter to include either ??-repositories-intel.in or # ??-local-file-intel-repo.in based on if a BUILD was specified. # TMP=() for snippet in ${SNIPPETS[@]}; do if [[ "${BUILD}" != "" ]] && [[ "${BUILD}" != "N/A" ]]; then # If a build was specified, then do not include ??-repositories-intel.in and if [[ ${snippet} =~ ..-repositories-intel-com.in ]]; then continue fi else # If a build was NOT specified, then do not include ??-local-file-intel-repo.in and if [[ ${snippet} =~ ..-local-file-intel-repo.in ]]; then continue fi fi # If NO_REPO is set, then use neither repository if (( NO_REPO )); then if [[ ${snippet} =~ ..-local-file-intel-repo.in ]] || [[ ${snippet} =~ ..-repositories-intel-com.in ]]; then continue fi fi TMP+=(${snippet}) done SNIPPETS=(${TMP[@]}) # 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)) # Remove the Dockerfile if it exists; should check # if it is clean first, and abort if not. # [ -e ${DOCKERFILE} ] && rm ${DOCKERFILE} cat << EOM > ${DOCKERFILE} # syntax=docker/dockerfile:1.2 # Enable secrets # # 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 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 To build the image, you can run: export TAG=${OS_DISTRO}-${TAG_SUFFIX} scripts/build-image.sh EOM