Skip to content

Commit a29d81a

Browse files
Kalimuthu-Velappanmssonicbld
authored andcommitted
02.Version cache - docker cache build framework (sonic-net#12001)
During docker build, host files can be passed to the docker build through docker context files. But there is no straightforward way to transfer the files from docker build to host. This feature provides a tricky way to pass the cache contents from docker build to host. It tar's the cached content and encodes them as base64 format and passes it through a log file with a special tag as 'VCSTART and VCENT'. Slave.mk in the host, it extracts the cache contents from the log and stores them in the cache folder. Cache contents are encoded as base64 format for easy passing. <!-- Please make sure you've read and understood our contributing guidelines: https://github.com/Azure/SONiC/blob/gh-pages/CONTRIBUTING.md ** Make sure all your commits include a signature generated with `git commit -s` ** If this is a bug fix, make sure your description includes "fixes #xxxx", or "closes #xxxx" or "resolves #xxxx" Please provide the following information: --> #### Why I did it #### How I did it #### How to verify it
1 parent 5b64d82 commit a29d81a

11 files changed

+82
-16
lines changed

Makefile.work

+9-4
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,12 @@ SLAVE_TAG = $(shell \
229229

230230
COLLECT_DOCKER=DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \
231231
scripts/collect_docker_version_files.sh \
232-
$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) \
233-
target
232+
$(SLAVE_BASE_IMAGE) \
233+
target \
234+
$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) \
235+
$(SLAVE_DIR) \
236+
$(SLAVE_DIR)/Dockerfile
237+
234238
OVERLAY_MODULE_CHECK := \
235239
lsmod | grep -q "^overlay " &>/dev/null || \
236240
zgrep -q 'CONFIG_OVERLAY_FS=y' /proc/config.gz &>/dev/null || \
@@ -377,7 +381,8 @@ DOCKER_SLAVE_BASE_BUILD = docker build --no-cache \
377381
--build-arg http_proxy=$(http_proxy) \
378382
--build-arg https_proxy=$(https_proxy) \
379383
--build-arg no_proxy=$(no_proxy) \
380-
$(SLAVE_DIR) $(SPLIT_LOG) $(DOCKER_BASE_LOG)
384+
$(SLAVE_DIR) \
385+
$(SPLIT_LOG) $(DOCKER_BASE_LOG)
381386

382387
DOCKER_BASE_PULL = docker pull \
383388
$(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG)
@@ -508,7 +513,7 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \
508513

509514

510515
ifeq ($(filter clean,$(MAKECMDGOALS)),)
511-
COLLECT_BUILD_VERSION = { DBGOPT='$(DBGOPT)' scripts/collect_build_version_files.sh \$$?; }
516+
COLLECT_BUILD_VERSION = { scripts/collect_build_version_files.sh \$$?; }
512517
endif
513518

514519
ifdef SOURCE_FOLDER
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Base docker build
2+
FROM {{IMAGENAME}}
3+
4+
# Copy the cache data to host
5+
From scratch as output
6+
COPY --from={{IMAGENAME}} /cache.tgz cache.tgz
7+
8+
# Clean up the cache data
9+
FROM {{IMAGENAME}} as final
10+
RUN rm /cache.tgz
11+

scripts/collect_build_version_files.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ mkdir -p $VERSION_SLAVE_PATH
2323

2424
scripts/versions_manager.py merge -t $VERSION_SLAVE_PATH -b $LOG_VERSION_PATH -e $POST_VERSION_PATH
2525

