forked from edge-core/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_docker.sh
executable file
·142 lines (126 loc) · 4.44 KB
/
build_docker.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/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
retry_times=3
## 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
set +e
for (( i=$retry_times; i>0; i-- )); do
timeout 1h docker build --no-cache -t $docker_image_name $DOCKER_BUILD_DIR
ret_code=$?
case $ret_code in
# Docker build without error.
"0")
break
;;
# Docker build timeout
"124")
docker_try_rmi $docker_image_name # Remove the exist image
if [[ $i -eq 1 ]]; then
echo "Failed to build container [$docker_image_name] in $retry_times times, exit. "
rm -rf $DOCKER_BUILD_DIR
exit $ret_code
else
echo "Failed to build container [$docker_image_name], retry. "
fi
;;
# Command "Timeout" return error.
"125"|"126"|"127"|"137")
echo "Error with command \"timeout\", exit. "
break
;;
# Docker build got error
*)
rm -rf $DOCKER_BUILD_DIR # Replace the trap_up function
exit $ret_code ;;
esac
done
## Get the ID of the built image
## Note: inspect output has quotation characters, so sed to remove it as an argument
set -e
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