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

fix(arm64): use qemu to do the packaging step for arm64 images refs: #ENGEN-715 #520

Merged
merged 12 commits into from
Aug 3, 2022
Merged
6 changes: 6 additions & 0 deletions .ci/setup_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ if [ "$RESTY_IMAGE_TAG" != "bionic" ] && [ "$RESTY_IMAGE_TAG" != "18.04" ] && [
exit 0
fi

sudo apt-get install -y \
qemu \
binfmt-support \
qemu-user-static

docker version
RESULT=$?
if [ "$RESULT" != "0" ]; then
Expand Down Expand Up @@ -36,6 +41,7 @@ if ! [ -x "$(command -v docker-machine)" ]; then
sudo install docker-machine /usr/local/bin/docker-machine
fi

set -e
curiositycasualty marked this conversation as resolved.
Show resolved Hide resolved
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true
echo "$REDHAT_PASSWORD" | docker login -u "$REDHAT_USERNAME" registry.access.redhat.com --password-stdin || true
docker-machine version
Expand Down
3 changes: 1 addition & 2 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ pipeline {
}
}
environment {
AWS_ACCESS_KEY = "instance-profile"
PATH = "/home/ubuntu/bin/:${env.PATH}"
PACKAGE_TYPE = "rpm"
}
Expand All @@ -161,7 +160,7 @@ pipeline {
sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin || true'
sh 'git clone --single-branch --branch ${KONG_SOURCE} https://github.com/Kong/kong.git ${KONG_SOURCE_LOCATION}'
sh 'make RESTY_IMAGE_BASE=src RESTY_IMAGE_TAG=src PACKAGE_TYPE=src package-kong test cleanup'
sh 'make RESTY_IMAGE_BASE=alpine RESTY_IMAGE_TAG=3.10 PACKAGE_TYPE=apk CACHE=false UPDATE_CACHE=true DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` package-kong test cleanup'
sh 'make RESTY_IMAGE_BASE=alpine RESTY_IMAGE_TAG=3 PACKAGE_TYPE=apk CACHE=false UPDATE_CACHE=true DOCKER_MACHINE_ARM64_NAME="jenkins-kong-"`cat /proc/sys/kernel/random/uuid` package-kong test cleanup'
}
}
stage('Kong OSS DEB') {
Expand Down
49 changes: 37 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ OFFICIAL_RELEASE ?= true
PACKAGE_CONFLICTS ?= `grep PACKAGE_CONFLICTS $(KONG_SOURCE_LOCATION)/.requirements | awk -F"=" '{print $$2}'`
PACKAGE_PROVIDES ?= `grep PACKAGE_PROVIDES $(KONG_SOURCE_LOCATION)/.requirements | awk -F"=" '{print $$2}'`
PACKAGE_REPLACES ?= `grep PACKAGE_REPLACES $(KONG_SOURCE_LOCATION)/.requirements | awk -F"=" '{print $$2}'`
DOCKER_RELEASE_REPOSITORY ?= `grep DOCKER_RELEASE_REPOSITORY $(KONG_SOURCE_LOCATION)/.requirements | awk -F"=" '{print $$2}'`
Copy link
Contributor

Choose a reason for hiding this comment

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

Did this get tested with kong-ee? I am skeptical this would correctly overwrite with the variable's value in .requirements (https://github.com/Kong/kong-ee/blob/c2d854b8dea021ab581588b8e758665a519e4746/.requirements#L9)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't find a way to keep this PR backwards compatible with current Kong CE which doesn't have a value for DOCKER_RELEASE_REPOSITORY.

Someway of in order of precedence:

  1. use an environment variable
  2. use the DOCKER_RELEASE_REPOSITORY value from .requirements
  3. some sensible default

Copy link
Contributor

Choose a reason for hiding this comment

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

I think our build infrastructure for the gateway product already presumes that default values pertain to the building of CE. So option 3, a sensible default for the value required for the CE build, makes sense to me.

DOCKER_RELEASE_REPOSITORY?="kong/kong"

KONG_TEST_CONTAINER_NAME=kong-tests
KONG_TEST_CONTAINER_TAG?=5000/kong-$(RESTY_IMAGE_BASE)-$(RESTY_IMAGE_TAG)
KONG_TEST_IMAGE_NAME?=localhost:$(KONG_TEST_CONTAINER_TAG)
KONG_TEST_CONTAINER_TAG?=$(KONG_VERSION)-$(RESTY_IMAGE_BASE)-$(RESTY_IMAGE_TAG)
ADDITIONAL_TAG_LIST?=
KONG_TEST_IMAGE_NAME?=$(DOCKER_RELEASE_REPOSITORY):$(KONG_TEST_CONTAINER_TAG)

# This logic should mirror the kong-build-tools equivalent
KONG_VERSION?=`$(KONG_SOURCE_LOCATION)/distribution/grep-kong-version.sh`
Expand Down Expand Up @@ -99,7 +100,7 @@ BUILDX_INFO ?= $(shell docker buildx 2>&1 >/dev/null; echo $?)
DOCKER_LABELS?=--label org.opencontainers.image.version=$(KONG_VERSION) --label org.opencontainers.image.created=`date -u +'%Y-%m-%dT%H:%M:%SZ'` --label org.opencontainers.image.revision=$(KONG_SHA)

ifeq ($(BUILDX),false)
DOCKER_COMMAND?=docker build --progress=$(DOCKER_BUILD_PROGRESS) $(KONG_EE_PORTS_FLAG) --build-arg BUILDPLATFORM=x/amd64 $(DOCKER_LABELS)
DOCKER_COMMAND?=docker build --build-arg TARGETPLATFORM=linux/amd64 --progress=$(DOCKER_BUILD_PROGRESS) $(KONG_EE_PORTS_FLAG) $(DOCKER_LABELS)
else
DOCKER_COMMAND?=docker buildx build --progress=$(DOCKER_BUILD_PROGRESS) $(KONG_EE_PORTS_FLAG) --push --platform="linux/amd64,linux/arm64" $(DOCKER_LABELS)
endif
Expand Down Expand Up @@ -328,6 +329,25 @@ test-kong: kong-test-container
bash -c 'healthy=$$(docker-compose ps | grep healthy | wc -l); while [[ "$$(( $$healthy ))" != "3" ]]; do docker-compose ps && sleep 5; done'
docker exec kong /kong/.ci/run_tests.sh && make update-cache-images

release-kong-docker-images: test
ifeq ($(BUILDX),false)
docker push $(KONG_TEST_IMAGE_NAME)
else
docker push $(DOCKER_RELEASE_REPOSITORY):amd64-$(KONG_TEST_CONTAINER_TAG)
docker push $(DOCKER_RELEASE_REPOSITORY):arm64-$(KONG_TEST_CONTAINER_TAG)
docker manifest create $(KONG_TEST_IMAGE_NAME) -a \
$(DOCKER_RELEASE_REPOSITORY):amd64-$(KONG_TEST_CONTAINER_TAG) \
$(DOCKER_RELEASE_REPOSITORY):arm64-$(KONG_TEST_CONTAINER_TAG)
docker manifest push $(KONG_TEST_IMAGE_NAME)
endif
for ADDITIONAL_TAG in $(ADDITIONAL_TAG_LIST); do \
docker run -t --rm \
-v ~/.docker/config.json:/tmp/auth.json \
quay.io/skopeo/stable:latest \
copy --all docker://docker.io/$(KONG_TEST_IMAGE_NAME) \
docker://docker.io/$(DOCKER_RELEASE_REPOSITORY):$$ADDITIONAL_TAG ; \
done

release-kong: test
ARCHITECTURE=amd64 \
RESTY_IMAGE_BASE=$(RESTY_IMAGE_BASE) \
Expand Down Expand Up @@ -410,34 +430,39 @@ ifneq ($(RESTY_IMAGE_BASE),src)
endif

build-test-container:
ifneq ($(RESTY_IMAGE_BASE),src)
touch test/kong_license.private
ARCHITECTURE=amd64 \
KONG_PACKAGE_NAME=$(KONG_PACKAGE_NAME) \
PACKAGE_TYPE=$(PACKAGE_TYPE) \
RESTY_IMAGE_BASE=$(RESTY_IMAGE_BASE) \
RESTY_IMAGE_TAG=$(RESTY_IMAGE_TAG) \
KONG_VERSION=$(KONG_VERSION) \
KONG_PACKAGE_NAME=$(KONG_PACKAGE_NAME) \
KONG_TEST_IMAGE_NAME=$(KONG_TEST_IMAGE_NAME) \
DOCKER_RELEASE_REPOSITORY=$(DOCKER_RELEASE_REPOSITORY) \
KONG_TEST_CONTAINER_TAG=$(KONG_TEST_CONTAINER_TAG) \
DOCKER_KONG_VERSION=$(DOCKER_KONG_VERSION) \
DOCKER_BUILD_PROGRESS=$(DOCKER_BUILD_PROGRESS) \
DOCKER_LABELS="$(DOCKER_LABELS)" \
test/build_container.sh
docker tag $(DOCKER_RELEASE_REPOSITORY):amd64-$(KONG_TEST_CONTAINER_TAG) \
$(DOCKER_RELEASE_REPOSITORY):$(KONG_TEST_CONTAINER_TAG)
docker tag $(DOCKER_RELEASE_REPOSITORY):amd64-$(KONG_TEST_CONTAINER_TAG) \
$(KONG_TEST_IMAGE_NAME)
ifeq ($(BUILDX),true)
DOCKER_MACHINE_NAME=$(shell docker-machine env $(DOCKER_MACHINE_ARM64_NAME) | grep 'DOCKER_MACHINE_NAME=".*"' | cut -d\" -f2) \
DOCKER_TLS_VERIFY=1 \
DOCKER_HOST=$(shell docker-machine env $(DOCKER_MACHINE_ARM64_NAME) | grep 'DOCKER_HOST=".*"' | cut -d\" -f2) \
DOCKER_CERT_PATH=$(shell docker-machine env $(DOCKER_MACHINE_ARM64_NAME) | grep 'DOCKER_CERT_PATH=".*"' | cut -d\" -f2) \
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && \
Copy link
Contributor

Choose a reason for hiding this comment

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

So, does this PR do away with docker-machine? If so, we should also strip out the docker-machine install.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not.

We use docker-machine / a remote arm worker for the purposes of building Kong arm64. The final step of packaing and placing said package onto the host system output/ directory is via qemu.

ARCHITECTURE=arm64 \
KONG_PACKAGE_NAME=$(KONG_PACKAGE_NAME) \
PACKAGE_TYPE=$(PACKAGE_TYPE) \
RESTY_IMAGE_BASE=$(RESTY_IMAGE_BASE) \
RESTY_IMAGE_TAG=$(RESTY_IMAGE_TAG) \
KONG_VERSION=$(KONG_VERSION) \
KONG_PACKAGE_NAME=$(KONG_PACKAGE_NAME) \
KONG_TEST_IMAGE_NAME=$(KONG_TEST_IMAGE_NAME) \
DOCKER_RELEASE_REPOSITORY=$(DOCKER_RELEASE_REPOSITORY) \
KONG_TEST_CONTAINER_TAG=$(KONG_TEST_CONTAINER_TAG) \
DOCKER_KONG_VERSION=$(DOCKER_KONG_VERSION) \
DOCKER_LABELS="$(DOCKER_LABELS)" \
test/build_container.sh
endif
endif

setup-tests: cleanup-tests
ifneq ($(RESTY_IMAGE_BASE),src)
Expand Down
65 changes: 25 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,19 @@ Packaging arm64 architectures additionally requires:

hutchic marked this conversation as resolved.
Show resolved Hide resolved
- [Docker-machine](https://github.com/docker/machine)
- [Buildx Docker plugin](https://github.com/docker/buildx)
- AWS Credentials
- AWS Credentials (or access via an instance profile)

## Packaging a Kong Distribution
Packaging kong-ee additionally requires:

The default build task builds an Ubuntu bionic package of Kong where the Kong source is assumed to be
in a sibling directory to where this repository is cloned
- A `GITHUB_TOKEN` environment variable with access to Kong's private github repositories

## Building a Kong Package

```
export PACKAGE_TYPE=deb RESTY_IMAGE_BASE=ubuntu RESTY_IMAGE_TAG=20.04 # defaults if not set
make package-kong
ls output/
kong-0.0.0.bionic.all.deb
```

**Environment variables:**

You can find all available environment variables at the top of the [Makefile](https://github.com/Kong/kong-build-tools/blob/master/Makefile).
The most common ones are the following:

```
RESTY_IMAGE_BASE=ubuntu|centos|rhel|debian|alpine|amazonlinux
RESTY_IMAGE_TAG=18.04|20.04|7|8|9|10|11|latest|latest
PACKAGE_TYPE=deb|rpm|apk
kong-x.y.z.20.04.all.deb
```

### Details
Expand All @@ -55,7 +46,23 @@ The Docker files in the dockerfiles directory build on each other in the followi
- `Dockerfile.package` builds on top of the result of `Dockerfile.kong` to package Kong using `fpm-entrypoint.sh`
- `Dockerfile.kong` builds on top of the result of `Dockerfile.openresty` to build Kong using `build-kong.sh`
- `Dockerfile.openresty` builds on top of the result of `Dockerfile.(deb|apk|rpm)` to build the Kong prerequisites using `openresty-build-tools/kong-ngx-build`
- `Dockerfile.(deb|apk|rpm)` builds the compilation / building prerequisites
- [github://kong/kong-build-tools-base-images](https://github.com/Kong/kong-build-tools-base-images) builds the compilation / building prerequisites

## Building a Kong Docker Image

Prerequisite: you did the packaging step
```
export KONG_TEST_CONTAINER_NAME=kong/kong:x.y.z-ubuntu-20.04 #default if not set
make build-test-container
```

## Releasing Docker Images

Prerequisite: you did the packaging step and you're logged into docker with the necessary push permissions
```
export DOCKER_RELEASE_REPOSITORY=kong/kong KONG_TEST_CONTAINER_TAG=x.y.z-ubuntu-20.04 #default if not set
make release-kong-docker-images
```

## Running Kong Tests

Expand All @@ -82,29 +89,7 @@ TEST_SUITE = "dbless|plugins|unit|integration"
- `Dockerfile.openresty` builds on top of the result of `Dockerfile.(deb|apk|rpm)` to build the Kong prerequisites using `openresty-build-tools/kong-ngx-build`
- `Dockerfile.(deb|apk|rpm)` builds the compilation / building prerequisites

### Debugging Tests

If you want to mirror a failed test from CI pull the test image the CI built and retag it:

```
docker pull mashape/kong-build-tools:test-33c8ceb-e2bb1fd54f8d5c12f989a801a44979b610-14
docker tag mashape/kong-build-tools:test-33c8ceb-e2bb1fd54f8d5c12f989a801a44979b610-14 mashape/kong-build-tools:test
```

If you're trying to test local Kong source code build the test image:

```
make kong-test-container
```

Now spin up the containers using docker-compose and jump into the Kong image
```
docker-compose up -d
docker-compose exec kong /bin/bash
./ci/run_tests.sh
```

## Running Functional Tests
## Running Packaging / Smoke Tests

The Kong Build Tools functional tests suite run a tests on a Kong package which we then integrate
into our official docker build image dockerfile.
Expand Down
7 changes: 5 additions & 2 deletions dockerfiles/Dockerfile.package
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ ARG RESTY_IMAGE_TAG="18.04"
ARG PACKAGE_TYPE
ARG KONG_VERSION
ARG KONG_PACKAGE_NAME
ARG BUILDPLATFORM
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM}
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM}

ARG PACKAGE_CONFLICTS="kong-enterprise-edition"
ENV PACKAGE_CONFLICTS $PACKAGE_CONFLICTS
Expand All @@ -40,4 +43,4 @@ COPY kong.logrotate /tmp/build/etc/kong/kong.logrotate
RUN /fpm-entrypoint.sh

FROM alpine
COPY --from=FPM /output /output
COPY --from=FPM /output /output
3 changes: 1 addition & 2 deletions fpm-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ elif [ "$PACKAGE_TYPE" == "rpm" ]; then
OUTPUT_FILE_SUFFIX=".el${RESTY_IMAGE_TAG}"
fi
fi
OUTPUT_FILE_SUFFIX="${OUTPUT_FILE_SUFFIX}."$(echo ${BUILDPLATFORM} | awk -F "/" '{ print $2}')

OUTPUT_FILE_SUFFIX="${OUTPUT_FILE_SUFFIX}."$(echo ${TARGETPLATFORM} | awk -F "/" '{ print $2}')
ROCKSPEC_VERSION=`basename /tmp/build/build/usr/local/lib/luarocks/rocks/kong/*`

if [ "$PACKAGE_TYPE" == "apk" ]; then
Expand Down
14 changes: 10 additions & 4 deletions test/build_container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -e

DOCKER_BUILD_ARGS=()

KONG_TEST_IMAGE_NAME=$DOCKER_RELEASE_REPOSITORY:$ARCHITECTURE-$KONG_TEST_CONTAINER_TAG

image_id=$(docker image inspect -f '{{.ID}}' "$KONG_TEST_IMAGE_NAME" || true)
if [ -n "$image_id" ]; then
msg_test "Tests image Name: $KONG_TEST_IMAGE_NAME"
Expand All @@ -19,7 +21,7 @@ chmod -R 755 docker-kong/*.sh
if [ "$RESTY_IMAGE_BASE" == "src" ]; then
exit 0
elif [ "$RESTY_IMAGE_BASE" == "alpine" ]; then
cp output/*${ARCHITECTURE}*.apk.tar.gz docker-kong/kong.apk.tar.gz
cp output/${KONG_PACKAGE_NAME}-${KONG_VERSION}.${ARCHITECTURE}.apk.tar.gz docker-kong/kong.apk.tar.gz
elif [ "$PACKAGE_TYPE" == "deb" ]; then
cp output/*${ARCHITECTURE}*.deb docker-kong/kong.deb
else
Expand All @@ -45,14 +47,18 @@ pushd ./docker-kong
DOCKER_BUILD_ARGS+=(--label "org.opencontainers.image.revision=$DOCKER_LABEL_REVISION")
fi

DOCKER_BUILD_ARGS+=(--platform linux/${ARCHITECTURE})
DOCKER_BUILD_ARGS+=(--no-cache)
DOCKER_BUILD_ARGS+=(--pull)
DOCKER_BUILD_ARGS+=(--build-arg ASSET=local .)

docker build --progress=${DOCKER_BUILD_PROGRESS:-auto} -t $KONG_TEST_IMAGE_NAME -f Dockerfile.$PACKAGE_TYPE \

docker build \
--progress=${DOCKER_BUILD_PROGRESS:-auto} \
-t $KONG_TEST_IMAGE_NAME \
-f Dockerfile.$PACKAGE_TYPE \
${DOCKER_LABELS} \
"${DOCKER_BUILD_ARGS[@]}"

docker run -t $KONG_TEST_IMAGE_NAME kong version
msg_test "Tests image Name: $KONG_TEST_IMAGE_NAME"
popd

Expand Down
1 change: 1 addition & 0 deletions test/tests/01-package/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ then
major="${RESTY_IMAGE_TAG%%.*}"
docker run -d --name user-validation-tests --rm -e KONG_DATABASE=off -v $PWD:/src registry.access.redhat.com/ubi${major}/ubi tail -f /dev/null
else
docker rmi ${RESTY_IMAGE_BASE}:${RESTY_IMAGE_TAG} --force
docker run -d --name user-validation-tests --rm -e KONG_DATABASE=off -v $PWD:/src ${RESTY_IMAGE_BASE}:${RESTY_IMAGE_TAG} tail -f /dev/null
fi

Expand Down