2020-12-21 01:31:10 -06:00
|
|
|
#!/bin/bash
|
|
|
|
|
2023-05-24 11:25:12 -05:00
|
|
|
[[ ! -z "${DBGOPT}" && $0 =~ ${DBGOPT} ]] && set -x
|
2022-12-11 19:20:56 -06:00
|
|
|
|
|
|
|
BUILDINFO_BASE=/usr/local/share/buildinfo
|
|
|
|
|
|
|
|
SCRIPT_SRC_PATH=src/sonic-build-hooks
|
|
|
|
if [ -e ${SCRIPT_SRC_PATH} ]; then
|
2023-05-24 11:25:12 -05:00
|
|
|
. ${SCRIPT_SRC_PATH}/scripts/utils.sh
|
2022-12-11 19:20:56 -06:00
|
|
|
else
|
2023-05-24 11:25:12 -05:00
|
|
|
. ${BUILDINFO_BASE}/scripts/utils.sh
|
2022-12-11 19:20:56 -06:00
|
|
|
fi
|
|
|
|
|
2020-12-21 01:31:10 -06:00
|
|
|
IMAGENAME=$1
|
|
|
|
DOCKERFILE=$2
|
|
|
|
ARCH=$3
|
2022-12-11 19:20:56 -06:00
|
|
|
DOCKERFILE_TARGET=$4
|
2020-12-21 01:31:10 -06:00
|
|
|
DISTRO=$5
|
|
|
|
|
2022-12-11 19:20:56 -06:00
|
|
|
|
2020-12-21 01:31:10 -06:00
|
|
|
[ -z "$BUILD_SLAVE" ] && BUILD_SLAVE=n
|
2022-12-11 19:20:56 -06:00
|
|
|
[ -z "$DOCKERFILE_TARGET" ] && DOCKERFILE_TARGET=$DOCKERFILE
|
|
|
|
DOCKERFILE_PATH=$(dirname "$DOCKERFILE_TARGET")
|
2020-12-21 01:31:10 -06:00
|
|
|
BUILDINFO_PATH="${DOCKERFILE_PATH}/buildinfo"
|
|
|
|
BUILDINFO_VERSION_PATH="${BUILDINFO_PATH}/versions"
|
2022-12-01 18:28:45 -06:00
|
|
|
DOCKER_PATH=$(dirname $DOCKERFILE)
|
2020-12-21 01:31:10 -06:00
|
|
|
|
|
|
|
[ -d $BUILDINFO_PATH ] && rm -rf $BUILDINFO_PATH
|
|
|
|
mkdir -p $BUILDINFO_VERSION_PATH
|
|
|
|
|
|
|
|
# Get the debian distribution from the docker base image
|
|
|
|
if [ -z "$DISTRO" ]; then
|
|
|
|
DOCKER_BASE_IMAGE=$(grep "^FROM" $DOCKERFILE | head -n 1 | awk '{print $2}')
|
|
|
|
DISTRO=$(docker run --rm --entrypoint "" $DOCKER_BASE_IMAGE cat /etc/os-release | grep VERSION_CODENAME | cut -d= -f2)
|
2022-12-04 01:04:36 -06:00
|
|
|
if [ -z "$DISTRO" ]; then
|
|
|
|
DISTRO=$(docker run --rm --entrypoint "" $DOCKER_BASE_IMAGE cat /etc/apt/sources.list | grep deb.debian.org | awk '{print $3}')
|
|
|
|
[ -z "$DISTRO" ] && DISTRO=jessie
|
|
|
|
fi
|
2020-12-21 01:31:10 -06:00
|
|
|
fi
|
|
|
|
|
2023-04-11 04:07:26 -05:00
|
|
|
if [[ "$IMAGENAME" == sonic-slave-* ]] || [[ "$IMAGENAME" == docker-base-* ]] || [[ "$IMAGENAME" == docker-ptf ]]; then
|
2022-11-08 18:09:53 -06:00
|
|
|
scripts/build_mirror_config.sh ${DOCKERFILE_PATH} $ARCH $DISTRO
|
|
|
|
fi
|
|
|
|
|
2021-07-09 01:30:26 -05:00
|
|
|
# add script for reproducible build. using sha256 instead of tag for docker base image.
|
|
|
|
scripts/docker_version_control.sh $@
|
|
|
|
|
|
|
|
DOCKERFILE_PRE_SCRIPT='# Auto-Generated for buildinfo
|
2022-12-11 19:20:56 -06:00
|
|
|
ARG SONIC_VERSION_CACHE
|
|
|
|
ARG SONIC_VERSION_CONTROL_COMPONENTS
|
2020-12-21 01:31:10 -06:00
|
|
|
COPY ["buildinfo", "/usr/local/share/buildinfo"]
|
2022-12-01 18:28:45 -06:00
|
|
|
COPY vcache/ /sonic/target/vcache/'${IMAGENAME}'
|
2020-12-21 01:31:10 -06:00
|
|
|
RUN dpkg -i /usr/local/share/buildinfo/sonic-build-hooks_1.0_all.deb
|
2022-12-01 18:28:45 -06:00
|
|
|
ENV IMAGENAME='${IMAGENAME}'
|
2022-12-11 19:20:56 -06:00
|
|
|
ENV DISTRO='${DISTRO}'
|
2022-12-01 18:28:45 -06:00
|
|
|
RUN pre_run_buildinfo '${IMAGENAME}'
|
|
|
|
'
|
2020-12-21 01:31:10 -06:00
|
|
|
|
|
|
|
# Add the auto-generate code if it is not added in the target Dockerfile
|
2022-12-11 19:20:56 -06:00
|
|
|
if [ ! -f $DOCKERFILE_TARGET ] || ! grep -q "Auto-Generated for buildinfo" $DOCKERFILE_TARGET; then
|
2020-12-21 01:31:10 -06:00
|
|
|
# Insert the docker build script before the RUN command
|
|
|
|
LINE_NUMBER=$(grep -Fn -m 1 'RUN' $DOCKERFILE | cut -d: -f1)
|
|
|
|
TEMP_FILE=$(mktemp)
|
|
|
|
awk -v text="${DOCKERFILE_PRE_SCRIPT}" -v linenumber=$LINE_NUMBER 'NR==linenumber{print text}1' $DOCKERFILE > $TEMP_FILE
|
|
|
|
|
|
|
|
# Append the docker build script at the end of the docker file
|
2022-12-01 18:28:45 -06:00
|
|
|
echo -e "\nRUN post_run_buildinfo ${IMAGENAME} " >> $TEMP_FILE
|
2022-12-11 19:20:56 -06:00
|
|
|
echo -e "\nRUN post_run_cleanup ${IMAGENAME} " >> $TEMP_FILE
|
2020-12-21 01:31:10 -06:00
|
|
|
|
2022-12-11 19:20:56 -06:00
|
|
|
cat $TEMP_FILE > $DOCKERFILE_TARGET
|
2020-12-21 01:31:10 -06:00
|
|
|
rm -f $TEMP_FILE
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Copy the build info config
|
2022-12-11 19:20:56 -06:00
|
|
|
mkdir -p ${BUILDINFO_PATH}
|
2020-12-21 01:31:10 -06:00
|
|
|
cp -rf src/sonic-build-hooks/buildinfo/* $BUILDINFO_PATH
|
|
|
|
|
|
|
|
# Generate the version lock files
|
|
|
|
scripts/versions_manager.py generate -t "$BUILDINFO_VERSION_PATH" -n "$IMAGENAME" -d "$DISTRO" -a "$ARCH"
|
|
|
|
|
|
|
|
touch $BUILDINFO_VERSION_PATH/versions-deb
|
2022-12-01 18:28:45 -06:00
|
|
|
|
|
|
|
# Create the cache directories
|
|
|
|
LOCAL_CACHE_DIR=target/vcache/${IMAGENAME}
|
|
|
|
mkdir -p ${LOCAL_CACHE_DIR} ${DOCKER_PATH}/vcache/
|
|
|
|
chmod -f 777 ${LOCAL_CACHE_DIR} ${DOCKER_PATH}/vcache/
|
2022-12-11 19:20:56 -06:00
|
|
|
|
|
|
|
if [[ "$SKIP_BUILD_HOOK" == y || ${ENABLE_VERSION_CONTROL_DOCKER} != y ]]; then
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2023-05-24 11:25:12 -05:00
|
|
|
# Version cache
|
2022-12-11 19:20:56 -06:00
|
|
|
DOCKER_IMAGE_NAME=${IMAGENAME}
|
|
|
|
IMAGE_DBGS_NAME=${DOCKER_IMAGE_NAME//-/_}_image_dbgs
|
|
|
|
|
|
|
|
if [[ ${DOCKER_IMAGE_NAME} == sonic-slave-* ]]; then
|
|
|
|
GLOBAL_CACHE_DIR=${SONIC_VERSION_CACHE_SOURCE}/${DOCKER_IMAGE_NAME}
|
|
|
|
else
|
|
|
|
GLOBAL_CACHE_DIR=/vcache/${DOCKER_IMAGE_NAME}
|
|
|
|
fi
|
|
|
|
|
|
|
|
SRC_VERSION_PATH=files/build/versions
|
|
|
|
if [ ! -z ${SONIC_VERSION_CACHE} ]; then
|
|
|
|
|
|
|
|
# Version files for SHA calculation
|
|
|
|
VERSION_FILES="${SRC_VERSION_PATH}/dockers/${DOCKER_IMAGE_NAME}/versions-*-${DISTRO}-${ARCH} ${SRC_VERSION_PATH}/default/versions-*"
|
|
|
|
DEP_FILES="Dockerfile.j2"
|
|
|
|
if [[ ${DOCKER_IMAGE_NAME} =~ '-dbg' ]]; then
|
|
|
|
DEP_DBG_FILES="build_debug_docker_j2.sh"
|
|
|
|
fi
|
|
|
|
|
|
|
|
#Calculate the version SHA
|
|
|
|
VERSION_SHA="$( (echo -n "${!IMAGE_DBGS_NAME}"; \
|
|
|
|
(cd ${DOCKER_PATH}; cat ${DEP_FILES}); \
|
|
|
|
cat ${DEP_DBG_FILES} ${VERSION_FILES}) \
|
|
|
|
| sha1sum | awk '{print substr($1,0,23);}')"
|
|
|
|
|
|
|
|
GLOBAL_CACHE_FILE=${GLOBAL_CACHE_DIR}/${DOCKER_IMAGE_NAME}-${VERSION_SHA}.tgz
|
|
|
|
LOCAL_CACHE_FILE=${LOCAL_CACHE_DIR}/cache.tgz
|
|
|
|
GIT_FILE_STATUS=$(git status -s ${DEP_FILES})
|
|
|
|
|
|
|
|
# Create the empty cache tar file as local cache
|
|
|
|
if [[ ! -f ${LOCAL_CACHE_FILE} ]]; then
|
|
|
|
tar -zcf ${LOCAL_CACHE_FILE} -T /dev/null
|
|
|
|
chmod -f 777 ${LOCAL_CACHE_FILE}
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Global cache file exists, load from global cache.
|
|
|
|
if [[ -e ${GLOBAL_CACHE_FILE} ]]; then
|
|
|
|
cp ${GLOBAL_CACHE_FILE} ${LOCAL_CACHE_FILE}
|
|
|
|
touch ${GLOBAL_CACHE_FILE}
|
|
|
|
else
|
|
|
|
# When file is modified, Global SHA is calculated with the local change.
|
|
|
|
# Load from the previous version of build cache if exists
|
|
|
|
VERSIONS=( "HEAD" "HEAD~1" "HEAD~2" )
|
|
|
|
for VERSION in ${VERSIONS[@]}; do
|
|
|
|
VERSION_PREV_SHA="$( (echo -n "${!IMAGE_DBGS_NAME}"; \
|
|
|
|
(cd ${DOCKER_PATH}; git --no-pager show $(ls -f ${DEP_FILES}|sed 's|.*|'${VERSION}':./&|g')); \
|
|
|
|
(git --no-pager show $(ls -f ${DEP_DBG_FILES} ${VERSION_FILES}|sed 's|.*|'${VERSION}':&|g'))) \
|
|
|
|
| sha1sum | awk '{print substr($1,0,23);}')"
|
|
|
|
GLOBAL_PREV_CACHE_FILE=${GLOBAL_CACHE_DIR}/${DOCKER_IMAGE_NAME}-${VERSION_PREV_SHA}.tgz
|
|
|
|
if [[ -e ${GLOBAL_PREV_CACHE_FILE} ]]; then
|
|
|
|
cp ${GLOBAL_PREV_CACHE_FILE} ${LOCAL_CACHE_FILE}
|
|
|
|
touch ${GLOBAL_PREV_CACHE_FILE}
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
rm -f ${DOCKER_PATH}/vcache/cache.tgz
|
|
|
|
ln -f ${LOCAL_CACHE_FILE} ${DOCKER_PATH}/vcache/cache.tgz
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
# Delete the cache file if version cache is disabled.
|
|
|
|
rm -f ${DOCKER_PATH}/vcache/cache.tgz
|
|
|
|
fi
|
|
|
|
|