26-
rm -rf $BUILD_VERSION_PATH/*
26+
[ -d $BUILD_VERSION_PATH ] && rm -rf $BUILD_VERSION_PATH/*
2727

2828
exit $RET

scripts/collect_docker_version_files.sh

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#!/bin/bash
22

3+
set -x
34
DOCKER_IMAGE=$1
45
TARGET_PATH=$2
6+
DOCKER_IMAGE_TAG=$3
7+
DOCKER_PATH=$4
8+
DOCKER_FILE=$5
59

610
[ -z "$TARGET_PATH" ] && TARGET_PATH=./target
711

812
DOCKER_IMAGE_NAME=$(echo $DOCKER_IMAGE | cut -d: -f1 | sed "s/-$DOCKER_USERNAME\$//")
9-
DOCKER_CONTAINER=$DOCKER_IMAGE_NAME
13+
#Create the container specific to the user tag and slave tag
14+
DOCKER_CONTAINER=${DOCKER_IMAGE_TAG/:/-}
1015
TARGET_VERSIONS_PATH=$TARGET_PATH/versions/dockers/$DOCKER_IMAGE_NAME
1116

1217
[ -d $TARGET_VERSIONS_PATH ] && rm -rf $TARGET_VERSIONS_PATH
@@ -18,8 +23,16 @@ export DOCKER_CLI_EXPERIMENTAL=enabled
1823
if docker container inspect $DOCKER_IMAGE > /dev/null 2>&1; then
1924
docker container rm $DOCKER_IMAGE > /dev/null
2025
fi
21-
docker create --name $DOCKER_CONTAINER --entrypoint /bin/bash $DOCKER_IMAGE
26+
docker create --name $DOCKER_CONTAINER --entrypoint /bin/bash $DOCKER_IMAGE_TAG
2227
docker cp -L $DOCKER_CONTAINER:/etc/os-release $TARGET_VERSIONS_PATH/
2328
docker cp -L $DOCKER_CONTAINER:/usr/local/share/buildinfo/pre-versions $TARGET_VERSIONS_PATH/
2429
docker cp -L $DOCKER_CONTAINER:/usr/local/share/buildinfo/post-versions $TARGET_VERSIONS_PATH/
30+
31+
# Save the cache contents from docker build
32+
IMAGENAME=${DOCKER_IMAGE_TAG} j2 files/build_templates/build_docker_cache.j2 > ${DOCKER_FILE}.cleanup
33+
docker tag ${DOCKER_IMAGE_TAG} tmp-${DOCKER_IMAGE_TAG}
34+
DOCKER_BUILDKIT=1 docker build -f ${DOCKER_PATH}/Dockerfile.cleanup --target output -o target/vcache/${DOCKER_IMAGE_NAME} ${DOCKER_PATH}
35+
DOCKER_BUILDKIT=1 docker build -f ${DOCKER_PATH}/Dockerfile.cleanup --no-cache --target final --tag ${DOCKER_IMAGE_TAG} ${DOCKER_PATH}
36+
docker rmi tmp-${DOCKER_IMAGE_TAG}
37+
2538
docker container rm $DOCKER_CONTAINER

scripts/collect_host_image_version_files.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
TARGET=$1
44
FILESYSTEM_ROOT=$2
55
VERSIONS_PATH=$TARGET/versions/host-image
6+
IMAGENAME="host-image"
67

78
[ -d $VERSIONS_PATH ] && sudo rm -rf $VERSIONS_PATH
89
mkdir -p $VERSIONS_PATH
910

10-
sudo LANG=C chroot $FILESYSTEM_ROOT post_run_buildinfo
11+
mkdir -p target/vcache/${IMAGENAME}
12+
sudo LANG=C chroot $FILESYSTEM_ROOT post_run_buildinfo ${IMAGENAME}
1113

1214
cp -r $FILESYSTEM_ROOT/usr/local/share/buildinfo/pre-versions $VERSIONS_PATH/
1315
cp -r $FILESYSTEM_ROOT/usr/local/share/buildinfo/post-versions $VERSIONS_PATH/

scripts/prepare_docker_buildinfo.sh

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ DISTRO=$5
1111
DOCKERFILE_PATH=$(dirname "$DOCKERFILE_TARGE")
1212
BUILDINFO_PATH="${DOCKERFILE_PATH}/buildinfo"
1313
BUILDINFO_VERSION_PATH="${BUILDINFO_PATH}/versions"
14+
DOCKER_PATH=$(dirname $DOCKERFILE)
1415

1516
[ -d $BUILDINFO_PATH ] && rm -rf $BUILDINFO_PATH
1617
mkdir -p $BUILDINFO_VERSION_PATH
@@ -31,8 +32,11 @@ scripts/docker_version_control.sh $@
3132

3233
DOCKERFILE_PRE_SCRIPT='# Auto-Generated for buildinfo
3334
COPY ["buildinfo", "/usr/local/share/buildinfo"]
35+
COPY vcache/ /sonic/target/vcache/'${IMAGENAME}'
3436
RUN dpkg -i /usr/local/share/buildinfo/sonic-build-hooks_1.0_all.deb
35-
RUN pre_run_buildinfo'
37+
ENV IMAGENAME='${IMAGENAME}'
38+
RUN pre_run_buildinfo '${IMAGENAME}'
39+
'
3640

3741
# Add the auto-generate code if it is not added in the target Dockerfile
3842
if [ ! -f $DOCKERFILE_TARGE ] || ! grep -q "Auto-Generated for buildinfo" $DOCKERFILE_TARGE; then
@@ -42,7 +46,7 @@ if [ ! -f $DOCKERFILE_TARGE ] || ! grep -q "Auto-Generated for buildinfo" $DOCKE
4246
awk -v text="${DOCKERFILE_PRE_SCRIPT}" -v linenumber=$LINE_NUMBER 'NR==linenumber{print text}1' $DOCKERFILE > $TEMP_FILE
4347

4448
# Append the docker build script at the end of the docker file
45-
echo -e "\nRUN post_run_buildinfo" >> $TEMP_FILE
49+
echo -e "\nRUN post_run_buildinfo ${IMAGENAME} " >> $TEMP_FILE
4650

4751
cat $TEMP_FILE > $DOCKERFILE_TARGE
4852
rm -f $TEMP_FILE
@@ -55,3 +59,8 @@ cp -rf src/sonic-build-hooks/buildinfo/* $BUILDINFO_PATH
5559
scripts/versions_manager.py generate -t "$BUILDINFO_VERSION_PATH" -n "$IMAGENAME" -d "$DISTRO" -a "$ARCH"
5660

5761
touch $BUILDINFO_VERSION_PATH/versions-deb
62+
63+
# Create the cache directories
64+
LOCAL_CACHE_DIR=target/vcache/${IMAGENAME}
65+
mkdir -p ${LOCAL_CACHE_DIR} ${DOCKER_PATH}/vcache/
66+
chmod -f 777 ${LOCAL_CACHE_DIR} ${DOCKER_PATH}/vcache/

slave.mk

+12-3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ configure :
112112
$(Q)mkdir -p $(PYTHON_DEBS_PATH)
113113
$(Q)mkdir -p $(PYTHON_WHEELS_PATH)
114114
$(Q)mkdir -p $(DPKG_ADMINDIR_PATH)
115+
$(Q)mkdir -p $(TARGET_PATH)/vcache
115116
$(Q)echo $(PLATFORM) > .platform
116117
$(Q)echo $(PLATFORM_ARCH) > .arch
117118

@@ -934,8 +935,10 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g
934935
--label Tag=$(SONIC_IMAGE_VERSION) \
935936
-f $(TARGET_DOCKERFILE)/Dockerfile.buildinfo \
936937
-t $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
938+
937939
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
938-
scripts/collect_docker_version_files.sh $(DOCKER_IMAGE_REF) $(TARGET_PATH)
940+
scripts/collect_docker_version_files.sh $* $(TARGET_PATH) $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
941+
939942
$(call docker-image-save,$*,$@)
940943
# Clean up
941944
if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi
@@ -1013,6 +1016,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform
10131016
mkdir -p $($*.gz_PATH)/files $(LOG)
10141017
mkdir -p $($*.gz_PATH)/python-debs $(LOG)
10151018
mkdir -p $($*.gz_PATH)/python-wheels $(LOG)
1019+
mkdir -p $(TARGET_PATH)/vcache/$* $($*.gz_PATH)/vcache $(LOG)
10161020
sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG)
10171021
sudo mount --bind $($*.gz_FILES_PATH) $($*.gz_PATH)/files $(LOG)
10181022
sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG)
@@ -1054,9 +1058,11 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform
10541058
--label Tag=$(SONIC_IMAGE_VERSION) \
10551059
$($(subst -,_,$(notdir $($*.gz_PATH)))_labels) \
10561060
-t $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
1061+
10571062
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
1058-
scripts/collect_docker_version_files.sh $(DOCKER_IMAGE_REF) $(TARGET_PATH)
1063+
scripts/collect_docker_version_files.sh $* $(TARGET_PATH) $(DOCKER_IMAGE_REF) $($*.gz_PATH) $($*.gz_PATH)/Dockerfile $(LOG)
10591064
if [ ! -z $(filter $*.gz,$(SONIC_PACKAGES_LOCAL)) ]; then docker tag $(DOCKER_IMAGE_REF) $*:$(SONIC_IMAGE_VERSION); fi
1065+
10601066
$(call docker-image-save,$*,$@)
10611067
# Clean up
10621068
if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi
@@ -1085,6 +1091,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG
10851091

10861092
mkdir -p $($*.gz_PATH)/debs $(LOG)
10871093
sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG)
1094+
mkdir -p $(TARGET_PATH)/vcache/$*-dbg $($*.gz_PATH)/vcache $(LOG)
10881095
# Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs
10891096
$(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++'))
10901097
$(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++'))
@@ -1108,9 +1115,11 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG
11081115
--label Tag=$(SONIC_IMAGE_VERSION) \
11091116
--file $($*.gz_PATH)/Dockerfile-dbg \
11101117
-t $(DOCKER_DBG_IMAGE_REF) $($*.gz_PATH) $(LOG)
1118+
11111119
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
1112-
scripts/collect_docker_version_files.sh $(DOCKER_DBG_IMAGE_REF) $(TARGET_PATH)
1120+
scripts/collect_docker_version_files.sh $*-dbg $(TARGET_PATH) $(DOCKER_DBG_IMAGE_REF) $($*.gz_PATH) $($*.gz_PATH)/Dockerfile-dbg $(LOG)
11131121
if [ ! -z $(filter $*.gz,$(SONIC_PACKAGES_LOCAL)) ]; then docker tag $(DOCKER_IMAGE_REF) $*:$(SONIC_IMAGE_VERSION); fi
1122+
11141123
$(call docker-image-save,$*-$(DBG_IMAGE_MARK),$@)
11151124
# Clean up
11161125
docker rmi -f $(DOCKER_IMAGE_REF) &> /dev/null || true

sonic-slave-buster/Dockerfile.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ RUN add-apt-repository \
599599
$(lsb_release -cs) \
600600
stable"
601601
RUN apt-get update
602-
RUN apt-get install -y docker-ce=5:18.09.5~3-0~debian-buster docker-ce-cli=5:18.09.5~3-0~debian-buster
602+
RUN apt-get install -y docker-ce=5:20.10.21~3-0~debian-buster docker-ce-cli=5:20.10.21~3-0~debian-buster
603603
RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs {{ DOCKER_EXTRA_OPTS }}\"" >> /etc/default/docker
604604
RUN update-alternatives --set iptables /usr/sbin/iptables-legacy
605605

src/sonic-build-hooks/scripts/buildinfo_base.sh

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ REPR_MIRROR_URL_PATTERN='http:\/\/packages.trafficmanager.net\/'
1515
DPKG_INSTALLTION_LOCK_FILE=/tmp/.dpkg_installation.lock
1616

1717
. $BUILDINFO_PATH/config/buildinfo.config
18+
if [ -e /vcache ]; then
19+
PKG_CACHE_PATH=/vcache/${IMAGENAME}
20+
else
21+
PKG_CACHE_PATH=/sonic/target/vcache/${IMAGENAME}
22+
fi
23+
PKG_CACHE_FILE_NAME=${PKG_CACHE_PATH}/cache.tgz
24+
mkdir -p ${PKG_CACHE_PATH}
25+
26+
1827

1928
URL_PREFIX=$(echo "${PACKAGE_URL_PREFIX}" | sed -E "s#(//[^/]*/).*#\1#")
2029

