Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/itf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Install qemu
run: |
sudo apt-get update
sudo apt-get install -y qemu-system-arm
sudo apt-get install -y qemu-system-arm qemu-system-x86 cloud-image-utils
- name: Enable KVM group perms
run: |
sudo chmod 666 /dev/kvm
Expand Down
16 changes: 16 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,19 @@ http_file(
sha256 = "9ca3891b27e4b7bbf6c519d8924283e89c03b62513a988f751a3ee3d10c293e4",
urls = ["https://github.com/elektrobit/eb_corbos_toolkit/releases/download/v2.0.0-beta1/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.tar.gz"],
)

###############################################################################
#
# Ubuntu minimal cloud image for x86_64 Linux QEMU integration tests
#
# Pinned to a dated release directory so the download stays reproducible. The
# minimal image is used instead of the full server image to reduce test times.
# The file uses the ".img" extension but is in fact a qcow2 image.
#
###############################################################################
http_file(
name = "ubuntu_noble_minimal_cloudimg_amd64",
downloaded_file_path = "ubuntu-24.04-minimal-cloudimg-amd64.img",
sha256 = "b3064efb500d71d6ccbe619b1716062b803e285116e040627b430aaee14cced6",
urls = ["https://cloud-images.ubuntu.com/minimal/releases/noble/release-20260801/ubuntu-24.04-minimal-cloudimg-amd64.img"],
)
45 changes: 43 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,47 @@ QEMU targets are configured using a JSON configuration file that specifies netwo
}
```

#### Linux QEMU images

Running tests with Linux is supported:

Ubuntu:

```starlark
py_itf_test(
name = "test_qemu_ubuntu",
srcs = ["test_qemu_ubuntu.py"],
args = [
"--qemu-rootfs=$(location //test/resources/ubuntu_x86_64:image)",
"--qemu-config=$(location //test/resources/ubuntu_x86_64:qemu_config)",
],
data = [
"//test/resources/ubuntu_x86_64:image",
"//test/resources/ubuntu_x86_64:qemu_config",
],
plugins = ["@score_itf//score/itf/plugins:qemu_plugin"],
)
```

Ebclfsa:

```starlark
py_itf_test(
name = "test_qemu_ebclfsa",
srcs = ["test_qemu_ebclfsa.py"],
args = [
"--qemu-rootfs=$(location //test/resources/ebclfsa_aarch64:image)",
"--qemu-kernel=$(location //test/resources/ebclfsa_aarch64:kernel)",
"--qemu-config=$(location //test/resources/ebclfsa_aarch64:qemu_config)",
],
data = [
"//test/resources/ebclfsa_aarch64:image",
"//test/resources/ebclfsa_aarch64:kernel",
"//test/resources/ebclfsa_aarch64:qemu_config",
],
plugins = ["@score_itf//score/itf/plugins:qemu_plugin"],
)
```

### Capability-Based Tests

Expand Down Expand Up @@ -442,9 +483,9 @@ bazel test //test:test_docker \
### QEMU Tests

```bash
# With pre-built QEMU image
# With a pre-built QEMU root filesystem image
bazel test //test:test_qemu \
--test_arg="--qemu-image=/path/to/kernel.img"
--test_arg="--qemu-rootfs=/path/to/rootfs.img"
Comment thread
lurtz marked this conversation as resolved.
```

## QEMU Setup (Linux)
Expand Down
24 changes: 23 additions & 1 deletion test/integration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ py_itf_test(
py_itf_test(
name = "test_ebclfsa_ping",
srcs = [
"test_ebclfsa_ping.py",
"test_ping.py",
],
args = [
"--qemu-config=$(location //test/resources/ebclfsa_aarch64:qemu_config)",
Expand All @@ -233,13 +233,35 @@ py_itf_test(
],
)

py_itf_test(
name = "test_ubuntu_ping",
srcs = [
"test_ping.py",
],
args = [
"--qemu-config=$(location //test/resources/ubuntu_x86_64:qemu_config)",
"--qemu-rootfs=$(location //test/resources/ubuntu_x86_64:image)",
],
data = [
"//test/resources/ubuntu_x86_64:image",
"//test/resources/ubuntu_x86_64:qemu_config",
],
plugins = [
"//score/itf/plugins:qemu_plugin",
],
tags = [
"manual",
],
)

test_suite(
name = "linux_qemu_tests",
tags = [
"manual",
],
tests = [
":test_ebclfsa_ping",
":test_ubuntu_ping",
],
)

Expand Down
File renamed without changes.
54 changes: 54 additions & 0 deletions test/resources/ubuntu_x86_64/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

genrule(
name = "itf-image",
srcs = [
"@ubuntu_noble_minimal_cloudimg_amd64//file",
"build_image.sh",
"render_user_data.py",
"cloud-init/user-data",
"cloud-init/meta-data",
"qemu_config.json",
],
outs = ["ubuntu-x86_64-itf/ubuntu-24.04-minimal-cloudimg-amd64.img"],
cmd = """
bash $(location build_image.sh) \
$(RULEDIR) \
$(location @ubuntu_noble_minimal_cloudimg_amd64//file) \
$(RULEDIR)/ubuntu-x86_64-itf/ubuntu-24.04-minimal-cloudimg-amd64.img \
$(location cloud-init/user-data) \
$(location cloud-init/meta-data) \
$(location qemu_config.json) \
$(location render_user_data.py)
""",
tags = [
"manual",
],
visibility = ["//visibility:private"],
)

filegroup(
name = "image",
srcs = [":ubuntu-x86_64-itf/ubuntu-24.04-minimal-cloudimg-amd64.img"],
tags = [
"manual",
],
visibility = ["//visibility:public"],
)

filegroup(
name = "qemu_config",
srcs = ["qemu_config.json"],
visibility = ["//:__subpackages__"],
)
122 changes: 122 additions & 0 deletions test/resources/ubuntu_x86_64/build_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/bin/bash
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
#
# Turns a stock Ubuntu cloud image into an image that can be driven by the score
# ITF QEMU plugin.
#
# The image is booted exactly once with a cloud-init NoCloud seed image attached.
# cloud-init applies the configuration from a rendered cloud-init/user-data
# derived from qemu_config.json, then powers the machine off again, so this
# script simply has to wait for QEMU to exit.
#
# Usage: build_image.sh <working dir> <source image> <target image> <user-data> <meta-data> <qemu-config> <user-data-renderer>

set -euxo pipefail

if [[ $# -ne 7 ]]; then
echo "Error: Expected 7 arguments (working directory, source image, target image, cloud-init user-data, cloud-init meta-data, qemu config, user-data renderer)" >&2
exit 1
fi

WORKING_DIR="$1"
IMAGE_SOURCE="$2"
IMAGE_TARGET="$3"
USER_DATA="$4"
META_DATA="$5"
QEMU_CONFIG="$6"
USER_DATA_RENDERER="$7"

# Size of the resulting disk. The stock cloud image ships a small virtual disk;
# growing it leaves room for artifacts uploaded by tests.
IMAGE_SIZE="8G"
# Upper bound for the customization boot. Generous because the build machine may
# not provide KVM, in which case QEMU falls back to TCG emulation.
BOOT_TIMEOUT_SECONDS=1200

for tool in qemu-system-x86_64 qemu-img cloud-localds python3; do
if ! command -v "${tool}" &>/dev/null; then
echo "Error: ${tool} is not installed. Please install it to proceed." >&2
exit 1
fi
done

if [[ ! -f "${IMAGE_SOURCE}" ]]; then
echo "Error: Image source is not a file: ${IMAGE_SOURCE}" >&2
exit 1
fi

for f in "${USER_DATA}" "${META_DATA}"; do
if [[ ! -f "${f}" ]]; then
echo "Error: cloud-init file does not exist: ${f}" >&2
exit 1
fi
done

if [[ ! -f "${QEMU_CONFIG}" ]]; then
echo "Error: QEMU config does not exist: ${QEMU_CONFIG}" >&2
exit 1
fi

if [[ ! -f "${USER_DATA_RENDERER}" ]]; then
echo "Error: user-data renderer does not exist: ${USER_DATA_RENDERER}" >&2
exit 1
fi

mkdir -p "$(dirname "${IMAGE_TARGET}")"
rm -f "${IMAGE_TARGET}"
cp -L "${IMAGE_SOURCE}" "${IMAGE_TARGET}"

# The image file must be writable, both for the customization boot below and for
# the qemu overlay handling in the ITF QEMU plugin.
chmod +w "${IMAGE_TARGET}"
qemu-img resize "${IMAGE_TARGET}" "${IMAGE_SIZE}"

SEED_IMAGE="${WORKING_DIR}/score-itf-seed.img"
USER_DATA_RENDERED="${WORKING_DIR}/score-itf-user-data.yaml"
rm -f "${SEED_IMAGE}"

# Keep cloud-init network settings in sync with runtime QEMU settings.
python3 "${USER_DATA_RENDERER}" "${QEMU_CONFIG}" "${USER_DATA}" "${USER_DATA_RENDERED}"

cloud-localds "${SEED_IMAGE}" "${USER_DATA_RENDERED}" "${META_DATA}"

QEMU_LOG="${WORKING_DIR}/qemu_customization.log"

# -no-reboot makes QEMU exit instead of restarting, should cloud-init decide to
# reboot rather than power off.
timeout "${BOOT_TIMEOUT_SECONDS}" qemu-system-x86_64 \
-accel kvm -accel tcg \
-machine pc \
-cpu Cascadelake-Server-v5 \
-smp 2 \
-m 2048 \
-no-reboot \
-device virtio-blk-pci,drive=vd0 -drive if=none,format=qcow2,file="${IMAGE_TARGET}",id=vd0 \
-device virtio-blk-pci,drive=vd1 -drive if=none,format=raw,file="${SEED_IMAGE}",id=vd1,readonly=on \
-netdev user,id=net0 \
-device virtio-net-pci,netdev=net0 \
-nographic \
-serial mon:stdio </dev/null >"${QEMU_LOG}" 2>&1

rm -f "${SEED_IMAGE}"
rm -f "${USER_DATA_RENDERED}"

# cloud-init reports failures on stdout but still powers the machine off, so the
# exit code of QEMU alone is not a sufficient success criterion.
if ! grep -q "score ITF image customization finished" "${QEMU_LOG}"; then
echo "Error: cloud-init did not complete the image customization." >&2
echo "----- QEMU log -----" >&2
cat "${QEMU_LOG}" >&2
exit 1
fi
2 changes: 2 additions & 0 deletions test/resources/ubuntu_x86_64/cloud-init/meta-data
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
instance-id: score-itf-ubuntu-x86-64
local-hostname: score-itf
Loading
Loading