From 58061d25f604b096b2434be6c50fa1108f0d4a4b Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 2 Mar 2021 23:03:02 -0800 Subject: [PATCH 1/9] dockerfile based binary building Using cross compilation toolchains that work from any platform Adds darwin/arm64 support and bake targets. Static and dynamic binary targets are available, both with glibc and musl. Signed-off-by: Tonis Tiigi (cherry picked from commit 6423da8dcd076433b2629cfababa0fde9965b389) Signed-off-by: Tibor Vass --- .dockerignore | 1 - Dockerfile | 55 ++++++++++++++++++++++++++++++++++ docker-bake.hcl | 45 ++++++++++++++++++++++++++++ scripts/build/.variables | 14 +++++---- scripts/build/binary | 64 +++++++++++++++++++++++++++++++++++----- scripts/build/cross | 33 --------------------- scripts/build/dynbinary | 24 --------------- scripts/build/osx | 22 -------------- 8 files changed, 165 insertions(+), 93 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-bake.hcl delete mode 100755 scripts/build/cross delete mode 100755 scripts/build/dynbinary delete mode 100755 scripts/build/osx diff --git a/.dockerignore b/.dockerignore index 80d9bd96ddda..1718dd67c28f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,5 @@ .circleci .dockerignore -.git .github .gitignore appveyor.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000000..3dfb8f7e3fe7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +#syntax=docker/dockerfile:1.2 + +ARG BASE_VARIANT=alpine +ARG GO_VERSION=1.13.15 + +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable +FROM --platform=$BUILDPLATFORM golang:1.16-${BASE_VARIANT} AS golatest + +FROM gostable AS go-linux +FROM gostable AS go-windows +FROM golatest AS go-darwin + +FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:810dc54d5144f133a218e88e319184bf8b9ce01d37d46ddb37573e90decd9eef AS xx + +FROM go-${TARGETOS} AS build-base-alpine +COPY --from=xx / / +RUN apk add --no-cache clang lld file +WORKDIR /go/src/github.com/docker/cli + +FROM build-base-alpine AS build-alpine +ARG TARGETPLATFORM +# gcc is installed for libgcc only +RUN xx-apk add --no-cache musl-dev gcc + +FROM go-${TARGETOS} AS build-base-buster +COPY --from=xx / / +RUN apt-get update && apt-get install --no-install-recommends -y clang lld file +WORKDIR /go/src/github.com/docker/cli + +FROM build-base-buster AS build-buster +ARG TARGETPLATFORM +RUN xx-apt install --no-install-recommends -y libc6-dev libgcc-8-dev + +FROM build-${BASE_VARIANT} AS build +# GO_LINKMODE defines if static or dynamic binary should be produced +ARG GO_LINKMODE=static +# GO_BUILDTAGS defines additional build tags +ARG GO_BUILDTAGS +# GO_STRIP strips debugging symbols if set +ARG GO_STRIP +# CGO_ENABLED manually sets if cgo is used +ARG CGO_ENABLED +# VERSION sets the version for the produced binary +ARG VERSION +RUN --mount=ro --mount=type=cache,target=/root/.cache \ + --mount=from=dockercore/golang-cross:xx-sdk-extras,target=/xx-sdk,src=/xx-sdk \ + xx-go --wrap && \ + # export GOCACHE=$(go env GOCACHE)/$(xx-info)$([ -f /etc/alpine-release ] && echo "alpine") && \ + TARGET=/out ./scripts/build/binary && \ + xx-verify $([ "$GO_LINKMODE" = "static" ] && echo "--static") /out/docker + +FROM build-base-${BASE_VARIANT} AS dev + +FROM scratch AS binary +COPY --from=build /out . diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 000000000000..0fb3fe2bec02 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,45 @@ +variable "VERSION" { + default = "" +} + +variable "USE_GLIBC" { + default = "" +} + +variable "STRIP_TARGET" { + default = "" +} + +group "default" { + targets = ["binary"] +} + +target "binary" { + target = "binary" + platforms = ["local"] + output = ["build"] + args = { + BASE_VARIANT = USE_GLIBC != "" ? "buster" : "alpine" + VERSION = VERSION + GO_STRIP = STRIP_TARGET + } +} + +target "dynbinary" { + inherits = ["binary"] + args = { + GO_LINKMODE = "dynamic" + } +} + +target "_all_platforms" { + platforms = ["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"] +} + +target "cross" { + inherits = ["binary", "_all_platforms"] +} + +target "dynbinary-cross" { + inherits = ["dynbinary", "_all_platforms"] +} diff --git a/scripts/build/.variables b/scripts/build/.variables index 094209cd5039..ea0e952d291a 100755 --- a/scripts/build/.variables +++ b/scripts/build/.variables @@ -1,6 +1,8 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -eu +TARGET=${TARGET:-"build"} + PLATFORM=${PLATFORM:-} VERSION=${VERSION:-"unknown-version"} GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} @@ -20,15 +22,15 @@ export LDFLAGS="\ ${LDFLAGS:-} \ " -GOOS="${GOOS:-$(go env GOHOSTOS)}" -GOARCH="${GOARCH:-$(go env GOHOSTARCH)}" +GOOS="$(go env GOOS)" +GOARCH="$(go env GOARCH)" if [ "${GOARCH}" = "arm" ]; then - GOARM="${GOARM:-$(go env GOHOSTARM)}" + GOARM="$(go env GOARM)" fi -TARGET="build/docker-$GOOS-$GOARCH" +TARGET="$TARGET/docker-${GOOS}-${GOARCH}" if [ "${GOARCH}" = "arm" ] && [ -n "${GOARM}" ]; then - TARGET="${TARGET}-v${GOARM}" + TARGET="${TARGET}-v${GOARM}" fi if [ "${GOOS}" = "windows" ]; then diff --git a/scripts/build/binary b/scripts/build/binary index 41c4196cc801..d03262b2a887 100755 --- a/scripts/build/binary +++ b/scripts/build/binary @@ -1,14 +1,64 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # # Build a static binary for the host OS/ARCH # -set -eu -o pipefail +set -eu -source ./scripts/build/.variables +: "${CGO_ENABLED=}" +: "${GO_LINKMODE=static}" +: "${GO_BUILDMODE=}" +: "${GO_BUILDTAGS=}" +: "${GO_STRIP=}" -echo "Building statically linked $TARGET" -export CGO_ENABLED=0 -go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}" +set -x +. ./scripts/build/.variables -ln -sf "$(basename "${TARGET}")" build/docker +if [ -z "$CGO_ENABLED" ]; then + case "$(go env GOOS)" in + linux) + case "$(go env GOARCH)" in + amd64|arm64|arm|s390x) + CGO_ENABLED=1 + ;; + *) + CGO_ENABLED=0 + ;; + esac + ;; + darwin|windows) + CGO_ENABLED=1 + ;; + *) + CGO_ENABLED=0 + ;; + esac +fi +export CGO_ENABLED +if [ "$CGO_ENABLED" = "1" ] && [ "$(go env GOOS)" != "windows" ]; then + case "$(go env GOARCH)" in + mips*|ppc64) + # pie build mode is not supported on mips architectures + ;; + *) + GO_BUILDMODE="-buildmode=pie" + ;; + esac + GO_BUILDTAGS="$GO_BUILDTAGS pkcs11" +fi + +if [ "$CGO_ENABLED" = "1" ] && [ "$GO_LINKMODE" = "static" ] && [ "$(go env GOOS)" = "linux" ]; then + LDFLAGS="$LDFLAGS -extldflags -static" +fi + +if [ -n "$GO_STRIP" ]; then + LDFLAGS="$LDFLAGS -s -w" +fi + +echo "Building $GO_LINKMODE $(basename "${TARGET}")" + +export GO111MODULE=auto + +go build -o "${TARGET}" -tags "${GO_BUILDTAGS}" --ldflags "${LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}" + +ln -sf "$(basename "${TARGET}")" "$(dirname "${TARGET}")/docker" diff --git a/scripts/build/cross b/scripts/build/cross deleted file mode 100755 index 51c22c3607a6..000000000000 --- a/scripts/build/cross +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -# -# Build a binary for all supported platforms -# - -set -eu -o pipefail - -BUILDDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export SHELL=bash - -jobs=( - "$BUILDDIR/windows" \ - "$BUILDDIR/osx" \ - "GOOS=linux GOARCH=amd64 $BUILDDIR/binary" \ - "GOOS=linux GOARCH=arm $BUILDDIR/binary" \ - "GOOS=linux GOARCH=ppc64le $BUILDDIR/binary" \ - "GOOS=linux GOARCH=s390x $BUILDDIR/binary" \ -) - -# Outside of circleCI run all at once. On circleCI run two at a time because -# each container has access to two cores. -group=${CROSS_GROUP-"all"} - -if [ "$group" = "all" ]; then - - echo "Building binaries for all platforms" - parallel ::: "${jobs[@]}" - exit 0 - -fi - -declare -i start="$group*2" -parallel ::: "${jobs[@]:$start:2}" diff --git a/scripts/build/dynbinary b/scripts/build/dynbinary deleted file mode 100755 index 67bc785dae55..000000000000 --- a/scripts/build/dynbinary +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# -# Build a dynamically linked binary for the host OS/ARCH -# - -set -eu -o pipefail - -source ./scripts/build/.variables - -echo "Building dynamically linked $TARGET" -export CGO_ENABLED=1 -case "$(go env GOARCH)" in - mips*|ppc64) - # pie build mode is not supported on mips architectures - GO_BUILDMODE="" - ;; - *) - GO_BUILDMODE="-buildmode=pie" - ;; -esac - -go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" ${GO_BUILDMODE} "${SOURCE}" - -ln -sf "$(basename "${TARGET}")" build/docker diff --git a/scripts/build/osx b/scripts/build/osx deleted file mode 100755 index a075ede41271..000000000000 --- a/scripts/build/osx +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -# -# Build an osx binary from linux -# - -set -eu -o pipefail - -source ./scripts/build/.variables - -export CGO_ENABLED=1 -export GOOS=darwin -export GOARCH=amd64 -export CC=o64-clang -export CXX=o64-clang++ -export LDFLAGS="$LDFLAGS -linkmode external -s" -export LDFLAGS_STATIC_DOCKER='-extld='${CC} - -# Override TARGET -TARGET="build/docker-$GOOS-$GOARCH" - -echo "Building $TARGET" -go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}" From fcc05e5ea1fb1719b14e56febab17aba9a3a396b Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 00:56:55 -0800 Subject: [PATCH 2/9] update windows resources generation New solution is not hardcoded to amd64 but integrates with the cross toolchain and support creating arm binaries. Go has been updated so that ASLR works Signed-off-by: Tonis Tiigi (cherry picked from commit 8b822c9219afb4ca323e573a4f5586c95d1a43ad) Signed-off-by: Tibor Vass --- .gitignore | 3 +-- Dockerfile | 8 +++--- cli/winresources/res_windows.go | 4 +-- scripts/build/binary | 18 ++++++++++++- scripts/build/windows | 23 ----------------- scripts/gen/windows-resources | 45 --------------------------------- 6 files changed, 24 insertions(+), 77 deletions(-) delete mode 100755 scripts/build/windows delete mode 100755 scripts/gen/windows-resources diff --git a/.gitignore b/.gitignore index a1f1bc9dafe5..c479555c8809 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,7 @@ Thumbs.db .editorconfig /build/ -cli/winresources/rsrc_386.syso -cli/winresources/rsrc_amd64.syso +cli/winresources/rsrc_*.syso /man/man1/ /man/man5/ /man/man8/ diff --git a/Dockerfile b/Dockerfile index 3dfb8f7e3fe7..13ff22d41bbf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,14 +7,14 @@ FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable FROM --platform=$BUILDPLATFORM golang:1.16-${BASE_VARIANT} AS golatest FROM gostable AS go-linux -FROM gostable AS go-windows +FROM golatest AS go-windows FROM golatest AS go-darwin -FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:810dc54d5144f133a218e88e319184bf8b9ce01d37d46ddb37573e90decd9eef AS xx +FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:620d36a9d7f1e3b102a5c7e8eff12081ac363828b3a44390f24fa8da2d49383d AS xx FROM go-${TARGETOS} AS build-base-alpine COPY --from=xx / / -RUN apk add --no-cache clang lld file +RUN apk add --no-cache clang lld llvm file git WORKDIR /go/src/github.com/docker/cli FROM build-base-alpine AS build-alpine @@ -44,12 +44,14 @@ ARG CGO_ENABLED ARG VERSION RUN --mount=ro --mount=type=cache,target=/root/.cache \ --mount=from=dockercore/golang-cross:xx-sdk-extras,target=/xx-sdk,src=/xx-sdk \ + --mount=type=tmpfs,target=cli/winresources \ xx-go --wrap && \ # export GOCACHE=$(go env GOCACHE)/$(xx-info)$([ -f /etc/alpine-release ] && echo "alpine") && \ TARGET=/out ./scripts/build/binary && \ xx-verify $([ "$GO_LINKMODE" = "static" ] && echo "--static") /out/docker FROM build-base-${BASE_VARIANT} AS dev +COPY . . FROM scratch AS binary COPY --from=build /out . diff --git a/cli/winresources/res_windows.go b/cli/winresources/res_windows.go index 3f755cc4bdbf..033995d0bcec 100644 --- a/cli/winresources/res_windows.go +++ b/cli/winresources/res_windows.go @@ -5,7 +5,7 @@ These resources are used to provide * An icon * A Windows manifest declaring Windows version support -The resource object files are generated with go generate. +The resource object files are generated when building with scripts/build/binary . The resource source files are located in scripts/winresources. This occurs automatically when you run scripts/build/windows. @@ -14,5 +14,3 @@ is included. */ package winresources - -//go:generate ../../scripts/gen/windows-resources diff --git a/scripts/build/binary b/scripts/build/binary index d03262b2a887..e4c5e12a6b44 100755 --- a/scripts/build/binary +++ b/scripts/build/binary @@ -11,7 +11,6 @@ set -eu : "${GO_BUILDTAGS=}" : "${GO_STRIP=}" -set -x . ./scripts/build/.variables if [ -z "$CGO_ENABLED" ]; then @@ -55,6 +54,23 @@ if [ -n "$GO_STRIP" ]; then LDFLAGS="$LDFLAGS -s -w" fi +if [ "$(go env GOOS)" = "windows" ]; then + # Generate a Windows file version of the form major,minor,patch,build + VERSION_QUAD=$(printf "%s" "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | tr . , | sed -re 's/^[0-9]+$/\0,0/' | sed -re 's/^[0-9]+,[0-9]+$/\0,0/' | sed -re 's/^[0-9]+,[0-9]+,[0-9]+$/\0,0/') + + set -- + [ -n "$VERSION" ] && set -- "$@" -D "DOCKER_VERSION=\"$VERSION\"" + [ -n "$VERSION_QUAD" ] && set -- "$@" -D "DOCKER_VERSION_QUAD=$VERSION_QUAD" + [ -n "$GITCOMMIT" ] && set -- "$@" -D "DOCKER_COMMIT=\"$GITCOMMIT\"" + + windres=$($(go env CC) --print-prog-name=windres) + + target="$(dirname "$0")/../../cli/winresources/rsrc_$(go env GOARCH).syso" + mkdir -p "$(dirname "${target}")" + "$windres" -i "$(dirname "$0")/../winresources/docker.rc" -o "$target" "$@" + echo "package winresources" > "$(dirname "${target}")/stub_windows.go" +fi + echo "Building $GO_LINKMODE $(basename "${TARGET}")" export GO111MODULE=auto diff --git a/scripts/build/windows b/scripts/build/windows deleted file mode 100755 index cd6d2eea9064..000000000000 --- a/scripts/build/windows +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -# -# Build a windows binary from linux -# - -set -eu -o pipefail - -source ./scripts/build/.variables - -export CC=x86_64-w64-mingw32-gcc -export CGO_ENABLED=1 -export GOOS=windows -export GOARCH=amd64 - -# Override TARGET -TARGET="build/docker-$GOOS-$GOARCH.exe" - -echo "Generating windows resources" -go generate ./cli/winresources - -echo "Building $TARGET" -# TODO: -tags pkcs11 -go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}" diff --git a/scripts/gen/windows-resources b/scripts/gen/windows-resources deleted file mode 100755 index e9cdff8bbab7..000000000000 --- a/scripts/gen/windows-resources +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash -# -# Compile the Windows resources into the sources -# - -set -eu -o pipefail - -SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# shellcheck source=/go/src/github.com/docker/cli/scripts/build/.variables -source "$SCRIPTDIR"/../build/.variables - -RESOURCES=$SCRIPTDIR/../winresources - -TEMPDIR=$(mktemp -d) -trap 'rm -rf $TEMPDIR' EXIT - -if [ "$(go env GOHOSTOS)" = "windows" ]; then - WINDRES=windres -else - # Cross compiling - WINDRES=x86_64-w64-mingw32-windres -fi - -# Generate a Windows file version of the form major,minor,patch,build (with any part optional) -VERSION_QUAD=$(printf "%s" "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | tr . ,) - -# Pass version and commit information into the resource compiler -defs= -[ -n "$VERSION" ] && defs+=( "-D DOCKER_VERSION=\"$VERSION\"") -[ -n "$VERSION_QUAD" ] && defs+=( "-D DOCKER_VERSION_QUAD=$VERSION_QUAD") -[ -n "$GITCOMMIT" ] && defs+=( "-D DOCKER_COMMIT=\"$GITCOMMIT\"") - -makeres() { - # shellcheck disable=SC2086 - "$WINDRES" \ - -i "$RESOURCES/$1" \ - -o "$3" \ - -F "$2" \ - --use-temp-file \ - -I "$TEMPDIR" \ - ${defs[*]} -} - -makeres docker.rc pe-x86-64 rsrc_amd64.syso -makeres docker.rc pe-i386 rsrc_386.syso From 33dacda24f5b69a3a0630c745287e82f0e887447 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 01:05:04 -0800 Subject: [PATCH 3/9] add windows/arm64 target Signed-off-by: Tonis Tiigi (cherry picked from commit a2a1de5f0e14471ea8dabc745eabd5d3d8e10fe9) Signed-off-by: Tibor Vass --- Dockerfile | 6 +++++- docker-bake.hcl | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 13ff22d41bbf..719b0873aa97 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,12 @@ FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable FROM --platform=$BUILDPLATFORM golang:1.16-${BASE_VARIANT} AS golatest FROM gostable AS go-linux -FROM golatest AS go-windows FROM golatest AS go-darwin +FROM golatest AS go-windows-amd64 +FROM golatest AS go-windows-386 +FROM golatest AS go-windows-arm +FROM --platform=$BUILDPLATFORM tonistiigi/golang:497feff1-${BASE_VARIANT} AS go-windows-arm64 +FROM go-windows-${TARGETARCH} AS go-windows FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:620d36a9d7f1e3b102a5c7e8eff12081ac363828b3a44390f24fa8da2d49383d AS xx diff --git a/docker-bake.hcl b/docker-bake.hcl index 0fb3fe2bec02..d450aaf29bb5 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -33,7 +33,7 @@ target "dynbinary" { } target "_all_platforms" { - platforms = ["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"] + platforms = concat(["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"], USE_GLIBC!=""?[]:["windows/arm64"]) } target "cross" { From 048a84614630f477611fc6e85a21e602c2c4d94b Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 13:16:05 -0800 Subject: [PATCH 4/9] update circleci cross target Signed-off-by: Tonis Tiigi (cherry picked from commit bd3e853c7a8136137853532e42b1017de47237cf) Signed-off-by: Tibor Vass --- .circleci/config.yml | 24 +++++++++--------------- docker-bake.hcl | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 801ee5bf5082..ca64e0d10fd6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,7 @@ jobs: docker: [{image: 'docker:19.03-git'}] environment: DOCKER_BUILDKIT: 1 + BUILDX_VERSION: "v0.5.1" parallelism: 3 steps: - checkout @@ -55,21 +56,14 @@ jobs: - run: name: "Docker info" command: docker info - - run: - name: "Cross - build image" - command: | - docker build --progress=plain -f dockerfiles/Dockerfile.cross --tag cli-builder:$CIRCLE_BUILD_NUM . - - run: - name: "Cross" - command: | - name=cross-$CIRCLE_BUILD_NUM-$CIRCLE_NODE_INDEX - docker run \ - -e CROSS_GROUP=$CIRCLE_NODE_INDEX \ - --name $name cli-builder:$CIRCLE_BUILD_NUM \ - make cross - docker cp \ - $name:/go/src/github.com/docker/cli/build \ - /work/build + - run: apk add make curl + - run: mkdir -vp ~/.docker/cli-plugins/ + - run: curl -fsSL --output ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-amd64 + - run: chmod a+x ~/.docker/cli-plugins/docker-buildx + - run: docker buildx version + - run: docker context create buildctx + - run: docker buildx create --use buildctx && docker buildx inspect --bootstrap + - run: GROUP_INDEX=$CIRCLE_NODE_INDEX GROUP_TOTAL=$CIRCLE_NODE_TOTAL docker buildx bake cross --progress=plain - store_artifacts: path: /work/build diff --git a/docker-bake.hcl b/docker-bake.hcl index d450aaf29bb5..7443f4d627e3 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -32,8 +32,26 @@ target "dynbinary" { } } +variable "GROUP_TOTAL" { + default = "1" +} + +variable "GROUP_INDEX" { + default = "0" +} + +function "platforms" { + params = [USE_GLIBC] + result = concat(["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"], USE_GLIBC!=""?[]:["windows/arm64"]) +} + +function "glen" { + params = [platforms, GROUP_TOTAL] + result = ceil(length(platforms)/GROUP_TOTAL) +} + target "_all_platforms" { - platforms = concat(["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"], USE_GLIBC!=""?[]:["windows/arm64"]) + platforms = slice(platforms(USE_GLIBC), GROUP_INDEX*glen(platforms(USE_GLIBC), GROUP_TOTAL),min(length(platforms(USE_GLIBC)), (GROUP_INDEX+1)*glen(platforms(USE_GLIBC), GROUP_TOTAL))) } target "cross" { From c1c3d3b3aa01eaf4741f4344103c20c936a54863 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 14:13:46 -0800 Subject: [PATCH 5/9] remove unused targets More can be removed/refactored but avoiding a huge change. Signed-off-by: Tonis Tiigi (cherry picked from commit 706e857a90974e4ac9349a3c588419fe62d29df3) Signed-off-by: Tibor Vass --- Makefile | 19 +++++-------------- docker.Makefile | 20 -------------------- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 96c6379c9383..9e62210c330e 100644 --- a/Makefile +++ b/Makefile @@ -30,37 +30,28 @@ lint: ## run all the lint tools gometalinter --config gometalinter.json ./... .PHONY: binary -binary: ## build executable for Linux - @echo "WARNING: binary creates a Linux executable. Use cross for macOS or Windows." - ./scripts/build/binary +binary: + docker buildx bake binary .PHONY: plugins plugins: ## build example CLI plugins ./scripts/build/plugins .PHONY: cross -cross: ## build executable for macOS and Windows - ./scripts/build/cross - -.PHONY: binary-windows -binary-windows: ## build executable for Windows - ./scripts/build/windows +cross: + docker buildx bake cross .PHONY: plugins-windows plugins-windows: ## build example CLI plugins for Windows ./scripts/build/plugins-windows -.PHONY: binary-osx -binary-osx: ## build executable for macOS - ./scripts/build/osx - .PHONY: plugins-osx plugins-osx: ## build example CLI plugins for macOS ./scripts/build/plugins-osx .PHONY: dynbinary dynbinary: ## build dynamically linked binary - ./scripts/build/dynbinary + USE_GLIBC=1 docker buildx bake dynbinary vendor: vendor.conf ## check that vendor matches vendor.conf rm -rf vendor diff --git a/docker.Makefile b/docker.Makefile index 804133b2fb5f..4f582b7fb7c3 100644 --- a/docker.Makefile +++ b/docker.Makefile @@ -38,11 +38,6 @@ build_linter_image: # build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment cat ./dockerfiles/Dockerfile.lint | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(LINTER_IMAGE_NAME) - -.PHONY: build_cross_image -build_cross_image: - # build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment - cat ./dockerfiles/Dockerfile.cross | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(CROSS_IMAGE_NAME) - - .PHONY: build_shell_validate_image build_shell_validate_image: # build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment @@ -80,22 +75,10 @@ test-unit: build_docker_image ## run unit tests (using go test) .PHONY: test ## run unit and e2e tests test: test-unit test-e2e -.PHONY: cross -cross: build_cross_image ## build the CLI for macOS and Windows - $(DOCKER_RUN) $(CROSS_IMAGE_NAME) make cross - -.PHONY: binary-windows -binary-windows: build_cross_image ## build the CLI for Windows - $(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@ - .PHONY: plugins-windows plugins-windows: build_cross_image ## build the example CLI plugins for Windows $(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@ -.PHONY: binary-osx -binary-osx: build_cross_image ## build the CLI for macOS - $(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@ - .PHONY: plugins-osx plugins-osx: build_cross_image ## build the example CLI plugins for macOS $(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@ @@ -120,9 +103,6 @@ fmt: ## run gofmt vendor: build_docker_image vendor.conf ## download dependencies (vendor/) listed in vendor.conf $(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make vendor -dynbinary: build_cross_image ## build the CLI dynamically linked - $(DOCKER_RUN) -it $(CROSS_IMAGE_NAME) make dynbinary - .PHONY: authors authors: ## generate AUTHORS file from git history $(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make authors From 84cc7d87cc6545d9966b83a51867ab48c2def467 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 14:20:02 -0800 Subject: [PATCH 6/9] update readme with new examples Signed-off-by: Tonis Tiigi (cherry picked from commit b099c9c9ee7802ceb8436d10cceb1604a78b01cd) Signed-off-by: Tibor Vass --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e21bccec0c04..770d68c1db8f 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,31 @@ Development `docker/cli` is developed using Docker. -Build a linux binary: +Build CLI from source: ``` -$ make -f docker.Makefile binary +$ docker buildx bake ``` Build binaries for all supported platforms: ``` -$ make -f docker.Makefile cross +$ docker buildx bake cross ``` +Build for a specific platform: + +``` +$ docker buildx bake --set binary.platform=linux/arm64 +``` + +Build dynamic binary for glibc or musl: + +``` +$ USE_GLIBC=1 docker buildx bake dynbinary +``` + + Run all linting: ``` @@ -44,12 +57,6 @@ Start an interactive development environment: $ make -f docker.Makefile shell ``` -In the development environment you can run many tasks, including build binaries: - -``` -$ make binary -``` - Legal ===== *Brought to you courtesy of our legal counsel. For more context, From 8bc4062fc0c51e12b93f6b2a99ec885e6221df8d Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 5 Mar 2021 14:34:32 -0800 Subject: [PATCH 7/9] set default version from git Signed-off-by: Tonis Tiigi (cherry picked from commit 26b633d37bb0ff69cd7210ce4004038fb732bf08) Signed-off-by: Tibor Vass --- scripts/build/.variables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build/.variables b/scripts/build/.variables index ea0e952d291a..ece560174a7b 100755 --- a/scripts/build/.variables +++ b/scripts/build/.variables @@ -4,7 +4,7 @@ set -eu TARGET=${TARGET:-"build"} PLATFORM=${PLATFORM:-} -VERSION=${VERSION:-"unknown-version"} +VERSION=${VERSION:-$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags | sed 's/^v//' 2>/dev/null || echo "unknown-version" )} GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} BUILDTIME=${BUILDTIME:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")} From feb6f439e314d38664817fd7243385da4a1f7dfc Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 6 Apr 2021 17:28:12 +0000 Subject: [PATCH 8/9] Makefile: have binary, cross, dynbinary targets not use docker for backwards compat Signed-off-by: Tibor Vass --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9e62210c330e..47f43eff8089 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ lint: ## run all the lint tools .PHONY: binary binary: - docker buildx bake binary + ./scripts/build/binary .PHONY: plugins plugins: ## build example CLI plugins @@ -39,7 +39,7 @@ plugins: ## build example CLI plugins .PHONY: cross cross: - docker buildx bake cross + ./scripts/build/binary .PHONY: plugins-windows plugins-windows: ## build example CLI plugins for Windows @@ -51,7 +51,7 @@ plugins-osx: ## build example CLI plugins for macOS .PHONY: dynbinary dynbinary: ## build dynamically linked binary - USE_GLIBC=1 docker buildx bake dynbinary + GO_LINKMODE=dynamic ./scripts/build/binary vendor: vendor.conf ## check that vendor matches vendor.conf rm -rf vendor From dc017bdda3786b82c39326563fa9c63c84d8529c Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 6 Apr 2021 20:10:31 +0000 Subject: [PATCH 9/9] bake: remove windows targets other than windows/amd64 Docker 20.10 only supports windows/amd64, and though tonistiigi/xx allows us to support many other architectures, I preferred to not have to vendor in 12k lines of golang.org/x/sys just to get windows/arm64 working. This is only meant for 20.10. Signed-off-by: Tibor Vass --- docker-bake.hcl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-bake.hcl b/docker-bake.hcl index 7443f4d627e3..909dd4fc189e 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -41,8 +41,8 @@ variable "GROUP_INDEX" { } function "platforms" { - params = [USE_GLIBC] - result = concat(["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"], USE_GLIBC!=""?[]:["windows/arm64"]) + params = [] + result = ["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64"] } function "glen" { @@ -51,7 +51,7 @@ function "glen" { } target "_all_platforms" { - platforms = slice(platforms(USE_GLIBC), GROUP_INDEX*glen(platforms(USE_GLIBC), GROUP_TOTAL),min(length(platforms(USE_GLIBC)), (GROUP_INDEX+1)*glen(platforms(USE_GLIBC), GROUP_TOTAL))) + platforms = slice(platforms(), GROUP_INDEX*glen(platforms(), GROUP_TOTAL),min(length(platforms()), (GROUP_INDEX+1)*glen(platforms(), GROUP_TOTAL))) } target "cross" {