blob: 5e9c9a20275a21986cd37df4769745cef28e9a95 [file] [log] [blame]
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/dist/resource.gni")
# Generates a disk image in qcow2 format. The disk images created by this template are simple
# regions of specific byte patterns that can be read in tests. The resultant image will be exposed
# as a resource that can be included into a fuchsia package by simply adding it as a dependency.
#
# disk_size (required)
# The size of disk to generate. This can be in bytes, or use suffixes k/M/G/T/P/E. For example,
# `disk_size = 10G` will create a 10 GiB disk image.
#
# filename (optional, default = $target_name.qcow2)
# The name of the generated disk image.
#
# cluster_size (optional, default = 64k)
# The qcow cluster size to use for the generated image. Number formats accepted are the same as
# described in `disk_size`.
#
# writes (optional, default = [])
# The `writes` argument allows for some data to be written to the disk by writing a byte
# pattern to a range of bytes on the disk. This takes a string of the form:
#
# "<disk_offset>+<length>=<byte>"
#
# Where `disk_offset` and `length` both accept number formats as described in the `disk_size`
# option. `byte` is a integer in the range 0 <= byte < 256. For example, the string:
# "20M+1M=0xab" will write 1 MiB of '0xab' bytes to the disk image starting 20 MiB into the
# file.
#
# All of the written ranges must be fully contained within the bounds of the generated file, as
# specified by the `disk_size` option.
#
# Ex:
# qcow_test_image("my_image") {
# filename = "output.qcow2"
# disk_size = "10G"
# cluster_size = "256k"
# writes = [
# # The first 1KiB of the file will be set to '0x01'.
# "0+1k=1",
# # 3 bytes of '0xaa' will be written at a 1GiB offset.
# "1G+3=0xaa",
# ]
# }
#
# fuchsia_unittest_package("my_test") {
# deps = [
# ":my_image",
# ":my_test_component",
# ]
# }
#
template("qcow_test_image") {
assert(defined(invoker.disk_size), "disk_size must be specified")
filename = "${target_name}.qcow2"
if (defined(invoker.filename)) {
filename = invoker.filename
}
cluster_size = "64k"
if (defined(invoker.cluster_size)) {
cluster_size = invoker.cluster_size
}
raw_disk_target = "gen_${target_name}_raw_image"
qcow_disk_target = "gen_${target_name}_qcow_image"
# Generate a flat/sparse image. Despite being potentially large files these will not take up much
# disk space (assuming the host platform and filesystem can properly support sparse files).
#
# We do this as a first step to generate the layout of the disk image, which will then be passed
# to `qemu-img convert` to create a qcow image.
action(raw_disk_target) {
script = "//src/virtualization/lib/qcow/scripts/gen-sparse-image.py"
output = "${target_gen_dir}/${filename}.raw"
args = [
"--file",
rebase_path(output, root_build_dir),
"--size",
invoker.disk_size,
]
if (defined(invoker.writes)) {
foreach(write, invoker.writes) {
args += [
"--write",
write,
]
}
}
outputs = [ output ]
}
# Pass the flat image file through qemu-img to convert it into a qcow image file.
action(qcow_disk_target) {
script = "//prebuilt/third_party/qemu/${host_os}-${host_cpu}/bin/qemu-img"
deps = [ ":${raw_disk_target}" ]
raw_disk_outputs = get_target_outputs(":${raw_disk_target}")
inputs = raw_disk_outputs
args = [
"convert",
# Quiet
"-q",
# Input format
"-f",
"raw",
# Output format
"-O",
"qcow2",
# qcow options
"-o",
"cluster_size=${cluster_size}",
# Input file
rebase_path(raw_disk_outputs[0], root_build_dir),
# Output file
rebase_path("${target_gen_dir}/${filename}", root_build_dir),
]
outputs = [ "$target_gen_dir/$filename" ]
}
# Expose the generated file as a resource so that it can be easily included into a test package.
resource(target_name) {
deps = [ ":${qcow_disk_target}" ]
sources = get_target_outputs(":${qcow_disk_target}")
outputs = [ "data/{{source_file_part}}" ]
}
}