Skip to content

Commit

Permalink
Support ARM builds (#997)
Browse files Browse the repository at this point in the history
* Support ARM builds

Signed-off-by: Stavros Foteinopoulos <[email protected]>

* Debug failure

Signed-off-by: Stavros Foteinopoulos <[email protected]>

* Refactor tagging as arm images weren't tagged properly

Signed-off-by: Stavros Foteinopoulos <[email protected]>

---------

Signed-off-by: Stavros Foteinopoulos <[email protected]>
  • Loading branch information
stafot authored Jan 8, 2024
1 parent a92d0da commit 954488e
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 32 deletions.
16 changes: 11 additions & 5 deletions .github/actions/docker-build/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ description: Reusable action to build repos' docker images
runs:
using: composite
steps:
- name: cd/build-docker
run: make build-image
shell: bash

- name: ci/prepare-docker-environment
uses: ./.github/actions/docker-prepare
- name: cd/scan-docker-security
uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5 # v0.8.0
with:
Expand All @@ -31,5 +29,13 @@ runs:
severity: "CRITICAL"

- name: cd/docker-push
run: ./scripts/push-docker.sh
run: ./scripts/push-docker-e2e.sh
shell: bash
- name: cd/push-image-pr
run: "make push-image-pr"
shell: bash
if: "${{ inputs.is_pr }}"
- name: cd/push-image
run: "make push-image"
shell: bash
if: "${{ !inputs.is_pr }}"
11 changes: 11 additions & 0 deletions .github/actions/docker-prepare/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: 'docker-prepare'
description: 'Install docker requirements'

runs:
using: 'composite'
steps:
- name: ci/setup-buildx
uses: docker/setup-buildx-action@v3
with:
version: v0.12.0
4 changes: 2 additions & 2 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
env:
TAG: ${{ github.ref_name }}
REF_NAME: ${{ github.ref_name }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
uses: ./.github/actions/docker-build
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ jobs:
- name: ci/build-docker
env:
REF_NAME: ${{ github.ref_name }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
uses: ./.github/actions/docker-build
66 changes: 56 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

## Tool Versions
GOLANG_VERSION := $(shell cat go.mod | grep "^go " | cut -d " " -f 2)
ALPINE_VERSION = 3.18.2
ALPINE_VERSION = 3.19
TERRAFORM_VERSION=1.5.5
KOPS_VERSION=v1.27.2
HELM_VERSION=v3.11.2
KUBECTL_VERSION=v1.24.4
POSTGRES_VERSION=14.8
ARCH ?= amd64

## Docker Build Versions
DOCKER_BUILD_IMAGE := golang:$(GOLANG_VERSION)
Expand All @@ -23,6 +24,7 @@ DOCKER_BASE_IMAGE = alpine:$(ALPINE_VERSION)
GO ?= $(shell command -v go 2> /dev/null)
PACKAGES=$(shell go list ./... | grep -v internal/mocks)
MATTERMOST_CLOUD_IMAGE ?= mattermost/mattermost-cloud:test
MATTERMOST_CLOUD_REPO ?= mattermost/mattermost-cloud
MATTERMOST_CLOUD_E2E_IMAGE ?= mattermost/mattermost-cloud-e2e:test
MACHINE = $(shell uname -m)
GOFLAGS ?= $(GOFLAGS:)
Expand Down Expand Up @@ -151,39 +153,83 @@ dist: build

.PHONY: build
build: ## Build the mattermost-cloud
@echo Building Mattermost-Cloud
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -ldflags '$(LDFLAGS)' -gcflags all=-trimpath=$(PWD) -asmflags all=-trimpath=$(PWD) -a -installsuffix cgo -o build/_output/bin/cloud ./cmd/cloud
@echo Building Mattermost-Cloud for ARCH=$(ARCH)
@if [ "$(ARCH)" = "amd64" ]; then \
export GOARCH="amd64"; \
elif [ "$(ARCH)" = "arm64" ]; then \
export GOARCH="arm64"; \
elif [ "$(ARCH)" = "arm" ]; then \
export GOARCH="arm"; \
else \
echo "Unknown architecture $(ARCH)"; \
exit 1; \
fi; \
GOOS=linux CGO_ENABLED=0 $(GO) build -ldflags '$(LDFLAGS)' -gcflags all=-trimpath=$(PWD) -asmflags all=-trimpath=$(PWD) -a -installsuffix cgo -o build/_output/bin/cloud-$$GOARCH ./cmd/cloud

build-image: ## Build the docker image for mattermost-cloud
@echo Building Mattermost-cloud Docker Image
docker build \
@if [ -z "$(DOCKER_USERNAME)" ] || [ -z "$(DOCKER_PASSWORD)" ]; then \
echo "DOCKER_USERNAME and/or DOCKER_PASSWORD not set. Skipping Docker login."; \
else \
echo $(DOCKER_PASSWORD) | docker login --username $(DOCKER_USERNAME) --password-stdin; \
fi
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg DOCKER_BUILD_IMAGE=$(DOCKER_BUILD_IMAGE) \
--build-arg DOCKER_BASE_IMAGE=$(DOCKER_BASE_IMAGE) \
. -f build/Dockerfile -t $(MATTERMOST_CLOUD_IMAGE) \
--no-cache
--no-cache \
--push

build-image-with-tag: ## Build the docker image for mattermost-cloud
@echo Building Mattermost-cloud Docker Image
@if [ -z "$(DOCKER_USERNAME)" ] || [ -z "$(DOCKER_PASSWORD)" ]; then \
echo "DOCKER_USERNAME and/or DOCKER_PASSWORD not set. Skipping Docker login."; \
else \
echo $(DOCKER_PASSWORD) | docker login --username $(DOCKER_USERNAME) --password-stdin; \
fi
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg DOCKER_BUILD_IMAGE=$(DOCKER_BUILD_IMAGE) \
--build-arg DOCKER_BASE_IMAGE=$(DOCKER_BASE_IMAGE) \
. -f build/Dockerfile -t $(MATTERMOST_CLOUD_IMAGE) -t $(MATTERMOST_CLOUD_REPO):${TAG} \
--no-cache \
--push

.PHONY: push-image-pr
push-image-pr:
@echo Push Image PR
./scripts/push-image-pr.sh

.PHONY: push-image
push-image:
@echo Push Image
./scripts/push-image.sh

get-terraform: ## Download terraform only if it's not available. Used in the docker build
@if [ ! -f build/terraform ]; then \
curl -Lo build/terraform.zip https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && cd build && unzip terraform.zip &&\
curl -Lo build/terraform.zip "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_$(ARCH).zip" &&\
echo "Downloaded file details:" && ls -l build/terraform.zip &&\
cd build && unzip terraform.zip &&\
chmod +x terraform && rm terraform.zip;\
fi

get-kops: ## Download kops only if it's not available. Used in the docker build
@if [ ! -f build/kops ]; then \
curl -Lo build/kops https://github.com/kubernetes/kops/releases/download/${KOPS_VERSION}/kops-linux-amd64 &&\
curl -Lo build/kops https://github.com/kubernetes/kops/releases/download/${KOPS_VERSION}/kops-linux-$(ARCH) &&\
chmod +x build/kops;\
fi

get-helm: ## Download helm only if it's not available. Used in the docker build
@if [ ! -f build/helm ]; then \
curl -Lo build/helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz &&\
curl -Lo build/helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-$(ARCH).tar.gz &&\
cd build && tar -zxvf helm.tar.gz &&\
cp linux-amd64/helm helm && chmod +x helm && rm helm.tar.gz && rm -rf linux-amd64;\
cp linux-$(ARCH)/helm helm && chmod +x helm && rm helm.tar.gz && rm -rf linux-$(ARCH);\
fi

get-kubectl: ## Download kubectl only if it's not available. Used in the docker build
@if [ ! -f build/kubectl ]; then \
curl -Lo build/kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl &&\
curl -Lo build/kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/$(ARCH)/kubectl &&\
chmod +x build/kubectl;\
fi

Expand Down
23 changes: 17 additions & 6 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@

# Build the mattermost cloud
ARG DOCKER_BUILD_IMAGE=golang:1.20
ARG DOCKER_BASE_IMAGE=alpine:3.18.2
ARG DOCKER_BASE_IMAGE=alpine:3.19

FROM ${DOCKER_BUILD_IMAGE} AS build
WORKDIR /mattermost-cloud/
COPY . /mattermost-cloud/
RUN apt-get update -yq && apt-get install -yq unzip
RUN make get-terraform get-kops get-helm get-kubectl
RUN make build

# Detect architecture and set ARCH
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
ARCH="amd64"; \
elif [ "$ARCH" = "aarch64" ]; then \
ARCH="arm64"; \
elif [ "$ARCH" = "armv7l" ] || [ "$ARCH" = "armv6l" ]; then \
ARCH="arm"; \
fi && \
echo "ARCH=$ARCH" && \
apt-get update -yq && apt-get install -yq unzip && \
make get-terraform ARCH=$ARCH get-kops ARCH=$ARCH get-helm ARCH=$ARCH get-kubectl ARCH=$ARCH && \
make build ARCH=$ARCH

# Final Image
FROM ${DOCKER_BASE_IMAGE}
Expand All @@ -19,7 +30,7 @@ LABEL name="Mattermost Cloud" \
maintainer="[email protected]" \
vendor="Mattermost" \
distribution-scope="public" \
architecture="x86_64" \
architecture="x86_64, arm64" \
url="https://mattermost.com" \
io.k8s.description="Mattermost Cloud creates, configures and helps manage K8s Clusters and Mattermost installations on Kubernetes" \
io.k8s.display-name="Mattermost Cloud"
Expand All @@ -34,7 +45,7 @@ COPY --from=build /mattermost-cloud/build/kops /usr/local/bin/
COPY --from=build /mattermost-cloud/build/helm /usr/local/bin/
COPY --from=build /mattermost-cloud/build/kubectl /usr/local/bin/
COPY --from=build /mattermost-cloud/manifests /mattermost-cloud/manifests
COPY --from=build /mattermost-cloud/build/_output/bin/cloud /mattermost-cloud/cloud
COPY --from=build /mattermost-cloud/cmd/cloud /mattermost-cloud/cloud
COPY --from=build /mattermost-cloud/build/bin /usr/local/bin
RUN /usr/local/bin/user_setup
WORKDIR /mattermost-cloud/
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.e2e
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Build the mattermost cloud e2e
ARG DOCKER_BUILD_IMAGE=golang:1.20
ARG DOCKER_BASE_IMAGE=alpine:3.18.2
ARG DOCKER_BASE_IMAGE=alpine:3.19

FROM ${DOCKER_BUILD_IMAGE} AS build
WORKDIR /mattermost-cloud-e2e/
Expand Down
8 changes: 2 additions & 6 deletions scripts/push-docker.sh → scripts/push-docker-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,23 @@

set -euox

echo $DOCKERHUB_TOKEN | docker login --username $DOCKERHUB_USERNAME --password-stdin
echo $DOCKER_PASSWORD | docker login --username $DOCKER_USERNAME --password-stdin

if [ "$TAG" = "" ]; then
echo "TAG was not provided"
exit 1
fi


echo "Tagging images with SHA $TAG"

docker tag mattermost/mattermost-cloud:test mattermost/mattermost-cloud:$TAG
docker tag mattermost/mattermost-cloud-e2e:test mattermost/mattermost-cloud-e2e:$TAG

docker push mattermost/mattermost-cloud:$TAG
docker push mattermost/mattermost-cloud-e2e:$TAG

if [ "$REF_NAME" = "master" ] || [ "$REF_NAME" = "main" ]; then
echo "Tagging images with 'latest' tag"

docker tag mattermost/mattermost-cloud:test mattermost/mattermost-cloud:latest
docker tag mattermost/mattermost-cloud-e2e:test mattermost/mattermost-cloud-e2e:latest

docker push mattermost/mattermost-cloud:latest
docker push mattermost/mattermost-cloud-e2e:latest
fi
5 changes: 5 additions & 0 deletions scripts/push-image-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
set -e
set -u

make build-image-with-tag
15 changes: 15 additions & 0 deletions scripts/push-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
set -e
set -u

: ${GITHUB_REF_TYPE:?}
: ${GITHUB_REF_NAME:?}

if [ "${GITHUB_REF_TYPE:-}" = "branch" ]; then
echo "Pushing latest for $GITHUB_REF_NAME..."
export TAG=latest
else
echo "Pushing release $GITHUB_REF_NAME..."
export TAG="$GITHUB_REF_NAME"
fi
make build-image-with-tag

0 comments on commit 954488e

Please sign in to comment.