From afbf404373cd656db307c2e94f879de4918fd199 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Mon, 10 Aug 2026 16:26:08 +0000 Subject: [PATCH 1/7] Add Ubuntu image and Ubuntu QEMU plugin support Ubuntu is a popular Linux distribution, and it is useful to be able to run integration tests on it. --- .github/workflows/itf.yml | 2 +- MODULE.bazel | 16 +++ scripts/BUILD | 7 + scripts/render_user_data.py | 63 +++++++++ test/integration/BUILD | 24 +++- .../{test_ebclfsa_ping.py => test_ping.py} | 0 test/resources/ubuntu_x86_64/BUILD | 54 ++++++++ test/resources/ubuntu_x86_64/build_image.sh | 122 ++++++++++++++++++ .../ubuntu_x86_64/cloud-init/meta-data | 2 + .../ubuntu_x86_64/cloud-init/user-data | 105 +++++++++++++++ test/resources/ubuntu_x86_64/qemu_config.json | 13 ++ 11 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 scripts/render_user_data.py rename test/integration/{test_ebclfsa_ping.py => test_ping.py} (100%) create mode 100644 test/resources/ubuntu_x86_64/BUILD create mode 100644 test/resources/ubuntu_x86_64/build_image.sh create mode 100644 test/resources/ubuntu_x86_64/cloud-init/meta-data create mode 100644 test/resources/ubuntu_x86_64/cloud-init/user-data create mode 100644 test/resources/ubuntu_x86_64/qemu_config.json diff --git a/.github/workflows/itf.yml b/.github/workflows/itf.yml index c34888ee..7e3d834f 100644 --- a/.github/workflows/itf.yml +++ b/.github/workflows/itf.yml @@ -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 diff --git a/MODULE.bazel b/MODULE.bazel index 011b211a..11c3f09f 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -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"], +) diff --git a/scripts/BUILD b/scripts/BUILD index e56e35b3..7d4230f7 100644 --- a/scripts/BUILD +++ b/scripts/BUILD @@ -19,3 +19,10 @@ sh_binary( ], visibility = ["//visibility:public"], ) + +exports_files( + [ + "render_user_data.py", + ], + visibility = ["//visibility:public"], +) diff --git a/scripts/render_user_data.py b/scripts/render_user_data.py new file mode 100644 index 00000000..dbe72649 --- /dev/null +++ b/scripts/render_user_data.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# 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 +# ******************************************************************************* + +"""Render cloud-init user-data using network values from qemu_config.json.""" + +from __future__ import annotations + +import ipaddress +import json +import sys + + +def main() -> None: + if len(sys.argv) != 4: + raise SystemExit("Error: Expected 3 arguments (qemu config, user-data template, rendered user-data)") + + qemu_config_path = sys.argv[1] + user_data_template_path = sys.argv[2] + user_data_rendered_path = sys.argv[3] + + with open(qemu_config_path, encoding="utf-8") as f: + qemu_config = json.load(f) + + networks = qemu_config.get("networks") + if not isinstance(networks, list) or not networks: + raise SystemExit("Error: qemu_config.json must provide at least one network") + + network = networks[0] + for key in ("ip_address", "gateway"): + if key not in network: + raise SystemExit(f"Error: missing '{key}' in first network entry") + + ip_address = str(network["ip_address"]) + gateway = str(network["gateway"]) + ipaddress.ip_address(ip_address) + ipaddress.ip_address(gateway) + + with open(user_data_template_path, encoding="utf-8") as f: + user_data = f.read() + + if "__SCORE_ITF_IP_ADDRESS__" not in user_data or "__SCORE_ITF_GATEWAY__" not in user_data: + raise SystemExit("Error: user-data template placeholders are missing") + + user_data = user_data.replace("__SCORE_ITF_IP_ADDRESS__", ip_address) + user_data = user_data.replace("__SCORE_ITF_GATEWAY__", gateway) + + with open(user_data_rendered_path, "w", encoding="utf-8") as f: + f.write(user_data) + + +if __name__ == "__main__": + main() diff --git a/test/integration/BUILD b/test/integration/BUILD index 7a43c8cd..22e21e5a 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -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)", @@ -233,6 +233,27 @@ 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 = [ @@ -240,6 +261,7 @@ test_suite( ], tests = [ ":test_ebclfsa_ping", + ":test_ubuntu_ping", ], ) diff --git a/test/integration/test_ebclfsa_ping.py b/test/integration/test_ping.py similarity index 100% rename from test/integration/test_ebclfsa_ping.py rename to test/integration/test_ping.py diff --git a/test/resources/ubuntu_x86_64/BUILD b/test/resources/ubuntu_x86_64/BUILD new file mode 100644 index 00000000..82a051bf --- /dev/null +++ b/test/resources/ubuntu_x86_64/BUILD @@ -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", + "//scripts: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 //scripts: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__"], +) diff --git a/test/resources/ubuntu_x86_64/build_image.sh b/test/resources/ubuntu_x86_64/build_image.sh new file mode 100644 index 00000000..8c69bf3f --- /dev/null +++ b/test/resources/ubuntu_x86_64/build_image.sh @@ -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 + +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 "${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 diff --git a/test/resources/ubuntu_x86_64/cloud-init/meta-data b/test/resources/ubuntu_x86_64/cloud-init/meta-data new file mode 100644 index 00000000..a004b717 --- /dev/null +++ b/test/resources/ubuntu_x86_64/cloud-init/meta-data @@ -0,0 +1,2 @@ +instance-id: score-itf-ubuntu-x86-64 +local-hostname: score-itf diff --git a/test/resources/ubuntu_x86_64/cloud-init/user-data b/test/resources/ubuntu_x86_64/cloud-init/user-data new file mode 100644 index 00000000..378691be --- /dev/null +++ b/test/resources/ubuntu_x86_64/cloud-init/user-data @@ -0,0 +1,105 @@ +#cloud-config +# ******************************************************************************* +# 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 usable by the score ITF QEMU +# plugin. This configuration is applied on a single throw-away boot performed by +# build_image.sh; afterwards cloud-init disables itself so that the resulting +# image is self-contained and boots straight into the configured state. +# +# The resulting image intentionally allows passwordless root SSH login. It is +# meant for integration testing only and must never be used in production. + +ssh_pwauth: true + +package_update: true +packages: + - iputils-ping + +write_files: + # Static address matching the tap0 device created by scripts/run_under_qemu.sh + # and the "networks" entry of qemu_config.json. + - path: /etc/netplan/99-score-itf.yaml + permissions: "0600" + owner: root:root + content: | + network: + version: 2 + renderer: networkd + ethernets: + itf0: + match: + name: "en*" + dhcp4: false + dhcp6: false + link-local: [] + optional: true + addresses: + - __SCORE_ITF_IP_ADDRESS__/16 + routes: + - to: default + via: __SCORE_ITF_GATEWAY__ + on-link: true + + # Prevent cloud-init from re-generating /etc/netplan/50-cloud-init.yaml. + - path: /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg + permissions: "0644" + owner: root:root + content: | + network: {config: disabled} + + # The ITF connects as root with an empty password (see QemuTarget.ssh). + - path: /etc/ssh/sshd_config.d/99-integration-test.conf + permissions: "0644" + owner: root:root + content: | + PermitRootLogin yes + PermitEmptyPasswords yes + PasswordAuthentication yes + KbdInteractiveAuthentication no + UseDNS no + +runcmd: + # A single fail-fast script: build_image.sh treats the absence of the marker + # printed at the very end as a build failure, so a partially customized image + # can never be produced. + - - bash + - -eux + - -c + - | + # Clear the root password so that password authentication succeeds with "". + passwd -d root + # pam_unix must accept empty passwords, otherwise sshd rejects the login + # even with PermitEmptyPasswords. + grep -q 'pam_unix\.so.*nullok' /etc/pam.d/common-auth || + sed -i 's/\(pam_unix\.so\)/\1 nullok/' /etc/pam.d/common-auth + grep -q 'pam_unix\.so.*nullok' /etc/pam.d/common-auth + # Drop the DHCP configuration generated by cloud-init, it would conflict + # with the static configuration written above. + rm -f /etc/netplan/50-cloud-init.yaml + netplan generate + # Make sure sshd is started on boot (Ubuntu 24.04 uses socket activation). + systemctl enable ssh.socket + # Speed up boot: nothing must wait for a network that only comes up once + # QEMU has attached the tap device. + systemctl disable systemd-networkd-wait-online.service + # From now on the image is fully configured; never run cloud-init again. + touch /etc/cloud/cloud-init.disabled + sync + echo "score ITF image customization finished" > /dev/console + +power_state: + mode: poweroff + message: score ITF image customization finished + timeout: 60 + condition: true diff --git a/test/resources/ubuntu_x86_64/qemu_config.json b/test/resources/ubuntu_x86_64/qemu_config.json new file mode 100644 index 00000000..e5e38ae8 --- /dev/null +++ b/test/resources/ubuntu_x86_64/qemu_config.json @@ -0,0 +1,13 @@ +{ + "networks": [ + { + "name": "tap0", + "ip_address": "169.254.158.190", + "gateway": "169.254.21.88" + } + ], + "ssh_port": 22, + "qemu_num_cores": 2, + "qemu_ram_size": "2G", + "qemu_machine": "pc-x86_64" +} From 7382eeba763d1defa8fde0a891b20de92eac858a Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Thu, 13 Aug 2026 14:54:07 +0000 Subject: [PATCH 2/7] Make scripts for building Ubuntu and Ebclfsa images public Also add using Linux QEMU images to README --- README.md | 49 ++++++++++++++++++- scripts/BUILD | 2 + .../build_ebclfsa_aarch64_image.sh | 0 .../build_ubuntu_x86_64_image.sh | 2 +- test/resources/ebclfsa_aarch64/BUILD | 4 +- test/resources/ubuntu_x86_64/BUILD | 4 +- 6 files changed, 54 insertions(+), 7 deletions(-) rename test/resources/ebclfsa_aarch64/build_image.sh => scripts/build_ebclfsa_aarch64_image.sh (100%) rename test/resources/ubuntu_x86_64/build_image.sh => scripts/build_ubuntu_x86_64_image.sh (96%) diff --git a/README.md b/README.md index 408a3fe2..b8fa280d 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,51 @@ QEMU targets are configured using a JSON configuration file that specifies netwo } ``` +#### Linux QEMU images + +The repository includes two image build flows that are meant to be consumed by QEMU tests. +These take a base image and customize it for ITF testing. The resulting images are stored in the Bazel cache and can be used in tests. + +For Ubuntu image building take a look at `test/resources/ubuntu_x86_64/BUILD` and for Ebclfsa image building take a look at `test/resources/ebclfsa_aarch64/BUILD`. +Using the prepared images, run your ITF tests. + +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 @@ -442,9 +487,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" ``` ## QEMU Setup (Linux) diff --git a/scripts/BUILD b/scripts/BUILD index 7d4230f7..f1ef38bf 100644 --- a/scripts/BUILD +++ b/scripts/BUILD @@ -22,6 +22,8 @@ sh_binary( exports_files( [ + "build_ebclfsa_aarch64_image.sh", + "build_ubuntu_x86_64_image.sh", "render_user_data.py", ], visibility = ["//visibility:public"], diff --git a/test/resources/ebclfsa_aarch64/build_image.sh b/scripts/build_ebclfsa_aarch64_image.sh similarity index 100% rename from test/resources/ebclfsa_aarch64/build_image.sh rename to scripts/build_ebclfsa_aarch64_image.sh diff --git a/test/resources/ubuntu_x86_64/build_image.sh b/scripts/build_ubuntu_x86_64_image.sh similarity index 96% rename from test/resources/ubuntu_x86_64/build_image.sh rename to scripts/build_ubuntu_x86_64_image.sh index 8c69bf3f..7fe2cf3d 100644 --- a/test/resources/ubuntu_x86_64/build_image.sh +++ b/scripts/build_ubuntu_x86_64_image.sh @@ -20,7 +20,7 @@ # 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 +# Usage: build_ubuntu_x86_64_image.sh set -euxo pipefail diff --git a/test/resources/ebclfsa_aarch64/BUILD b/test/resources/ebclfsa_aarch64/BUILD index bd8335bb..37246647 100644 --- a/test/resources/ebclfsa_aarch64/BUILD +++ b/test/resources/ebclfsa_aarch64/BUILD @@ -41,14 +41,14 @@ genrule( srcs = [ ":extract-fastdev-image", ":network_config_tar", - "build_image.sh", + "//scripts:build_ebclfsa_aarch64_image.sh", ], outs = [ "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic", "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64-vmlinux", ], cmd = """ - bash $(location build_image.sh) \ + bash $(location //scripts:build_ebclfsa_aarch64_image.sh) \ $(RULEDIR) \ $(RULEDIR)/ebcl-qemuarm64 \ $(RULEDIR)/ebcl-qemuarm64-itf \ diff --git a/test/resources/ubuntu_x86_64/BUILD b/test/resources/ubuntu_x86_64/BUILD index 82a051bf..a37e6822 100644 --- a/test/resources/ubuntu_x86_64/BUILD +++ b/test/resources/ubuntu_x86_64/BUILD @@ -15,7 +15,7 @@ genrule( name = "itf-image", srcs = [ "@ubuntu_noble_minimal_cloudimg_amd64//file", - "build_image.sh", + "//scripts:build_ubuntu_x86_64_image.sh", "//scripts:render_user_data.py", "cloud-init/user-data", "cloud-init/meta-data", @@ -23,7 +23,7 @@ genrule( ], outs = ["ubuntu-x86_64-itf/ubuntu-24.04-minimal-cloudimg-amd64.img"], cmd = """ - bash $(location build_image.sh) \ + bash $(location //scripts:build_ubuntu_x86_64_image.sh) \ $(RULEDIR) \ $(location @ubuntu_noble_minimal_cloudimg_amd64//file) \ $(RULEDIR)/ubuntu-x86_64-itf/ubuntu-24.04-minimal-cloudimg-amd64.img \ From cad85ed3e00847db1fcf41dda29400a2f06ad451 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Mon, 17 Aug 2026 10:47:00 +0000 Subject: [PATCH 3/7] make scripts for building images private --- README.md | 6 +----- scripts/BUILD | 9 --------- test/resources/ebclfsa_aarch64/BUILD | 4 ++-- .../resources/ebclfsa_aarch64/build_image.sh | 0 test/resources/ubuntu_x86_64/BUILD | 8 ++++---- .../resources/ubuntu_x86_64/build_image.sh | 2 +- .../resources/ubuntu_x86_64}/render_user_data.py | 0 7 files changed, 8 insertions(+), 21 deletions(-) rename scripts/build_ebclfsa_aarch64_image.sh => test/resources/ebclfsa_aarch64/build_image.sh (100%) rename scripts/build_ubuntu_x86_64_image.sh => test/resources/ubuntu_x86_64/build_image.sh (96%) rename {scripts => test/resources/ubuntu_x86_64}/render_user_data.py (100%) diff --git a/README.md b/README.md index b8fa280d..39d487b2 100644 --- a/README.md +++ b/README.md @@ -218,11 +218,7 @@ QEMU targets are configured using a JSON configuration file that specifies netwo #### Linux QEMU images -The repository includes two image build flows that are meant to be consumed by QEMU tests. -These take a base image and customize it for ITF testing. The resulting images are stored in the Bazel cache and can be used in tests. - -For Ubuntu image building take a look at `test/resources/ubuntu_x86_64/BUILD` and for Ebclfsa image building take a look at `test/resources/ebclfsa_aarch64/BUILD`. -Using the prepared images, run your ITF tests. +Running tests with Linux is supported: Ubuntu: diff --git a/scripts/BUILD b/scripts/BUILD index f1ef38bf..e56e35b3 100644 --- a/scripts/BUILD +++ b/scripts/BUILD @@ -19,12 +19,3 @@ sh_binary( ], visibility = ["//visibility:public"], ) - -exports_files( - [ - "build_ebclfsa_aarch64_image.sh", - "build_ubuntu_x86_64_image.sh", - "render_user_data.py", - ], - visibility = ["//visibility:public"], -) diff --git a/test/resources/ebclfsa_aarch64/BUILD b/test/resources/ebclfsa_aarch64/BUILD index 37246647..bd8335bb 100644 --- a/test/resources/ebclfsa_aarch64/BUILD +++ b/test/resources/ebclfsa_aarch64/BUILD @@ -41,14 +41,14 @@ genrule( srcs = [ ":extract-fastdev-image", ":network_config_tar", - "//scripts:build_ebclfsa_aarch64_image.sh", + "build_image.sh", ], outs = [ "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic", "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64-vmlinux", ], cmd = """ - bash $(location //scripts:build_ebclfsa_aarch64_image.sh) \ + bash $(location build_image.sh) \ $(RULEDIR) \ $(RULEDIR)/ebcl-qemuarm64 \ $(RULEDIR)/ebcl-qemuarm64-itf \ diff --git a/scripts/build_ebclfsa_aarch64_image.sh b/test/resources/ebclfsa_aarch64/build_image.sh similarity index 100% rename from scripts/build_ebclfsa_aarch64_image.sh rename to test/resources/ebclfsa_aarch64/build_image.sh diff --git a/test/resources/ubuntu_x86_64/BUILD b/test/resources/ubuntu_x86_64/BUILD index a37e6822..7de5b388 100644 --- a/test/resources/ubuntu_x86_64/BUILD +++ b/test/resources/ubuntu_x86_64/BUILD @@ -15,22 +15,22 @@ genrule( name = "itf-image", srcs = [ "@ubuntu_noble_minimal_cloudimg_amd64//file", - "//scripts:build_ubuntu_x86_64_image.sh", - "//scripts:render_user_data.py", + "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 //scripts:build_ubuntu_x86_64_image.sh) \ + 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 //scripts:render_user_data.py) + $(location render_user_data.py) """, tags = [ "manual", diff --git a/scripts/build_ubuntu_x86_64_image.sh b/test/resources/ubuntu_x86_64/build_image.sh similarity index 96% rename from scripts/build_ubuntu_x86_64_image.sh rename to test/resources/ubuntu_x86_64/build_image.sh index 7fe2cf3d..8c69bf3f 100644 --- a/scripts/build_ubuntu_x86_64_image.sh +++ b/test/resources/ubuntu_x86_64/build_image.sh @@ -20,7 +20,7 @@ # derived from qemu_config.json, then powers the machine off again, so this # script simply has to wait for QEMU to exit. # -# Usage: build_ubuntu_x86_64_image.sh +# Usage: build_image.sh set -euxo pipefail diff --git a/scripts/render_user_data.py b/test/resources/ubuntu_x86_64/render_user_data.py similarity index 100% rename from scripts/render_user_data.py rename to test/resources/ubuntu_x86_64/render_user_data.py From 3e9b9b81187e5b37c9e70ed4e5a5b1b0f190154b Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Tue, 18 Aug 2026 15:39:43 +0000 Subject: [PATCH 4/7] use Ubuntu and Ebclfsa images from os_images --- MODULE.bazel | 29 +---- README.md | 20 +-- test/integration/BUILD | 20 +-- test/resources/ebclfsa_aarch64/BUILD | 85 ------------ test/resources/ebclfsa_aarch64/build_image.sh | 105 --------------- .../config-overlay/etc/config/network/network | 12 -- .../ebclfsa_aarch64/qemu_config.json | 14 -- test/resources/ubuntu_x86_64/BUILD | 54 -------- test/resources/ubuntu_x86_64/build_image.sh | 122 ------------------ .../ubuntu_x86_64/cloud-init/meta-data | 2 - .../ubuntu_x86_64/cloud-init/user-data | 105 --------------- test/resources/ubuntu_x86_64/qemu_config.json | 13 -- .../ubuntu_x86_64/render_user_data.py | 63 --------- 13 files changed, 26 insertions(+), 618 deletions(-) delete mode 100644 test/resources/ebclfsa_aarch64/BUILD delete mode 100644 test/resources/ebclfsa_aarch64/build_image.sh delete mode 100644 test/resources/ebclfsa_aarch64/config-overlay/etc/config/network/network delete mode 100644 test/resources/ebclfsa_aarch64/qemu_config.json delete mode 100644 test/resources/ubuntu_x86_64/BUILD delete mode 100644 test/resources/ubuntu_x86_64/build_image.sh delete mode 100644 test/resources/ubuntu_x86_64/cloud-init/meta-data delete mode 100644 test/resources/ubuntu_x86_64/cloud-init/user-data delete mode 100644 test/resources/ubuntu_x86_64/qemu_config.json delete mode 100644 test/resources/ubuntu_x86_64/render_user_data.py diff --git a/MODULE.bazel b/MODULE.bazel index 11c3f09f..643351de 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -223,30 +223,13 @@ use_repo(imagefs, "score_qnx_x86_64_ifs_toolchain") ############################################################################### # -# EBclfsa fastdev archive repository for Linux QEMU integration tests +# Linux QEMU images from the dedicated os_images repository # ############################################################################### -http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") +bazel_dep(name = "os_images", version = "0.0.0") -http_file( - name = "eb_corbos_toolkit_fastdev_archive", - downloaded_file_path = "fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.tar.gz", - 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"], +git_override( + module_name = "os_images", + commit = "b58e764aded6f5afeb13e612913ce8753eae2aac", + remote = "https://github.com/eclipse-score/os_images.git", ) diff --git a/README.md b/README.md index 39d487b2..7bfdd1a1 100644 --- a/README.md +++ b/README.md @@ -227,12 +227,12 @@ 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)", + "--qemu-rootfs=$(location @os_images//ubuntu_x86_64:image)", + "--qemu-config=$(location @os_images//ubuntu_x86_64:qemu_config)", ], data = [ - "//test/resources/ubuntu_x86_64:image", - "//test/resources/ubuntu_x86_64:qemu_config", + "@os_images//ubuntu_x86_64:image", + "@os_images//ubuntu_x86_64:qemu_config", ], plugins = ["@score_itf//score/itf/plugins:qemu_plugin"], ) @@ -245,14 +245,14 @@ 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)", + "--qemu-rootfs=$(location @os_images//ebclfsa_aarch64:image)", + "--qemu-kernel=$(location @os_images//ebclfsa_aarch64:kernel)", + "--qemu-config=$(location @os_images//ebclfsa_aarch64:qemu_config)", ], data = [ - "//test/resources/ebclfsa_aarch64:image", - "//test/resources/ebclfsa_aarch64:kernel", - "//test/resources/ebclfsa_aarch64:qemu_config", + "@os_images//ebclfsa_aarch64:image", + "@os_images//ebclfsa_aarch64:kernel", + "@os_images//ebclfsa_aarch64:qemu_config", ], plugins = ["@score_itf//score/itf/plugins:qemu_plugin"], ) diff --git a/test/integration/BUILD b/test/integration/BUILD index 22e21e5a..66a190ec 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -216,14 +216,14 @@ py_itf_test( "test_ping.py", ], args = [ - "--qemu-config=$(location //test/resources/ebclfsa_aarch64:qemu_config)", - "--qemu-kernel=$(location //test/resources/ebclfsa_aarch64:kernel)", - "--qemu-rootfs=$(location //test/resources/ebclfsa_aarch64:image)", + "--qemu-config=$(location @os_images//ebclfsa_aarch64:qemu_config)", + "--qemu-kernel=$(location @os_images//ebclfsa_aarch64:kernel)", + "--qemu-rootfs=$(location @os_images//ebclfsa_aarch64:image)", ], data = [ - "//test/resources/ebclfsa_aarch64:image", - "//test/resources/ebclfsa_aarch64:kernel", - "//test/resources/ebclfsa_aarch64:qemu_config", + "@os_images//ebclfsa_aarch64:image", + "@os_images//ebclfsa_aarch64:kernel", + "@os_images//ebclfsa_aarch64:qemu_config", ], plugins = [ "//score/itf/plugins:qemu_plugin", @@ -239,12 +239,12 @@ py_itf_test( "test_ping.py", ], args = [ - "--qemu-config=$(location //test/resources/ubuntu_x86_64:qemu_config)", - "--qemu-rootfs=$(location //test/resources/ubuntu_x86_64:image)", + "--qemu-config=$(location @os_images//ubuntu_x86_64:qemu_config)", + "--qemu-rootfs=$(location @os_images//ubuntu_x86_64:image)", ], data = [ - "//test/resources/ubuntu_x86_64:image", - "//test/resources/ubuntu_x86_64:qemu_config", + "@os_images//ubuntu_x86_64:image", + "@os_images//ubuntu_x86_64:qemu_config", ], plugins = [ "//score/itf/plugins:qemu_plugin", diff --git a/test/resources/ebclfsa_aarch64/BUILD b/test/resources/ebclfsa_aarch64/BUILD deleted file mode 100644 index bd8335bb..00000000 --- a/test/resources/ebclfsa_aarch64/BUILD +++ /dev/null @@ -1,85 +0,0 @@ -# ******************************************************************************* -# 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 -# ******************************************************************************* - -load("@rules_pkg//pkg:tar.bzl", "pkg_tar") - -genrule( - name = "extract-fastdev-image", - srcs = ["@eb_corbos_toolkit_fastdev_archive//file"], - outs = [ - "ebcl-qemuarm64/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic", - "ebcl-qemuarm64/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64-vmlinux", - ], - cmd = "mkdir -p $(RULEDIR)/ebcl-qemuarm64 && tar xzf $(location @eb_corbos_toolkit_fastdev_archive//file) -C $(RULEDIR)/ebcl-qemuarm64 && chmod +w $(RULEDIR)/ebcl-qemuarm64/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic", - tags = [ - "manual", - ], - visibility = ["//visibility:private"], -) - -pkg_tar( - name = "network_config_tar", - srcs = [ - "config-overlay/etc/config/network/network", - ], - mode = "0644", - package_dir = "/etc/config/network", -) - -genrule( - name = "itf-image", - srcs = [ - ":extract-fastdev-image", - ":network_config_tar", - "build_image.sh", - ], - outs = [ - "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic", - "ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64-vmlinux", - ], - cmd = """ - bash $(location build_image.sh) \ - $(RULEDIR) \ - $(RULEDIR)/ebcl-qemuarm64 \ - $(RULEDIR)/ebcl-qemuarm64-itf \ - $(location :network_config_tar) - """, - tags = [ - "manual", - ], - visibility = ["//visibility:private"], -) - -filegroup( - name = "image", - srcs = [":ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64.wic"], - tags = [ - "manual", - ], - visibility = ["//visibility:public"], -) - -filegroup( - name = "kernel", - srcs = [":ebcl-qemuarm64-itf/fastdev-ubuntu-ebclfsa-ebcl-qemuarm64-vmlinux"], - tags = [ - "manual", - ], - visibility = ["//visibility:public"], -) - -filegroup( - name = "qemu_config", - srcs = ["qemu_config.json"], - visibility = ["//:__subpackages__"], -) diff --git a/test/resources/ebclfsa_aarch64/build_image.sh b/test/resources/ebclfsa_aarch64/build_image.sh deleted file mode 100644 index 3bc99418..00000000 --- a/test/resources/ebclfsa_aarch64/build_image.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/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 -# ******************************************************************************* - -set -euxo pipefail - -if [[ $# -lt 4 ]]; then - echo "Error: Expected at least 4 arguments (working directory, image source location, image target location, and one or more tar files to deploy relative to the root of the image)" >&2 - exit 1 -fi - -if ! command -v sshpass &> /dev/null; then - echo "Error: sshpass is not installed. Please install it to proceed." >&2 - exit 1 -fi - -WORKING_DIR="$1" -IMAGE_SOURCE="$2" -IMAGE_TARGET="$3" -shift 3 -DEPLOY_SRCS=("$@") - -if [[ ! -d "${IMAGE_SOURCE}" ]]; then - echo "Error: Image source location is not a directory: ${IMAGE_SOURCE}" >&2 - exit 1 -fi - -if ! find "${IMAGE_SOURCE}" -maxdepth 1 \( -name "*.wic" -type f -o -name "*.wic" -type l \) | grep -q .; then - echo "Error: No .wic file found in ${IMAGE_SOURCE}" >&2 - exit 1 -fi - -if ! find "${IMAGE_SOURCE}" -maxdepth 1 \( -name "*vmlinux" -type f -o -name "*vmlinux" -type l \) | grep -q .; then - echo "Error: No vmlinux file found in ${IMAGE_SOURCE}" >&2 - exit 1 -fi - -if [[ -e "${IMAGE_TARGET}" && ! -d "${IMAGE_TARGET}" ]]; then - echo "Error: Image target location exists but is not a directory: ${IMAGE_TARGET}" >&2 - exit 1 -fi - -for src in "${DEPLOY_SRCS[@]}"; do - if [[ ! -f "${src}" ]]; then - echo "Error: Deploy source file does not exist: ${src}" >&2 - exit 1 - fi - if [[ ! "${src}" =~ \.tar(\.(gz|bz2|xz))?$ ]]; then - echo "Error: Deploy source is not a tar file: ${src}" >&2 - exit 1 - fi -done - -mkdir -p "${IMAGE_TARGET}" -rm -f "${IMAGE_TARGET:?}/"* -cp -L "${IMAGE_SOURCE}"/* "${IMAGE_TARGET}"/ - -IMAGE=$(find "${IMAGE_TARGET}" -maxdepth 1 \( -name "*.wic" -type f -o -name "*.wic" -type l \) -print -quit) -KERNEL=$(find "${IMAGE_TARGET}" -maxdepth 1 \( -name "*vmlinux" -type f -o -name "*vmlinux" -type l \) -print -quit) - -# The image file must be writable for qemu overlay handling. -chmod +w "${IMAGE}" - -qemu-system-aarch64 -m 2048 -cpu cortex-a53 \ - -kernel "${KERNEL}" \ - -machine "virt,virtualization=true,gic-version=3" \ - -smp 8 \ - -device virtio-blk-device,drive=vd0 -drive if=none,format=raw,file="${IMAGE}",id=vd0 \ - -append "root=/dev/vda1 sdk_enable lisa_syscall_whitelist=2026 rw sharedmem.enable_sharedmem=0 init=/usr/bin/ebclfsa-cflinit" \ - -netdev user,id=net0,net=192.168.7.0/24,dhcpstart=192.168.7.2,dns=192.168.7.3,host=192.168.7.5,hostfwd=tcp::2222-:22 \ - -device virtio-net-device,netdev=net0 \ - -pidfile "${WORKING_DIR}/qemu.pid" \ - -nographic > "${WORKING_DIR}/qemu_deployment.log" & - -for _ in {1..60}; do - if sshpass -p linux ssh -o StrictHostKeyChecking=no -o ConnectTimeout=1 -p 2222 root@localhost true 2>/dev/null; then - break - fi - sleep 1 -done - -for src in "${DEPLOY_SRCS[@]}"; do - sshpass -p linux scp -rp -o StrictHostKeyChecking=no -P 2222 "${src}" root@localhost:/ - sshpass -p linux ssh -o StrictHostKeyChecking=no -p 2222 root@localhost "tar -xf /$(basename "${src}") -C /" - sshpass -p linux ssh -o StrictHostKeyChecking=no -p 2222 root@localhost "rm -f /$(basename "${src}")" -done - -# Enable root login and empty passwords for integration testing, not for production use. -sshpass -p linux ssh -o StrictHostKeyChecking=no -p 2222 root@localhost "printf 'PermitRootLogin yes\nPermitEmptyPasswords yes\nPasswordAuthentication yes\n' > /etc/ssh/sshd_config.d/99-integration-test.conf" -sshpass -p linux ssh -o StrictHostKeyChecking=no -p 2222 root@localhost "sed -i 's/^root:[^:]*:/root::/' /etc/shadow && sync && crinit-ctl poweroff" || true - -if [[ -f "${WORKING_DIR}/qemu.pid" ]]; then - wait "$(cat "${WORKING_DIR}/qemu.pid")" 2>/dev/null || true - rm -f "${WORKING_DIR}/qemu.pid" -fi diff --git a/test/resources/ebclfsa_aarch64/config-overlay/etc/config/network/network b/test/resources/ebclfsa_aarch64/config-overlay/etc/config/network/network deleted file mode 100644 index f2a81178..00000000 --- a/test/resources/ebclfsa_aarch64/config-overlay/etc/config/network/network +++ /dev/null @@ -1,12 +0,0 @@ -config interface 'loopback' - option device 'lo' - option proto 'static' - option ipaddr '127.0.0.1' - option netmask '255.0.0.0' - -config interface 'lan' - option device 'eth0' - option proto 'static' - option ipaddr '169.254.158.190' - option netmask '255.255.0.0' - option gateway '169.254.21.88' diff --git a/test/resources/ebclfsa_aarch64/qemu_config.json b/test/resources/ebclfsa_aarch64/qemu_config.json deleted file mode 100644 index 9c7237b9..00000000 --- a/test/resources/ebclfsa_aarch64/qemu_config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "networks": [ - { - "name": "tap0", - "ip_address": "169.254.158.190", - "gateway": "169.254.21.88" - } - ], - "ssh_port": 22, - "qemu_num_cores": 2, - "qemu_ram_size": "1G", - "qemu_machine": "virt-aarch64", - "qemu_kernel_cmdline": "root=/dev/vda1 sdk_enable lisa_syscall_whitelist=2026 rw sharedmem.enable_sharedmem=0 init=/usr/bin/ebclfsa-cflinit" -} diff --git a/test/resources/ubuntu_x86_64/BUILD b/test/resources/ubuntu_x86_64/BUILD deleted file mode 100644 index 7de5b388..00000000 --- a/test/resources/ubuntu_x86_64/BUILD +++ /dev/null @@ -1,54 +0,0 @@ -# ******************************************************************************* -# 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__"], -) diff --git a/test/resources/ubuntu_x86_64/build_image.sh b/test/resources/ubuntu_x86_64/build_image.sh deleted file mode 100644 index 8c69bf3f..00000000 --- a/test/resources/ubuntu_x86_64/build_image.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/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 - -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 "${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 diff --git a/test/resources/ubuntu_x86_64/cloud-init/meta-data b/test/resources/ubuntu_x86_64/cloud-init/meta-data deleted file mode 100644 index a004b717..00000000 --- a/test/resources/ubuntu_x86_64/cloud-init/meta-data +++ /dev/null @@ -1,2 +0,0 @@ -instance-id: score-itf-ubuntu-x86-64 -local-hostname: score-itf diff --git a/test/resources/ubuntu_x86_64/cloud-init/user-data b/test/resources/ubuntu_x86_64/cloud-init/user-data deleted file mode 100644 index 378691be..00000000 --- a/test/resources/ubuntu_x86_64/cloud-init/user-data +++ /dev/null @@ -1,105 +0,0 @@ -#cloud-config -# ******************************************************************************* -# 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 usable by the score ITF QEMU -# plugin. This configuration is applied on a single throw-away boot performed by -# build_image.sh; afterwards cloud-init disables itself so that the resulting -# image is self-contained and boots straight into the configured state. -# -# The resulting image intentionally allows passwordless root SSH login. It is -# meant for integration testing only and must never be used in production. - -ssh_pwauth: true - -package_update: true -packages: - - iputils-ping - -write_files: - # Static address matching the tap0 device created by scripts/run_under_qemu.sh - # and the "networks" entry of qemu_config.json. - - path: /etc/netplan/99-score-itf.yaml - permissions: "0600" - owner: root:root - content: | - network: - version: 2 - renderer: networkd - ethernets: - itf0: - match: - name: "en*" - dhcp4: false - dhcp6: false - link-local: [] - optional: true - addresses: - - __SCORE_ITF_IP_ADDRESS__/16 - routes: - - to: default - via: __SCORE_ITF_GATEWAY__ - on-link: true - - # Prevent cloud-init from re-generating /etc/netplan/50-cloud-init.yaml. - - path: /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg - permissions: "0644" - owner: root:root - content: | - network: {config: disabled} - - # The ITF connects as root with an empty password (see QemuTarget.ssh). - - path: /etc/ssh/sshd_config.d/99-integration-test.conf - permissions: "0644" - owner: root:root - content: | - PermitRootLogin yes - PermitEmptyPasswords yes - PasswordAuthentication yes - KbdInteractiveAuthentication no - UseDNS no - -runcmd: - # A single fail-fast script: build_image.sh treats the absence of the marker - # printed at the very end as a build failure, so a partially customized image - # can never be produced. - - - bash - - -eux - - -c - - | - # Clear the root password so that password authentication succeeds with "". - passwd -d root - # pam_unix must accept empty passwords, otherwise sshd rejects the login - # even with PermitEmptyPasswords. - grep -q 'pam_unix\.so.*nullok' /etc/pam.d/common-auth || - sed -i 's/\(pam_unix\.so\)/\1 nullok/' /etc/pam.d/common-auth - grep -q 'pam_unix\.so.*nullok' /etc/pam.d/common-auth - # Drop the DHCP configuration generated by cloud-init, it would conflict - # with the static configuration written above. - rm -f /etc/netplan/50-cloud-init.yaml - netplan generate - # Make sure sshd is started on boot (Ubuntu 24.04 uses socket activation). - systemctl enable ssh.socket - # Speed up boot: nothing must wait for a network that only comes up once - # QEMU has attached the tap device. - systemctl disable systemd-networkd-wait-online.service - # From now on the image is fully configured; never run cloud-init again. - touch /etc/cloud/cloud-init.disabled - sync - echo "score ITF image customization finished" > /dev/console - -power_state: - mode: poweroff - message: score ITF image customization finished - timeout: 60 - condition: true diff --git a/test/resources/ubuntu_x86_64/qemu_config.json b/test/resources/ubuntu_x86_64/qemu_config.json deleted file mode 100644 index e5e38ae8..00000000 --- a/test/resources/ubuntu_x86_64/qemu_config.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "networks": [ - { - "name": "tap0", - "ip_address": "169.254.158.190", - "gateway": "169.254.21.88" - } - ], - "ssh_port": 22, - "qemu_num_cores": 2, - "qemu_ram_size": "2G", - "qemu_machine": "pc-x86_64" -} diff --git a/test/resources/ubuntu_x86_64/render_user_data.py b/test/resources/ubuntu_x86_64/render_user_data.py deleted file mode 100644 index dbe72649..00000000 --- a/test/resources/ubuntu_x86_64/render_user_data.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -# ******************************************************************************* -# 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 -# ******************************************************************************* - -"""Render cloud-init user-data using network values from qemu_config.json.""" - -from __future__ import annotations - -import ipaddress -import json -import sys - - -def main() -> None: - if len(sys.argv) != 4: - raise SystemExit("Error: Expected 3 arguments (qemu config, user-data template, rendered user-data)") - - qemu_config_path = sys.argv[1] - user_data_template_path = sys.argv[2] - user_data_rendered_path = sys.argv[3] - - with open(qemu_config_path, encoding="utf-8") as f: - qemu_config = json.load(f) - - networks = qemu_config.get("networks") - if not isinstance(networks, list) or not networks: - raise SystemExit("Error: qemu_config.json must provide at least one network") - - network = networks[0] - for key in ("ip_address", "gateway"): - if key not in network: - raise SystemExit(f"Error: missing '{key}' in first network entry") - - ip_address = str(network["ip_address"]) - gateway = str(network["gateway"]) - ipaddress.ip_address(ip_address) - ipaddress.ip_address(gateway) - - with open(user_data_template_path, encoding="utf-8") as f: - user_data = f.read() - - if "__SCORE_ITF_IP_ADDRESS__" not in user_data or "__SCORE_ITF_GATEWAY__" not in user_data: - raise SystemExit("Error: user-data template placeholders are missing") - - user_data = user_data.replace("__SCORE_ITF_IP_ADDRESS__", ip_address) - user_data = user_data.replace("__SCORE_ITF_GATEWAY__", gateway) - - with open(user_data_rendered_path, "w", encoding="utf-8") as f: - f.write(user_data) - - -if __name__ == "__main__": - main() From 33742432095eb4014c6a59e54ce5258d97f9f03e Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Tue, 18 Aug 2026 15:41:17 +0000 Subject: [PATCH 5/7] make os_images a dev dependency --- MODULE.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index 643351de..1136251e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -226,7 +226,7 @@ use_repo(imagefs, "score_qnx_x86_64_ifs_toolchain") # Linux QEMU images from the dedicated os_images repository # ############################################################################### -bazel_dep(name = "os_images", version = "0.0.0") +bazel_dep(name = "os_images", version = "0.0.0", dev_dependency = True) git_override( module_name = "os_images", From e2c96a28a3ec968470c168adfdf4eda7ed21fca0 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Tue, 18 Aug 2026 15:46:53 +0000 Subject: [PATCH 6/7] format bazel code --- MODULE.bazel | 1 - 1 file changed, 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1136251e..f6415d28 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -227,7 +227,6 @@ use_repo(imagefs, "score_qnx_x86_64_ifs_toolchain") # ############################################################################### bazel_dep(name = "os_images", version = "0.0.0", dev_dependency = True) - git_override( module_name = "os_images", commit = "b58e764aded6f5afeb13e612913ce8753eae2aac", From d63ca484c9e562d7da8369d3ac744eaf7e8b2cdb Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Tue, 18 Aug 2026 17:32:07 +0000 Subject: [PATCH 7/7] use main branch of os_images --- MODULE.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index f6415d28..67ff2d20 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -229,6 +229,6 @@ use_repo(imagefs, "score_qnx_x86_64_ifs_toolchain") bazel_dep(name = "os_images", version = "0.0.0", dev_dependency = True) git_override( module_name = "os_images", - commit = "b58e764aded6f5afeb13e612913ce8753eae2aac", + commit = "a024787e2ddb4ceed6ac6fe63b3847ab937c0b5d", remote = "https://github.com/eclipse-score/os_images.git", )