docker_push.sh 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #!/bin/bash
  2. #
  3. # vi: expandtab tabstop=4 shiftwidth=0
  4. set -o errexit
  5. set -o pipefail
  6. if [ "$DEBUG" == "true" ]; then
  7. set -ex
  8. export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
  9. fi
  10. readlink_mac() {
  11. cd $(dirname $1)
  12. TARGET_FILE=$(basename $1)
  13. # Iterate down a (possible) chain of symlinks
  14. while [ -L "$TARGET_FILE" ]; do
  15. TARGET_FILE=$(readlink $TARGET_FILE)
  16. cd $(dirname $TARGET_FILE)
  17. TARGET_FILE=$(basename $TARGET_FILE)
  18. done
  19. # Compute the canonicalized name by finding the physical path
  20. # for the directory we're in and appending the target file.
  21. PHYS_DIR=$(pwd -P)
  22. REAL_PATH=$PHYS_DIR/$TARGET_FILE
  23. }
  24. get_current_arch() {
  25. local current_arch
  26. case $(uname -m) in
  27. x86_64)
  28. current_arch=amd64
  29. ;;
  30. aarch64)
  31. current_arch=arm64
  32. ;;
  33. riscv64)
  34. current_arch=riscv64
  35. ;;
  36. esac
  37. echo $current_arch
  38. }
  39. ALLARCH=("amd64" "arm64" "riscv64")
  40. pushd $(
  41. cd "$(dirname "$0")"
  42. pwd
  43. ) >/dev/null
  44. readlink_mac $(basename "$0")
  45. cd "$(dirname "$REAL_PATH")"
  46. CUR_DIR=$(pwd)
  47. SRC_DIR=$(cd .. && pwd)
  48. popd >/dev/null
  49. DOCKER_DIR="$SRC_DIR/build/docker"
  50. # https://docs.docker.com/develop/develop-images/build_enhancements/
  51. export DOCKER_BUILDKIT=1
  52. # https://github.com/docker/buildx#with-buildx-or-docker-1903
  53. export DOCKER_CLI_EXPERIMENTAL=enabled
  54. REGISTRY=${REGISTRY:-docker.io/yunion}
  55. TAG=${TAG:-latest}
  56. CURRENT_ARCH=$(get_current_arch)
  57. ARCH=${ARCH:-$CURRENT_ARCH}
  58. build_bin() {
  59. local BUILD_ARCH=$2
  60. local BUILD_CGO=$3
  61. case "$1" in
  62. climc)
  63. rm -vf _output/bin/*cli
  64. env $BUILD_ARCH $BUILD_CGO make -C "$SRC_DIR" docker-alpine-build F="cmd/$1 cmd/*cli"
  65. ;;
  66. *)
  67. env $BUILD_ARCH $BUILD_CGO make -C "$SRC_DIR" docker-alpine-build F="cmd/$1"
  68. ;;
  69. esac
  70. }
  71. # build_bundle_libraries() {
  72. # for bundle_component in 'host-image'; do
  73. # if [ $1 == $bundle_component ]; then
  74. # $CUR_DIR/bundle_libraries.sh _output/bin/bundles/$1 _output/bin/$1
  75. # break
  76. # fi
  77. # done
  78. # }
  79. build_image() {
  80. local tag=$1
  81. local file=$2
  82. local path=$3
  83. local arch
  84. if [[ "$tag" == *:5000/* ]]; then
  85. arch=$(arch)
  86. case $arch in
  87. x86_64)
  88. docker buildx build -t "$tag" -f "$2" "$3" --output type=docker --platform linux/amd64
  89. ;;
  90. aarch64)
  91. docker buildx build -t "$tag" -f "$2" "$3" --output type=docker --platform linux/arm64
  92. ;;
  93. riscv64)
  94. docker buildx build -t "$tag" -f "$2" "$3" --output type=docker --platform linux/riscv64
  95. ;;
  96. *)
  97. echo wrong arch
  98. exit 1
  99. ;;
  100. esac
  101. else
  102. if [[ "$tag" == *"amd64" || "$ARCH" == "" || "$ARCH" == "amd64" || "$ARCH" == "x86_64" || "$ARCH" == "x86" ]]; then
  103. docker buildx build -t "$tag" -f "$file" "$path" --push --platform linux/amd64
  104. elif [[ "$tag" == *"arm64" || "$ARCH" == "arm64" ]]; then
  105. docker buildx build -t "$tag" -f "$file" "$path" --push --platform linux/arm64
  106. elif [[ "$tag" == *"riscv64" || "$ARCH" == "riscv64" ]]; then
  107. docker buildx build -t "$tag" -f "$file" "$path" --push --platform linux/riscv64
  108. else
  109. docker buildx build -t "$tag" -f "$file" "$path" --push
  110. fi
  111. docker pull "$tag"
  112. fi
  113. }
  114. buildx_and_push() {
  115. local tag=$1
  116. local file=$2
  117. local path=$3
  118. local arch=$4
  119. if [[ "$DRY_RUN" == "true" ]]; then
  120. echo "[$(readlink -f ${BASH_SOURCE}):${LINENO} ${FUNCNAME[0]}] return for DRY_RUN"
  121. return
  122. fi
  123. docker buildx build -t "$tag" --platform "linux/$arch" -f "$2" "$3" --push
  124. docker pull --platform "linux/$arch" "$tag"
  125. }
  126. get_image_name() {
  127. local component=$1
  128. local arch=$2
  129. local is_all_arch=$3
  130. local img_name="$REGISTRY/$component:$TAG"
  131. if [[ -n "$arch" && "$is_all_arch" == "true" ]]; then
  132. img_name="${img_name}-$arch"
  133. fi
  134. echo $img_name
  135. }
  136. build_process() {
  137. local component=$1
  138. local arch=$2
  139. local is_all_arch=$3
  140. local img_name=$(get_image_name $component $arch $is_all_arch)
  141. local build_env=""
  142. case "$component" in
  143. host)
  144. build_env="$build_env CGO_ENABLED=1"
  145. ;;
  146. *)
  147. build_env="$build_env CGO_ENABLED=0"
  148. ;;
  149. esac
  150. build_bin $component
  151. if [[ "$DRY_RUN" == "true" ]]; then
  152. echo "[$(readlink -f ${BASH_SOURCE}):${LINENO} ${FUNCNAME[0]}] return for DRY_RUN"
  153. return
  154. fi
  155. # build_bundle_libraries $component
  156. build_image $img_name $DOCKER_DIR/Dockerfile.$component $SRC_DIR
  157. }
  158. build_process_with_buildx() {
  159. local component=$1
  160. local arch=$2
  161. local is_all_arch=$3
  162. local img_name=$(get_image_name $component $arch $is_all_arch)
  163. build_env="GOARCH=$arch"
  164. case "$component" in
  165. host)
  166. build_env="$build_env CGO_ENABLED=1"
  167. ;;
  168. *)
  169. build_env="$build_env CGO_ENABLED=0"
  170. ;;
  171. esac
  172. case "$component" in
  173. host | torrent)
  174. buildx_and_push $img_name $DOCKER_DIR/multi-arch/Dockerfile.$component $SRC_DIR $arch
  175. ;;
  176. *)
  177. build_bin $component $build_env
  178. buildx_and_push $img_name $DOCKER_DIR/Dockerfile.$component $SRC_DIR $arch
  179. ;;
  180. esac
  181. }
  182. general_build() {
  183. local component=$1
  184. # 如果未指定,则默认使用当前架构
  185. local arch=${2:-$CURRENT_ARCH}
  186. local is_all_arch=$3
  187. if [[ "$CURRENT_ARCH" == "$arch" ]]; then
  188. build_process $component $arch $is_all_arch
  189. else
  190. build_process_with_buildx $component $arch $is_all_arch
  191. fi
  192. }
  193. make_manifest_image() {
  194. local component=$1
  195. local arch=$2
  196. local img_name=$(get_image_name $component "" "false")
  197. if [[ "$DRY_RUN" == "true" ]]; then
  198. echo "[$(readlink -f ${BASH_SOURCE}):${LINENO} ${FUNCNAME[0]}] return for DRY_RUN"
  199. return
  200. fi
  201. CMD="docker buildx imagetools create -t ${img_name} "
  202. for ac in "${ALLARCH[@]}"; do
  203. if [[ "${arch}" == "all" || "${arch}" == *"$ac"* ]]; then
  204. CMD="${CMD} ${img_name}-${ac}"
  205. fi
  206. done
  207. echo "$CMD"
  208. $CMD
  209. }
  210. ALL_COMPONENTS=$(ls cmd | grep -v '.*cli$' | xargs)
  211. if [ "$#" -lt 1 ]; then
  212. echo "No component is specified~"
  213. echo "You can specify a component in [$ALL_COMPONENTS]"
  214. echo "If you want to build all components, specify the component to: all."
  215. exit
  216. elif [ "$#" -eq 1 ] && [ "$1" == "all" ]; then
  217. echo "Build all onecloud docker images"
  218. COMPONENTS=$ALL_COMPONENTS
  219. else
  220. COMPONENTS=$@
  221. fi
  222. cd $SRC_DIR
  223. mkdir -p $SRC_DIR/_output
  224. show_update_cmd() {
  225. local component=$1
  226. local spec=$1
  227. local name=$1
  228. local tag=$TAG
  229. case "$component" in
  230. 'apigateway')
  231. spec='apiGateway'
  232. ;;
  233. 'apimap')
  234. spec='apiMap'
  235. ;;
  236. 'baremetal-agent')
  237. spec='baremetalagent'
  238. name='baremetal-agent'
  239. ;;
  240. 'host')
  241. spec='hostagent'
  242. ;;
  243. 'host-deployer')
  244. spec='hostdeployer'
  245. ;;
  246. 'host-health')
  247. spec='hostagent/HostHealth'
  248. ;;
  249. 'host-image')
  250. spec='hostimage'
  251. ;;
  252. 'region')
  253. spec='regionServer'
  254. ;;
  255. 'region-dns')
  256. spec='regionDNS'
  257. ;;
  258. 'vpcagent')
  259. spec='vpcAgent'
  260. ;;
  261. 'esxi-agent')
  262. spec='esxiagent'
  263. ;;
  264. 'mcp-server')
  265. spec='mcpServer'
  266. ;;
  267. esac
  268. echo "kubectl patch oc -n onecloud default --type='json' -p='[{op: replace, path: /spec/${spec}/imageName, value: ${name}},{"op": "replace", "path": "/spec/${spec}/repository", "value": "${REGISTRY}"},{"op": "add", "path": "/spec/${spec}/tag", "value": "${tag}"}]'"
  269. }
  270. for component in $COMPONENTS; do
  271. if [[ $component == *cli ]]; then
  272. echo "Please build image for climc"
  273. continue
  274. fi
  275. echo "Start to build component: $component"
  276. multiarch=""
  277. for ac in "${ALLARCH[@]}"; do
  278. if [[ "$ARCH" == "$ac" ]]; then
  279. # single arch
  280. if [ -e "$DOCKER_DIR/Dockerfile.$component" ]; then
  281. general_build $component $ARCH "false"
  282. fi
  283. elif [[ "$ARCH" == "all" || "$ARCH" == *"$ac"* ]]; then
  284. multiarch="true"
  285. general_build $component $ac "true"
  286. fi
  287. done
  288. if [[ "$multiarch" == "true" ]]; then
  289. make_manifest_image $component $ARCH
  290. fi
  291. done
  292. echo ""
  293. for component in $COMPONENTS; do
  294. if [[ $component == *cli ]]; then
  295. continue
  296. fi
  297. show_update_cmd $component
  298. done