sonic-buildimage/build_docker.sh
Konstantin Vasin bf90b498a4
[Build] use pigz to speed up a build (#12825)
Why I did it

It's possible to speed up some parts of a build using parallel compression/decompression.
This is especially important for build_debian.sh.

How I did it
pigz is a parallel implementation of gzip: https://zlib.net/pigz/
Some programs like docker and mkinitramfs can automatically detect and use it instead of gzip.
For tar we need to select it directly.

To enable this feature you need to set GZ_COMPRESS_PROGRAM=pigz
2022-12-17 14:38:31 -08:00

110 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
## This script is to automate the preparation for docker images for SONiC.
## If registry server and port provided, the images will be pushed there.
set -e
. ./functions.sh
usage() {
cat >&2 <<EOF
Usage:
sudo ./build_docker.sh [-i DOCKER_IMAGE_NAME] [-t DOCKER_IMAGE_TAG] DOCKER_BUILD_DIR [REGISTRY_SERVER REGISTRY_PORT REGISTRY_USERNAME REGISTRY_PASSWD]
Description:
-i DOCKER_IMAGE_NAME
Specify the docker image's name, by default it is DOCKER_BUILD_DIR
-t DOCKER_IMAGE_TAG
Specify the docker image's tag, by default it is latest
DOCKER_BUILD_DIR
The directory containing Dockerfile
REGISTRY_SERVER
The server name of the docker registry
REGISTRY_PORT
The port of the docker registry
Example:
./build_docker.sh -i docker-orchagent-mlnx docker-orchagent
EOF
}
docker_image_name=''
docker_image_tag=latest
## The option-string tells getopts which options to expect and which of them must have an argument
## When you want getopts to expect an argument for an option, just place a : (colon) after the proper option flag
## If the very first character of the option-string is a :, getopts switches to "silent error reporting mode".
while getopts "i:t:" opt; do
case $opt in
i)
docker_image_name=$OPTARG
;;
t)
docker_image_tag=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
esac
done
shift "$((OPTIND - 1))"
## Dockerfile directory
DOCKER_BUILD_DIR=dockers/$1
shift 1
[ -f "$DOCKER_BUILD_DIR"/Dockerfile ] || {
echo "Invalid DOCKER_BUILD_DIR directory" >&2
exit 1
}
[ -n "$docker_image_name" ] || {
docker_image_name=$(basename $DOCKER_BUILD_DIR)
}
## Copy dependencies
## Note: Dockerfile ADD doesn't support reference files outside the folder, so copy it locally
if ls deps/* 1>/dev/null 2>&1; then
trap_push "rm -rf $DOCKER_BUILD_DIR/deps"
mkdir -p $DOCKER_BUILD_DIR/deps
cp -r deps/* $DOCKER_BUILD_DIR/deps
fi
## Copy the suggested Debian sources
## ref: https://wiki.debian.org/SourcesList
trap_push "rm -rf $DOCKER_BUILD_DIR/deps"
cp -r files $DOCKER_BUILD_DIR/files
docker_try_rmi $docker_image_name
## Build the docker image
docker build --no-cache -t $docker_image_name $DOCKER_BUILD_DIR
## Get the ID of the built image
## Note: inspect output has quotation characters, so sed to remove it as an argument
image_id=$(docker inspect --format="{{json .Id}}" $docker_image_name | sed -e 's/^"//' -e 's/"$//')
## Flatten the image by importing an exported container on this image
## Note: it will squash the image with only one layer and lost all metadata such as ENTRYPOINT,
## so apply only to the base image
## TODO: wait docker-squash supporting Docker 1.10+
## ref: https://github.com/jwilder/docker-squash/issues/45
if [ "$docker_image_name" = "docker-base" ]; then
## Run old image in a container
tmp_container=$(docker run -d ${docker_image_name} /bin/bash)
## Export the container's filesystem, then import as a new image
docker export $tmp_container | docker import - ${docker_image_name}
## Remove the container
docker rm -f $tmp_container || true
## Remove the old image
docker rmi -f $image_id || true
fi
## Save the docker image in a gz file
mkdir -p target
command -v pigz > /dev/null && GZ_COMPRESS_PROGRAM=pigz || GZ_COMPRESS_PROGRAM=gzip
docker save $docker_image_name | $GZ_COMPRESS_PROGRAM -c > target/$docker_image_name.gz
if [ -n "$1" ]; then
./push_docker.sh target/$docker_image_name.gz $@ $docker_image_tag
fi