From 27d7c50384b11d6a3c5982c7e20e89ec360d542a Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 22 Oct 2021 00:49:20 +0000 Subject: [PATCH] Add arm64 to releases This moves all the release builds into a Dockerfile which is a bit cleaner for setting up our build environment. Non-linux/amd64 builds are cross-compiled. Currently onlinux linux/amd64, linux/arm64, and windows/amd64 are supported, but is easy to add more, provided their is a cross-compile toolchain available for it. Signed-off-by: Brian Goff --- .dockerignore | 4 + .github/workflows/release.yml | 187 ++++-------------- .../workflows/release/Dockerfile.ubuntu-18.04 | 92 +++++++++ Makefile | 3 +- Makefile.windows | 6 +- script/setup/install-cni-windows | 8 +- script/setup/install-runhcs-shim | 40 ++++ 7 files changed, 180 insertions(+), 160 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/release/Dockerfile.ubuntu-18.04 create mode 100755 script/setup/install-runhcs-shim diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..6745fa3fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.github/ +.dockerignore +releases/ +bin/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d509fa72b..dc307251e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,17 +53,18 @@ jobs: runs-on: ${{ matrix.os }} needs: [check] timeout-minutes: 10 - strategy: matrix: - os: [ubuntu-18.04, windows-2019] - + os: [ubuntu-18.04] + platform: + - linux/amd64 + - linux/arm64 + - windows/amd64 steps: - name: Install Go uses: actions/setup-go@v2 with: go-version: '1.17.3' - - name: Set env shell: bash env: @@ -71,15 +72,8 @@ jobs: run: | releasever=${{ github.ref }} releasever="${releasever#refs/tags/}" - os=linux - [[ "${MOS}" =~ "windows" ]] && { - os=windows - } echo "RELEASE_VER=${releasever}" >> $GITHUB_ENV echo "GOPATH=${{ github.workspace }}" >> $GITHUB_ENV - echo "OS=${os}" >> $GITHUB_ENV - echo "${{ github.workspace }}/bin" >> $GITHUB_PATH - - name: Checkout containerd uses: actions/checkout@v2 with: @@ -90,169 +84,54 @@ jobs: ref: ${{ github.ref }} path: src/github.com/containerd/containerd - - name: HCS Shim commit - id: hcsshim_commit - if: startsWith(matrix.os, 'windows') - shell: bash - run: echo "::set-output name=sha::$(grep 'Microsoft/hcsshim ' go.mod | awk '{print $2}')" - working-directory: src/github.com/containerd/containerd - - - name: Checkout hcsshim source - if: startsWith(matrix.os, 'windows') - uses: actions/checkout@v2 + - name: Setup buildx instance + uses: docker/setup-buildx-action@v1 with: - repository: Microsoft/hcsshim - ref: ${{ steps.hcsshim_commit.outputs.sha }} - path: src/github.com/Microsoft/hcsshim - + use: true + - uses: crazy-max/ghaction-github-runtime@v1 # sets up needed vars for caching to github - name: Make shell: bash run: | - make build - make binaries - rm bin/containerd-stress* - [[ "${OS}" == "windows" ]] && { - ( - bindir="$(pwd)/bin" - cd ../../Microsoft/hcsshim - GO111MODULE=on go build -mod=vendor -o "${bindir}/containerd-shim-runhcs-v1.exe" ./cmd/containerd-shim-runhcs-v1 - ) - } - TARFILE="containerd-${RELEASE_VER#v}-${OS}-amd64.tar.gz" - tar czf ${TARFILE} bin/ - sha256sum ${TARFILE} >${TARFILE}.sha256sum - working-directory: src/github.com/containerd/containerd - - - name: Save build binaries - uses: actions/upload-artifact@v2 - with: - name: containerd-binaries-${{ matrix.os }} - path: src/github.com/containerd/containerd/*.tar.gz* - - - name: Make cri-containerd tar - shell: bash - env: - RUNC_FLAVOR: runc - run: | - if [[ "${OS}" == "linux" ]]; then - sudo apt-get update - sudo apt-get install -y gperf - sudo -E PATH=$PATH script/setup/install-seccomp + cache="--cache-from=type=gha,scope=containerd-release --cache-to=type=gha,scope=containerd-release" + if [[ "${PLATFORM}" =~ "windows" ]]; then + # For Windows the cni build script generates a config but shells out to powershell (and also assume it is running on windows) to get a gateway and subnet. + # The values provided here are taken from packages that we previously generated. + export GATEWAY=172.21.16.1 + export PREFIX_LEN=12 + BUILD_ARGS="--build-arg GATEWAY --build-arg PREFIX_LEN" fi - make cri-release cri-cni-release - working-directory: src/github.com/containerd/containerd + docker buildx build ${cache} --build-arg RELEASE_VER --build-arg GO_VERSION ${BUILD_ARGS} -f .github/workflows/release/Dockerfile.${{matrix.os}} --platform=${PLATFORM} -o releases/ . + echo PLATFORM_CLEAN=${PLATFORM/\//-} >> $GITHUB_ENV - - name: Save cri-containerd binaries + # Remove symlinks since we don't want these in the release Artifacts + find ./releases/ -maxdepth 1 -type l | xargs rm + working-directory: src/github.com/containerd/containerd + env: + GO_VERSION: '1.17.2' + PLATFORM: ${{ matrix.platform }} + - name: Save Artifacts uses: actions/upload-artifact@v2 with: - name: cri-containerd-binaries-${{ matrix.os }} - path: src/github.com/containerd/containerd/releases/cri-containerd-*.tar.gz* + name: release-tars-${{env.PLATFORM_CLEAN}} + path: src/github.com/containerd/containerd/releases/*.tar.gz* release: name: Create containerd Release runs-on: ubuntu-18.04 timeout-minutes: 10 needs: [build, check] - outputs: - upload_url: ${{ steps.create_release.outputs.upload_url }} - steps: - name: Download builds and release notes uses: actions/download-artifact@v2 with: path: builds - name: Create Release - id: create_release - uses: actions/create-release@v1.1.2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: softprops/action-gh-release@v1 with: - tag_name: ${{ github.ref }} - release_name: containerd ${{ needs.check.outputs.stringver }} - body_path: ./builds/containerd-release-notes/release-notes.md + token: ${{ secrets.GITHUB_TOKEN }} + fail_on_unmatched_files: true draft: false prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }} - - release-upload: - name: Upload containerd tarballs - runs-on: ubuntu-18.04 - timeout-minutes: 10 - needs: [release] - - strategy: - matrix: - os: [ubuntu-18.04, windows-2019] - - steps: - - name: Download builds and release notes - uses: actions/download-artifact@v2 - with: - path: builds - - name: Catalog build assets for upload - id: catalog - env: - OS: ${{ matrix.os }} - run: | - _filenum=1 - for f in `ls "builds/containerd-binaries-${OS}"`; do - echo "::set-output name=file${_filenum}::${f}" - let "_filenum+=1" - done - for f in `ls builds/cri-containerd-binaries-${OS}`; do - echo "::set-output name=file${_filenum}::${f}" - let "_filenum+=1" - done - - name: Upload containerd tarball - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file1 }} - asset_name: ${{ steps.catalog.outputs.file1 }} - asset_content_type: application/gzip - - name: Upload sha256 sum - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file2 }} - asset_name: ${{ steps.catalog.outputs.file2 }} - asset_content_type: text/plain - - name: Upload cri containerd tarball - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/cri-containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file3 }} - asset_name: ${{ steps.catalog.outputs.file3 }} - asset_content_type: application/gzip - - name: Upload cri sha256 sum - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/cri-containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file4 }} - asset_name: ${{ steps.catalog.outputs.file4 }} - asset_content_type: text/plain - - name: Upload cri/cni containerd tarball - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/cri-containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file5 }} - asset_name: ${{ steps.catalog.outputs.file5 }} - asset_content_type: application/gzip - - name: Upload cri/cni sha256 sum - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.release.outputs.upload_url }} - asset_path: ./builds/cri-containerd-binaries-${{ matrix.os }}/${{ steps.catalog.outputs.file6 }} - asset_name: ${{ steps.catalog.outputs.file6 }} - asset_content_type: text/plain + body_path: ./builds/containerd-release-notes/release-notes.md + files: | + builds/release-tars-**/* \ No newline at end of file diff --git a/.github/workflows/release/Dockerfile.ubuntu-18.04 b/.github/workflows/release/Dockerfile.ubuntu-18.04 new file mode 100644 index 000000000..51892a177 --- /dev/null +++ b/.github/workflows/release/Dockerfile.ubuntu-18.04 @@ -0,0 +1,92 @@ +# Copyright The containerd 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. + +ARG GO_VERSION +ARG GO_IMAGE=golang:${GO_VERSION} +FROM --platform=$BUILDPLATFORM $GO_IMAGE AS go + +FROM --platform=$BUILDPLATFORM ubuntu:18.04 AS base +SHELL ["/bin/bash", "-xec"] +# Ubuntu has entirely separate repos for non-amd64 architectures +# Because of this we can't just add new arches, we need to update the repo list first +RUN \ + echo deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ bionic main multiverse restricted universe > /etc/apt/sources.list; \ + echo deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ bionic-updates main multiverse restricted universe >> /etc/apt/sources.list; \ + echo deb [arch=amd64] http://security.ubuntu.com/ubuntu/ bionic-security main multiverse restricted universe >> /etc/apt/sources.lis; \ + echo deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports/ bionic main multiverse restricted universe >> /etc/apt/sources.list; \ + echo deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main multiverse restricted universe >> /etc/apt/sources.list +RUN dpkg --add-architecture arm64 +RUN apt-get update && apt-get install -y \ + binutils-mingw-w64 \ + crossbuild-essential-arm64 \ + g++-mingw-w64-x86-64 \ + git \ + libseccomp-dev:amd64 \ + libseccomp-dev:arm64 \ + pkg-config +ARG TARGETARCH +ARG TARGETVARIANT +ARG TARGETOS +# btrfs-progs cannot have multiple arch versions installed at the same time +# Unfortunately this is also means we can't share a build cache between arches beyond this point. +# +# Also note this won't work with 32bit arm versions, and likely some other things such as ppc. +# For that we'd need to translate $TARGETARCH and $TARGETVARIANT into Ubuntu specific values. +# Since we don't support these architectures right now this is good enough. +RUN \ + if [ "$TARGETOS" = "linux" ]; then \ + apt-get update && \ + apt-get install -y btrfs-progs:${TARGETARCH}; \ + fi +ENV PATH=/usr/local/go/bin:$PATH +ENV GOPATH=/go +ENV CGO_ENABLED=1 + +FROM base AS linux-arm64 +ENV CC=aarch64-linux-gnu-gcc +RUN \ + PKG_CONFIG_PATH="$(pkg-config --variable pc_path pkg-config)"; \ + for i in $(find /usr/lib -name 'pkgconfig'); do \ + PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:$i"; \ + done; \ + echo export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}" > /tmp/pkgconfig + +FROM base AS linux-amd64 + +FROM base AS windows-amd64 +ENV CC=x86_64-w64-mingw32-gcc +# Set variables used by cni script which would otherwise shell out to powershell +ARG GATEWAY +ENV GATEWAY=$GATEWAY +ARG PREFIX_LEN +ENV PREFIX_LEN=$PREFIX_LEN + +FROM ${TARGETOS}-${TARGETARCH}${TARGETVARIANT} AS target +COPY . /go/src/github.com/containerd/containerd +WORKDIR /go/src/github.com/containerd/containerd +ARG TARGETARCH +ARG TARGETOS +ENV GOARCH=$TARGETARCH +ENV GOOS=$TARGETOS +ENV OS=$TARGETOS +ARG RELEASE_VER +ENV VERSION=$RELEASE_VER +RUN \ + --mount=type=bind,from=go,source=/usr/local/go,target=/usr/local/go \ + --mount=type=cache,target=/root/.cache/go-build \ + [ -f /tmp/pkgconfig ] && . /tmp/pkgconfig; \ + make release cri-release cri-cni-release + +FROM scratch AS release +COPY --from=target /go/src/github.com/containerd/containerd/releases/ / diff --git a/Makefile b/Makefile index 567b9c36b..cbf03e783 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ MANDIR ?= $(DATADIR)/man TEST_IMAGE_LIST ?= # Used to populate variables in version package. -VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always) +VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always) REVISION=$(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi) PACKAGE=github.com/containerd/containerd SHIM_CGO_ENABLED ?= 0 @@ -271,6 +271,7 @@ install-man: man @echo "$(WHALE) $@" $(foreach manpage,$(addprefix man/,$(MANPAGES)), $(call installmanpage,$(manpage),$(subst .,,$(suffix $(manpage))),$(notdir $(manpage)))) + releases/$(RELEASE).tar.gz: $(BINARIES) @echo "$(WHALE) $@" @rm -rf releases/$(RELEASE) releases/$(RELEASE).tar.gz diff --git a/Makefile.windows b/Makefile.windows index 56164e424..4f4125aa5 100644 --- a/Makefile.windows +++ b/Makefile.windows @@ -22,7 +22,11 @@ ifeq ($(GOARCH),amd64) TESTFLAGS_RACE= -race endif -BINARIES:=$(addsuffix .exe,$(BINARIES)) +WINDOWS_SHIM=bin/containerd-shim-runhcs-v1.exe +BINARIES := $(addsuffix .exe,$(BINARIES)) $(WINDOWS_SHIM) + +$(WINDOWS_SHIM): script/setup/install-runhcs-shim go.mod + DESTDIR=$(PWD)/bin $< bin/%.exe: cmd/% FORCE $(BUILD_BINARY) diff --git a/script/setup/install-cni-windows b/script/setup/install-cni-windows index 19c4aa7e9..32534c0de 100755 --- a/script/setup/install-cni-windows +++ b/script/setup/install-cni-windows @@ -65,10 +65,10 @@ calculate_subnet() { # nat already exists on the Windows VM, the subnet and gateway # we specify should match that. -gateway="$(powershell -c "(Get-NetIPAddress -InterfaceAlias 'vEthernet (nat)' -AddressFamily IPv4).IPAddress")" -prefix_len="$(powershell -c "(Get-NetIPAddress -InterfaceAlias 'vEthernet (nat)' -AddressFamily IPv4).PrefixLength")" +: ${GATEWAY:="$(powershell -c "(Get-NetIPAddress -InterfaceAlias 'vEthernet (nat)' -AddressFamily IPv4).IPAddress")"} +: ${PREFIX_LEN:="$(powershell -c "(Get-NetIPAddress -InterfaceAlias 'vEthernet (nat)' -AddressFamily IPv4).PrefixLength")"} -subnet="$(calculate_subnet "$gateway" "$prefix_len")" +subnet="$(calculate_subnet "$GATEWAY" "$PREFIX_LEN")" # The "name" field in the config is used as the underlying # network type right now (see @@ -85,7 +85,7 @@ bash -c 'cat >"'"${CNI_CONFIG_DIR}"'"/0-containerd-nat.conf <