Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiarch: Build multiarch binaries and images #24

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 76 additions & 49 deletions .github/workflows/image-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ jobs:
id-token: write # needed for signing the images with GitHub OIDC Token

runs-on: ubuntu-latest
env:
WF_BPFMAN_AGENT_IMG: quay.io/bpfman/bpfman-agent
WF_BPFMAN_OPERATOR_IMG: quay.io/bpfman/bpfman-operator
WF_MULTIARCH_TARGETS: amd64 arm64 ppc64le s390x
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -51,6 +47,75 @@ jobs:
# set latest tag for default branch
type=raw,value=latest,enable={{is_default_branch}}

name: Build Image (${{ matrix.image.image }})
steps:
- name: Checkout bpfman
uses: actions/checkout@v4

- name: Install cosign
uses: sigstore/cosign-installer@v3.5.0

- name: Login to quay.io/bpfman
uses: redhat-actions/podman-login@v1
if: ${{ github.event_name == 'push' && matrix.image.repository == 'bpfman'}}
with:
registry: ${{ matrix.image.registry }}
username: ${{ secrets.BPFMAN_USERNAME }}
password: ${{ secrets.BPFMAN_ROBOT_TOKEN }}

- name: Extract metadata (tags, labels) for image
id: meta
uses: docker/metadata-action@v5.5.1
with:
images: ${{ matrix.image.registry }}/${{ matrix.image.repository }}/${{ matrix.image.image }}
tags: ${{ matrix.image.tags }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Set push flag
id: set-push
run: |
if [ ${{ github.event_name }} == 'push' ]; then
echo "push_flag=true" >> "$GITHUB_OUTPUT"
else
echo "push_flag=false" >> "$GITHUB_OUTPUT"
fi

- name: Build and push
id: build-push-image
uses: docker/build-push-action@v5
with:
platforms: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x
push: ${{ fromJSON(steps.set-push.outputs.push_flag) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm why the fromJSON() function call here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think just steps.set-push.outputs.push_flag would work

Copy link
Contributor Author

@Billy99 Billy99 Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to convert from the string "true" to a boolean true/false. It balked at just passing steps.set-push.outputs.push_flag.

tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
file: ${{ matrix.image.dockerfile }}
build-args: ${{ matrix.image.build_args }}
context: ${{ matrix.image.context }}

- name: Sign the images with GitHub OIDC Token
if: ${{ github.event_name == 'push' }}
run: |
readarray -t tags <<<"${{ steps.meta.outputs.tags }}"
for tag in ${tags[@]}; do
cosign sign -y "${tag}@${{ steps.push-image.outputs.digest }}"
done

generate-and-push-bundle-images:
permissions:
contents: read
packages: write
id-token: write # needed for signing the images with GitHub OIDC Token

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image:
- registry: quay.io
repository: bpfman
image: bpfman-operator-bundle
Expand All @@ -64,21 +129,17 @@ jobs:
# set latest tag for default branch
type=raw,value=latest,enable={{is_default_branch}}

name: Build Image (${{ matrix.image.image }})
name: Build Bundle Image (${{ matrix.image.image }})
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
# prettier-ignore
go-version: '1.22' # yamllint disable-line rule:quoted-strings
- name: Checkout bpfman
uses: actions/checkout@v4

- uses: sigstore/cosign-installer@v3.5.0
- name: Install cosign
uses: sigstore/cosign-installer@v3.5.0

- name: Generate olm bundle on disk
if: ${{ matrix.image.image == 'bpfman-operator-bundle' }}
run: |
make bundle
make bundle-build

- name: Login to quay.io/bpfman
uses: redhat-actions/podman-login@v1
Expand All @@ -95,21 +156,10 @@ jobs:
images: ${{ matrix.image.registry }}/${{ matrix.image.repository }}/${{ matrix.image.image }}
tags: ${{ matrix.image.tags }}

- name: Build image
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait are we still actually building the bundle image anywhere?

Copy link
Contributor Author

@Billy99 Billy99 Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's in it's own job, line 132 (https://github.com/bpfman/bpfman-operator/pull/24/files#diff-502adaf7a495a56eb3ecef9c7f4c295ce0ac343f9b0d4e2fd321910fdf8f58bdR132). I was on the fence on one job or two. There are a handful of common steps (Checkout bpfman, Install Golang, etc), but several that are specific to bundle (Generate olm bundle on disk, Push to registry) and even more in the Build Image job that don't need to run.

Copy link
Member

@astoycos astoycos Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that it's in it's own job now and that's alright since we don't have to build it for every different platform, however in the

name: Build Bundle Image (${{ matrix.image.image }})
job I don't see where we're building the bundle image,

make bundle just makes sure all the manifests for the bundle are generated

id: build-image
uses: redhat-actions/buildah-build@v2
with:
image: ${{ matrix.image.image }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
containerfiles: ${{ matrix.image.dockerfile }}
build-args: ${{ matrix.image.build_args }}
context: ${{ matrix.image.context }}

- name: Push to registry
id: push-image
uses: redhat-actions/push-to-registry@v2
if: ${{ github.event_name == 'push' && matrix.image.image != 'mutli-arch-images' }}
if: ${{ github.event_name == 'push' }}
with:
tags: ${{ steps.meta.outputs.tags }}

Expand All @@ -120,26 +170,3 @@ jobs:
for tag in ${tags[@]}; do
cosign sign -y "${tag}@${{ steps.push-image.outputs.digest }}"
done
- name: get short sha
run: |
echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

- name: Build operator multi arch images
if: ${{ matrix.image.image == 'bpfman-operator' }}
run: |
BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}:${{ env.short_sha }}" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}:${{ env.short_sha }}" MULTIARCH_TARGETS="${{ env.WF_MULTIARCH_TARGETS }}" make build-operator-images

- name: Push operator multi arch images and manifest
if: ${{ github.event_name == 'push' && matrix.image.image == 'bpfman-operator' }}
run: |
BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}:${{ env.short_sha }}" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}:${{ env.short_sha }}" MULTIARCH_TARGETS="${{ env.WF_MULTIARCH_TARGETS }}" make operator-images

- name: Build agent multi arch images
if: ${{ matrix.image.image == 'bpfman-agent' }}
run: |
BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}:${{ env.short_sha }}" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}:${{ env.short_sha }}" MULTIARCH_TARGETS="${{ env.WF_MULTIARCH_TARGETS }}" make build-agent-images

- name: Push agent multi arch images and manifest
if: ${{ github.event_name == 'push' && matrix.image.image == 'bpfman-agent' }}
run: |
BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}:${{ env.short_sha }}" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}:${{ env.short_sha }}" MULTIARCH_TARGETS="${{ env.WF_MULTIARCH_TARGETS }}" make agent-images
118 changes: 78 additions & 40 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,76 @@ jobs:
uses: apache/skywalking-eyes@cd7b195c51fd3d6ad52afceb760719ddc6b3ee91

build-lint-test:
name: Build, lint, test
name: Build (Go ${{ matrix.go }} - ${{ matrix.arch.arch }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go: ['1.22']
arch:
- arch: amd64
filename: linux-x86_64
- arch: arm64
filename: linux-arm64
- arch: ppc64le
filename: linux-ppc64le
- arch: s390x
filename: linux-s390x
steps:
- name: install make
run: sudo apt-get install make
- name: set up go 1.x
uses: actions/setup-go@v3
- name: Install go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: checkout
uses: actions/checkout@v3
- name: check format

- name: Checkout bpfman-operator
uses: actions/checkout@v4

- name: Check format
if: ${{ matrix.arch.arch == 'amd64' }}
run: make fmt && git add -A && git diff --exit-code
- name: build, lint, test
run: make build lint test
- name: check clean vendors
run: go mod vendor
- name: Report coverage
if: ${{ matrix.go == '1.22' }}
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

- name: Build Operator and Agent
run: GOARCH=${{ matrix.arch.arch }} make build

- name: Run lint
if: ${{ matrix.arch.arch == 'amd64' }}
run: make lint

- name: Verify Autogenerated Code
if: ${{ matrix.arch.arch == 'amd64' }}
run: make verify

- name: Run test
if: ${{ matrix.arch.arch == 'amd64' }}
run: make test

- name: Archive Go code coverage results
if: ${{ matrix.arch.arch == 'amd64' && matrix.go == '1.22' }}
uses: actions/upload-artifact@v4
with:
files: ./cover.out
flags: unittests
fail_ci_if_error: false
verbose: true
name: coverage-go
path: cover.out
if-no-files-found: error

- name: Check clean vendors
if: ${{ matrix.arch.arch == 'amd64' }}
run: go mod vendor

bundle-check:
runs-on: ubuntu-latest
name: Checking bundle up-to-date
steps:
- name: install make
run: sudo apt-get install make
- name: checkout
uses: actions/checkout@v3
- name: Verify generated bundle manifest
if: ${{ matrix.arch.arch == 'amd64' }}
run: |
make bundle
git diff --exit-code -I'^ createdAt: ' bundle

kubernetes-integration-tests:
name: Kubernetes Integration Tests (Go ${{ matrix.go }} - amd64)
runs-on: ubuntu-latest
strategy:
matrix:
go: ['1.22']
env:
WF_BPFMAN_AGENT_IMG: quay.io/bpfman/bpfman-agent:int-test
WF_BPFMAN_OPERATOR_IMG: quay.io/bpfman/bpfman-operator:int-test
BPFMAN_AGENT_IMG: quay.io/bpfman/bpfman-agent:int-test
BPFMAN_OPERATOR_IMG: quay.io/bpfman/bpfman-operator:int-test
XDP_PASS_PRIVATE_IMAGE_CREDS: ${{ secrets.XDP_PASS_PRIVATE_IMAGE_CREDS }}
steps:
- name: Check disk space
Expand All @@ -84,8 +102,8 @@ jobs:
- name: Check disk space again
run: df -h

- name: set up go 1.x
uses: actions/setup-go@v3
- name: Install go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}

Expand All @@ -96,37 +114,57 @@ jobs:
key: ${{ runner.os }}-build-codegen-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-build-codegen-
- name: checkout repository

- name: Checkout bpfman-operator
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: build images
- name: Build Operator and Agent images
run: |
MULTIARCH_TARGETS="amd64" BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}" make build-images
make build-images

- name: run integration tests
- name: Run integration tests
run: |
BPFMAN_AGENT_IMG="${{ env.WF_BPFMAN_AGENT_IMG }}-amd64" BPFMAN_OPERATOR_IMG="${{ env.WF_BPFMAN_OPERATOR_IMG}}-amd64" make test-integration
make test-integration

- name: Check disk space
run: df -h

## Upload diagnostics if integration test step failed.
- name: upload diagnostics
- name: Upload diagnostics
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: kubernetes-integration-test-diag
path: /tmp/ktf-diag*
if-no-files-found: ignore

coverage:
needs: [build-lint-test]
runs-on: ubuntu-latest
steps:
- name: Download golang coverage artifacts
uses: actions/download-artifact@v4
with:
name: coverage-go

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: ./cover.out
flags: unittests
fail_ci_if_error: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for breaking this out.

verbose: true

build-workflow-complete:
needs:
[
check-license,
build-lint-test,
bundle-check,
coverage,
kubernetes-integration-tests,
]
runs-on: ubuntu-latest
Expand Down
18 changes: 12 additions & 6 deletions Containerfile.bpfman-agent
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Build the manager binary
ARG TARGETPLATFORM
ARG BUILDPLATFORM
FROM docker.io/library/golang:1.22 as bpfman-agent-build
ARG BUILDPLATFORM=linux/amd64

FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22 as bpfman-agent-build

# The following ARGs are set internally by docker/build-push-action in github actions
ARG TARGETOS
ARG TARGETPLATFORM
ARG TARGETARCH
ARG TARGETPLATFORM

RUN echo "TARGETOS=${TARGETOS} TARGETARCH=${TARGETARCH} BUILDPLATFORM=${BUILDPLATFORM} TARGETPLATFORM=${TARGETPLATFORM}"

WORKDIR /usr/src/bpfman-operator

Expand All @@ -31,7 +35,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -mod ven

# Use the fedora minimal image to reduce the size of the final image but still
# be able to easily install extra packages.
FROM quay.io/fedora/fedora-minimal
FROM --platform=$TARGETPLATFORM quay.io/fedora/fedora-minimal
ARG DNF_CMD="microdnf"

# The full fedora image can be used for debugging purposes. To use it, comment
Expand All @@ -40,13 +44,15 @@ ARG DNF_CMD="microdnf"
# ARG DNF_CMD="dnf"

ARG TARGETARCH
ARG TARGETPLATFORM

WORKDIR /
COPY --from=bpfman-agent-build /usr/src/bpfman-operator/bpfman-agent .

# Install crictl
RUN ${DNF_CMD} -y install wget tar gzip
ARG VERSION="v1.28.0"
RUN wget https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-${TARGETARCH}.tar.gz
RUN wget --no-check-certificate https://github.com/kubernetes-sigs/cri-tools/releases/download/${VERSION}/crictl-${VERSION}-linux-${TARGETARCH}.tar.gz
RUN tar zxvf crictl-${VERSION}-linux-${TARGETARCH}.tar.gz -C /usr/local/bin
RUN rm -f crictl-${VERSION}-linux-${TARGETARCH}.tar.gz
RUN ${DNF_CMD} -y clean all
Expand Down
Loading
Loading