src/sonic-build-hooks/scripts/post_run_buildinfo

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#!/bin/bash
22

3+
IMAGENAME=$1
4+
35
. /usr/local/share/buildinfo/scripts/buildinfo_base.sh
46

57
# Collect the version files
68
collect_version_files $POST_VERSION_PATH
79

8-
[ -d $BUILD_VERSION_PATH ] && [ ! -z "$(ls -A $BUILD_VERSION_PATH)" ] && cp -rf $BUILD_VERSION_PATH/* $POST_VERSION_PATH
9-
rm -rf $BUILD_VERSION_PATH/*
10+
#Save the cache file for exporting it to host.
11+
tar -C ${PKG_CACHE_PATH} --exclude=cache.tgz -zcvf /cache.tgz .
1012

1113
# Disable the build hooks
1214
symlink_build_hooks -d

src/sonic-build-hooks/scripts/pre_run_buildinfo

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/bash
22

3+
IMAGENAME=$1
4+
35
. /usr/local/share/buildinfo/scripts/buildinfo_base.sh
46

57
[ -d $DIFF_VERSION_PATH ] && rm -rf $DIFF_VERSION_PATH
@@ -15,10 +17,14 @@ update_version_files
1517
symlink_build_hooks
1618
set_reproducible_mirrors
1719

20+
mkdir -p /var/cache/apt/archives/
21+
1822
chmod -R a+rw $BUILDINFO_PATH
1923

2024
if [ "$ENABLE_VERSION_CONTROL_DEB" == "y" ] && [ -f $VERSION_DEB_PREFERENCE ]; then
2125
cp -f $VERSION_DEB_PREFERENCE /etc/apt/preferences.d/
2226
fi
2327

28+
DISTRO=${DISTRO} apt-get update && apt-get install -y rsync
29+
2430
exit 0

0 commit comments

Comments
 (0)