Skip to content
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
55 changes: 55 additions & 0 deletions .github/workflows/runtime-interface-client_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,61 @@ jobs:
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

integration-test-matrix:
runs-on: ${{ matrix.arch.runner }}
strategy:
# Run every OS/arch combination to completion so one failure doesn't mask the others.
fail-fast: false
matrix:
buildspec:
- buildspec.os.alpine.yml
- buildspec.os.amazoncorretto.yml
- buildspec.os.amazonlinux.1.yml
- buildspec.os.amazonlinux.2.yml
- buildspec.os.debian.yml
- buildspec.os.ubuntu.yml
arch:
- label: x64
runner: ubuntu-latest
platform: linux/amd64
- label: arm64
runner: ubuntu-24.04-arm
platform: linux/arm64/v8
exclude:
# Amazon Linux 1 was never published for ARM64 (x86_64 only), so
# public.ecr.aws/amazonlinux/amazonlinux:1 has no arm64 manifest.
- buildspec: buildspec.os.amazonlinux.1.yml
arch:
label: arm64
runner: ubuntu-24.04-arm
platform: linux/arm64/v8
name: "integration-test (${{ matrix.buildspec }} / ${{ matrix.arch.label }})"
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
with:
install: true

- name: Run OS integration test - 'test-integ' target
working-directory: ./aws-lambda-java-runtime-interface-client
run: make test-integ BUILDSPEC=test/integration/codebuild/${{ matrix.buildspec }}
env:
PLATFORM_FILTER: ${{ matrix.arch.platform }}

integration-test:
needs: integration-test-matrix
if: always()
runs-on: ubuntu-latest
steps:
- name: Check integration-test results
run: |
if [ "${{ needs.integration-test-matrix.result }}" != "success" ]; then
echo "Integration tests failed on one or more OS/arch combinations"
exit 1
fi

smoke-test:
needs: smoke-test-arch
if: always()
Expand Down
3 changes: 3 additions & 0 deletions aws-lambda-java-runtime-interface-client/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
compile-flags.txt
ric-dev-environment/codeartifact-properties.mk

# aws-lambda-cpp prebuilt lib + headers, fetched and staged at build time
src/main/jni/deps/aws-lambda-cpp/
11 changes: 8 additions & 3 deletions aws-lambda-java-runtime-interface-client/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ test:

.PHONY: setup-codebuild-agent
setup-codebuild-agent:
docker build -t codebuild-agent \
test/integration/codebuild-local/docker-retry.sh docker build --load -t codebuild-agent \
--build-arg ARCHITECTURE=$(ARCHITECTURE_ALIAS) \
- < test/integration/codebuild-local/Dockerfile.agent
-f test/integration/codebuild-local/Dockerfile.agent \
test/integration/codebuild-local

# Smoke tests are split per-architecture so CI can run each set on a native
# runner. Running the linux/arm64/v8 combos under QEMU on an x86_64 host makes
Expand All @@ -46,9 +47,13 @@ test-smoke-aarch64: setup-codebuild-agent
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild/buildspec.os.alpine.yml alpine 3.15 corretto11 linux/arm64/v8
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild/buildspec.os.amazoncorretto.yml amazoncorretto amazoncorretto 11 linux/arm64/v8

# BUILDSPEC can point to the buildspec directory (default, runs every OS) or to a
# single buildspec file, which is how CI parallelizes the run across OSes.
BUILDSPEC ?= test/integration/codebuild

.PHONY: test-integ
test-integ: setup-codebuild-agent
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_all.sh test/integration/codebuild
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_all.sh $(BUILDSPEC)

# Command to run everytime you make changes to verify everything works
.PHONY: dev
Expand Down
2 changes: 1 addition & 1 deletion aws-lambda-java-runtime-interface-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ You can include this package in your preferred base image to make that base imag

### Creating a Docker Image for Lambda with the Runtime Interface Client

Choose a preferred base image. The Runtime Interface Client is tested on Amazon Linux, Alpine, Ubuntu, Debian, and CentOS. The requirements are that the image is:
Choose a preferred base image. The Runtime Interface Client is tested on Amazon Linux, Alpine, Ubuntu, and Debian. The requirements are that the image is:

* built for x86_64 and ARM64
* contains Java >= 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ ARG AWS_REGION
RUN if [ -n "${AWS_REGION}" ]; then echo "${AWS_REGION}" > /etc/yum/vars/awsregion; fi

