{"id":2215442,"url":"http://patchwork.ozlabs.org/api/patches/2215442/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/patch/0368afc4ba7b720ba103b1d84566d9d164caaf61.1774367359.git.felix.huettner@digits.schwarz/","project":{"id":68,"url":"http://patchwork.ozlabs.org/api/projects/68/?format=json","name":"Open Virtual Network development","link_name":"ovn","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<0368afc4ba7b720ba103b1d84566d9d164caaf61.1774367359.git.felix.huettner@digits.schwarz>","list_archive_url":null,"date":"2026-03-24T15:54:58","name":"[ovs-dev,RFC,v2] ci: Use containers for all runs.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"63fb1a9b4f8fd8d0d657bd71ec0e11126d628b84","submitter":{"id":92762,"url":"http://patchwork.ozlabs.org/api/people/92762/?format=json","name":"Felix Huettner","email":"felix.huettner@digits.schwarz"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/ovn/patch/0368afc4ba7b720ba103b1d84566d9d164caaf61.1774367359.git.felix.huettner@digits.schwarz/mbox/","series":[{"id":497310,"url":"http://patchwork.ozlabs.org/api/series/497310/?format=json","web_url":"http://patchwork.ozlabs.org/project/ovn/list/?series=497310","date":"2026-03-24T15:54:58","name":"[ovs-dev,RFC,v2] ci: Use containers for all runs.","version":2,"mbox":"http://patchwork.ozlabs.org/series/497310/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2215442/comments/","check":"fail","checks":"http://patchwork.ozlabs.org/api/patches/2215442/checks/","tags":{},"related":[],"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","ovs-dev@lists.linuxfoundation.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=RL9drmjJ;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp4.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=RL9drmjJ","smtp1.osuosl.org; dmarc=pass (p=reject dis=none)\n header.from=digits.schwarz","smtp1.osuosl.org; dkim=pass (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=RL9drmjJ"],"Received":["from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgF4135dGz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 02:55:13 +1100 (AEDT)","from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id AD84541020;\n\tTue, 24 Mar 2026 15:55:11 +0000 (UTC)","from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id MxuM7oB1Y66a; Tue, 24 Mar 2026 15:55:10 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id 2D64140FE6;\n\tTue, 24 Mar 2026 15:55:10 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 13108C04E8;\n\tTue, 24 Mar 2026 15:55:10 +0000 (UTC)","from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 4C0F0C04E7\n for <dev@openvswitch.org>; Tue, 24 Mar 2026 15:55:09 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 3E21981B23\n for <dev@openvswitch.org>; Tue, 24 Mar 2026 15:55:09 +0000 (UTC)","from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id nSDu5zcFXOHV for <dev@openvswitch.org>;\n Tue, 24 Mar 2026 15:55:07 +0000 (UTC)","from mail-ed1-x563.google.com (mail-ed1-x563.google.com\n [IPv6:2a00:1450:4864:20::563])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 0BFA181B35\n for <dev@openvswitch.org>; Tue, 24 Mar 2026 15:55:06 +0000 (UTC)","by mail-ed1-x563.google.com with SMTP id\n 4fb4d7f45d1cf-668d70fabc4so2948261a12.1\n for <dev@openvswitch.org>; Tue, 24 Mar 2026 08:55:06 -0700 (PDT)","from smtpproxy-deployment-9c4bdbc9c-pfjf9.de2.smtp.exclaimer.net\n ([20.113.217.23]) by smtp-relay.gmail.com with ESMTPS id\n 4fb4d7f45d1cf-66a6b8212easm71134a12.14.2026.03.24.08.55.03\n for <dev@openvswitch.org>\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 24 Mar 2026 08:55:03 -0700 (PDT)","from mail-wr1-f71.google.com (209.85.221.71) by\n smtpproxy-deployment-9c4bdbc9c-pfjf9.de2.smtp.exclaimer.net\n (20.113.217.16/28) with Exclaimer Signature Manager ESMTP Proxy\n smtpproxy-deployment-9c4bdbc9c-pfjf9.de2.smtp.exclaimer.net\n (tlsversion=TLS12, tlscipher=TLS_DIFFIEHELLMAN_WITH_AES256_NONE); Tue, 24\n Mar 2026 15:55:03 +0000","by mail-wr1-f71.google.com with SMTP id\n ffacd0b85a97d-43b7ec737c1so1399128f8f.1\n for <dev@openvswitch.org>; Tue, 24 Mar 2026 08:55:02 -0700 (PDT)","from SDGDEU-G5041VBR ([185.124.194.86])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43b87f80976sm970355f8f.4.2026.03.24.08.55.00\n for <dev@openvswitch.org>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 24 Mar 2026 08:55:00 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp4.osuosl.org 2D64140FE6","OpenDKIM Filter v2.11.0 smtp1.osuosl.org 0BFA181B35"],"Received-SPF":"Pass (mailfrom) identity=mailfrom;\n client-ip=2a00:1450:4864:20::563; helo=mail-ed1-x563.google.com;\n envelope-from=felix.huettner@digits.schwarz; receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp1.osuosl.org 0BFA181B35","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=digits.schwarz; s=google; t=1774367704; x=1774972504; darn=openvswitch.org;\n h=mime-version:mail-followup-to:message-id:subject:to:date:from:from\n :to:cc:subject:date:message-id:reply-to;\n bh=ifE27ZPC5RFrPkbNdgNRV3sGxQapi6ZGJZicvlBR/j4=;\n b=RL9drmjJIK3PFREsDnW9WUTYX74wvhJPCgtSgMbdKMoH3idkQCtT1zzTCTYVuh+EVn\n A28X0xZaKBUbR/WZjhpGCm127L2bcZ9SyLJjNQBOOhp1e/Fkgbe5X8DC9Lc7stPiJU9G\n cqKJ0BoHGlqvc4EsgrigYncNP2zpbJSPSq1nhOn/rGdGM6YE8QeWDKknxGYRwJk1rkHC\n 1/3maoJimobUxlBeVbn8twRdYalUCWmBdGbxrEyu0rv0RjUtq21FSBN7uzflHHvAHwZJ\n XZ/1QCb+yu5Xz0p6k09OvxNzkSbBT6jjAMwayz/mgV3+6RNKVJH7Iv2ITaGgjqZQqZce\n LDsA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774367704; x=1774972504;\n h=mime-version:mail-followup-to:message-id:subject:to:date:from\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=ifE27ZPC5RFrPkbNdgNRV3sGxQapi6ZGJZicvlBR/j4=;\n b=XsAu8Mu6jrO4iWP2NBKPqfP2w8ju55i8LNZgMmbaJk47qiFTU9keST4rpZUXCN2T2I\n uKcd9PZiOLvP5mCLL6n4XXURgam/p+ynnQihNjnoyDmCD2r7tprHfA2gZMGP96MUSMHz\n Arj53m7c6SzhyljzcE9Tgc95sLh8yqw/QmQyl5F6vkWkAxmCGe6dO1SALGtsW2/ZKdUE\n Za94Xt0Md1nXPdLfl6wHUoum0fZpWiOrXyod5yxWzXGalhFy+jS2kItFpHRnR/qzO3XH\n ax1dukmyW3F/PckHVVTDlEpHOBwXH2laWbRP4eTLAxswTL52V574SARwrUM/DyrRB9eZ\n iVxA==","X-Gm-Message-State":"AOJu0YwDWZAARTl2zCWGAMTk8u1Yt2E7dkffm6jbw5JsMKmcCrJE5Is1\n QsJzhIrqRBQ2VNb6y86WQi17VsvbSgEzOB+0L5z4XZw1XzCT2vo7jhPogqRNLDoR9HOghtPHFXY\n ycK2RnkD71Wo3qkc/Hg7PnDqga4awN45OIxC1crTGil5qca/JWhfh/+o7qbC0a1ftBG/CnU7edH\n fHAVvjbaSccsBc3h23SLbRQlOV3kzdptUuhjmSQyDrhYN6pLFTvRFKml6SdabP7bHj1VW19ZAIV\n 3G9jggH4aRGkxDaMDI=","X-Gm-Gg":"ATEYQzwVwVe6zWN9YPF64Lpkz3GC3du8/6GlaLYVtOB1VEdAk3BLZ78R5PdMvritILl\n 446eIq/SGLlFlfD46q77sjpNSBFwskm6JosPliOExaQj0s+Vu8xxfn4Juyy+jZSvcNmNY4MQkbG\n bL2mVW3+4ABiy2LIN/eT5nWz3bGis9x/NDPfQvMrq83nPu9F2tS+t28y2yg8LpsPFURXNEt/jqI\n KRqAzDp61jdh02NzIuKCxMTnImmrIvSYC2dA6OUM4rbwHAxy6ZoLun8AX2gHzClPDdb892R2uzO\n 0p8E06syFYRddMkjT1+yDrb4YFThap5muKHZJO01Q/6O+sY+4gkkmrh9zu8WmLWsKHez3gANobo\n p9DnsmHHGt1XksY5KHZK+aV9y4QnV+wPWQWmhs4aHMYKCVnkEIJx4+4VFxxKb6WwPvz36nXKSV3\n WHrqcfd4iCw/1/K6M8r8Zu","X-Received":["by 2002:a05:6402:280a:b0:660:f1a1:e8dc with SMTP id\n 4fb4d7f45d1cf-668c9c456eamr12177745a12.25.1774367703873;\n Tue, 24 Mar 2026 08:55:03 -0700 (PDT)","by 2002:a05:6000:609:b0:439:abcd:b317 with SMTP id\n ffacd0b85a97d-43b889a49f9mr13280f8f.14.1774367701660;\n Tue, 24 Mar 2026 08:55:01 -0700 (PDT)","by 2002:a05:6000:609:b0:439:abcd:b317 with SMTP id\n ffacd0b85a97d-43b889a49f9mr13213f8f.14.1774367700807;\n Tue, 24 Mar 2026 08:55:00 -0700 (PDT)"],"X-Relaying-Domain":"digits.schwarz","X-ExclaimerHostedSignatures-MessageProcessed":"true","X-ExclaimerProxyLatency":"10522370","X-ExclaimerImprintLatency":"6894776","X-ExclaimerImprintAction":"f44bbca18c844b66a65e763c8aec4f3c","X-Google-Original-From":"Felix Huettner <felix.huettner@stackit.cloud>","Date":"Tue, 24 Mar 2026 16:54:58 +0100","To":"dev@openvswitch.org","Message-ID":"\n <0368afc4ba7b720ba103b1d84566d9d164caaf61.1774367359.git.felix.huettner@digits.schwarz>","Mail-Followup-To":"dev@openvswitch.org","MIME-Version":"1.0","X-please-dont-add-a-signature":"thanks","X-Schwarz-Google-ToExclaimerByDomain":"1","Content-Disposition":"inline","X-Content-Filtered-By":"Mailman/MimeDel 2.1.30","Subject":"[ovs-dev] [RFC ovn v2] ci: Use containers for all runs.","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","From":"Felix Huettner via dev <ovs-dev@openvswitch.org>","Reply-To":"Felix Huettner <felix.huettner@digits.schwarz>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"},"content":"Hi everyone,\n\nthe following is a preparation for running the OVN CI on\ncustom hosted runners. It currently only focuses on \"Build and Test\" and\nnot on other workflows.\n\nThe problem with normal Github Actions is that the CI Job is run\ndirectly on the CI runner. For the public runners they are spawned and\nafterwards destroyed by github themselves.\nFor custom CI runners that makes things quite complicated as there is no\nnice implementation of it.\n\nHowever github actions also supports running the actions within\ncontainers. This brings the benefit that we have finally a well known\nsystem where we start from and that the building host will not be filled\nwith trash.\nAlso it seems that custom runners natively support this which would make\ncustom runners significantly easier to use.\n\nIf you want to try this out you can just push it to a branch on your\nfork of the github repo. Note that this job will temporarily create a\n\"ovn-ci-tmp\" package/registry entry for your user.\n\nNote that i did not yet try this out with a custom runner. However since\ni will be unavailable for the next two weeks i wanted to share my\ncurrent state.\n\nThanks a lot,\nFelix\n\nSigned-off-by: Felix Huettner <felix.huettner@stackit.cloud>\n---\nv1->v2:\n  * natively use a container in the \"build-linux\" job\n  * ensure a init system is available to stop processes correctly\n  * add a cleanup job to remove the created container images\n  * modified restart_ovsdb_controller_updates: this is needed as we run\n      within a docker container which creates iptables nat rules. nft\n      therefor prints a warning\n  * modified dhcpd commands for tests: it seems that the dhcpd process\n      in there does not search for the leases file in the same directory\n      as the config per default.\n\n .ci/ci.sh                  |   6 +-\n .ci/linux-build.sh         |   4 +-\n .ci/linux-util.sh          |  10 +--\n .github/workflows/test.yml | 139 ++++++++++++++++++++++++++-----------\n tests/ovn-macros.at        |   2 +-\n tests/system-ovn.at        |   4 +-\n 6 files changed, 109 insertions(+), 56 deletions(-)\n\n\nbase-commit: b4d2c0369f92f5d57d850802934ac05feb2979d9","diff":"diff --git a/.ci/ci.sh b/.ci/ci.sh\nindex 76c364868..55cb75ca2 100755\n--- a/.ci/ci.sh\n+++ b/.ci/ci.sh\n@@ -174,11 +174,13 @@ fi\n CONTAINER_ID=\"$($CONTAINER_CMD run --privileged -d \\\n     --pids-limit=-1 \\\n     --security-opt apparmor=unconfined \\\n+    --cgroupns=host \\\n+    --cgroups=no-conmon \\\n     --env ASAN_OPTIONS=$ASAN_OPTIONS \\\n-    -v /lib/modules/$(uname -r):/lib/modules/$(uname -r):ro \\\n+    -v /host/lib/modules/$(uname -r):/lib/modules/$(uname -r):ro \\\n     -v $OVN_PATH:$CONTAINER_WORKSPACE/ovn:Z \\\n     -v $OVS_PATH:$CONTAINER_WORKSPACE/ovs:Z \\\n-    $IMAGE_NAME)\"\n+    $IMAGE_NAME tail -f /dev/null)\"\n trap remove_container EXIT\n \n copy_sources_to_workdir\ndiff --git a/.ci/linux-build.sh b/.ci/linux-build.sh\nindex d9b49b7b6..0b272d275 100755\n--- a/.ci/linux-build.sh\n+++ b/.ci/linux-build.sh\n@@ -19,7 +19,7 @@ TIMEOUT=${TIMEOUT:-\"0\"}\n \n function install_dpdk()\n {\n-    local DPDK_INSTALL_DIR=\"$(pwd)/dpdk-dir\"\n+    local DPDK_INSTALL_DIR=\"/workspace/dpdk-dir\"\n     local VERSION_FILE=\"${DPDK_INSTALL_DIR}/cached-version\"\n     local DPDK_PC=$(find $DPDK_INSTALL_DIR -type f -name libdpdk-libs.pc)\n \n@@ -168,7 +168,7 @@ function execute_tests()\n     fi\n \n     if [ \"$UNSTABLE\" ]; then\n-        if ! SKIP_UNSTABLE=no TEST_RANGE=\"-k unstable\" RECHECK=yes \\\n+        if ! SKIP_UNSTABLE=no TEST_RANGE=\"-k unstable -v\" RECHECK=yes \\\n                 run_tests; then\n             unstable_rc=1\n         fi\ndiff --git a/.ci/linux-util.sh b/.ci/linux-util.sh\nindex b5bd1f8c9..e4f5da377 100755\n--- a/.ci/linux-util.sh\n+++ b/.ci/linux-util.sh\n@@ -36,16 +36,8 @@ function fix_etc_hosts()\n     cp /etc/hosts ./hosts.bak\n     sed -E -n \\\n       '/^[[:space:]]*(#.*|[0-9a-fA-F:.]+([[:space:]]+[a-zA-Z0-9.-]+)+|)$/p' \\\n-      ./hosts.bak | sudo tee /etc/hosts\n+      ./hosts.bak | tee /etc/hosts\n \n     diff -u ./hosts.bak /etc/hosts || true\n }\n \n-# Workaround until https://github.com/actions/runner-images/issues/10015\n-# is resolved in some way.\n-function disable_apparmor()\n-{\n-    # https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2093797\n-    sudo aa-teardown || true\n-    sudo systemctl disable --now apparmor.service\n-}\ndiff --git a/.github/workflows/test.yml b/.github/workflows/test.yml\nindex 64073b228..55c79069e 100644\n--- a/.github/workflows/test.yml\n+++ b/.github/workflows/test.yml\n@@ -7,6 +7,9 @@ on:\n     # Run Sunday at midnight\n     - cron: '0 0 * * 0'\n \n+env:\n+  CI_IMAGE: &ci_image ghcr.io/${{ github.repository_owner }}/ovn-ci-tmp:${{ github.sha }}\n+\n concurrency:\n   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}\n   cancel-in-progress: true\n@@ -22,30 +25,34 @@ jobs:\n     # +-------+-------------------+-------------------+\n     # | !main |  Builds - Ubuntu  | xxxxxxxxxxxxxxxxx |\n     # +-------+-------------------+-------------------+\n+    defaults:\n+      run:\n+        shell: bash\n     env:\n-      DEPENDENCIES: podman\n+      DEPENDENCIES: podman make\n     name: Prepare container\n     if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule'\n     runs-on: ubuntu-24.04\n+    container:\n+      image: ubuntu:24.04\n+      options: --privileged\n \n     steps:\n       - uses: actions/checkout@v6\n \n       - name: Update APT cache\n-        run: sudo apt update\n+        run: apt update\n \n       - name: Install dependencies\n-        run: sudo apt install -y ${{ env.DEPENDENCIES }}\n+        run: apt install -y ${{ env.DEPENDENCIES }}\n \n       - name: Fix /etc/hosts file\n         run: |\n           . .ci/linux-util.sh\n           fix_etc_hosts\n \n-      - name: Disable apparmor\n-        run: |\n-          . .ci/linux-util.sh\n-          disable_apparmor\n+      - name: Log in container registry\n+        run: echo \"${{ secrets.GITHUB_TOKEN }}\" | podman login ghcr.io -u ${{ github.actor }} --password-stdin\n \n       - name: Choose image distro\n         if: github.event_name == 'push' || github.event_name == 'pull_request'\n@@ -67,20 +74,16 @@ jobs:\n         run: podman pull ghcr.io/ovn-org/ovn-tests:${{ env.IMAGE_DISTRO }}\n \n       - name: Tag image\n-        run: podman tag ovn-org/ovn-tests:${{ env.IMAGE_DISTRO }} ovn-org/ovn-tests\n+        run: podman tag ovn-org/ovn-tests:${{ env.IMAGE_DISTRO }} ${{ env.CI_IMAGE }}\n \n       - name: Export image\n-        run: podman save -o /tmp/image.tar --format oci-archive ovn-org/ovn-tests\n-\n-      - name: Cache image\n-        id: image_cache\n-        uses: actions/cache@v5\n-        with:\n-          path: /tmp/image.tar\n-          key: ${{ github.sha }}/${{ github.event_name }}\n+        run: podman push ${{ env.CI_IMAGE }}\n \n   build-linux:\n     needs: [prepare-container]\n+    defaults:\n+      run:\n+        shell: bash\n     env:\n       ARCH:        ${{ matrix.cfg.arch }}\n       CC:          ${{ matrix.cfg.compiler }}\n@@ -91,9 +94,13 @@ jobs:\n       TEST_RANGE:  ${{ matrix.cfg.test_range }}\n       SANITIZERS:  ${{ matrix.cfg.sanitizers }}\n       UNSTABLE:    ${{ matrix.cfg.unstable }}\n+      DEPENDENCIES: build-essential git podman\n \n     name: linux ${{ join(matrix.cfg.*, ' ') }}\n     runs-on: ubuntu-24.04\n+    container:\n+      image: *ci_image\n+      options: --privileged --init\n \n     strategy:\n       fail-fast: false\n@@ -126,11 +133,17 @@ jobs:\n         - { arch: x86, compiler: gcc, opts: --disable-ssl }\n \n     steps:\n+    - name: Update APT cache\n+      run: apt update\n+\n+    - name: Install dependencies\n+      run: apt install -y ${{ env.DEPENDENCIES }}\n+\n     - name: system-level-dependencies\n       if: ${{ startsWith(matrix.cfg.testsuite, 'system-test') }}\n       run: |\n-        sudo apt update\n-        sudo apt -y install linux-modules-extra-$(uname -r)\n+        apt update\n+        apt -y install linux-modules-extra-$(uname -r)\n \n     - name: checkout\n       if: github.event_name == 'push' || github.event_name == 'pull_request'\n@@ -166,38 +179,84 @@ jobs:\n         . .ci/linux-util.sh\n         fix_etc_hosts\n \n-    - name: Disable apparmor\n+    - name: Trust git repo\n+      run: git config --global --add safe.directory $(pwd)\n+\n+    - name: Setup hugepages\n+      if: matrix.cfg.dpdk == 'dpdk'\n       run: |\n-        . .ci/linux-util.sh\n-        disable_apparmor\n+        echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages\n+        mkdir /dev/hugepages\n+        mount -t hugetlbfs none /dev/hugepages\n \n-    - name: image cache\n-      id: image_cache\n-      uses: actions/cache@v5\n-      with:\n-        path: /tmp/image.tar\n-        key: ${{ github.sha }}/${{ github.event_name }}\n-\n-    - name: load image\n+    - name: build and test\n       run: |\n-        sudo podman load -i /tmp/image.tar\n-        podman load -i /tmp/image.tar\n-        rm -rf /tmp/image.tar\n+        ARCH=$ARCH CC=$CC LIBS=$LIBS OPTS=$OPTS TESTSUITE=$TESTSUITE \\\n+           TEST_RANGE=$TEST_RANGE SANITIZERS=$SANITIZERS DPDK=$DPDK \\\n+           RECHECK=$RECHECK UNSTABLE=$UNSTABLE TIMEOUT=2h \\\n+           BASE_VERSION=$BASE_VERSION ./.ci/linux-build.sh\n \n-    - name: build\n-      if: ${{ startsWith(matrix.cfg.testsuite, 'system-test') }}\n-      run: sudo -E ./.ci/ci.sh --archive-logs --timeout=2h\n-\n-    - name: build\n-      if: ${{ !startsWith(matrix.cfg.testsuite, 'system-test') }}\n-      run: ./.ci/ci.sh --archive-logs --timeout=2h\n+    - name: collect logs on failure\n+      if: failure() || cancelled()\n+      run: |\n+        mkdir -p /tmp/logcollector\n+        cp config.log /tmp/logcollector\n+        cp -r tests/testsuite.* /tmp/logcollector || true\n+        cp -r tests/system-*-testsuite.* /tmp/logcollector || true\n+        cp -r tests/upgrade-testsuite.* /tmp/logcollector || true\n+        tar -czf /tmp/logs.tgz /tmp/logcollector\n \n     - name: upload logs on failure\n       if: failure() || cancelled()\n       uses: actions/upload-artifact@v7\n       with:\n         name: logs-linux-${{ join(matrix.cfg.*, '-') }}\n-        path: logs.tgz\n+        path: /tmp/logs.tgz\n+\n+  cleanup:\n+    needs: [build-linux]\n+    name: Cleanup\n+    if: always()\n+    runs-on: ubuntu-24.04\n+    container:\n+      image: ubuntu:24.04\n+    permissions:\n+      packages: write\n+\n+    steps:\n+      - name: Update APT cache\n+        run: apt update\n+\n+      - name: Install dependencies\n+        run: apt install -y curl jq\n+\n+      - name: delete temporary image\n+        run: |\n+          if [ \"${{ github.event.repository.owner.type }}\" = \"Organization\" ]; then\n+            TYPE=\"orgs\"\n+          else\n+            TYPE=\"users\"\n+          fi\n+          PACKAGE_URL=\"https://api.github.com/${TYPE}/${{ github.repository_owner }}/packages/container/ovn-ci-tmp\"\n+          PACKAGE_VERSION_URL=\"${PACKAGE_URL}/versions\"\n+          VERSION_ID=$(curl -s \\\n+            -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n+            -H \"Accept: application/vnd.github+json\" \\\n+            \"$PACKAGE_VERSION_URL\" | jq -r '.[] | select(.metadata.container.tags[] == \"${{ github.sha }}\") | .id')\n+          if [ -n \"$VERSION_ID\" ]; then\n+            if curl --fail-with-body -s -X DELETE \\\n+              -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n+              -H \"Accept: application/vnd.github+json\" \\\n+              \"$PACKAGE_VERSION_URL/$VERSION_ID\"; then\n+                echo \"Package version deleted successfully\"\n+            else\n+                echo \"Package version seems to be the last one. Attempting to delete the whole package\"\n+                curl --fail-with-body -s -X DELETE \\\n+                  -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n+                  -H \"Accept: application/vnd.github+json\" \\\n+                  \"$PACKAGE_URL\"\n+            fi\n+          fi\n \n   build-osx:\n     env:\ndiff --git a/tests/ovn-macros.at b/tests/ovn-macros.at\nindex aeb4149d5..601c116ec 100644\n--- a/tests/ovn-macros.at\n+++ b/tests/ovn-macros.at\n@@ -1438,7 +1438,7 @@ stop_ovsdb_controller_updates() {\n restart_ovsdb_controller_updates() {\n   TCP_PORT=$1\n   echo Restarting updates from ovn-controller to ovsdb\n-  AT_CHECK([nft list ruleset | grep $TCP_PORT], [0], [ignore])\n+  AT_CHECK([nft list ruleset | grep $TCP_PORT], [0], [ignore], [ignore])\n   AT_CHECK([nft delete table ip ovn-test])\n }\n \ndiff --git a/tests/system-ovn.at b/tests/system-ovn.at\nindex 8d1f21609..1b11cab94 100644\n--- a/tests/system-ovn.at\n+++ b/tests/system-ovn.at\n@@ -12746,7 +12746,7 @@ chmod 775 $DHCP_TEST_DIR\n chmod 664 $DHCP_TEST_DIR/dhcpd.leases\n \n \n-NETNS_DAEMONIZE([server], [dhcpd -4 -f -cf $DHCP_TEST_DIR/dhcpd.conf s1 > dhcpd.log 2>&1], [dhcpd.pid])\n+NETNS_DAEMONIZE([server], [dhcpd -4 -f -cf $DHCP_TEST_DIR/dhcpd.conf -lf $DHCP_TEST_DIR/dhcpd.leases s1 > dhcpd.log 2>&1], [dhcpd.pid])\n \n NS_CHECK_EXEC([server], [tcpdump -l -nvv -i s1  udp > pkt.pcap 2>tcpdump_err &])\n OVS_WAIT_UNTIL([grep \"listening\" tcpdump_err])\n@@ -21370,7 +21370,7 @@ chmod 775 $DHCP_TEST_DIR\n chmod 664 $DHCP_TEST_DIR/dhcpd.leases\n \n # Start dhcpd as DHCP server in the server namespace.\n-NETNS_DAEMONIZE([server], [dhcpd -4 -f -cf $DHCP_TEST_DIR/dhcpd.conf server > $DHCP_TEST_DIR/dhcpd.log 2>&1], [dhcpd.pid])\n+NETNS_DAEMONIZE([server], [dhcpd -4 -f -cf $DHCP_TEST_DIR/dhcpd.conf -lf $DHCP_TEST_DIR/dhcpd.leases server > $DHCP_TEST_DIR/dhcpd.log 2>&1], [dhcpd.pid])\n \n # Give dhcpd time to start.\n sleep 1\n","prefixes":["ovs-dev","RFC","v2"]}