From 14148e783ff349568586e31f40dd55e86aca520b Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Mon, 29 Jun 2026 17:14:49 +0200 Subject: [PATCH 1/2] chore: wip --- MODULE.bazel | 26 +++++++++++++++++++++ ci/container/files/packages.common | 10 ++++---- rs/tests/BUILD.bazel | 24 ++++++++++++++++++- rs/tests/driver/src/driver/local_backend.rs | 22 +++++++++++++++++ rs/tests/system_tests.bzl | 1 + 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 5d7629a5cfae..6efcbe19869a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1218,6 +1218,32 @@ new_local_repository( path = "/usr", ) +# libvirtd and its QEMU connection driver, fetched as Debian packages and +# extracted in //rs/tests (see the `libvirtd` and `libvirt_driver_qemu` +# genrules). The local system-test backend +# (rs/tests/driver/src/driver/local_backend.rs) spawns this libvirtd and points +# it at the extracted QEMU driver via LIBVIRT_DRIVER_DIR, so the container image +# no longer needs `libvirt-daemon` / `libvirt-daemon-driver-qemu` installed (see +# ci/container/files/packages.common). +# +# Pinned to the same version (12.0.0-1ubuntu5.1) as the `libvirt0` runtime +# library that `libvirt-dev` installs in the container, so the daemon and driver +# are ABI-compatible with it. To bump: pick a snapshot.ubuntu.com date carrying +# the desired version and update the urls + sha256 (the sha256 of the .deb). +http_file( + name = "libvirt_daemon_deb", + downloaded_file_path = "libvirt-daemon.deb", + sha256 = "fb483c656580988c87815615c3959d9d521bb9f4cb71b4f2932cbc572272ec50", + url = "https://snapshot.ubuntu.com/ubuntu/20260629T000000Z/pool/main/libv/libvirt/libvirt-daemon_12.0.0-1ubuntu5.1_amd64.deb", +) + +http_file( + name = "libvirt_daemon_driver_qemu_deb", + downloaded_file_path = "libvirt-daemon-driver-qemu.deb", + sha256 = "339590925f2427086df6305726656f32d5a1607d538b3a6cfcadfba65704c38a", + url = "https://snapshot.ubuntu.com/ubuntu/20260629T000000Z/pool/main/libv/libvirt/libvirt-daemon-driver-qemu_12.0.0-1ubuntu5.1_amd64.deb", +) + # Mainnet canister references canisters = use_repo_rule("//bazel:mainnet-canisters.bzl", "canisters") diff --git a/ci/container/files/packages.common b/ci/container/files/packages.common index 9343a4b57498..2003306e2521 100644 --- a/ci/container/files/packages.common +++ b/ci/container/files/packages.common @@ -46,10 +46,12 @@ zstd iputils-ping # for ping6 required by the bazel-test-bare-metal # Local system-test backend (libvirt/QEMU; see rs/tests/driver/src/driver/local_backend.rs). -# Provides per-test libvirtd subprocess + KVM-accelerated QEMU + dnsmasq for the -# libvirt network's DHCP. -libvirt-daemon -libvirt-daemon-driver-qemu +# Provides KVM-accelerated QEMU + dnsmasq for the libvirt network's DHCP + OVMF +# firmware. The libvirtd daemon and its QEMU connection driver are intentionally +# NOT installed here: they are fetched as Debian packages via Bazel and extracted +# into the test runfiles (see //rs/tests:libvirtd and //rs/tests:libvirt_driver_qemu), +# then run with LIBVIRT_DRIVER_DIR pointed at the extracted driver. The libvirt +# runtime library they link against (libvirt0) is still pulled in by `libvirt-dev`. qemu-system-x86 qemu-utils dnsmasq-base diff --git a/rs/tests/BUILD.bazel b/rs/tests/BUILD.bazel index 83991a102e2c..e39f228845d3 100644 --- a/rs/tests/BUILD.bazel +++ b/rs/tests/BUILD.bazel @@ -255,10 +255,32 @@ genrule( cmd = "sed < $< 's/$$/-test/' > $@", ) +# libvirtd and the QEMU connection driver for the local system-test backend +# (rs/tests/driver/src/driver/local_backend.rs), extracted from Debian packages +# fetched via Bazel (@libvirt_daemon_deb / @libvirt_daemon_driver_qemu_deb in +# MODULE.bazel) instead of copied from the container image. This keeps +# `libvirt-daemon` / `libvirt-daemon-driver-qemu` out of the image (see +# ci/container/files/packages.common); the libvirt runtime library they link +# against still comes from `libvirt-dev`'s `libvirt0` dependency. The backend +# runs `:libvirtd` with LIBVIRT_DRIVER_DIR pointed at `:libvirt_driver_qemu`'s +# directory so the monolithic daemon loads the QEMU driver (only) from there. +# `dpkg-deb --fsys-tarfile` decompresses the .deb's data archive to a tar stream +# from which `tar -xO` writes the single member to stdout. genrule( name = "libvirtd", + srcs = ["@libvirt_daemon_deb//file"], outs = ["libvirtd.bin"], - cmd = "cp -L /usr/sbin/libvirtd $@", + cmd = "dpkg-deb --fsys-tarfile $(location @libvirt_daemon_deb//file) | tar -xO ./usr/sbin/libvirtd > $@", + local = True, + tags = ["manual"], + target_compatible_with = ["@platforms//os:linux"], +) + +genrule( + name = "libvirt_driver_qemu", + srcs = ["@libvirt_daemon_driver_qemu_deb//file"], + outs = ["libvirt_driver_qemu.so"], + cmd = "dpkg-deb --fsys-tarfile $(location @libvirt_daemon_driver_qemu_deb//file) | tar -xO ./usr/lib/x86_64-linux-gnu/libvirt/connection-driver/libvirt_driver_qemu.so > $@", local = True, tags = ["manual"], target_compatible_with = ["@platforms//os:linux"], diff --git a/rs/tests/driver/src/driver/local_backend.rs b/rs/tests/driver/src/driver/local_backend.rs index a666149e9116..6fa875d938bd 100644 --- a/rs/tests/driver/src/driver/local_backend.rs +++ b/rs/tests/driver/src/driver/local_backend.rs @@ -319,6 +319,27 @@ impl LocalBackend { info!(logger, "Spawning libvirtd (session mode)"; "conf" => %conf_path.display(), "socket" => %socket_path.display()); let libvirtd_path = get_dependency_path_from_env("ENV_DEPS__LIBVIRTD_PATH"); + + // The QEMU connection driver (libvirt_driver_qemu.so) is provided by + // Bazel (//rs/tests:libvirt_driver_qemu), extracted from a Debian + // package, rather than installed in the container image. Point libvirtd + // at the directory holding it via LIBVIRT_DRIVER_DIR so the monolithic + // daemon loads the QEMU driver from there. The other connection drivers + // (network, storage, secret, ...) are intentionally absent: the local + // backend manages networking and disks itself and only needs + // `qemu:///session`, so libvirtd simply skips the driver modules it + // cannot find in that directory. Canonicalized to an absolute path + // because the value read from the environment is runfiles-relative. + let qemu_driver_path = get_dependency_path_from_env("ENV_DEPS__LIBVIRT_DRIVER_QEMU_PATH") + .canonicalize() + .context("canonicalizing the bazel-provided QEMU driver path")?; + let libvirt_driver_dir = qemu_driver_path.parent().with_context(|| { + format!( + "QEMU driver path {} has no parent directory", + qemu_driver_path.display() + ) + })?; + // We deliberately do not keep the `Child` handle. libvirtd must outlive // this (setup) process so forked task subprocesses can `connect_only` to // its socket; dropping the handle is harmless because @@ -333,6 +354,7 @@ impl LocalBackend { .arg(&pid_path) .env("HOME", &state_home) .env("XDG_RUNTIME_DIR", &xdg_runtime_dir) + .env("LIBVIRT_DRIVER_DIR", libvirt_driver_dir) .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()) diff --git a/rs/tests/system_tests.bzl b/rs/tests/system_tests.bzl index 374a6dd18c76..aadcc6a0bc6f 100644 --- a/rs/tests/system_tests.bzl +++ b/rs/tests/system_tests.bzl @@ -284,6 +284,7 @@ def system_test( _local_only_deps["ENV_DEPS__UNIVERSAL_VM_DISK_IMG_PATH"] = "@farm_universal_vm_img//file" _local_only_deps["ENV_DEPS__PROMETHEUS_VM_DISK_IMG_PATH"] = "@farm_prometheus_vm_img//file" _local_only_deps["ENV_DEPS__LIBVIRTD_PATH"] = "//rs/tests:libvirtd" + _local_only_deps["ENV_DEPS__LIBVIRT_DRIVER_QEMU_PATH"] = "//rs/tests:libvirt_driver_qemu" _local_only_deps["ENV_DEPS__DNSMASQ_PATH"] = "//rs/tests:dnsmasq" local_dep_env = { From 03a7cd8364c16f5173b41e52c34349c3b5cbd722 Mon Sep 17 00:00:00 2001 From: IDX GitHub Automation <> Date: Mon, 29 Jun 2026 15:19:38 +0000 Subject: [PATCH 2/2] Updating container images to tag: df92634d8ba5b2d6d2de4924ac7f93c08ad20ae7e3d172ffab98ea97dbbc44c1 ic-build: sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 ic-dev: sha256:1fa9ada331eeb070d35a4972395ae8296d07642c03306682a144c5977dbda65c --- .devcontainer/devcontainer.json | 2 +- .github/workflows/api-bn-recovery-test.yml | 2 +- .github/workflows/ci-main.yml | 2 +- .github/workflows/ci-pr-only.yml | 2 +- .github/workflows/container-api-bn-recovery.yml | 2 +- .github/workflows/container-scan-nightly.yml | 2 +- .github/workflows/local-system-tests.yml | 2 +- .github/workflows/pocket-ic-tests-windows.yml | 2 +- .github/workflows/rate-limits-backend-release.yml | 2 +- .github/workflows/release-testing.yml | 2 +- .github/workflows/rosetta-release.yml | 2 +- .github/workflows/salt-sharing-canister-release.yml | 2 +- .github/workflows/schedule-daily.yml | 2 +- .github/workflows/schedule-rust-bench.yml | 2 +- .github/workflows/system-tests-benchmarks-nightly.yml | 2 +- .github/workflows/update-mainnet-canister-revisions.yaml | 2 +- ci/container/TAG | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 60360aae40dd..1aac9be5277f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "image": "ghcr.io/dfinity/ic-dev@sha256:7d6f48fc1f2b0ddf229c4f325ec468f27225f8be7fe46836d6b44d23602ddca1", + "image": "ghcr.io/dfinity/ic-dev@sha256:1fa9ada331eeb070d35a4972395ae8296d07642c03306682a144c5977dbda65c", "remoteUser": "ubuntu", "privileged": true, "runArgs": [ diff --git a/.github/workflows/api-bn-recovery-test.yml b/.github/workflows/api-bn-recovery-test.yml index c1703d2bcaf6..5337e7903f3c 100644 --- a/.github/workflows/api-bn-recovery-test.yml +++ b/.github/workflows/api-bn-recovery-test.yml @@ -22,7 +22,7 @@ jobs: runs-on: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/home/buildifier/.local/share/containers" diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 823feae357c8..718b1a3c7661 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -33,7 +33,7 @@ jobs: runs-on: &dind-large-setup labels: dind-large container: &container-setup - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 90 diff --git a/.github/workflows/ci-pr-only.yml b/.github/workflows/ci-pr-only.yml index 3a9093ab8768..3a270a23a4b0 100644 --- a/.github/workflows/ci-pr-only.yml +++ b/.github/workflows/ci-pr-only.yml @@ -37,7 +37,7 @@ jobs: runs-on: &dind-small-setup labels: dind-small container: &container-setup - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --mount type=tmpfs,target="/tmp/containers" steps: diff --git a/.github/workflows/container-api-bn-recovery.yml b/.github/workflows/container-api-bn-recovery.yml index 994ed8024207..5cda5aa61a87 100644 --- a/.github/workflows/container-api-bn-recovery.yml +++ b/.github/workflows/container-api-bn-recovery.yml @@ -28,7 +28,7 @@ jobs: runs-on: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/home/buildifier/.local/share/containers" diff --git a/.github/workflows/container-scan-nightly.yml b/.github/workflows/container-scan-nightly.yml index d8360bcf76c7..8b3893b16008 100644 --- a/.github/workflows/container-scan-nightly.yml +++ b/.github/workflows/container-scan-nightly.yml @@ -12,7 +12,7 @@ jobs: runs-on: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 60 diff --git a/.github/workflows/local-system-tests.yml b/.github/workflows/local-system-tests.yml index 826e999e8658..4b6f164cf980 100644 --- a/.github/workflows/local-system-tests.yml +++ b/.github/workflows/local-system-tests.yml @@ -19,7 +19,7 @@ jobs: runs-on: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 600 diff --git a/.github/workflows/pocket-ic-tests-windows.yml b/.github/workflows/pocket-ic-tests-windows.yml index 59bb5176fc8c..6bce4264091e 100644 --- a/.github/workflows/pocket-ic-tests-windows.yml +++ b/.github/workflows/pocket-ic-tests-windows.yml @@ -45,7 +45,7 @@ jobs: bazel-build-pocket-ic: name: Bazel Build PocketIC container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 90 diff --git a/.github/workflows/rate-limits-backend-release.yml b/.github/workflows/rate-limits-backend-release.yml index 47b483c8bec4..fba6f764b817 100644 --- a/.github/workflows/rate-limits-backend-release.yml +++ b/.github/workflows/rate-limits-backend-release.yml @@ -32,7 +32,7 @@ jobs: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host -v /var/tmp:/var/tmp -v /ceph-s3-info:/ceph-s3-info --mount type=tmpfs,target="/tmp/containers" diff --git a/.github/workflows/release-testing.yml b/.github/workflows/release-testing.yml index 975b3e6a54c5..7822df6de5c3 100644 --- a/.github/workflows/release-testing.yml +++ b/.github/workflows/release-testing.yml @@ -35,7 +35,7 @@ jobs: group: dm1 labels: dind-large container: &container-setup - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 180 diff --git a/.github/workflows/rosetta-release.yml b/.github/workflows/rosetta-release.yml index ce7f3117ab4e..4c2b18f39f7a 100644 --- a/.github/workflows/rosetta-release.yml +++ b/.github/workflows/rosetta-release.yml @@ -22,7 +22,7 @@ jobs: runs-on: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" environment: DockerHub diff --git a/.github/workflows/salt-sharing-canister-release.yml b/.github/workflows/salt-sharing-canister-release.yml index 94b4596d619f..9a0998c01cb5 100644 --- a/.github/workflows/salt-sharing-canister-release.yml +++ b/.github/workflows/salt-sharing-canister-release.yml @@ -32,7 +32,7 @@ jobs: labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host -v /var/tmp:/var/tmp -v /ceph-s3-info:/ceph-s3-info --mount type=tmpfs,target="/tmp/containers" diff --git a/.github/workflows/schedule-daily.yml b/.github/workflows/schedule-daily.yml index afa6a29835b5..d611f16205bd 100644 --- a/.github/workflows/schedule-daily.yml +++ b/.github/workflows/schedule-daily.yml @@ -14,7 +14,7 @@ jobs: runs-on: &dind-large-setup labels: dind-large container: &container-setup - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 720 # 12 hours diff --git a/.github/workflows/schedule-rust-bench.yml b/.github/workflows/schedule-rust-bench.yml index e5b81bd77b1e..03636268c5ae 100644 --- a/.github/workflows/schedule-rust-bench.yml +++ b/.github/workflows/schedule-rust-bench.yml @@ -24,7 +24,7 @@ jobs: # see linux-x86-64 runner group labels: rust-benchmarks container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 # running on bare metal machine using ubuntu user options: --user ubuntu --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 720 # 12 hours diff --git a/.github/workflows/system-tests-benchmarks-nightly.yml b/.github/workflows/system-tests-benchmarks-nightly.yml index e050c38fd66b..0bd709e9dd1b 100644 --- a/.github/workflows/system-tests-benchmarks-nightly.yml +++ b/.github/workflows/system-tests-benchmarks-nightly.yml @@ -17,7 +17,7 @@ jobs: group: dm1 labels: dind-large container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host --mount type=tmpfs,target="/tmp/containers" timeout-minutes: 480 diff --git a/.github/workflows/update-mainnet-canister-revisions.yaml b/.github/workflows/update-mainnet-canister-revisions.yaml index 7cd03731b58a..6e79b10e9fac 100644 --- a/.github/workflows/update-mainnet-canister-revisions.yaml +++ b/.github/workflows/update-mainnet-canister-revisions.yaml @@ -25,7 +25,7 @@ jobs: labels: dind-small environment: CREATE_PR container: - image: ghcr.io/dfinity/ic-build@sha256:a50deb1a24fafa90553a1ba65551a4e8d955bce42e8f0d9d8e53ecc82f8f9c35 + image: ghcr.io/dfinity/ic-build@sha256:14610fcd4086e840b3899265084c36167b1819f820956a97ab41661e24eb73a1 options: >- -e NODE_NAME --privileged --cgroupns host -v /var/tmp:/var/tmp -v /ceph-s3-info:/ceph-s3-info --mount type=tmpfs,target="/tmp/containers" env: diff --git a/ci/container/TAG b/ci/container/TAG index ca790995816c..4da0f029b4dd 100644 --- a/ci/container/TAG +++ b/ci/container/TAG @@ -1 +1 @@ -d395e4504a1bf0cf387cbf17335b6a6cf47373e886e00994723ae3de5e53b107 +df92634d8ba5b2d6d2de4924ac7f93c08ad20ae7e3d172ffab98ea97dbbc44c1