RUN yum install -y \
cmake3 \
tar \
gzip \
make \
Expand All @@ -33,18 +32,12 @@ RUN ./configure \
make && \
make install

# Install aws-lambda-cpp dependency
ADD ./deps/aws-lambda-cpp-* /src/deps/aws-lambda-cpp
RUN mkdir -p /src/deps/aws-lambda-cpp/build
WORKDIR /src/deps/aws-lambda-cpp/build
RUN cmake3 .. \
-DENABLE_LTO=OFF \
-DCMAKE_CXX_FLAGS="-fPIC -DBACKWARD_SYSTEM_UNKNOWN" \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_INSTALL_PREFIX=$(pwd)/../../artifacts \
-DCMAKE_MODULE_PATH=$(pwd)/../../artifacts/lib/pkgconfig && \
make && \
make install
# Install prebuilt aws-lambda-cpp dependency. The static library and headers
# were fetched and GPG-verified on the host by build-jni-lib.sh; here we only
# COPY them into the artifacts tree the native client links against (the build
# container never reaches the network).
COPY ./deps/aws-lambda-cpp/include /src/deps/artifacts/include
COPY ./deps/aws-lambda-cpp/lib/libaws-lambda-runtime.a /src/deps/artifacts/lib/

# Build native client
ADD *.cpp *.h /src/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ ARG CURL_VERSION
RUN apk update && \
apk add \
openjdk11 \
cmake \
file \
g++ \
gcc \
Expand All @@ -31,17 +30,8 @@ RUN ./configure \
make && \
make install

# Install aws-lambda-cpp dependency
ADD ./deps/aws-lambda-cpp-* /src/deps/aws-lambda-cpp
RUN mkdir -p /src/deps/aws-lambda-cpp/build
WORKDIR /src/deps/aws-lambda-cpp/build
RUN cmake .. \
-DCMAKE_CXX_FLAGS="-fPIC -DBACKWARD_SYSTEM_UNKNOWN" \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_INSTALL_PREFIX=$(pwd)/../../artifacts\
-DCMAKE_MODULE_PATH=$(pwd)/../../artifacts/lib/pkgconfig && \
make && \
make install
COPY ./deps/aws-lambda-cpp/include /src/deps/artifacts/include
COPY ./deps/aws-lambda-cpp/lib/libaws-lambda-runtime.a /src/deps/artifacts/lib/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Curious how the alpine leg works with a glibc-built .a, since alpine doesn't have glibc (musl) — before this we compiled from source inside the container, so is musl's glibc symbol compat enough here or should upstream publish a musl variant too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The prebuilt .a is just an archive of relocatable object files, so what matters isn't the libc it was built on but which external symbols its objects actually reference and none of them are glibc-specific.

The final .so in the musl leg still links against the musl-built static curl and musl libc inside the Alpine container, with libstdc++/libgcc statically linked, so nothing glibc leaks in on that side either.

Code used

curl -fsSL -o lib.a https://github.com/awslabs/aws-lambda-cpp/releases/download/v1.0.1/libaws-lambda-runtime-x86_64.a
ar x lib.a

for f in *.o; do readelf -sW "$f"; done | grep -c "@GLIBC_"
# returns nothins

This is also why the tests are passing

# Build native client
ADD *.cpp *.h /src/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,67 @@ MULTI_ARCH=${2}
BUILD_OS=${3}
BUILD_ARCH=${4}
CURL_VERSION=7.83.1
# Registry hosting the base images. Defaults to public.ecr.aws for local and
# GitHub-hosted builds; the release workflow overrides it with the ECR
# pull-through cache so egress-locked runners don't hit public.ecr.aws.

BASE_REGISTRY="${BASE_REGISTRY:-public.ecr.aws}"
AWS_REGION="${AWS_REGION:-${AWS_DEFAULT_REGION:-}}"

# aws-lambda-cpp is consumed as the prebuilt static library published on the
# upstream GitHub release rather than being compiled from a vendored source
# tree. We fetch and GPG-verify it
ALC_VERSION="1.0.1"
ALC_TAG="v${ALC_VERSION}"
ALC_REPO_URL="https://github.com/awslabs/aws-lambda-cpp"
ALC_RELEASE_URL="${ALC_REPO_URL}/releases/download/${ALC_TAG}"
ALC_SIGNING_KEY_URL="https://raw.githubusercontent.com/awslabs/aws-lambda-cpp/${ALC_TAG}/signing-public-key.asc"
ALC_STAGE_DIR="${SRC_DIR}/deps/aws-lambda-cpp"

