runtime-rs: Add FC tests and rename rs-fc to fc-rs

WiP: Add tests for runtime-rs FC support.

Signed-off-by: Anastassios Nanos <ananos@nubificus.co.uk>
This commit is contained in:
Anastassios Nanos
2026-04-02 07:13:53 +00:00
parent c4a0b8e102
commit f48cd23836
11 changed files with 90 additions and 13 deletions

View File

@@ -88,7 +88,7 @@ jobs:
fail-fast: false
matrix:
containerd_version: ['lts', 'active']
vmm: ['clh', 'cloud-hypervisor', 'dragonball', 'qemu', 'qemu-runtime-rs']
vmm: ['clh', 'cloud-hypervisor', 'dragonball', 'qemu', 'qemu-runtime-rs', 'fc-rs']
runs-on: ubuntu-22.04
env:
CONTAINERD_VERSION: ${{ matrix.containerd_version }}
@@ -283,6 +283,7 @@ jobs:
- qemu
- cloud-hypervisor
- qemu-runtime-rs
- fc-rs
runs-on: ubuntu-22.04
env:
KATA_HYPERVISOR: ${{ matrix.vmm }}

View File

@@ -275,7 +275,7 @@ Each hypervisor has a dedicated configuration file:
|------------|----------------|-----------------|
| QEMU |`configuration-qemu-runtime-rs.toml` |`configuration-qemu.toml` |
| Cloud Hypervisor | `configuration-cloud-hypervisor.toml` | `configuration-clh.toml` |
| Firecracker | `configuration-rs-fc.toml` | `configuration-fc.toml` |
| Firecracker | `configuration-fc-rs.toml` | `configuration-fc.toml` |
| Dragonball | `configuration-dragonball.toml` (default) | `No` |
> **Note:** Configuration files are typically installed in `/opt/kata/share/defaults/kata-containers/` or `/opt/kata/share/defaults/kata-containers/runtime-rs/` or `/usr/share/defaults/kata-containers/`.

View File

@@ -423,7 +423,7 @@ endif
ifneq (,$(FCCMD))
KNOWN_HYPERVISORS += $(HYPERVISOR_FC)
CONFIG_FILE_FC = configuration-rs-fc.toml
CONFIG_FILE_FC = configuration-fc-rs.toml
CONFIG_FC = config/$(CONFIG_FILE_FC)
CONFIG_FC_IN = $(CONFIG_FC).in
CONFIG_PATH_FC = $(abspath $(CONFDIR)/$(CONFIG_FILE_FC))

View File

@@ -157,7 +157,7 @@ Configuration files in `config/`:
| `configuration-dragonball.toml.in` | Dragonball | Built-in VMM |
| `configuration-qemu-runtime-rs.toml.in` | QEMU | Default external |
| `configuration-cloud-hypervisor.toml.in` | Cloud Hypervisor | Modern VMM |
| `configuration-rs-fc.toml.in` | Firecracker | Lightweight microVM |
| `configuration-fc-rs.toml.in` | Firecracker | Lightweight microVM |
| `configuration-remote.toml.in` | Remote | Remote hypervisor |
| `configuration-qemu-tdx-runtime-rs.toml.in` | QEMU + TDX | Intel TDX confidential computing |
| `configuration-qemu-snp-runtime-rs.toml.in` | QEMU + SEV-SNP | AMD SEV-SNP confidential computing |

View File

