|
- #!/usr/bin/env bash
-
- # Copyright 2021 The KubeEdge Authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
-
- set -o errexit
- set -o nounset
- set -o pipefail
-
- sedna::buildx::prepare_env() {
- # Check whether buildx exists.
- if ! docker buildx >/dev/null 2>&1; then
- echo "ERROR: docker buildx not available. Docker 19.03 or higher is required with experimental features enabled" >&2
- exit 1
- fi
-
- # Use tonistiigi/binfmt that is to enable an execution of different multi-architecture containers
- docker run --privileged --rm tonistiigi/binfmt --install all
-
- # Create a new builder which gives access to the new multi-architecture features.
- builder_instance="sedna-buildx"
- if ! docker buildx inspect $builder_instance >/dev/null 2>&1; then
- docker buildx create --use --name $builder_instance --driver docker-container
- fi
- docker buildx use $builder_instance
-
- # go speed tag with CGO_ENABLED=1 and alpine image
- _speed_buildx_for_cgo_alpine_
- }
-
- _speed_buildx_for_go_() {
- # docker speed build command for go
- echo 'go env -w GOOS="$TARGETOS" GOARCH="$TARGETARCH"' | _feed_to_dockerfile_RUN_command
- }
-
- _speed_buildx_for_cgo_alpine_() {
- # docker speed build command for go with CGO_ENABLED=1 and alpine image
-
- cat <<'EOF' | _feed_to_dockerfile_RUN_command
- # download cc(cross compiler) from https://musl.cc
- # the example url: https://musl.cc/aarch64-linux-musl-cross.tgz
- apk add curl
-
- # translate some architecture names
- arch=$(echo $TARGETARCH | sed "s@arm64@aarch64@")
-
- cc_url=$(curl musl.cc | grep /${arch}-${TARGETOS}-.*-cross)
- cc_filename=$(basename $cc_url) # aarch64-linux-musl-cross.tgz
- cc_name=$(echo $cc_filename | cut -f1 -d.) # aarch64-linux-musl-cross
- # download and extract
- curl -O $cc_url; tar xf $cc_filename
-
- # find the real cc name
- cc_bin=$PWD/$cc_name/bin # aarch64-linux-musl-cross/bin
- export PATH="$cc_bin:$PATH"
-
- # cc=aarch64-linux-musl-cc
- # set CC path, and enable CGO
- go env -w CC=$(echo $cc_bin/$arch-$TARGETOS-*-cc) CGO_ENABLED=1
-
- go env -w GOOS="$TARGETOS" GOARCH="$TARGETARCH"
- EOF
- }
-
- _feed_to_dockerfile_RUN_command() {
- # add '; \' for each command line
- speed_switch_cmd='RUN test "$TARGETPLATFORM" = "$BUILDPLATFORM" || ('
- printf "$speed_switch_cmd"
- while read run_cmd; do
- run_cmd=$(echo "$run_cmd" | sed 's@^\s*@@;s@\s*$@@;') # skip leading/trailing spaces
- run_cmd="${run_cmd%# *}" # skip comment
- run_cmd="${run_cmd%#;}" # skip trailing ';'
-
- # skip empty command
- [ -n "${run_cmd}" ] && {
- echo "$run_cmd; \\\\"
- }
- done
- printf ")"
- }
-
- sedna::buildx:generate-speed-dockerfile() {
- # Add buildx improvement for cross compilation if Dockerfile is added by the specified tag
- # see more details for buildx https://github.com/docker/buildx#building-multi-platform-images
- local input_dockerfile=${1}
-
- local -a speed_tags=(
- # The cross buildx tag in Dockerfile, it should be placed at the line before FROM instruction
- # e.g. from build/gm/Dockerfile
- # # _speed_buildx_for_go_
- # FROM golang:1.14-alpine3.11 AS builder
-
- # go speed tag
- _speed_buildx_for_go_
-
- )
-
- local base_cmds='
- # These ARGs are built in docker build
- # see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
- ARG TARGETPLATFORM BUILDPLATFORM TARGETARCH TARGETOS
-
- RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM(=$TARGETOS/$TARGETARCH).."
- '
-
- # FROM command pattern
- local from_pattern='^\s*FROM\s' # 0+ leading whitespace, 'FROM' word, a whitespace
- local from_part='FROM --platform=$BUILDPLATFORM ' # note tailing space
-
- for speed_tag in "${speed_tags[@]}"; do
- speed_tag_pattern="^# ${speed_tag}$"
-
- if ! grep -q "$speed_tag_pattern" "$input_dockerfile"; then
- continue
- fi
-
- speed_cmds="$($speed_tag)"
-
- cross_cmds="
- # generated by sedna::buildx
- $base_cmds
- $speed_cmds
- # end generated by sedna::buildx
- "
-
- awk -v cross_cmds="$cross_cmds" -v from_part="$from_part" \
- "{
- if (/$speed_tag_pattern/) {
- tag_found = 1
- }
- if (tag_found && sub(/$from_pattern/, from_part)) {
- # add from_part to the FROM command, and print
- print
- print cross_cmds
- tag_found = 0
- } else {
- print
- }
- }" "$input_dockerfile"
-
- # only support one language for one Dockerfile
- return
- done
-
- # if not speed tag added, just output its
- cat "$input_dockerfile"
- }
-
- sedna::buildx::push-multi-platform-images() {
- sedna::buildx::prepare_env
-
- bash scripts/storage-initializer/push_image.sh
-
- for component in ${COMPONENTS[@]}; do
- echo "pushing ${PLATFORMS} image for $component"
-
- temp_dockerfile=build/${component}/buildx_dockerfile
- sedna::buildx:generate-speed-dockerfile build/${component}/Dockerfile > ${temp_dockerfile}
-
- docker buildx build --push \
- --build-arg GO_LDFLAGS=${GO_LDFLAGS} \
- --platform ${PLATFORMS} \
- -t ${IMAGE_REPO}/sedna-${component}:${IMAGE_TAG} \
- -f ${temp_dockerfile} .
-
- rm ${temp_dockerfile}
- done
- }
-
- sedna::buildx::build-multi-platform-images() {
- sedna::buildx::prepare_env
-
- mkdir -p ${OUT_IMAGESPATH}
- arch_array=(${PLATFORMS//,/ })
-
- for component in ${COMPONENTS[@]}; do
- echo "building ${PLATFORMS} image for ${component}"
- buildx_dockerfile=${OUT_IMAGESPATH}/${component}-buildx-Dockerfile
-
- sedna::buildx:generate-speed-dockerfile build/${component}/Dockerfile > ${buildx_dockerfile}
-
- for arch in ${arch_array[@]}; do
- dest_tar=${OUT_IMAGESPATH}/${component}-${IMAGE_TAG}-${arch////-}.tar
- echo "building ${arch} image for ${component} and the image will be saved in ${dest_tar}"
-
- docker buildx build -o type=docker,dest=${dest_tar} \
- --build-arg GO_LDFLAGS=${GO_LDFLAGS} \
- --platform ${arch} \
- -t ${IMAGE_REPO}/sedna-${component}:${IMAGE_TAG} \
- -f ${buildx_dockerfile} .
- done
- done
-
- }
|