Skip to content

Commit 8bd11c2

Browse files
Kalimuthu-Velappanpull[bot]
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 1e20ccc commit 8bd11c2

11 files changed

+82
-16
lines changed

Makefile.work

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

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

381386
DOCKER_BASE_PULL = docker pull \
382387
$(REGISTRY_SERVER):$(REGISTRY_PORT)/$(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG)
@@ -507,7 +512,7 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \
507512

508513

509514
ifeq ($(filter clean,$(MAKECMDGOALS)),)
510-
COLLECT_BUILD_VERSION = { DBGOPT='$(DBGOPT)' scripts/collect_build_version_files.sh \$$?; }
515+
COLLECT_BUILD_VERSION = { scripts/collect_build_version_files.sh \$$?; }
511516
endif
512517

513518
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
@@ -111,6 +111,7 @@ configure :
111111
$(Q)mkdir -p $(PYTHON_DEBS_PATH)
112112
$(Q)mkdir -p $(PYTHON_WHEELS_PATH)
113113
$(Q)mkdir -p $(DPKG_ADMINDIR_PATH)
114+
$(Q)mkdir -p $(TARGET_PATH)/vcache
114115
$(Q)echo $(PLATFORM) > .platform
115116
$(Q)echo $(PLATFORM_ARCH) > .arch
116117

@@ -914,8 +915,10 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.g
914915
--label Tag=$(SONIC_IMAGE_VERSION) \
915916
-f $(TARGET_DOCKERFILE)/Dockerfile.buildinfo \
916917
-t $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
918+
917919
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
918-
scripts/collect_docker_version_files.sh $(DOCKER_IMAGE_REF) $(TARGET_PATH)
920+
scripts/collect_docker_version_files.sh $* $(TARGET_PATH) $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
921+
919922
$(call docker-image-save,$*,$@)
920923
# Clean up
921924
if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi
@@ -993,6 +996,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform
993996
mkdir -p $($*.gz_PATH)/files $(LOG)
994997
mkdir -p $($*.gz_PATH)/python-debs $(LOG)
995998
mkdir -p $($*.gz_PATH)/python-wheels $(LOG)
999+
mkdir -p $(TARGET_PATH)/vcache/$* $($*.gz_PATH)/vcache $(LOG)
9961000
sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG)
9971001
sudo mount --bind $($*.gz_FILES_PATH) $($*.gz_PATH)/files $(LOG)
9981002
sudo mount --bind $(PYTHON_DEBS_PATH) $($*.gz_PATH)/python-debs $(LOG)
@@ -1034,9 +1038,11 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform
10341038
--label Tag=$(SONIC_IMAGE_VERSION) \
10351039
$($(subst -,_,$(notdir $($*.gz_PATH)))_labels) \
10361040
-t $(DOCKER_IMAGE_REF) $($*.gz_PATH) $(LOG)
1041+
10371042
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
1038-
scripts/collect_docker_version_files.sh $(DOCKER_IMAGE_REF) $(TARGET_PATH)
1043+
scripts/collect_docker_version_files.sh $* $(TARGET_PATH) $(DOCKER_IMAGE_REF) $($*.gz_PATH) $($*.gz_PATH)/Dockerfile $(LOG)
10391044
if [ ! -z $(filter $*.gz,$(SONIC_PACKAGES_LOCAL)) ]; then docker tag $(DOCKER_IMAGE_REF) $*:$(SONIC_IMAGE_VERSION); fi
1045+
10401046
$(call docker-image-save,$*,$@)
10411047
# Clean up
10421048
if [ -f $($*.gz_PATH).patch/series ]; then pushd $($*.gz_PATH) && quilt pop -a -f; [ -d .pc ] && rm -rf .pc; popd; fi
@@ -1065,6 +1071,7 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG
10651071

10661072
mkdir -p $($*.gz_PATH)/debs $(LOG)
10671073
sudo mount --bind $($*.gz_DEBS_PATH) $($*.gz_PATH)/debs $(LOG)
1074+
mkdir -p $(TARGET_PATH)/vcache/$*-dbg $($*.gz_PATH)/vcache $(LOG)
10681075
# Export variables for j2. Use path for unique variable names, e.g. docker_orchagent_debs
10691076
$(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_dbg_debs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_DEPENDS),RDEPENDS))\n" | awk '!a[$$0]++'))
10701077
$(eval export $(subst -,_,$(notdir $($*.gz_PATH)))_image_dbgs=$(shell printf "$(subst $(SPACE),\n,$(call expand,$($*.gz_DBG_IMAGE_PACKAGES)))\n" | awk '!a[$$0]++'))
@@ -1088,9 +1095,11 @@ $(addprefix $(TARGET_PATH)/, $(DOCKER_DBG_IMAGES)) : $(TARGET_PATH)/%-$(DBG_IMAG
10881095
--label Tag=$(SONIC_IMAGE_VERSION) \
10891096
--file $($*.gz_PATH)/Dockerfile-dbg \
10901097
-t $(DOCKER_DBG_IMAGE_REF) $($*.gz_PATH) $(LOG)
1098+
10911099
if [ x$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) == x"y" ]; then docker tag $(DOCKER_IMAGE_REF) $*; fi
1092-
scripts/collect_docker_version_files.sh $(DOCKER_DBG_IMAGE_REF) $(TARGET_PATH)
1100+
scripts/collect_docker_version_files.sh $*-dbg $(TARGET_PATH) $(DOCKER_DBG_IMAGE_REF) $($*.gz_PATH) $($*.gz_PATH)/Dockerfile-dbg $(LOG)
10931101
if [ ! -z $(filter $*.gz,$(SONIC_PACKAGES_LOCAL)) ]; then docker tag $(DOCKER_IMAGE_REF) $*:$(SONIC_IMAGE_VERSION); fi
1102+
10941103
$(call docker-image-save,$*-$(DBG_IMAGE_MARK),$@)
10951104
# Clean up
10961105
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\/debian'
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)