diff --git a/.github/workflows/build-runner.yml b/.github/workflows/build-runner.yml index 8097e16e..cfb989f7 100644 --- a/.github/workflows/build-runner.yml +++ b/.github/workflows/build-runner.yml @@ -1,22 +1,34 @@ on: push: branches: - - master + - master paths: - - 'runner/**' + - 'runner/**' jobs: build: runs-on: ubuntu-latest name: Build runner steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Build container image - run: make docker-build - working-directory: runner - - name: Docker Login - run: docker login -u summerwind -p ${{ secrets.DOCKER_ACCESS_TOKEN }} - - name: Push container image - run: make docker-push - working-directory: runner + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + buildx-version: latest + + - name: Login to GitHub Docker Registry + run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin + env: + DOCKERHUB_USERNAME: summerwind + DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + - name: Build Container Image + working-directory: runner + run: | + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag summerwind/actions-runner:latest \ + -f Dockerfile . --push diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96b3706e..f4dc30fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,28 +3,43 @@ name: Build on: push: branches: - - master + - master paths-ignore: - - 'runner/**' - - '.github/**' + - 'runner/**' + - '.github/**' jobs: build: runs-on: ubuntu-latest name: Build steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install kubebuilder - run: | - curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz - tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz - sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder - - name: Run tests - run: make test - - name: Build container image - run: make docker-build - - name: Docker Login - run: docker login -u summerwind -p ${{ secrets.DOCKER_ACCESS_TOKEN }} - - name: Push container image - run: make docker-push + - name: Checkout + uses: actions/checkout@v2 + + - name: Install kubebuilder + run: | + curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz + tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz + sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder + + - name: Run tests + run: make test + + - name: Set up Docker Buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + buildx-version: latest + + - name: Login to GitHub Docker Registry + run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin + env: + DOCKERHUB_USERNAME: summerwind + DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + - name: Build Container Image + run: | + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag summerwind/actions-runner-controller:latest \ + -f Dockerfile . --push diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5a4aa3a..413b3e9b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,27 +7,43 @@ jobs: runs-on: ubuntu-latest name: Release steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install tools - run: | - curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz - tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz - sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder - curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash - sudo mv kustomize /usr/local/bin - curl -L -O https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz - tar zxvf ghr_v0.13.0_linux_amd64.tar.gz - sudo mv ghr_v0.13.0_linux_amd64/ghr /usr/local/bin - - name: Set version - run: echo "::set-env name=VERSION::$(cat ${GITHUB_EVENT_PATH} | jq -r '.release.tag_name')" - - name: Upload artifacts - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: make github-release - - name: Build container image - run: make docker-build - - name: Docker Login - run: docker login -u summerwind -p ${{ secrets.DOCKER_ACCESS_TOKEN }} - - name: Push container image - run: make docker-push + - name: Checkout + uses: actions/checkout@v2 + + - name: Install tools + run: | + curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz + tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz + sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder + curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash + sudo mv kustomize /usr/local/bin + curl -L -O https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz + tar zxvf ghr_v0.13.0_linux_amd64.tar.gz + sudo mv ghr_v0.13.0_linux_amd64/ghr /usr/local/bin + + - name: Set version + run: echo "::set-env name=VERSION::$(cat ${GITHUB_EVENT_PATH} | jq -r '.release.tag_name')" + + - name: Upload artifacts + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: make github-release + + - name: Set up Docker Buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + buildx-version: latest + + - name: Login to GitHub Docker Registry + run: echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin + env: + DOCKERHUB_USERNAME: summerwind + DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + - name: Build Container Image + run: | + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag summerwind/actions-runner-controller:${{ env.VERSION }} \ + -f Dockerfile . --push diff --git a/Dockerfile b/Dockerfile index 6dfb4f6d..be348e2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,37 @@ # Build the manager binary FROM golang:1.13 as builder +ARG TARGETPLATFORM + WORKDIR /workspace + +ENV GO111MODULE=on \ + CGO_ENABLED=0 + # Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum +COPY go.mod go.sum ./ + # cache deps before building and copying source so that we don't need to re-download as much # and so that source changes don't invalidate our downloaded layer RUN go mod download # Copy the go source -COPY main.go main.go -COPY api/ api/ -COPY controllers/ controllers/ -COPY github/ github/ +COPY . . # Build -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go +RUN export GOOS=$(echo ${TARGETPLATFORM} | cut -d / -f1) && \ + export GOARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) && \ + GOARM=$(echo ${TARGETPLATFORM} | cut -d / -f3 | cut -c2-) && \ + go build -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details FROM gcr.io/distroless/static:nonroot + WORKDIR / + COPY --from=builder /workspace/manager . + USER nonroot:nonroot ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index 0f216230..21273fdc 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,23 @@ else GOBIN=$(shell go env GOBIN) endif +# default list of platforms for which multiarch image is built +ifeq (${PLATFORMS}, ) + export PLATFORMS="linux/amd64,linux/arm64" +endif + +# if IMG_RESULT is unspecified, by default the image will be pushed to registry +ifeq (${IMG_RESULT}, load) + export PUSH_ARG="--load" + # if load is specified, image will be built only for the build machine architecture. + export PLATFORMS="local" +else ifeq (${IMG_RESULT}, cache) + # if cache is specified, image will only be available in the build cache, it won't be pushed or loaded + # therefore no PUSH_ARG will be specified +else + export PUSH_ARG="--push" +endif + all: manager # Run tests @@ -62,6 +79,18 @@ docker-build: test docker-push: docker push ${NAME}:${VERSION} +docker-buildx: + export DOCKER_CLI_EXPERIMENTAL=enabled + @if ! docker buildx ls | grep -q container-builder; then\ + docker buildx create --platform ${PLATFORMS} --name container-builder --use;\ + fi + docker buildx build --platform ${PLATFORMS} \ + --build-arg RUNNER_VERSION=${RUNNER_VERSION} \ + --build-arg DOCKER_VERSION=${DOCKER_VERSION} \ + -t "${NAME}:${VERSION}" \ + -f Dockerfile \ + . ${PUSH_ARG} + # Generate the release manifest file release: manifests cd config/manager && kustomize edit set image controller=${NAME}:${VERSION} diff --git a/runner/Dockerfile b/runner/Dockerfile index 632545f3..a87f4a3a 100644 --- a/runner/Dockerfile +++ b/runner/Dockerfile @@ -1,7 +1,8 @@ FROM ubuntu:18.04 -ARG RUNNER_VERSION -ARG DOCKER_VERSION +ARG TARGETPLATFORM +ARG RUNNER_VERSION=2.272.0 +ARG DOCKER_VERSION=19.03.12 ENV DEBIAN_FRONTEND=noninteractive RUN apt update -y \ @@ -9,46 +10,55 @@ RUN apt update -y \ && add-apt-repository -y ppa:git-core/ppa \ && apt update -y \ && apt install -y --no-install-recommends \ - build-essential \ - curl \ - ca-certificates \ - dnsutils \ - ftp \ - git \ - iproute2 \ - iputils-ping \ - jq \ - libunwind8 \ - locales \ - netcat \ - openssh-client \ - parallel \ - rsync \ - shellcheck \ - sudo \ - telnet \ - time \ - tzdata \ - unzip \ - upx \ - wget \ - zip \ - zstd \ + build-essential \ + curl \ + ca-certificates \ + dnsutils \ + ftp \ + git \ + iproute2 \ + iputils-ping \ + jq \ + libunwind8 \ + locales \ + netcat \ + openssh-client \ + parallel \ + rsync \ + shellcheck \ + sudo \ + telnet \ + time \ + tzdata \ + unzip \ + upx \ + wget \ + zip \ + zstd \ && rm -rf /var/lib/apt/lists/* -RUN curl -L -o docker.tgz https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \ +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && curl -L -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_${ARCH} \ + && chmod +x /usr/local/bin/dumb-init + +# Docker download supports arm64 as aarch64 & amd64 as x86_64 +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "arm64" ]; then export ARCH=aarch64 ; fi \ + && if [ "$ARCH" = "amd64" ]; then export ARCH=x86_64 ; fi \ + && curl -L -o docker.tgz https://download.docker.com/linux/static/stable/${ARCH}/docker-${DOCKER_VERSION}.tgz \ && tar zxvf docker.tgz \ && install -o root -g root -m 755 docker/docker /usr/local/bin/docker \ && rm -rf docker docker.tgz \ - && curl -L -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 \ - && chmod +x /usr/local/bin/dumb-init \ && adduser --disabled-password --gecos "" --uid 1000 runner \ && usermod -aG sudo runner \ && echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers -RUN mkdir -p /runner \ +# Runner download supports amd64 as x64 +RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ + && if [ "$ARCH" = "amd64" ]; then export ARCH=x64 ; fi \ + && mkdir -p /runner \ && cd /runner \ - && curl -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz \ + && curl -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz \ && tar xzf ./runner.tar.gz \ && rm runner.tar.gz \ && ./bin/installdependencies.sh \ diff --git a/runner/Makefile b/runner/Makefile index fb598155..9fa50f3c 100644 --- a/runner/Makefile +++ b/runner/Makefile @@ -4,9 +4,38 @@ TAG ?= latest RUNNER_VERSION ?= 2.273.4 DOCKER_VERSION ?= 19.03.12 +# default list of platforms for which multiarch image is built +ifeq (${PLATFORMS}, ) + export PLATFORMS="linux/amd64,linux/arm64" +endif + +# if IMG_RESULT is unspecified, by default the image will be pushed to registry +ifeq (${IMG_RESULT}, load) + export PUSH_ARG="--load" + # if load is specified, image will be built only for the build machine architecture. + export PLATFORMS="local" +else ifeq (${IMG_RESULT}, cache) + # if cache is specified, image will only be available in the build cache, it won't be pushed or loaded + # therefore no PUSH_ARG will be specified +else + export PUSH_ARG="--push" +endif + docker-build: docker build --build-arg RUNNER_VERSION=${RUNNER_VERSION} --build-arg DOCKER_VERSION=${DOCKER_VERSION} -t ${NAME}:${TAG} -t ${NAME}:v${RUNNER_VERSION} . docker-push: docker push ${NAME}:${TAG} docker push ${NAME}:v${RUNNER_VERSION} + +docker-buildx: + export DOCKER_CLI_EXPERIMENTAL=enabled + @if ! docker buildx ls | grep -q container-builder; then\ + docker buildx create --platform ${PLATFORMS} --name container-builder --use;\ + fi + docker buildx build --platform ${PLATFORMS} \ + --build-arg RUNNER_VERSION=${RUNNER_VERSION} \ + --build-arg DOCKER_VERSION=${DOCKER_VERSION} \ + -t "${NAME}:latest" \ + -f Dockerfile \ + . ${PUSH_ARG}