diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml new file mode 100644 index 0000000..b7280e8 --- /dev/null +++ b/.github/workflows/build-images.yaml @@ -0,0 +1,112 @@ +name: Build images + +on: + workflow_call: + inputs: + build_type: + required: true + type: string + +env: + BUILDKIT_CACHE_MAP: | + { + "var-cache-apt": "/var/cache/apt", + "var-lib-apt": "/var/lib/apt", + "ccache": "/ccache" + } + + DO_PUSH: y + +jobs: + build-images: + runs-on: + - ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + # for git describe + fetch-depth: 0 + + - name: Prepare repo + run: | + git config --global user.email "dummy@example.com" + git config --global user.name "dummy user" + + - name: Login to the registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY_DOMAIN }} + username: ${{ secrets.QUAY_USER_ID }} + password: ${{ secrets.QUAY_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: docker + + - name: Set up Buildkit Cache action + run: | + set -e + git clone https://github.com/reproducible-containers/buildkit-cache-dance.git + cd buildkit-cache-dance + git checkout 5b81f4d29dc8397a7d341dba3aeecc7ec54d6361 + + - name: Restore apt caches + uses: actions/cache/restore@v3 + with: + path: | + var-lib-apt + var-cache-apt + key: apt-${{ hashFiles('Dockerfile') }}-${{ hashFiles('vpp-builder.Dockerfile') }}-${{ hashFiles('vpp.spec') }} + restore-keys: apt- + + - name: Restore ccache + uses: actions/cache/restore@v3 + with: + path: ccache + key: ccache-${{ inputs.build_type }}-${{ hashFiles('Dockerfile') }}-${{ hashFiles('vpp-builder.Dockerfile') }}-${{ hashFiles('vpp.spec') }} + restore-keys: ccache-${{ inputs.build_type }}- + + - name: Inject caches into docker + run: + node ./buildkit-cache-dance/dist/index.js --cache-map "${BUILDKIT_CACHE_MAP}" + + - name: Build images + id: build + run: | + BUILD_TYPE="${{ inputs.build_type }}" \ + CI_BUILD=1 \ + BUILDKIT_PROGRESS=plain \ + DO_PUSH="${{ env.DO_PUSH }}" \ + BASE_REPO="${{ vars.BASE_REPO }}" \ + BUILDER_REPO="${{ vars.BUILDER_REPO }}" \ + QUAY_IO_IMAGE_EXPIRES_AFTER="${{ vars.QUAY_IO_IMAGE_EXPIRES_AFTER }}" \ + make image + + - name: Retag base image + if: github.ref_type == 'tag' + run: | + BUILD_TYPE="${{ inputs.build_type }}" BASE_REPO="${{ vars.BASE_REPO }}" build/retag-base-image.sh + + - name: Extract caches from docker + run: + node ./buildkit-cache-dance/dist/index.js --extract --cache-map "${BUILDKIT_CACHE_MAP}" + + - name: Save apt caches + if: steps.build.outputs.registry_cache_used == 'none' + uses: actions/cache/save@v3 + with: + path: | + var-lib-apt + var-cache-apt + key: apt-${{ hashFiles('Dockerfile') }}-${{ hashFiles('vpp-builder.Dockerfile') }}-${{ hashFiles('vpp.spec') }} + + - name: Save ccache + if: steps.build.outputs.registry_cache_used != 'vpp-base' + uses: actions/cache/save@v3 + with: + path: ccache + key: ccache-${{ inputs.build_type }}-${{ hashFiles('Dockerfile') }}-${{ hashFiles('vpp-builder.Dockerfile') }}-${{ hashFiles('vpp.spec') }} + diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..5d6defa --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,18 @@ +name: CI + +on: + push: + branches: + - "**" + +jobs: + build-images: + strategy: + matrix: + build_type: [debug, release] + + uses: ./.github/workflows/build-images.yaml + with: + build_type: ${{ matrix.build_type }} + secrets: inherit + diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml deleted file mode 100644 index 49edd8b..0000000 --- a/.github/workflows/main.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: CI - -on: - push: - branches: - - "**" - -env: - REGISTRY: "quay.io" - IMAGE_NAME: travelping/fpp-vpp - # this points to buildkitd k8s service - BUILDKITD_ADDR: tcp://buildkitd:1234 - -jobs: - build: - runs-on: - - ubuntu-22.04 - strategy: - matrix: - build_type: [debug, release] - env: - QUAY_USER_ID: ${{ secrets.QUAY_USER_ID }} - QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Prepare repo - run: | - git config --global user.email "dummy@example.com" - git config --global user.name "dummy user" - hack/update-vpp.sh - - name: Login to quay.io - uses: docker/login-action@v1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.QUAY_USER_ID }} - password: ${{ secrets.QUAY_TOKEN }} - - name: Build fpp-vpp image - run: | - BUILD_TYPE="${{ matrix.build_type }}" hack/ci-build.sh - mv /tmp/_out _out - - name: Upload debs - uses: actions/upload-artifact@v4 - with: - name: debs-${{ matrix.build_type }} - path: _out/* - - name: Upload image.txt - uses: actions/upload-artifact@v4 - with: - name: image-${{ matrix.build_type }} - path: image-${{ matrix.build_type }}.txt - - name: Upload image.txt for the dev image - uses: actions/upload-artifact@v4 - with: - name: image-dev-${{ matrix.build_type }} - path: image-dev-${{ matrix.build_type }}.txt - - # dummy job for release.yaml to wait on - conclude: - runs-on: - - ubuntu-22.04 - needs: - - build - steps: - - name: Dummy step - run: echo ok diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a1fc73e..6ebbbc2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,149 +1,88 @@ name: Release + on: push: - tags: - - "*" + tags: ["v*"] jobs: - release: - runs-on: self-hosted - steps: - - name: Clean the workspace - uses: docker://alpine - with: - args: /bin/sh -c "rm -rf /github/workspace/.* 2>/dev/null || rm -rf /github/workspace/*" - - - name: Checkout - uses: actions/checkout@v2 - - - name: Wait for build to succeed - uses: fountainhead/action-wait-for-check@v1.0.0 - id: wait-for-build - with: - token: ${{ secrets.GITHUB_TOKEN }} - checkName: conclude - ref: ${{ github.sha }} - timeoutSeconds: 6000 - - - name: Fail if the build did not succeed - if: steps.wait-for-build.outputs.conclusion == 'failure' - run: exit 1 - - # increase our chances of getting the artifacts on 1st try - - name: Delay - run: sleep 20 - - # It may take some time for the workflow to finish and the artifacts to appear - # FIXME: https://github.com/dawidd6/action-download-artifact/issues/43 - - name: Get debug image name - uses: dawidd6/action-download-artifact@v2 - continue-on-error: true - id: download - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-debug - - # FIXME: no clean way to retry the action - - name: Delay - if: steps.download.outcome=='failure' - run: sleep 40 - - - name: Retry download (1) - if: steps.download.outcome=='failure' - uses: dawidd6/action-download-artifact@v2 - continue-on-error: true - id: download1 - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-debug - - - name: Delay - if: steps.download1.outcome=='failure' - run: sleep 80 + retag-base-image: + runs-on: + - ubuntu-24.04 - - name: Retry download (2) - if: steps.download1.outcome=='failure' - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-debug + strategy: + matrix: + build_type: [debug, release] - - name: Promote (retag) the debug image - env: - REGISTRY_LOGIN: ${{ secrets.QUAY_USER_ID }} - REGISTRY_PASSWORD: ${{ secrets.QUAY_TOKEN }} - run: | - # hack/retag-unexpire.sh quay.io travelping/upg source_tag dest_tag - hack/retag-unexpire.sh $(sed 's@/@ @;s/:/ /' image-debug.txt) "${GITHUB_REF##*/}_debug" - - - name: Get release image name - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-release - - - name: Promote (retag) the release image - env: - REGISTRY_LOGIN: ${{ secrets.QUAY_USER_ID }} - REGISTRY_PASSWORD: ${{ secrets.QUAY_TOKEN }} - run: | - # hack/retag-unexpire.sh quay.io travelping/upg source_tag dest_tag - hack/retag-unexpire.sh $(sed 's@/@ @;s/:/ /' image-release.txt) "${GITHUB_REF##*/}_release" - - - name: Get dev release image name - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-dev-release - - - name: Promote (retag) the dev release image - env: - REGISTRY_LOGIN: ${{ secrets.QUAY_USER_ID }} - REGISTRY_PASSWORD: ${{ secrets.QUAY_TOKEN }} - run: | - hack/retag-unexpire.sh $(sed 's@/@ @;s/:/ /' image-dev-release.txt) "${GITHUB_REF##*/}_dev_release" - - - name: Get dev debug image name - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yaml - workflow_conclusion: success - commit: ${{github.sha}} - name: image-dev-debug - - - name: Promote (retag) the dev debug image - env: - REGISTRY_LOGIN: ${{ secrets.QUAY_USER_ID }} - REGISTRY_PASSWORD: ${{ secrets.QUAY_TOKEN }} - run: | - hack/retag-unexpire.sh $(sed 's@/@ @;s/:/ /' image-dev-debug.txt) "${GITHUB_REF##*/}_dev_debug" - - - name: Build Changelog - id: build_changelog - uses: mikepenz/release-changelog-builder-action@v1 - if: ${{ !contains(github.ref, 'test') }} - with: - configuration: "changelog-config.json" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + # for git describe + fetch-depth: 0 + + - name: Prepare repo + run: | + git config --global user.email "dummy@example.com" + git config --global user.name "dummy user" + + - name: Login to the registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY_DOMAIN }} + username: ${{ secrets.QUAY_USER_ID }} + password: ${{ secrets.QUAY_TOKEN }} + + - name: Ensure base image to retag is present + id: ensure-base-image-to-retag + run: | + BUILD_TYPE="${{ matrix.build_type }}" BASE_REPO="${{ vars.BASE_REPO }}" build/ensure-base-image-to-retag.sh + + - name: Retag base image + if: steps.ensure-base-image-to-retag.outputs.image_to_retag_present == 'true' + run: | + BUILD_TYPE="${{ matrix.build_type }}" BASE_REPO="${{ vars.BASE_REPO }}" build/retag-base-image.sh + + outputs: + debug_image_to_retag_present: ${{ steps.ensure-base-image-to-retag.outputs.debug_image_to_retag_present }} + release_image_to_retag_present: ${{ steps.ensure-base-image-to-retag.outputs.release_image_to_retag_present }} + + rebuild-and-tag-base-release-image: + needs: retag-base-image + if: needs.retag-base-image.outputs.release_image_to_retag_present == 'false' + uses: ./.github/workflows/build-images.yaml + with: + build_type: release + secrets: inherit + + rebuild-and-tag-base-debug-image: + needs: retag-base-image + if: needs.retag-base-image.outputs.debug_image_to_retag_present == 'false' + uses: ./.github/workflows/build-images.yaml + with: + build_type: debug + secrets: inherit + + changelog: + runs-on: + - ubuntu-24.04 - - name: Post the release - uses: softprops/action-gh-release@v1 - # TODO: prerelease for 'pre' - # TODO: no release for 'test' - if: ${{ !contains(github.ref, 'test') }} - with: - body: ${{ steps.build_changelog.outputs.changelog }} - prerelease: ${{ contains(github.ref, 'pre') }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Build Changelog + id: build_changelog + uses: mikepenz/release-changelog-builder-action@v5 + with: + configuration: "changelog-config.json" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Post the release + uses: softprops/action-gh-release@v2 + with: + body: ${{ steps.build_changelog.outputs.changelog }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile index c2a2c08..5906ced 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,68 +1,7 @@ # syntax = docker/dockerfile:experimental -FROM ubuntu:20.04 AS build-base-stage +ARG BUILDER_IMAGE -WORKDIR / - -ENV BUILDKIT_VERSION "v0.8.2" -ENV BUILDCTL_SHA256 "b64aec46fb438ea844616b3205c33b01a3a49ea7de1f8539abd0daeb4f07b9f9" -ENV INDENT_SHA256 "12185be748db620f8f7799ea839f0d10ce643b9f5ab1805c960e56eb27941236" -ENV LIBC_SHA256 "9a8caf9f33448a8f2f526e94d00c70cdbdd735caec510df57b3283413df7882a" -# Go version in ppa:longsleep/golang-backports -ENV GO_PACKAGE "golang-1.22-go" - -COPY vpp/Makefile /vpp-src/Makefile -COPY vpp/build/external /vpp-src/build/external - -RUN echo "wireshark-common wireshark-common/install-setuid boolean true" | debconf-set-selections - -# netbase is needed for Scapy -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=private \ - --mount=target=/var/cache/apt,type=cache,sharing=private \ - apt-get update && \ - apt-get dist-upgrade -yy && \ - apt-get install -y software-properties-common ccache && \ - add-apt-repository ppa:longsleep/golang-backports && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - build-essential sudo git netbase curl ca-certificates \ - ${GO_PACKAGE} iproute2 gdb tcpdump iputils-ping libpcap-dev \ - dumb-init gdbserver clang-11 && \ - curl -sSL "https://github.com/moby/buildkit/releases/download/${BUILDKIT_VERSION}/buildkit-${BUILDKIT_VERSION}.linux-amd64.tar.gz" | \ - tar -xvz -C /usr/local bin/buildctl && \ - echo "${BUILDCTL_SHA256} /usr/local/bin/buildctl" | sha256sum -c && \ - cd /vpp-src && \ - curl -sSL -O http://mirrors.kernel.org/ubuntu/pool/main/i/indent/indent_2.2.12-1_amd64.deb && \ - echo "${INDENT_SHA256} /vpp-src/indent_2.2.12-1_amd64.deb" | sha256sum -c && \ - apt-get install -y --no-install-recommends \ - /vpp-src/indent_2.2.12-1_amd64.deb && \ - rm /vpp-src/indent_2.2.12-1_amd64.deb && \ - git config --global user.email "dummy@example.com" && \ - git config --global user.name "dummy user" && \ - git init && \ - git add Makefile && \ - git commit -m "dummy commit" && \ - git tag -a v20.05-rc0 -m "dummy tag" && \ - make UNATTENDED=yes install-dep install-ext-dep && \ - apt-get clean && \ - rm -rf /vpp-src && \ - ln -s /usr/lib/go-1.22/bin/go /usr/bin/go && \ - ln -s /usr/lib/go-1.22/bin/gofmt /usr/bin/gofmt - -ENV PATH="/usr/lib/ccache:$PATH" -ENV CCACHE_DIR=/ccache -ENV CCACHE_MAXSIZE=400M -ENV CCACHE_COMPRESS=true -ENV CCACHE_COMPRESSLEVEL=6 - -ENV GOPATH /go - -RUN go install github.com/onsi/ginkgo/ginkgo@v1.16.5 && \ - mv /go/bin/ginkgo /usr/local/bin - -RUN go install golang.org/x/tools/gopls@v0.11.0 && \ - mv /go/bin/gopls /usr/local/bin - -FROM build-base-stage AS build-stage +FROM ${BUILDER_IMAGE} AS build-stage ADD vpp /vpp-src @@ -71,12 +10,21 @@ ARG BUILD_TYPE RUN --mount=target=/vpp-src/build-root/.ccache,type=cache \ --mount=target=/ccache,type=cache \ + PATH="/usr/lib/ccache:$PATH"; \ case ${BUILD_TYPE} in \ - debug) target="pkg-deb-debug"; args="-DVPP_ENABLE_TRAJECTORY_TRACE=1";; \ - release) target="pkg-deb"; args="";; \ - *) echo >&2 "Bad BUILD_TYPE: ${BUILD_TYPE}";; \ + debug) \ + target="pkg-deb-debug"; \ + args="-DVPP_ENABLE_TRAJECTORY_TRACE=1 -DVPP_ENABLE_SANITIZE_ADDR=ON"; \ + ;; \ + release) \ + target="pkg-deb"; \ + args=""; \ + ;; \ + *) \ + echo >&2 "Bad BUILD_TYPE: ${BUILD_TYPE}"; \ + ;; \ esac; \ - echo "TARGET: ${target}" && \ + echo "Building target: ${target} with flags ${args}" && \ make -C /vpp-src "${target}" V=1 VPP_EXTRA_CMAKE_ARGS="${args}" && \ ccache -s && \ mkdir -p /out/debs && \ @@ -88,63 +36,80 @@ FROM scratch as artifacts COPY --from=build-stage /out/debs . # dev image starts here -FROM build-base-stage AS dev-stage +FROM ${BUILDER_IMAGE} AS dev-stage +ARG BUILDER_IMAGE +ARG BUILD_TYPE -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=private \ - --mount=target=/var/cache/apt,type=cache,sharing=private \ +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ --mount=target=/debs,source=/out/debs,from=build-stage,type=bind \ apt-get install --no-install-recommends -yy \ - /debs/vpp_*.deb \ - /debs/vpp-dbg_*.deb \ - /debs/vpp-plugin-core_*.deb \ - /debs/vpp-plugin-devtools_*.deb \ - /debs/vpp-plugin-dpdk*.deb \ - /debs/libvppinfra_*.deb \ - /debs/python3-vpp-api_*.deb \ - /debs/vpp-dev_*.deb \ - /debs/libvppinfra-dev_*.deb && \ - apt-get clean + /debs/vpp_*.deb \ + /debs/vpp-dbg_*.deb \ + /debs/vpp-plugin-core_*.deb \ + /debs/vpp-plugin-devtools_*.deb \ + /debs/vpp-plugin-dpdk*.deb \ + /debs/libvppinfra_*.deb \ + /debs/python3-vpp-api_*.deb \ + /debs/vpp-dev_*.deb \ + /debs/libvppinfra-dev_*.deb && \ + if [ "${BUILD_TYPE}" = "debug" ]; then \ + # Add stdc++ as dependency to vpp, so ASAN can intercept c++ stuff (like hyperscan) + apt-get update && \ + apt-get install --no-install-recommends -yy patchelf && \ + patchelf --add-needed $(realpath -s $(clang -print-file-name=libstdc++.so)) $(which vpp) && true; \ + fi # use clean vpp source so as not to make the image too bloated ADD vpp /vpp-src # provide symlinks needed for running the Pythonic integration tests RUN mkdir -p /vpp-src/build-root/build-test/src && \ - ln -fs /vpp-src/test/* /vpp-src/build-root/build-test/src/ -# fix git repo ownership issue -RUN git config --global --add safe.directory /src + ln -fs /vpp-src/test/* /vpp-src/build-root/build-test/src/&& \ + # fix git repo ownership issue + git config --global --add safe.directory /src # final image starts here -FROM ubuntu:20.04 AS final-stage +FROM ubuntu:22.04 AS final-stage ARG BUILD_TYPE WORKDIR / ENV VPP_INSTALL_SKIP_SYSCTL=1 -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=private \ - --mount=target=/var/cache/apt,type=cache,sharing=private \ +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + rm -f /etc/apt/apt.conf.d/docker-clean && \ apt-get update && apt-get dist-upgrade -yy && \ - apt-get install --no-install-recommends -yy liblz4-tool tar gdb gdbserver strace \ - libhyperscan5 libmbedcrypto3 libmbedtls12 libmbedx509-0 apt-utils \ - libpython3-stdlib \ - python3 python3-minimal python3.6 python3-minimal \ - python3-cffi python3-cffi-backend libnuma1 \ - libnl-3-200 libnl-route-3-200 libpcap0.8 - -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=private \ - --mount=target=/var/cache/apt,type=cache,sharing=private \ + apt-get install --no-install-recommends -yy \ + liblz4-tool tar gdb gdbserver strace apt-utils \ + libhyperscan5 libmbedcrypto7 libmbedtls-dev libmbedx509-1 \ + python3 python3-minimal libpython3-stdlib \ + python3-cffi python3-cffi-backend libnuma1 \ + libnl-3-200 libnl-route-3-200 libpcap0.8 + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ --mount=target=/debs,source=/out/debs,from=build-stage,type=bind \ extra_debs=; \ if [ "${BUILD_TYPE}" = "debug" ]; then \ - extra_debs="/debs/vpp-dev_*.deb /debs/libvppinfra-dev_*.deb"; \ + extra_debs="${extra_debs} /debs/vpp-dev_*.deb"; \ + extra_debs="${extra_debs} /debs/libvppinfra-dev_*.deb"; \ + # libasan8 compatible with clang-14/gcc-12 + extra_debs="${extra_debs} libasan8"; \ + # Add stdc++ as dependency to vpp, so ASAN can intercept c++ stuff + extra_debs="${extra_debs} patchelf"; \ + extra_debs="${extra_debs} libstdc++-12-dev"; \ fi && \ apt-get install --no-install-recommends -yy \ - /debs/vpp_*.deb \ - /debs/vpp-dbg_*.deb \ - /debs/vpp-plugin-core_*.deb \ - /debs/vpp-plugin-devtools_*.deb \ - /debs/vpp-plugin-dpdk*.deb \ - /debs/libvppinfra_*.deb \ - /debs/python3-vpp-api_*.deb \ - ${extra_debs} && \ - apt-get clean + /debs/vpp_*.deb \ + /debs/vpp-dbg_*.deb \ + /debs/vpp-plugin-core_*.deb \ + /debs/vpp-plugin-devtools_*.deb \ + /debs/vpp-plugin-dpdk*.deb \ + /debs/libvppinfra_*.deb \ + /debs/python3-vpp-api_*.deb \ + ${extra_debs} && \ + if [ "${BUILD_TYPE}" = "debug" ]; then \ + # Add stdc++ as dependency to vpp, so ASAN can intercept c++ stuff + patchelf --add-needed /usr/lib/gcc/x86_64-linux-gnu/12/libstdc++.so $(which vpp) && true; \ + fi ENTRYPOINT /usr/bin/vpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..79e0389 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +.PHONY: image initialize + +BUILD_TYPE ?= debug +CI_BUILD ?= 0 + +BASE_REPO ?= quay.io/travelping/fpp-vpp +BASE_TAG ?= local +BASE_HASH ?= $(shell git rev-parse HEAD) +BUILDER_REPO ?= quay.io/travelping/vpp-builder +BUILDER_HASH = $(shell build/getbuilderhash.sh) +QUAY_IO_IMAGE_EXPIRES_AFTER ?= + +export DOCKER_BUILDKIT = 1 + +image: initialize + BUILDER_REPO=${BUILDER_REPO} BUILDER_HASH=${BUILDER_HASH} \ + BASE_TAG=${BASE_TAG} \ + BASE_REPO=${BASE_REPO} BASE_HASH=${BASE_HASH} \ + BUILD_TYPE=${BUILD_TYPE} CI_BUILD=${CI_BUILD} \ + QUAY_IO_IMAGE_EXPIRES_AFTER=${QUAY_IO_IMAGE_EXPIRES_AFTER} \ + build/build.sh + +initialize: + build/ensure-initialized.sh + diff --git a/README.md b/README.md index 0e61bea..910a368 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ This command gives you access to VPP CLI (`vppctl`). To see the list of availabl Run this script to download FD.io VPP source code to the `vpp` directory and apply downstream patches stored in the `vpp-patches` folder: ``` -hack/update-vpp.sh +make initialize ``` ## Contribution @@ -51,7 +51,7 @@ You can add a new functionality or fix an encountered issue in the VPP code base To add a patch to FPP VPP, follow these steps: -1. Run the `hack/update-app.sh` script to download sources and downstream patches stored in the `vpp-patches` folder. +1. Run the `make initialize` script to download sources and downstream patches stored in the `vpp-patches` folder. 1. Provide changes to the code in the `vpp` directory and commit the output to git. 1. Create a patch using this command: ``` @@ -63,11 +63,6 @@ To add a patch to FPP VPP, follow these steps: ### Build the base image -> **Warning** -> -> You must prepare VPP source code before building an FPP VPP image. -> Make sure that `vpp` folder is present by running `hack/update-vpp.sh` first. - [`Dockerfile`](./Dockerfile) provided in this repository creates four types of build images: - `release` - optimized build with proper performance but without debug tools like `gdb` @@ -76,29 +71,25 @@ To add a patch to FPP VPP, follow these steps: - `dev_release` - development image that includes tools to build a VPP plugin, used for building a `release` image with this plugin - `dev_debug` - development image that includes tools to build a VPP plugin, used for building a `debug` image with this plugin -The type of image build is defined with `BUILD_TYPE` argument passed to `docker build`. -The possible options are `debug` or `release`. This parameter is required during the container build. +The type of image build is defined with the `BUILD_TYPE` argument passed to the `make` command. +The possible options are `debug` or `release`. The default is `debug`. -To build a release FPP VPP image with a patched VPP version installed inside, run: +To build `release` and `dev_release` FPP VPP images with a patched VPP version installed inside, run: ```console -$ DOCKER_BUILDKIT=1 docker build --build-arg BUILD_TYPE=release -f Dockerfile -t fpp-vpp:latest_release . +BUILD_TYPE=release make image ``` -You can set `BUILD_TYPE` to `debug` in the above command to get debug image. `latest_release` tag was applied above -to distinguish release or debug builds. +Remove `BUILD_TYPE` in the above command to get a debug image. The `local_release` tag was applied above to distinguish +release builds from debug builds. ### Build dev images To support building VPP plugins using FPP VPP base image, the [`Dockerfile`](./Dockerfile) includes a build target called `dev-stage`. This target includes source headers needed to build the VPP plugin. -To build release FPP VPP image with development tools included, run: - -```console -$ DOCKER_BUILDKIT=1 docker build --build-arg BUILD_TYPE=release -f Dockerfile -t fpp-vpp:latest_dev_release . --target dev-stage -``` +FPP VPP images with development tools included are built using the base image. -`latest_dev_release` image tag was applied to distinguish between the release image that runs modified VPP and +The `local_dev_release` image tag was applied to distinguish between the release image that runs the modified VPP and the development image used to build VPP plugins. `dev_release` image is required to build the VPP plugin with the resulting `release` type of image. diff --git a/build/build.sh b/build/build.sh new file mode 100755 index 0000000..250bf9b --- /dev/null +++ b/build/build.sh @@ -0,0 +1,151 @@ +#!/bin/bash + +set -o nounset + +: ${CI_BUILD:=} +: ${DO_PUSH:=} +: ${GITHUB_OUTPUT:=} +: ${QUAY_IO_IMAGE_EXPIRES_AFTER:=} + +DOCKER_BUILD="docker build" +if [[ "${DOCKER_BUILD_DEBUG:-}" -eq 1 ]]; then + export BUILDX_EXPERIMENTAL=1 + DOCKER_BUILD="docker buildx debug --on=error --invoke=/bin/bash build --progress=plain" +fi + +BUILD_OPTS=() +if [[ "${CI_BUILD}" -eq 1 ]]; then + if [[ -n "${QUAY_IO_IMAGE_EXPIRES_AFTER}" ]]; then + BUILD_OPTS+=(--label "quay.expires-after=${QUAY_IO_IMAGE_EXPIRES_AFTER}") + fi +fi + +DEV_IMAGE="${BASE_REPO}:${BASE_TAG}_dev_${BUILD_TYPE}" +IMAGE="${BASE_REPO}:${BASE_TAG}_${BUILD_TYPE}" +CACHED_DEV_IMAGE="${BASE_REPO}:dev-${BUILD_TYPE}-sha-${BASE_HASH}" +CACHED_IMAGE="${BASE_REPO}:${BUILD_TYPE}-sha-${BASE_HASH}" + +BUILDER_IMAGE="${BUILDER_REPO}:${BASE_TAG}" +CACHED_BUILDER_IMAGE="${BUILDER_REPO}:sha-${BUILDER_HASH}" + +function tag_cached_base_images_as_local() +{ + docker tag "${CACHED_DEV_IMAGE}" "${DEV_IMAGE}" + docker tag "${CACHED_IMAGE}" "${IMAGE}" + + if [[ -n "${GITHUB_OUTPUT}" ]]; then + echo "registry_cache_used=vpp-base" >> $GITHUB_OUTPUT + fi +} + +function tag_cached_dep_images_as_local() +{ + docker tag "${CACHED_BUILDER_IMAGE}" "${BUILDER_IMAGE}" + if [[ -n "${GITHUB_OUTPUT}" ]]; then + echo "registry_cache_used=vpp-builder" >> $GITHUB_OUTPUT + fi +} + +if [[ "${CI_BUILD}" -eq 1 ]]; then + try_pull_docker_image="$(dirname "${BASH_SOURCE}")/try-pull-docker-image.sh" + + if docker image inspect "${CACHED_DEV_IMAGE}" >/dev/null 2>&1 && + docker image inspect "${CACHED_IMAGE}" >/dev/null 2>&1; then + tag_cached_base_images_as_local + + exit 0 + else + "${try_pull_docker_image}" "${CACHED_DEV_IMAGE}" + PULL_RES="${?}" + if [[ "${PULL_RES}" -eq 0 ]]; then + "${try_pull_docker_image}" "${CACHED_IMAGE}" + PULL_RES="${?}" + fi + + case "${PULL_RES}" in + 0) + tag_cached_base_images_as_local + exit 0 + ;; + 2) + "$(dirname "${BASH_SOURCE}")/update-vpp.sh" + ;; + *) + exit 1 + ;; + esac + fi + + if docker image inspect "${CACHED_BUILDER_IMAGE}" >/dev/null 2>&1; then + tag_cached_dep_images_as_local + else + "${try_pull_docker_image}" "${CACHED_BUILDER_IMAGE}" + PULL_RES="${?}" + case "${PULL_RES}" in + 0) + tag_cached_dep_images_as_local + ;; + 2) + if ! ${DOCKER_BUILD} \ + -t "${BUILDER_IMAGE}" \ + -f vpp-builder.Dockerfile \ + "${BUILD_OPTS[@]}" \ + . + then + exit 1 + fi + + docker tag "${BUILDER_IMAGE}" "${CACHED_BUILDER_IMAGE}" + if [[ "${DO_PUSH,,}" == "y" ]]; then + docker push "${CACHED_BUILDER_IMAGE}" + fi + + if [[ -n "${GITHUB_OUTPUT}" ]]; then + echo "registry_cache_used=none" >> $GITHUB_OUTPUT + fi + ;; + *) + exit 1 + ;; + esac + fi +fi + +set -o errexit + +if [[ "${CI_BUILD}" -ne 1 ]]; then + ${DOCKER_BUILD} \ + -t "${BUILDER_IMAGE}" \ + -f vpp-builder.Dockerfile \ + "${BUILD_OPTS[@]}" \ + . +fi + +${DOCKER_BUILD} \ + -t "${DEV_IMAGE}" \ + --build-arg BUILDER_IMAGE="${BUILDER_IMAGE}" \ + --build-arg BUILD_TYPE="${BUILD_TYPE}" \ + --target dev-stage \ + "${BUILD_OPTS[@]}" \ + . +if [[ "${CI_BUILD}" -eq 1 ]]; then + docker tag "${DEV_IMAGE}" "${CACHED_DEV_IMAGE}" + if [[ "${DO_PUSH,,}" == "y" ]]; then + docker push "${CACHED_DEV_IMAGE}" + fi +fi + +${DOCKER_BUILD} \ + -t ${IMAGE} \ + --build-arg BUILDER_IMAGE="${BUILDER_IMAGE}" \ + --build-arg BUILD_TYPE="${BUILD_TYPE}" \ + --target final-stage \ + "${BUILD_OPTS[@]}" \ + . +if [[ "${CI_BUILD}" -eq 1 ]]; then + docker tag "${IMAGE}" "${CACHED_IMAGE}" + if [[ "${DO_PUSH,,}" == "y" ]]; then + docker push "${CACHED_IMAGE}" + fi +fi + diff --git a/build/ensure-base-image-to-retag.sh b/build/ensure-base-image-to-retag.sh new file mode 100755 index 0000000..248b6ad --- /dev/null +++ b/build/ensure-base-image-to-retag.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -o nounset + +: ${BASE_REPO:="quay.io/travelping/fpp-vpp"} +: ${BASE_HASH:=$(git rev-parse HEAD)} +: ${BUILD_TYPE:=debug} + +IMAGE_HASH_NAME="${BASE_REPO}:${BUILD_TYPE}-sha-${BASE_HASH}" +DEV_IMAGE_HASH_NAME="${BASE_REPO}:dev-${BUILD_TYPE}-sha-${BASE_HASH}" + +SCRIPT_DIR="$(dirname "${BASH_SOURCE}")" + +"${SCRIPT_DIR}/try-pull-docker-image.sh" "${IMAGE_HASH_NAME}" +PULL_RES="${?}" +if [[ "${PULL_RES}" -eq 0 ]]; then + "${SCRIPT_DIR}/try-pull-docker-image.sh" "${DEV_IMAGE_HASH_NAME}" + PULL_RES="${?}" +fi + +case "${PULL_RES}" in +0) + echo "image_to_retag_present=true" >> "${GITHUB_OUTPUT}" + echo "${BUILD_TYPE}_image_to_retag_present=true" >> "${GITHUB_OUTPUT}" + ;; +2) + echo "image_to_retag_present=false" >> "${GITHUB_OUTPUT}" + echo "${BUILD_TYPE}_image_to_retag_present=false" >> "${GITHUB_OUTPUT}" + ;; +*) + exit 1 + ;; +esac + diff --git a/build/ensure-initialized.sh b/build/ensure-initialized.sh new file mode 100755 index 0000000..027b385 --- /dev/null +++ b/build/ensure-initialized.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +CI_BUILD="${CI_BUILD:-}" + +if [[ "${CI_BUILD}" -eq 1 ]]; then + exit 0 +fi + +if [[ ! -d vpp ]] || ! find vpp -mindepth 1 -print -quit | grep -q .; then + "$(dirname "${BASH_SOURCE}")/update-vpp.sh" +fi + diff --git a/build/getbuilderhash.sh b/build/getbuilderhash.sh new file mode 100755 index 0000000..e09f037 --- /dev/null +++ b/build/getbuilderhash.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +CWD_GIT_PATH="$(git rev-parse --show-prefix)" +echo $(git rev-parse HEAD:${CWD_GIT_PATH}vpp-builder.Dockerfile)$(git rev-parse HEAD:${CWD_GIT_PATH}vpp.spec) | sha1sum | awk '{print $1}' diff --git a/build/retag-base-image.sh b/build/retag-base-image.sh new file mode 100755 index 0000000..84f8209 --- /dev/null +++ b/build/retag-base-image.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +set -o errexit +set -o nounset + +: ${BUILD_TYPE:=debug} +: ${BASE_REPO:="quay.io/travelping/fpp-vpp"} +: ${BASE_HASH:=$(git rev-parse HEAD)} + +IMAGE_HASH_NAME="${BASE_REPO}:${BUILD_TYPE}-sha-${BASE_HASH}" +DEV_IMAGE_HASH_NAME="${BASE_REPO}:dev-${BUILD_TYPE}-sha-${BASE_HASH}" + +SCRIPT_DIR="$(dirname "${BASH_SOURCE}")" + +RELEASE_TAG="${GITHUB_REF##*/}" +RELEASE_IMAGE_NAME="${BASE_REPO}:${RELEASE_TAG}_${BUILD_TYPE}" + +QUAY_IO_IMAGE_EXPIRES_AFTER="$(docker image inspect "${IMAGE_HASH_NAME}" | jq -r '.[0].Config.Labels."quay.expires-after"')" +if [[ "${QUAY_IO_IMAGE_EXPIRES_AFTER}" == null ]]; then + docker tag "${IMAGE_HASH_NAME}" "${RELEASE_IMAGE_NAME}" +else + echo "FROM ${IMAGE_HASH_NAME}" | docker buildx build -t "${RELEASE_IMAGE_NAME}" --label "quay.expires-after=" - +fi + +docker push "${RELEASE_IMAGE_NAME}" + +DEV_RELEASE_IMAGE_NAME="${BASE_REPO}:${RELEASE_TAG}_dev_${BUILD_TYPE}" + +QUAY_IO_IMAGE_EXPIRES_AFTER="$(docker image inspect "${DEV_IMAGE_HASH_NAME}" | jq -r '.[0].Config.Labels."quay.expires-after"')" +if [[ "${QUAY_IO_IMAGE_EXPIRES_AFTER}" == null ]]; then + docker tag "${DEV_IMAGE_HASH_NAME}" "${DEV_RELEASE_IMAGE_NAME}" +else + echo "FROM ${DEV_IMAGE_HASH_NAME}" | docker buildx build -t "${DEV_RELEASE_IMAGE_NAME}" --label "quay.expires-after=" - +fi + +docker push "${DEV_RELEASE_IMAGE_NAME}" + diff --git a/build/try-pull-docker-image.sh b/build/try-pull-docker-image.sh new file mode 100755 index 0000000..4f58878 --- /dev/null +++ b/build/try-pull-docker-image.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +echo "Trying to pull cached image: ${1}" > /dev/stderr +if ! PULL_ERR="$(docker pull "${1}" 2>&1 >/dev/null)"; then + if echo "${PULL_ERR}" | grep -q "unknown"; then + echo "Cached image: ${1} was not present" > /dev/stderr + exit 2 + else + echo "Error during attempt to pull cached image:" > /dev/stderr + echo "${PULL_ERR}" > /dev/stderr + exit 1 + fi +fi + +echo "Successfully pulled cached image: ${1}" > /dev/stderr + diff --git a/hack/update-vpp.sh b/build/update-vpp.sh similarity index 100% rename from hack/update-vpp.sh rename to build/update-vpp.sh diff --git a/hack/ci-build.sh b/hack/ci-build.sh deleted file mode 100755 index de3c750..0000000 --- a/hack/ci-build.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -set -o errexit -set -o nounset -set -o pipefail -set -o errtrace - -: ${REGISTRY:=quay.io} -: ${IMAGE_NAME:=travelping/upg-vpp} -: ${DOCKERFILE:=} -: ${BUILD_TYPE:=debug} -: ${NO_PUSH:=} -: ${IMAGE_EXPIRES_AFTER:=7d} -: ${TARGET_STAGE=final-stage} -: ${DOCKERFILE="Dockerfile"} - -. vpp.spec -function do_build { - # TODO: build branch images and export cache to the corresponding branch image - # --export-cache type=inline \ - # --import-cache type=registry,ref="${IMAGE_BASE_NAME}" \ - opts=(--progress=plain - --file "${DOCKERFILE}" - --build-arg BUILD_TYPE=${BUILD_TYPE} - --label "vpp.release=${VPP_RELEASE}" - --label "vpp.commit=${VPP_COMMIT}") - if [[ ${IMAGE_EXPIRES_AFTER} ]]; then - opts+=(--label "quay.expires-after=${IMAGE_EXPIRES_AFTER}") - fi - set -x - docker buildx build "${opts[@]}" . "$@" - set +x -} - -IMAGE_BASE_NAME="${REGISTRY}/${IMAGE_NAME}" -IMAGE_BASE_TAG="$(vpp/build-root/scripts/version | sed 's/~.*//')-$(git rev-parse HEAD|cut -c1-9)" -DEV_IMAGE_NAME="${IMAGE_BASE_NAME}:${IMAGE_BASE_TAG}_dev_${BUILD_TYPE}" -FINAL_IMAGE_NAME="${IMAGE_BASE_NAME}:${IMAGE_BASE_TAG}_${BUILD_TYPE}" - -echo >&2 "Building VPP and extracting the artifacts ..." -rm -rf /tmp/_out -mkdir /tmp/_out -do_build --target=artifacts --output type=local,dest=/tmp/_out - -echo >&2 "Building the dev image from ${DOCKERFILE} ..." -push=",push=true" -if [[ ${NO_PUSH} ]]; then - push="" -fi -do_build --target=dev-stage \ - --output type="image,\"name=${DEV_IMAGE_NAME}\"${push}" - -echo >&2 "Building the final image from ${DOCKERFILE} ..." -do_build --target=final-stage \ - --output type="image,\"name=${FINAL_IMAGE_NAME}\"${push}" - -echo "${DEV_IMAGE_NAME}" > "image-dev-${BUILD_TYPE}.txt" -echo "${FINAL_IMAGE_NAME}" > "image-${BUILD_TYPE}.txt" diff --git a/hack/retag-unexpire.sh b/hack/retag-unexpire.sh deleted file mode 100755 index a01463b..0000000 --- a/hack/retag-unexpire.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# Retag a docker image in the registry, removing quay.io specific expiration label -# (quay.expires-after) if it's present. -set -o errexit -set -o nounset -set -o pipefail -set -o errtrace - -if [[ $# < 4 ]]; then - echo "Usage: $0 registry image oldtag newtag" - exit 1 -fi - -registry="$1" -image="$2" -oldtag="$3" -newtag="$4" - -manifest=$(mktemp /tmp/retag-manifest.XXXXXX) -config=$(mktemp /tmp/retag-config.XXXXXX) -trap 'rm -- "${manifest}" "${config}"' INT TERM HUP EXIT - -function do_curl { - local url="$1" - shift - if [[ ${url} =~ ^/ ]]; then - url="https://${registry}/v2/${image}${url}" - fi - curl -sSL -H "Authorization: Bearer $token" \ - -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \ - "${url}" "$@" -} - -# Get the auth token -token="$(curl -s -u "${REGISTRY_LOGIN}:${REGISTRY_PASSWORD}" "https://${registry}/v2/auth?service=${registry}&scope=repository:${image}:push" | jq -r .token)" - -# Download the image manifest -do_curl "/manifests/${oldtag}">"${manifest}" -# Extract image config digest from the manifest -config_digest=$(cat "${manifest}" | jq -r .config.digest) - -# Download the image config, removing expiration label from it -do_curl "/blobs/${config_digest}" | jq 'del(.config.Labels["quay.expires-after"])' > "${config}" - -# Prepare to upload the blob with new config. -# Get last location: header after redirect -upload_location="$(do_curl "/blobs/uploads" -i -X POST | grep -i '^Location:' | tail -1 | sed 's/^[^ ]*: *//' | tr -d '[:space:]')" -if [[ ${upload_location} =~ .*\? ]]; then - upload_location="${upload_location}&" -else - upload_location="${upload_location}?" -fi - -new_config_digest="sha256:$(sha256sum "${config}" | cut -d' ' -f1)" -new_config_size="$(wc -c "${config}"|awk '{print $1}')" - -# Upload the new config -do_curl "${upload_location}digest=${new_config_digest}" -T "${config}" - -# Upload the manifest with replaced config using the new tag -do_curl "/manifests/${newtag}" -X PUT \ - -H 'Content-Type: application/vnd.docker.distribution.manifest.v2+json' \ - -d @<(jq ".config.digest|=\"${new_config_digest}\"|.config.size=${new_config_size}" "${manifest}") - -echo diff --git a/vpp-builder.Dockerfile b/vpp-builder.Dockerfile new file mode 100644 index 0000000..5ed7768 --- /dev/null +++ b/vpp-builder.Dockerfile @@ -0,0 +1,72 @@ +# syntax = docker/dockerfile:experimental +FROM ubuntu:22.04 + +WORKDIR / + +RUN echo "wireshark-common wireshark-common/install-setuid boolean true" | debconf-set-selections + +# netbase is needed for Scapy +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + rm -f /etc/apt/apt.conf.d/docker-clean && \ + echo "wireshark-common wireshark-common/install-setuid boolean true" | debconf-set-selections && \ + echo "debconf debconf/frontend select Noninteractive" | debconf-set-selections && \ + # install software-properties-common just to add ppa + apt-get update && \ + apt-get install -y software-properties-common && \ + # add reporistory for newer golang releases + add-apt-repository ppa:longsleep/golang-backports && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential sudo git \ + netbase curl ca-certificates ccache \ + iproute2 gdb tcpdump iputils-ping libpcap-dev \ + dumb-init gdbserver \ + # golang from ppa + golang-1.23-go \ + # clang also installed in vpp Makefile, make sure to match versions + clang \ + # llvm provides llc for xdp-tools build + llvm \ + # golang installs gcc-12 which clang uses via auto-detection for stdc++ library. + # But gcc-12 omits c++ stuff, so we add it manually. libstdc++-12-dev should be enough, but entire g++ is not that heavy to add. + g++-12 \ + && \ + ln -s /usr/lib/go-1.23/bin/go /usr/bin/go && \ + ln -s /usr/lib/go-1.23/bin/gofmt /usr/bin/gofmt && \ + # set clang as default C and C++ compiler + update-alternatives --set c++ /usr/bin/clang++ && \ + update-alternatives --set cc /usr/bin/clang + +# Configure ccache, but do not provide it in path. Each RUN should provide it separately +ENV CCACHE_DIR=/ccache \ + CCACHE_MAXSIZE=600M \ + CCACHE_COMPRESS=true \ + CCACHE_COMPRESSLEVEL=6 \ + GOPATH=/go + +# golang uses ccache as well +RUN --mount=target=/ccache,type=cache \ + PATH="/usr/lib/ccache:$PATH" && \ + go install github.com/onsi/ginkgo/v2/ginkgo@v2.27.2 && \ + mv /go/bin/ginkgo /usr/local/bin/ginkgo && \ + go install golang.org/x/tools/gopls@v0.11.0 && \ + mv /go/bin/gopls /usr/local/bin + +COPY vpp/Makefile /vpp-src/Makefile +COPY vpp/build/external /vpp-src/build/external + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=target=/ccache,type=cache \ + cd /vpp-src && \ + git config --global user.email "dummy@example.com" && \ + git config --global user.name "dummy user" && \ + git init && \ + git add Makefile && \ + git commit -m "dummy commit" && \ + # tag requred to have this format + git tag -a v24.02-rc0 -m "dummy tag" && \ + make UNATTENDED=yes install-dep install-ext-dep && \ + ccache -s && \ + rm -rf /vpp-src diff --git a/vpp-patches/0035-vlib-fix-typo-in-ASAN-stack-size-calculation.patch b/vpp-patches/0035-vlib-fix-typo-in-ASAN-stack-size-calculation.patch new file mode 100644 index 0000000..aed6cc9 --- /dev/null +++ b/vpp-patches/0035-vlib-fix-typo-in-ASAN-stack-size-calculation.patch @@ -0,0 +1,29 @@ +From 7538c8644631825cec2c5be8ed307538b721ff63 Mon Sep 17 00:00:00 2001 +From: Vladimir Zhigulin +Date: Fri, 4 Jul 2025 11:10:44 +0200 +Subject: [PATCH] vlib: fix typo in ASAN stack size calculation + +Type: fix + +Change-Id: I771ca783854f704fc333a6dd857831ffe5d70bd3 +Signed-off-by: Vladimir Zhigulin +--- + src/vlib/node_funcs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h +index 17677ee7a..a5096911d 100644 +--- a/src/vlib/node_funcs.h ++++ b/src/vlib/node_funcs.h +@@ -59,7 +59,7 @@ vlib_process_start_switch_stack (vlib_main_t * vm, vlib_process_t * p) + #ifdef CLIB_SANITIZE_ADDR + void *stack = p ? (void *) p->stack : vlib_thread_stacks[vm->thread_index]; + u32 stack_bytes = +- p ? (1ULL < p->log2_n_stack_bytes) : VLIB_THREAD_STACK_SIZE; ++ p ? (1ULL << p->log2_n_stack_bytes) : VLIB_THREAD_STACK_SIZE; + __sanitizer_start_switch_fiber (&vm->asan_stack_save, stack, stack_bytes); + #endif + } +-- +2.51.1.dirty + diff --git a/vpp-patches/0036-vlib-fix-typo-in-ASAN-fiber-switching.patch b/vpp-patches/0036-vlib-fix-typo-in-ASAN-fiber-switching.patch new file mode 100644 index 0000000..d1136e2 --- /dev/null +++ b/vpp-patches/0036-vlib-fix-typo-in-ASAN-fiber-switching.patch @@ -0,0 +1,34 @@ +From 7cf1569d5d6e3fe27987e44b1243c2561498d421 Mon Sep 17 00:00:00 2001 +From: Vladimir Zhigulin +Date: Mon, 20 Oct 2025 14:58:26 +0200 +Subject: [PATCH] vlib: fix typo in ASAN fiber switching + +Fixes ASAN error +"finishing a fiber switch that has not started" + +Type: fix + +Change-Id: I2f3153fb6635ebcad17942ae95889027c40c2525 +Signed-off-by: Vladimir Zhigulin +--- + src/vlib/node_funcs.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h +index a5096911d..2e5d9ef86 100644 +--- a/src/vlib/node_funcs.h ++++ b/src/vlib/node_funcs.h +@@ -71,8 +71,9 @@ vlib_process_finish_switch_stack (vlib_main_t * vm) + const void *bottom_old; + size_t size_old; + +- __sanitizer_finish_switch_fiber (&vm->asan_stack_save, &bottom_old, ++ __sanitizer_finish_switch_fiber (vm->asan_stack_save, &bottom_old, + &size_old); ++ vm->asan_stack_save = NULL; + #endif + } + +-- +2.51.1.dirty + diff --git a/vpp-patches/0037-memif-fix-invalid-pointer-after-suspend.patch b/vpp-patches/0037-memif-fix-invalid-pointer-after-suspend.patch new file mode 100644 index 0000000..d04548f --- /dev/null +++ b/vpp-patches/0037-memif-fix-invalid-pointer-after-suspend.patch @@ -0,0 +1,50 @@ +From ad754f45ca64e2b53323d4176bc36e235550798d Mon Sep 17 00:00:00 2001 +From: Vladimir Zhigulin +Date: Mon, 20 Oct 2025 16:30:45 +0200 +Subject: [PATCH] memif: fix invalid pointer after suspend + +Get rid of process suspend, since after it mif +pointer can point to freed memory. +Not much sense in this suspend anyways. + +Type: fix + +Change-Id: Ieb0500927c9fc71fcc0184693f182a469606fe00 +Signed-off-by: Vladimir Zhigulin +--- + src/plugins/memif/memif.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/src/plugins/memif/memif.c b/src/plugins/memif/memif.c +index 22f3e3dcd..ef342609f 100644 +--- a/src/plugins/memif/memif.c ++++ b/src/plugins/memif/memif.c +@@ -655,7 +655,7 @@ memif_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) + clib_socket_t *sock; + uword *event_data = 0, event_type; + u8 enabled = 0; +- f64 start_time, last_run_duration = 0, now; ++ f64 start_time, last_run_duration = 0; + clib_error_t *err; + + sock = clib_mem_alloc (sizeof (clib_socket_t)); +@@ -692,14 +692,8 @@ memif_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) + /* *INDENT-OFF* */ + pool_foreach (mif, mm->interfaces) + { +- memif_socket_file_t * msf = vec_elt_at_index (mm->socket_files, mif->socket_file_index); +- /* Allow no more than 10us without a pause */ +- now = vlib_time_now (vm); +- if (now > start_time + 10e-6) +- { +- vlib_process_suspend (vm, 100e-6); /* suspend for 100 us */ +- start_time = vlib_time_now (vm); +- } ++ memif_socket_file_t * msf = ++ vec_elt_at_index (mm->socket_files, mif->socket_file_index); + + if ((mif->flags & MEMIF_IF_FLAG_ADMIN_UP) == 0) + continue; +-- +2.51.1.dirty + diff --git a/vpp-patches/0038-http_static-fix-memory-hss_session-using-after-be-fr.patch b/vpp-patches/0038-http_static-fix-memory-hss_session-using-after-be-fr.patch new file mode 100644 index 0000000..a8ea82e --- /dev/null +++ b/vpp-patches/0038-http_static-fix-memory-hss_session-using-after-be-fr.patch @@ -0,0 +1,38 @@ +From bf0a6f8876dfb5e748e3786714595d6817a573ec Mon Sep 17 00:00:00 2001 +From: XiaomingJiang +Date: Mon, 23 Sep 2024 16:42:40 +0800 +Subject: [PATCH] http_static: fix memory hss_session using after be freed + +Type: fix + +Change-Id: Ic3d3de4198310361de876a8224e4f7cd0b48b698 +Signed-off-by: XiaomingJiang +--- + src/plugins/http_static/static_server.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c +index 9d9a68f7d..48e71f516 100644 +--- a/src/plugins/http_static/static_server.c ++++ b/src/plugins/http_static/static_server.c +@@ -58,8 +58,6 @@ hss_session_free (hss_session_t *hs) + { + hss_main_t *hsm = &hss_main; + +- pool_put (hsm->sessions[hs->thread_index], hs); +- + if (CLIB_DEBUG) + { + u32 save_thread_index; +@@ -68,6 +66,8 @@ hss_session_free (hss_session_t *hs) + memset (hs, 0xfa, sizeof (*hs)); + hs->thread_index = save_thread_index; + } ++ ++ pool_put (hsm->sessions[hs->thread_index], hs); + } + + /** \brief Disconnect a session +-- +2.51.1.dirty +