diff --git a/.github/workflows/update-snapshots.yml b/.github/workflows/update-snapshots.yml new file mode 100644 index 0000000..aa9657a --- /dev/null +++ b/.github/workflows/update-snapshots.yml @@ -0,0 +1,60 @@ +name: update-snapshots + +on: + workflow_dispatch: + +jobs: + update-snapshots: + runs-on: ubuntu-latest + strategy: + max-parallel: 1 + matrix: + runtime-param: [3.2, 3.3, 3.4, 4.0] + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Node 20 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: 20 + + - name: Cache Node modules + id: cache-node-modules + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: "**/node_modules" + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install Serverless Framework + run: sudo yarn global add serverless@3 --prefix /usr/local + + - name: Install dependencies + if: steps.cache-node-modules.outputs.cache-hit != 'true' + working-directory: integration_tests + run: yarn install + + - name: Install Crossbuild dependencies + run: | + sudo apt-get update --allow-releaseinfo-change --fix-missing + sudo apt install -y qemu-user-static binfmt-support + + - name: Update Snapshots (amd64) + env: + ARCH: amd64 + UPDATE_SNAPSHOTS: true + BUILD_LAYERS: true + DD_API_KEY: ${{ secrets.DD_API_KEY }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + RUNTIME_PARAM: ${{ matrix.runtime-param }} + run: ./scripts/run_integration_tests.sh + + - name: Upload snapshots + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: snapshots-${{ matrix.runtime-param }} + path: | + integration_tests/snapshots/ diff --git a/.gitlab/scripts/build_layer.sh b/.gitlab/scripts/build_layer.sh index c8505a9..fdc9f3f 100755 --- a/.gitlab/scripts/build_layer.sh +++ b/.gitlab/scripts/build_layer.sh @@ -41,9 +41,12 @@ function docker_build_zip { # Install datadog ruby in a docker container to avoid the mess from switching # between different ruby runtimes. + # + # NOTE: using the Lambda base image so native extensions (FFI, libddwaf) + # compile against the same libffi available at runtime on Lambda. temp_dir=$(mktemp -d) docker buildx build -t datadog-lambda-ruby-${arch}:$1 . --no-cache \ - --build-arg "image=ruby:${1}" \ + --build-arg "image=public.ecr.aws/lambda/ruby:${1}" \ --build-arg "runtime=${1}.0" \ --build-arg "git_ref=${ref}" \ --platform linux/${arch} \ diff --git a/Dockerfile b/Dockerfile index 432cc5e..cbf0f76 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,26 +6,41 @@ RUN echo "git_ref: $git_ref" # Install dev dependencies COPY . /var/task/datadog-lambda-rb WORKDIR /var/task/datadog-lambda-rb -RUN apt-get update -RUN apt-get install -y gcc zip binutils +# NOTE: AL2 (Ruby 3.2) uses yum, AL2023 (Ruby 3.3+) uses dnf +RUN PKG=$(command -v dnf || command -v yum) && \ + $PKG install -y gcc gcc-c++ make zip binutils libffi-devel # Install this gem RUN gem build datadog-lambda # Install ddtrace gem -RUN gem install datadog-lambda --install-dir "/opt/ruby/gems/$runtime" +RUN MAKEFLAGS="-j$(nproc)" \ + gem install datadog-lambda --install-dir "/opt/ruby/gems/$runtime" --no-document RUN set -eux; \ if [ -z "${git_ref:-}" ]; then \ # NOTE: datadog gem must be >= 2.24 to install on Ruby 4.0.x. - gem install datadog -v 2.30 --install-dir "/opt/ruby/gems/$runtime"; \ + MAKEFLAGS="-j$(nproc)" \ + gem install datadog -v 2.30 --install-dir "/opt/ruby/gems/$runtime" --no-document; \ else \ echo "building tracer from ref: $git_ref\n"; \ git clone https://github.com/DataDog/dd-trace-rb.git --depth 1 --single-branch -b $git_ref /tmp/dd-trace-rb; \ cd /tmp/dd-trace-rb; \ gem build datadog.gemspec; \ - gem install ./datadog-*.gem --install-dir "/opt/ruby/gems/$runtime"; \ + MAKEFLAGS="-j$(nproc)" \ + gem install ./datadog-*.gem --install-dir "/opt/ruby/gems/$runtime" --no-document; \ fi +# Recompile FFI from source — precompiled binaries ship ABI-specific ffi_c.so +# for Ruby 3.3/3.4 only. Ruby 3.2 ABI is missing, causing LoadError at boot +# when AppSec loads libddwaf → ffi → ffi_c. +# +# NOTE: runs after datadog gem as a defensive measure — force-replaces whatever +# transitive FFI variant was pulled, regardless of version resolution. +RUN gem uninstall ffi --all --ignore-dependencies --executables --force \ + --install-dir "/opt/ruby/gems/$runtime" || true +RUN MAKEFLAGS="-j$(nproc)" \ + gem install ffi --platform ruby --install-dir "/opt/ruby/gems/$runtime" --no-document + WORKDIR /opt # Remove native extension debase-ruby_core_source (25MB) runtimes below Ruby 2.6 RUN rm -rf ./ruby/gems/$runtime/gems/debase-ruby_core_source*/ diff --git a/scripts/build_layers.sh b/scripts/build_layers.sh index c0d005c..9cd1b65 100755 --- a/scripts/build_layers.sh +++ b/scripts/build_layers.sh @@ -37,9 +37,12 @@ function docker_build_zip { # Install datadog ruby in a docker container to avoid the mess from switching # between different ruby runtimes. + # + # NOTE: using the Lambda base image so native extensions (FFI, libddwaf) + # compile against the same libffi available at runtime on Lambda. temp_dir=$(mktemp -d) docker buildx build -t datadog-lambda-ruby-${arch}:$1 . --no-cache \ - --build-arg "image=ruby:${1}" \ + --build-arg "image=public.ecr.aws/lambda/ruby:${1}" \ --build-arg "runtime=${1}.0" \ --build-arg "git_ref=${ref}" \ --platform linux/${arch} \