-
Notifications
You must be signed in to change notification settings - Fork 302
Description
Hi there.
I’m ffgan, and I’m glad to share the progress and discussion regarding CDI support for riscv64(rv64) in this issue.
1. Background Discussion
My advisor, nijincheng, previously proposed adding rv64 support for kubevirt in kubevirt#14818. A more detailed discussion later took place on the mailing list: https://groups.google.com/g/kubevirt-dev/c/dObRKg8Stwo/m/y-1Fmcb3AwAJ
In short, we aim to contribute rv64 support to kubevirt. Based on the principle of community-first, we will provide as much assistance as possible to ensure kubevirt runs smoothly on rv64 and continue contributing to its long-term maintenance.
2. Principles of This Issue
As the first step in the above plan, this issue is opened here.
Before starting, we’ll follow two principles to ensure smooth progress:
-
Community first: fully respect community opinions.
-
Thorough discussion: ensure sufficient communication before decisions.
3. Current Status of kubevirt
After continuous effort, we’ve managed to get kubevirt running on rv64. We’re now actively testing kubevirt’s functest. Once that completes, we plan to open related PR to the main kubevirt repo.
The full functest relies on two repositories:
Therefore, enabling rv64 support for these two repositories is necessary. This issue focuses on adding rv64 support to CDI.
4. Current Status of CDI (Detailed)
Adding rv64 support for CDI is straightforward for Go itself; the real challenges are bazel and k8s. Below I describe each part in detail.
1. Bazel for rv64
Bazel doesn’t officially support rv64 yet, meaning there’s no prebuilt version available.
We need to build bazel from source, for example:
git clone https://gitee.com/kincheng-ni/bazel-v5.4.1.git
cd bazel-v5.4.1
# Ensure that OpenJDK 11 is installed
sudo dnf install java-11-openjdk-devel -y
./build.sh
# bazel will be in ./bazel-5.4.1-riscv64/bin/This repository includes some patches that enable building bazel 5.4.1 on rv64. If needed, I can help mirror this repo into the kubevirt organization.
Regarding Bazel, the following points require special clarification.
Kubernetes has already removed bazel support kubernetes#88553, and kubevirt is discussing the same kubevirt#14038.
According to bazel’s release page:
-
Bazel 5.x reached EOL in Jan 2025 (last: 5.4.1)
-
Bazel 6.x will reach EOL in Dec 2025
-
Bazel 7.x will reach EOL in Dec 2026
Community may need to consider whether to migrate to 7.x or remove bazel entirely.
There are two possible directions: upgrading and migrating to the 7.x version, or removing Bazel entirely. From a long-term perspective, removing Bazel is worth considering. However, the immediate challenge is that removing Bazel requires a massive amount of work — not only deleting all Bazel-related code, but also ensuring correctness and maintaining consistency between the pre- and post-removal states.
If Bazel is not removed, then compatibility issues arising from upgrading to a major version must be carefully considered. Another possible approach is to maintain the current state and wait for a more suitable time to engage in further discussions.
We fully respect the community’s decisions. If the community decides to remove Bazel, we will follow its direction closely and update all rv64-related KubeVirt support accordingly. We will not impose any additional burden on the existing community efforts and will actively assist in completing the related work.
2. Building the builder
When using bazel, we first build the builder image:
git clone https://github.com/ffgan/containerized-data-importer.git
cd containerized-data-importer
git switch rv64
cp ../bazel-v5.4.1/bazel-5.4.1-riscv64/bin/bazel-real hack/build/docker/riscv64/
./build-rv64.shIn my fork, I’ve modified the build to use fedorariscv/base:41 as the base image.
Then start a local registry:
$ docker run -d -p 5000:5000 --restart always --name registry registry:3And then we can push the builder image:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
127.0.0.1:5000/kubevirt/kubevirt-cdi-bazel-builder riscv64Test01 d2fbfa2ea026 4 minutes ago 1.97GB
$ docker push 127.0.0.1:5000/kubevirt/kubevirt-cdi-bazel-builder:riscv64Test013. bazel-build
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make bazel-buildRunning bazel-build on rv64 requires multiple fixes.
1. bazeldnf
The first modification needed is to update the RPM package dependencies by adding packages for rv64. This requires using bazeldnf. Currently, bazeldnf does not directly support rv64, so I used a modified version from this repository.
However, bazeldnf has a bug on rv64 that prevents it from being used to update KubeVirt dependencies directly. Details can be found in this issue. This problem may be related to the package repository being used and not necessarily to rv64 itself.
To enable bazeldnf support for rv64, I submitted a pull request. If the PR is successfully merged, I will attempt again to use bazeldnf on rv64 to update KubeVirt dependencies and submit a new PR to resolve this issue.
In the meantime, to update CDI’s RPM dependencies for rv64, I used the script from this repository with minor modifications. I placed the modified script in my own repository at https://github.com/ffgan/rpm-deps, used it to generate RPM dependencies suitable for rv64, and then manually pasted the results back into CDI.
To summarize:
We needed bazeldnf to work during Bazel’s analyze phase on rv64, so we used a custom bazeldnf repository. However, due to a bug, we couldn’t use make rpm-deps directly. Instead, I used a handwritten Python script to generate the required dependencies and then manually copied them back into CDI.
2. rules_go
Since rules_go does not directly support rv64, I submitted a simple PR to make rules_go work better under rv64. By upgrading to version 0.59.0, it can function properly on rv64. However, rules_go 0.59.0 requires Bazel 6.5.0 or higher, while our current Bazel version is 5.4.1.
Considering the earlier discussion about Bazel version compatibility, I believe we need to decide whether to upgrade to Bazel 7.x. If we don’t plan to upgrade, we can instead use a forked repository: https://github.com/Boring545/rules_go/releases/download/v0.46.0. With this version of rules_go, we won’t need to upgrade Bazel. If using a third-party repository raises security or maintenance concerns, I can help mirror this repository into the kubevirt organization to ensure availability and maintainability.
To minimize the amount of change introduced, I am currently using the latter approach.
With that in place, we can successfully run bazel-build.
4. build-functest
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make build-functestThe results show that everything went smoothly, with nothing significant to note.
5. test-unit
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make test-unitWhen running test-unit, since there is no available quay.io/prometheus/prometheus container for rv64, we need to manually build it. This process is rather involved, but in short, we need to build the Prometheus's rv64 image and tag it as quay.io/prometheus/prometheus:v2.44.0.
Due to several limitations, we can only build the rv64 Prometheus image through cross-compilation on x86:
make promu
promu crossbuild -p linux/riscv64
make npm_licenses
make common-docker-riscv64After building, we also need to manually tag it as quay.io/prometheus/prometheus:v2.44.0.
I’ve already submitted a PR to Prometheus regarding this process — see prometheus/prometheus#17508.
Once the above steps are complete, we can proceed to run test-unit.
Here’s one of the execution results:
Overall, it runs smoothly; you can refer to the log for details. There are indeed some errors, but now is not the time to address them. For the moment, we can consider the test as having passed successfully.
6. format
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make formatThe results show that everything went smoothly, with nothing significant to note.
7. vet
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make vetThe output of the last part is as follows. It’s likely due to an existing bug, not caused by rv64. Let’s consider it as a pass for now.
# kubevirt.io/containerized-data-importer/pkg/importer
# [kubevirt.io/containerized-data-importer/pkg/importer]
./gcs-datasource.go:61:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak
+ finish
+ docker stop --time 1 cf9b7df1c052941349d79d50cc2c9497bac92f41c9591631d1bfb1c11deae0f0
+ docker rm -f cf9b7df1c052941349d79d50cc2c9497bac92f41c9591631d1bfb1c11deae0f0
make: *** [Makefile:218: vet] Error 18. bazel-build-images
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make bazel-build-imagesSince this part involves building containers, the rules_docker used here also doesn’t support rv64. Therefore, we use a modified version of rules_docker, as shown below:
http_archive(
name = "io_bazel_rules_docker",
sha256 = "f5d26fcba1a99597a275e9a18971a4dcf44aecb109ccf8f080d080f1e6d9a10b",
strip_prefix = "rules_docker-0.16.0",
urls = [
"https://github.com/Boring545/rules_docker/releases/download/v0.16.0/rules_docker-v0.16.0.zip",
],
)If we want rules_docker to officially support rv64, the situation becomes a bit more complicated. rules_docker has already been deprecated, and the maintainer suggested switching to rules_oci instead. See this PR for details. However, rules_oci doesn’t handle RPMs very well, which makes things a bit troublesome.
If necessary, I might consider submitting a PR to add rv64 support to rules_oci in the future, but for now, it will be put on hold.
9. bazel-push-images
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make bazel-push-imagesIt can also be executed smoothly, with no additional notes required.
10. test-lint
BUILD_ARCH=riscv64 DOCKER_PREFIX="127.0.0.1:5000/kubevirt" QUAY_REPOSITORY=kubevirt-cdi-bazel-builder BUILDER_TAG=riscv64Test01 BUILDER_IMAGE=${DOCKER_PREFIX}/${QUAY_REPOSITORY}:${BUILDER_TAG} make test-lintLack of a quay.io/kubevirt/prom-metrics-linter container for rv64.
This container comes from kubevirt/monitoring and depends on distroless/base. There is currently a related issue: GoogleContainerTools/distroless#1269.
It has been modified to use an Alpine image, see ffgan/monitoring prom-metrics-linter container.
It can now run successfully.
11. Other build targets
For other targets, such as cluster-*, since Kubernetes does not yet officially support rv64, the relevant issue can be found here: kubernetes/kubernetes#116686. It is foreseeable that official rv64 support in Kubernetes will not be available in the short term.
However, this is not a problem—I have already tried deploying rv64's k3s, and it works properly. If we want cluster-* to be supported as well, I estimate that it would be a much larger topic, and it would be more appropriate to open a separate issue to address it. If consensus can be reached on the current issue, I believe I can soon open a new issue to elaborate on this and further promote the related progress.
12. Target's State
| target name | status |
|---|---|
| bazel-build | Y |
| build-functest | Y |
| test-unit | Y |
| format | Y |
| vet | Y |
| bazel-build-images | Y |
| bazel-push-images | Y |
| test-lint | Y |
| cluster-* | N |
13. Forked repositories used
| Name | URL | Description |
|---|---|---|
| bazel | https://gitee.com/kincheng-ni/bazel-v5.4.1.git | Build Bazel for rv64 |
| rules_go | https://github.com/Boring545/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip | Enables Bazel’s Go toolchain to work on rv64 |
| rules_docker | https://github.com/Boring545/rules_docker/releases/download/v0.16.0/rules_docker-v0.16.0.zip | Enables Bazel’s Docker toolchain to work on rv64 |
| bazeldnf | https://gitee.com/huang_a/bazeldnf/releases/download/v0.5.9/bazeldnf-v0.5.9.tar.gz | Allows Bazeldnf to run on rv64, but rpm-deps cannot be executed |
| bazeldnf-script | https://github.com/ffgan/rpm-deps.git | Used to generate RPM package dependencies on rv64 |
5. Current Status of CDI (Summary)
In summary, the current state of rv64 support in CDI is as follows:
CDI can basically be built and tested on rv64, and is overall usable on rv64. However, due to the lack of rv64 support in k8s, it is currently not possible to build all targets.
6. Discussion Regarding PRs
The above summarizes my recent attempts and results regarding CDI support for rv64. If there is anything incorrect, please feel free to point it out directly.
Regarding this issue, I hope we can discuss plans and approaches for CDI’s rv64 support, mainly focusing on the following points:
1. How to handle upstream repositories that do not support rv64
The obvious approach is to submit a PR to the upstream repository and wait for the upstream release to gain the required support. In fact, I have submitted a PR to rules_go upstream and am waiting for the release. However, the latest upstream versions often have minimum requirements—for example, rules_go 0.59.0 works on rv64 but requires Bazel 6.5.0, which conflicts with CDI.
A more reasonable approach is to follow upstream as closely as possible and upgrade our Bazel version. However, we understand that upgrading versions is not always easy, so we could also consider using our own fork to achieve rv64 support on lower versions. If we go with our own fork, I can assist the KubeVirt community in maintaining it: cloning all relevant forks and managing them under the KubeVirt GitHub organization to ensure usability. Other better approaches are also welcome.
Regarding this matter, I adhere to the principle of respecting the community’s opinion. Once a consensus is reached, I will promptly update the information regarding CDI’s rv64 support to ensure that CDI achieves robust rv64 compatibility.
2. Plan for CDI rv64 Support
My preliminary plan is to first have the community discuss the issues mentioned above, and then I will gradually submit the smallest possible PRs—following the principle of minimizing the PR review burden—to progressively enable CDI support for rv64.
- Resolve certain upstream dependency issues.
- Provide initial support for building CDI on rv64.
- Address issues related to starting clusters on rv64.
- Add CI coverage for rv64.
- Improve testing on rv64.
- Achieve full support for rv64.
Before completing the previous step, the next step should be avoided as much as possible to prevent excessive maintenance burden.
3. Regarding Cluster Startup Issues
Starting a cluster depends on k8s support for rv64. I do not intend to address this issue within this issue because it is too large in scope; I will open a separate issue to handle it. This cluster-related problem is not only present in CDI but also exists in KubeVirt, and it is also related to kubevirtci.
7. Additional Information
If you have any questions or concerns about the above, please feel free to ask — I’m happy to provide further details.
I hope this contribution can help kubevirt progress further toward rv64 support.
Co-authored by: [email protected]
Co-authored by: [email protected]
Co-authored by: [email protected]