function fetch_aws_lambda_cpp() {
arch=$1

release_arch="${arch/aarch_64/aarch64}"

if [ -f "${ALC_STAGE_DIR}/.staged-arch" ] && \
[ "$(cat "${ALC_STAGE_DIR}/.staged-arch")" == "${release_arch}" ]; then
echo "aws-lambda-cpp ${ALC_VERSION} (${release_arch}) already staged, skipping fetch"
return
fi

echo "Fetching prebuilt aws-lambda-cpp ${ALC_VERSION} for ${release_arch}"
rm -rf "${ALC_STAGE_DIR}"
mkdir -p "${ALC_STAGE_DIR}/lib" "${ALC_STAGE_DIR}/include"

local workdir
workdir=$(mktemp -d)
local lib_asset="libaws-lambda-runtime-${release_arch}.a"

curl -fsSL -o "${workdir}/${lib_asset}" "${ALC_RELEASE_URL}/${lib_asset}"
curl -fsSL -o "${workdir}/${lib_asset}.asc" "${ALC_RELEASE_URL}/${lib_asset}.asc"
curl -fsSL -o "${workdir}/SHA256SUMS" "${ALC_RELEASE_URL}/SHA256SUMS"
curl -fsSL -o "${workdir}/SHA256SUMS.asc" "${ALC_RELEASE_URL}/SHA256SUMS.asc"
curl -fsSL -o "${workdir}/signing-key.asc" "${ALC_SIGNING_KEY_URL}"

local gnupghome
gnupghome=$(mktemp -d)
gpg --homedir "${gnupghome}" --batch --quiet --import "${workdir}/signing-key.asc"
gpg --homedir "${gnupghome}" --batch --verify "${workdir}/${lib_asset}.asc" "${workdir}/${lib_asset}"
gpg --homedir "${gnupghome}" --batch --verify "${workdir}/SHA256SUMS.asc" "${workdir}/SHA256SUMS"
rm -rf "${gnupghome}"

# Cross-check the checksum too (defence in depth; SHA256SUMS is itself signed).
( cd "${workdir}" && grep "${lib_asset}\$" SHA256SUMS | sha256sum -c - )

cp "${workdir}/${lib_asset}" "${ALC_STAGE_DIR}/lib/libaws-lambda-runtime.a"

# Headers aren't a release asset, so take them from the source at the same
# tag. They are declarations only -- every symbol lives in the prebuilt lib.
curl -fsSL -o "${workdir}/src.tar.gz" "${ALC_REPO_URL}/archive/refs/tags/${ALC_TAG}.tar.gz"
tar -xzf "${workdir}/src.tar.gz" -C "${workdir}" "aws-lambda-cpp-${ALC_VERSION}/include"
cp -R "${workdir}/aws-lambda-cpp-${ALC_VERSION}/include/." "${ALC_STAGE_DIR}/include/"

echo "${release_arch}" > "${ALC_STAGE_DIR}/.staged-arch"
rm -rf "${workdir}"
}

function get_docker_platform() {
arch=$1

Expand Down Expand Up @@ -44,6 +99,8 @@ function build_for_libc_arch() {
arch=$2
artifact=$3

fetch_aws_lambda_cpp "${arch}"

docker_platform=$(get_docker_platform ${arch})

echo "Compiling the native library with libc implementation \`${libc_impl}\` on architecture \`${arch}\` using Docker platform \`${docker_platform}\`"
Expand Down Expand Up @@ -118,12 +175,10 @@ else
declare -a ARCHITECTURES=("x86_64" "aarch_64")
declare -a LIBC_IMPLS=("glibc" "musl")

# `arch` reports the host as `aarch64`, but we use Maven's classifier
# spelling `aarch_64` in ARCHITECTURES, so normalize before comparing.
host_arch=$(arch)
if [ "${host_arch}" == "aarch64" ]; then
host_arch="aarch_64"
fi
host_arch="$(arch)"
case "${host_arch}" in
aarch64|arm64) host_arch="aarch_64" ;;
esac

for arch in "${ARCHITECTURES[@]}"; do

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading