From 14d89c440e8fb0f4160eb3d904cd4dc0e3754d96 Mon Sep 17 00:00:00 2001 From: Ruoqing He Date: Tue, 27 Aug 2024 23:38:48 +0800 Subject: [PATCH] Introduce `riscv64` CI Introduce logic necessary for generating YAML needed by BuildKite, which are designed to work with image introduced in rust-vmm/rust-vmm-container#106. The container version is updated to v40 to enable CI on RISC-V platform. Signed-off-by: Ruoqing He --- .buildkite/autogenerate_pipeline.py | 61 +++++++++++++++++++++++++---- .buildkite/test_description.json | 12 ++++-- README.md | 19 ++++++++- 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/.buildkite/autogenerate_pipeline.py b/.buildkite/autogenerate_pipeline.py index a5fa0c1..63b5429 100755 --- a/.buildkite/autogenerate_pipeline.py +++ b/.buildkite/autogenerate_pipeline.py @@ -60,7 +60,12 @@ # This represents the version of the rust-vmm-container used # for running the tests. -CONTAINER_VERSION = "v38" +CONTAINER_VERSION = "v40" +# The suffix suggests that the dev image with `v{N}-riscv` tag is not to be +# confused with real `riscv64` image (it's actually a `x86_64` image with +# `qemu-system-riscv64` installed), since AWS yet has `riscv64` machines +# available. +CONTAINER_VERSION_RISCV = CONTAINER_VERSION + "-riscv" # This represents the version of the Buildkite Docker plugin. DOCKER_PLUGIN_VERSION = "v5.3.0" @@ -78,8 +83,8 @@ # More details here: https://github.com/rust-vmm/community/issues/137 DEFAULT_AGENT_TAG_HYPERVISOR = os.getenv("DEFAULT_AGENT_TAG_HYPERVISOR", "kvm") -PARENT_DIR = pathlib.Path(__file__).parent.resolve() - +BUILDKITE_PATH = pathlib.Path(__file__).parent.resolve() +REPO_ROOT_PATH = BUILDKITE_PATH.parent.parent class BuildkiteStep: """ @@ -237,6 +242,17 @@ def build(self, input): if "{target_platform}" in command: assert platform, "Command requires platform, but platform is missing." command = command.replace("{target_platform}", platform) + # Modify command and tag name for `riscv64` CI + if platform == "riscv64": + # Wrap command with '' to avoid escaping early by `ENTRYPOINT` + command = json.dumps(command) + # Overwrite image tag for riscv64 platform CI + self.step_config["plugins"][0][f"docker#{DOCKER_PLUGIN_VERSION}"]["image"] = f"rustvmm/dev:{CONTAINER_VERSION_RISCV}" + # Since we are using qemu-system inside a x86_64 container, we + # should set `platform` field to x86_64 and unset the hypervisor to + # be passed + platform = "x86_64" + hypervisor = "" self.step_config["command"] = command # Optional keys. @@ -287,7 +303,7 @@ class BuildkiteConfig: def __init__(self): self.bk_config = None - def build(self, input): + def build(self, input, platform_allowlist): """Build the final Buildkite configuration fron the json input.""" self.bk_config = {"steps": []} @@ -309,6 +325,11 @@ def build(self, input): platforms = [None] for platform in platforms: + # Filter test enabled in platform_allowlist + if platform not in platform_allowlist: + # Skip disabled platform + continue + step_input = copy.deepcopy(test) step_input["platform"] = platform if not step_input.get("hypervisor"): @@ -322,7 +343,18 @@ def build(self, input): return self.bk_config -def generate_pipeline(config_file): +def determine_allowlist(config_file): + """Determine the what platforms should be enabled for this crate""" + + try: + with open(config_file, 'r') as file: + platforms = [line.strip() for line in file.readlines()] + return platforms + except Exception as e: + # Fall back to default platform if anything goes wrong + return ["x86_64", "aarch64"] + +def generate_pipeline(config_file, platform_allowlist): """Generate the pipeline yaml file from a json configuration file.""" with open(config_file) as json_file: @@ -330,7 +362,7 @@ def generate_pipeline(config_file): json_file.close() config = BuildkiteConfig() - output = config.build(json_cfg) + output = config.build(json_cfg, platform_allowlist) yaml.dump(output, sys.stdout, sort_keys=False) @@ -361,7 +393,20 @@ def generate_pipeline(config_file): "--test-description", metavar="JSON_FILE", help="The path to the JSON file containing the test" " description for the CI.", - default=f"{PARENT_DIR}/test_description.json", + default=f"{BUILDKITE_PATH}/test_description.json", + ) + parser.add_argument( + "-p", + "--platform-allowlist", + metavar="PLATFORM_DOT_FILE", + help=( + "The path to the dotfile containing platforms the crate's CI should run on.\n" + "If the file does not exist, falls back to default `platform_allowlist` (x86_64 and arm64).\n" + "The dotfile contains strings of architectures to be enabled separated by\n" + "newlines." + ), + default=f"{REPO_ROOT_PATH}/.platform", ) args = parser.parse_args() - generate_pipeline(args.test_description) + platform_allowlist = determine_allowlist(args.platform_allowlist) + generate_pipeline(args.test_description, platform_allowlist) diff --git a/.buildkite/test_description.json b/.buildkite/test_description.json index d3c6e1c..b2cf243 100644 --- a/.buildkite/test_description.json +++ b/.buildkite/test_description.json @@ -5,7 +5,8 @@ "command": "RUSTFLAGS=\"-D warnings\" cargo build --release", "platform": [ "x86_64", - "aarch64" + "aarch64", + "riscv64" ] }, { @@ -25,7 +26,8 @@ "command": "cargo test --all-features --workspace", "platform": [ "x86_64", - "aarch64" + "aarch64", + "riscv64" ] }, { @@ -41,7 +43,8 @@ "command": "cargo clippy --workspace --bins --examples --benches --all-features --all-targets -- -D warnings -D clippy::undocumented_unsafe_blocks", "platform": [ "x86_64", - "aarch64" + "aarch64", + "riscv64" ] }, { @@ -49,7 +52,8 @@ "command": "RUSTFLAGS=\"-D warnings\" cargo check --all-targets --all-features --workspace", "platform": [ "x86_64", - "aarch64" + "aarch64", + "riscv64" ] }, { diff --git a/README.md b/README.md index ef5e3e2..4266f70 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,24 @@ For most use cases, overriding or extending the configuration is not necessary. want to do so if, for example, the platform needs a custom device that is not available on the existing test instances or if we need a specialized hypervisor. -6. The code owners of the repository will have to setup a WebHook for +6. Tests will be running on `x86_64` and `aarch64` platforms by default. To change +this, e.g. to enable other experimental platforms like `riscv64`, a `.platform` +file can be included in the repository root. This file documents what platforms +are to be enabled for the repository. + +If `.platform` file is provided, it will be strictly observed. In `.platform` +file, each platform are separated by newline character. Currently, we support +`x86_64`, `aarch64` and `riscv64` platforms. + +For example, we can enable tests to be run on `riscv64` platform in addition to +`x86_64` and `aarch64` by: +``` +x86_64 +aarch64 +riscv64 +``` + +7. The code owners of the repository will have to setup a WebHook for triggering the CI on [pull request](https://developer.github.com/v3/activity/events/types/#pullrequestevent) and [push](https://developer.github.com/v3/activity/events/types/#pushevent)