@@ -3,6 +3,8 @@
//
//SPDX-License-Identifier: Apache-2.0
use std::convert::TryFrom;
use crate::{
firecracker::{
inner_hypervisor::{FC_AGENT_SOCKET_NAME, ROOT},
@@ -121,7 +123,8 @@ impl FcInner {
let body_config: String = json!({
"mem_size_mib": self.config.memory_info.default_memory,
"vcpu_count": self.config.cpu_info.default_vcpus.ceil() as u8,
"vcpu_count": u8::try_from(self.config.cpu_info.default_vcpus.ceil() as u64)
.context("vcpu_count overflows u8")?,
})
.to_string();
let body_kernel: String = json!({
@@ -289,7 +292,7 @@ impl FcInner {
// A transport error (FC not ready yet) — retry.
Err(FcRequestError::Transport(e)) => {
debug!(sl(), "FC not reachable yet, retrying: {:?}", e);
std::thread::sleep(std::time::Duration::from_millis(10));
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
continue;
}
// An HTTP-level error from FC — fail immediately with the

View File

@@ -130,9 +130,11 @@ impl FcInner {
if !jailed {
if let Some(netns_path) = &netns {
debug!(sl(), "set netns for vmm master {:?}", &netns_path);
let netns_fd = std::fs::File::open(netns_path);
let _ = setns(netns_fd?.as_raw_fd(), CloneFlags::CLONE_NEWNET)
.context("set netns failed");
let netns_fd = std::fs::File::open(netns_path)?;
setns(netns_fd.as_raw_fd(), CloneFlags::CLONE_NEWNET)
.map_err(|e| std::io::Error::other(
format!("setns into {:?} failed: {}", netns_path, e),
))?;
}
}
if let Some(label) = selinux_label.as_ref() {

View File

@@ -33,7 +33,7 @@ impl FcInner {
.context("add block device"),
DeviceType::Network(network) => {
// Buffer network devices and send them to FC just before InstanceStart
// in start_vm(). Firecracker rejects PUT /network-interfaces after the
// in boot_vm(). Firecracker rejects PUT /network-interfaces after the
// VM has started, so we must ensure they arrive before InstanceStart.
// This mirrors the Go runtime's batch-configuration approach.
//

View File

@@ -517,7 +517,7 @@ function enabling_hypervisor() {
declare -r CONTAINERD_SHIM_KATA="/usr/local/bin/containerd-shim-kata-${KATA_HYPERVISOR}-v2"
case "${KATA_HYPERVISOR}" in
dragonball|cloud-hypervisor|qemu-runtime-rs|qemu-se-runtime-rs)
dragonball|cloud-hypervisor|qemu-runtime-rs|qemu-se-runtime-rs|fc-rs)
sudo ln -sf "${KATA_DIR}/runtime-rs/bin/containerd-shim-kata-v2" "${CONTAINERD_SHIM_KATA}"
declare -r CONFIG_DIR="${KATA_DIR}/share/defaults/kata-containers/runtime-rs"
;;
@@ -536,6 +536,61 @@ function enabling_hypervisor() {
}
# Sets up a devmapper thin-pool and reconfigures standalone containerd to use
# it as the default snapshotter. Required for block-device based hypervisors
# (e.g. Firecracker / fc-rs) that cannot use the overlayfs snapshotter.
# Expects containerd to already be installed and /etc/containerd/config.toml
# to exist (e.g. after `containerd config default | sudo tee ...`).
function configure_devmapper_for_containerd() {
info "Configuring devmapper snapshotter for standalone containerd"
sudo mkdir -p /var/lib/containerd/devmapper
sudo truncate --size 10G /var/lib/containerd/devmapper/data-disk.img
sudo truncate --size 1G /var/lib/containerd/devmapper/meta-disk.img
# Allocate loop devices dynamically to avoid conflicts with pre-existing ones.
local loop_data loop_meta
loop_data=$(sudo losetup --find --show /var/lib/containerd/devmapper/data-disk.img)
loop_meta=$(sudo losetup --find --show /var/lib/containerd/devmapper/meta-disk.img)
info "devmapper: data=${loop_data} meta=${loop_meta}"
# data device size in 512-byte sectors: 10 GiB = 10*1024*1024*1024/512 = 20971520
local data_sectors
data_sectors=$(sudo blockdev --getsz "${loop_data}")
sudo dmsetup create contd-thin-pool \
--table "0 ${data_sectors} thin-pool ${loop_meta} ${loop_data} 512 32768 1 skip_block_zeroing"
# Add the devmapper snapshotter plugin config only if not already present
# (makes the function idempotent on re-runs).
if ! sudo grep -q 'io.containerd.snapshotter.v1.devmapper' /etc/containerd/config.toml; then
cat <<'EOF' | sudo tee -a /etc/containerd/config.toml
[plugins."io.containerd.snapshotter.v1.devmapper"]
pool_name = "contd-thin-pool"
root_path = "/var/lib/containerd/devmapper"
base_image_size = "4096MB"
discard_blocks = true
EOF
fi
# Patch the default snapshotter to devmapper if not already set.
if ! sudo grep -q 'snapshotter = "devmapper"' /etc/containerd/config.toml; then
sudo sed -i \
's|snapshotter = "overlayfs"|snapshotter = "devmapper"|g' \
/etc/containerd/config.toml
fi
sudo systemctl restart containerd
# Verify the plugin came up healthy
local dm_status
dm_status=$(sudo ctr plugins ls | awk '$2 ~ /^devmapper$/ { print $4 }' || true)
[ "${dm_status}" = "ok" ] || \
die "containerd devmapper snapshotter not healthy (status: '${dm_status}')"
info "devmapper snapshotter configured and healthy"
}
function check_containerd_config_for_kata() {
# check containerd config
declare -r line1="default_runtime_name = \"kata\""

View File

@@ -51,8 +51,14 @@ function install_dependencies() {
# Create the default containerd configuration
sudo mkdir -p /etc/containerd
containerd config default > sudo tee /etc/containerd/config.toml
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
# Firecracker (fc-rs) uses block devices and requires the devmapper
# snapshotter; other hypervisors work fine with the default overlayfs.
if [ "${KATA_HYPERVISOR:-}" = "fc-rs" ]; then
configure_devmapper_for_containerd
fi
}
function collect_artifacts() {

View File

@@ -48,11 +48,21 @@ function run() {
# bash "${stability_dir}/agent_stability_test.sh"
}
function install_kata_for_stability() {
install_kata
# Firecracker (fc-rs) uses block devices and requires the devmapper
# snapshotter; other hypervisors work fine with the default overlayfs.
if [ "${KATA_HYPERVISOR:-}" = "fc-rs" ]; then
configure_devmapper_for_containerd
fi
}
function main() {
action="${1:-}"
case "${action}" in
install-dependencies) install_dependencies ;;
install-kata) install_kata ;;
install-kata) install_kata_for_stability ;;
enabling-hypervisor) enabling_hypervisor ;;
run) run ;;
*) >&2 die "Invalid argument" ;;