WIP/DNM - Add CentOS Stream 10 build support#1
Closed
lyarwood wants to merge 7 commits into
Closed
Conversation
Introduce KUBEVIRT_CENTOS_STREAM_VERSION environment variable to control which CentOS Stream version is used for container image RPMs. The default is 9 (current version). Key changes: - Create rpm/repo-cs9.yaml and rpm/repo-cs10.yaml with version-specific CentOS mirror URLs - Create rpm/centos_stream.bzl with Bazel macros for version selection using select() and config_setting - Update hack/rpm-deps.sh to generate versioned targets with _cs9/_cs10 suffix based on KUBEVIRT_CENTOS_STREAM_VERSION - Add hack/rpm-deps-aliases.sh to generate version-selecting aliases - Add BAZEL_CS_CONFIG to common.sh and all build scripts for automatic config selection based on the environment variable - Add Makefile targets: rpm-deps-cs9, rpm-deps-cs10, rpm-deps-all - Update .bazelrc with cs9/cs10 config settings Note: WORKSPACE and rpm/BUILD.bazel changes will be regenerated. Usage: # Build with CS9 (default) make bazel-build # Build with CS10 KUBEVIRT_CENTOS_STREAM_VERSION=10 make bazel-build # Regenerate RPM dependencies make rpm-deps-cs9 make rpm-deps-cs10 make rpm-deps-all Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
- Add path-based centos_stream_alias targets for libvirt-libs tar2files outputs (e.g., libvirt-libs_x86_64/usr/lib64) - Add compound config_settings for platform + CentOS Stream version combinations (e.g., x86_64_cs9, x86_64_cs10) - Update BUILD.bazel cc_library strip_include_prefix to be version-aware - Remove invalid top-level libvirt-libs aliases (tar2files creates path-based targets, not single targets) - Update sandbox_hash after CS10 sandbox regeneration Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
Add infrastructure for building CentOS Stream 10 based builder images: - Dockerfile.cs10: CS10 variant of the builder Dockerfile using quay.io/centos/centos:stream10 as base image - Uses Java 21 instead of Java 11 (CS10 only has Java 21+) - Uses -sf for python symlink (CS10 already has /usr/bin/python) - build-cs10.sh: Build script for CS10 builder images - common.sh: Add DOCKER_CS10_IMAGE and DOCKER_CS10_CROSS_IMAGE variables - dockerized: Select CS10 builder when KUBEVIRT_CENTOS_STREAM_VERSION=10 - Allows KUBEVIRT_BUILDER_IMAGE to override the version check - Makefile: Add builder-build-cs10 target Usage: 1. Build CS10 builder: make builder-build-cs10 2. Use local image: KUBEVIRT_BUILDER_IMAGE=quay.io/kubevirt/builder-cs10:<version>-amd64 3. Build with CS10: KUBEVIRT_CENTOS_STREAM_VERSION=10 make bazel-build Or with published image: 1. Set version: export KUBEVIRT_CS10_BUILDER_VERSION=<version> 2. Build: KUBEVIRT_CENTOS_STREAM_VERSION=10 make bazel-build The CS10 builder is required for building KubeVirt with CS10 RPMs because CS10's glibc uses the .relr.dyn ELF section format which requires a newer binutils than what's available in the CS9 builder. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
Add CentOS Stream 10 RPM dependencies for all architectures: - x86_64 - aarch64 - s390x CentOS Stream 9 packages remain at their original versions from main. Key changes: - Generate rpmtree and tar2files targets for CS10 - Add path-based aliases for libvirt-libs tar2files outputs - Add libvirt-libs to the aliases list in hack/rpm-deps-aliases.sh - Update sandbox_hash for CS10 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
In CentOS Stream 10, libvirt creates sockets in /run/libvirt/ but KubeVirt expects them at /var/run/libvirt/. Unlike CS9, the CS10 filesystem package creates /var/run as a directory instead of a symlink to /run. The BUILD.bazel changes: - Rename virt-launcher binary to virt-launcher-bin - Add entrypoint.sh wrapper script - Add var-run-symlink-tar for static symlink (backup) - Change container entrypoint to use the wrapper script Signed-off-by: Lee Yarwood <lyarwood@redhat.com> Assisted-By: Claude <noreply@anthropic.com>
Add a separate C/C++ toolchain configuration for CentOS Stream 10 which uses GCC 14 (paths under /usr/lib/gcc/x86_64-redhat-linux/14/). Key changes: - Create cc_toolchain_config_cs10.bzl with GCC 14 include paths - Register x86_64_linux_toolchain_cs10 with target_settings for is_cs10 - CS10 toolchain registered first for priority during resolution The toolchain is selected automatically when building with KUBEVIRT_CENTOS_STREAM_VERSION=10 based on the config_setting. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
Extend CentOS Stream 10 toolchain support to ARM64 and s390x architectures, complementing the existing x86_64 CS10 toolchain. Key changes: - Create cc_toolchain_config_cs10.bzl for aarch64 with GCC 14 paths - Create cc_toolchain_config_cs10.bzl for s390x with GCC 14 paths - Register aarch64_linux_toolchain_cs10 and s390x_linux_toolchain_cs10 - CS10 toolchains selected automatically via is_cs10 target_settings Tested with successful builds of C/C++ and Go binaries for both architectures using the crossbuild-aarch64 and crossbuild-s390x configs. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
Contributor
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: lyarwood The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
rthallisey
pushed a commit
that referenced
this pull request
Apr 10, 2026
The test is currently flaking. It uses ConsitsOf instead of Contains, to analyze the status which is currently showing 2 interfaces instead of one. The reason why the status includes two interfaces instead of one is as follows: The virt-handler's logic responsible for reporting interface status of SR-IOV devices is comprised of two steps: 1. Info is collected from the domain spec, while the MAC address is taken from the vmi.spec.domain.interfaces[].mac field (if exists) [1]. 2. Info from guest agent enriches the existing status entries in case the MAC address reported by GA can be correlated with the MAC address reported in the status [2]. Since the MAC address is unspecified in the spec, it is also unspecified in the status and is therefore not correlated. Since GA reporting is unrecognized, it is considered a guest only interface and is reported as an additional interface. This is a known issue kubevirt/kubevirt#16422. In order to fix correlation, set explicit MAC address in the spec in order to mitigate #1 above, and enable correlation in #2. The failure below [3] demonstrates how 2 interfaces were reported and how ConsitsOf was not satified with the results despite including the all the data that the gstruct matcher was asserting. [1] https://github.com/kubevirt/kubevirt/blob/395bd0da05f8b8d39326eb1b90da90b574a16e2b/pkg/network/setup/netstat.go#L308 [2] https://github.com/kubevirt/kubevirt/blob/395bd0da05f8b8d39326eb1b90da90b574a16e2b/pkg/network/setup/netstat.go#L333 [3] https://prow.ci.kubevirt.io/view/gs/kubevirt-prow/pr-logs/pull/kubevirt_kubevirt/16391/pull-kubevirt-e2e-kind-sriov/2004191256049094656 Expected <[]v1.VirtualMachineInstanceNetworkInterface | len:2, cap:2>: [ { IP: "", MAC: "", Name: "sriov-network", IPs: nil, PodInterfaceName: "podafa4cdb1f64", InterfaceName: "", InfoSource: "domain, multus-status", QueueCount: 0, LinkState: "", }, { IP: "", MAC: "86:4b:dc:31:e5:c8", Name: "", IPs: nil, PodInterfaceName: "", InterfaceName: "eth0", InfoSource: "guest-agent", QueueCount: 0, LinkState: "", }, ] to consist of <[]*gstruct.FieldsMatcher | len:1, cap:1>: [ { Fields: { "Name": <*matchers.EqualMatcher | 0xc0073e61a0>{ Expected: <string>"sriov-network", }, "InfoSource": <*matchers.ContainSubstringMatcher | 0xc004b126c0>{Substr: "domain", Args: nil}, }, IgnoreExtras: true, IgnoreMissing: false, failures: [ <*errors.NestedError | 0xc007a8d080>{ Path: ".Name", Err: <*errors.errorString | 0xc007108820>{ s: "Expected\n <string>: \nto equal\n <string>: sriov-network", }, }, <*errors.NestedError | 0xc007a8d0a0>{ Path: ".InfoSource", Err: <*errors.errorString | 0xc007108920>{ s: "Expected\n <string>: guest-agent\nto contain substring\n <string>: domain", }, }, ], }, ] the extra elements were <[]v1.VirtualMachineInstanceNetworkInterface | len:1, cap:1>: [ { IP: "", MAC: "86:4b:dc:31:e5:c8", Name: "", IPs: nil, PodInterfaceName: "", InterfaceName: "eth0", InfoSource: "guest-agent", QueueCount: 0, LinkState: "", Signed-off-by: Nir Dothan <ndothan@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
On NVIDIA GB200 Grace Blackwell systems, GPUs are on separate NUMA nodes from all CPUs by design. A 2-superchip GB200 exposes: NUMA 0: Grace CPU kubevirt#1 (CPUs 0-71, ~490 GB LPDDR5X) NUMA 1: Grace CPU kubevirt#2 (CPUs 72-143, ~490 GB LPDDR5X) NUMA 2: Blackwell GPU kubevirt#1 (no CPUs, ~188 GB HBM) NUMA 10: Blackwell GPU kubevirt#2 (no CPUs, ~188 GB HBM) The existing PCIe NUMA-aware topology code discovers the host NUMA node for each passthrough device but discards it when no vCPUs are pinned to that node, causing the device to fall back to the default pci.0 bus without NUMA affinity information. Extend LookupDevicesNumaNodes to return both aligned devices (host NUMA node has pinned vCPUs) and unaligned devices (host NUMA node has no pinned vCPUs but is a valid NUMA node). When the expander bus assigner encounters an unaligned device, it creates a CPU-less guest NUMA cell for the device's host NUMA node and places the device under a pcie-expander-bus targeting that cell. On a GB200 each GPU naturally gets its own expander bus and SMMUv3 IOMMU device through the standard per-NUMA topology path, since each GPU is on its own NUMA node. Also adds an explicit check for NUMA node -1 in GetDeviceNumaNode to avoid relying on uint32 overflow for devices without NUMA affinity. Ref: https://docs.nvidia.com/dccpu/grace-perf-tuning-guide/system.html Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
9 tasks
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…vices On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, sharing a single SMMUv3 IOMMU device. This causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller and smmuv3 IOMMU device. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…vices On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, sharing a single SMMUv3 IOMMU device. This causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller and smmuv3 IOMMU device. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…vices On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, sharing a single SMMUv3 IOMMU device. This causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller and smmuv3 IOMMU device. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…vices On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, sharing a single SMMUv3 IOMMU device. This causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller and smmuv3 IOMMU device. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…g a NUMA node On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, which means they share a single IOMMU device created by placeDevice. On ARM64 Grace systems this shared SMMUv3 causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 5, 2026
…g a NUMA node On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, which means they share a single IOMMU device created by placeDevice. On ARM64 Grace systems this shared SMMUv3 causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
lyarwood
added a commit
to lyarwood/kubevirt-aie
that referenced
this pull request
May 6, 2026
…g a NUMA node On a 2-superchip GB200, each Grace CPU has 2 Blackwell GPUs connected via NVLink-C2C that share the same sysfs NUMA node as the CPU socket: GPU 1 (0008:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 2 (0009:01:00.0): NUMA 0 (Grace CPU kubevirt#1) GPU 3 (0018:01:00.0): NUMA 1 (Grace CPU kubevirt#2) GPU 4 (0019:01:00.0): NUMA 1 (Grace CPU kubevirt#2) VEP 115's per-NUMA expander bus placement puts both GPUs on the same pcie-expander-bus, which means they share a single IOMMU device created by placeDevice. On ARM64 Grace systems this shared SMMUv3 causes CMD_SYNC timeout and tegra241_cmdqv errors in the guest, preventing multi-GPU initialization. When multiple IOMMU devices (marked with ACPI NodeSet "tofill") share a NUMA node, each now gets its own pcie-expander-bus controller. A single IOMMU device on a NUMA node continues to use the shared per-NUMA expander bus. Non-IOMMU devices always share a pcie-expander-bus per NUMA node. Ref: VOYAGER-707 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does
Before this PR:
KubeVirt can only be built using CentOS Stream 9 base images and RPM dependencies.
After this PR:
KubeVirt can be built with either CentOS Stream 9 (default) or CentOS Stream 10 using the
KUBEVIRT_CENTOS_STREAM_VERSIONenvironment variable.Key changes:
/var/runsymlink handling for CS10 compatibilityReferences
Why we need it and why it was done in this way
The following tradeoffs were made:
.relr.dynELF section format which requires newer binutils than available in CS9The following alternatives were considered:
Links to places where the discussion took place:
Special notes for your reviewer
Example workflow to build and test with CS10:
Checklist
This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR.
Approvers are expected to review this list.
Release note