#!/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