m/n/build: implement verity_image rule
verity_image provides a dm-verity target image together with its
mapping table.
Change-Id: I3a16dbae0c25130fdec16aec136792b7236c30e2
Reviewed-on: https://review.monogon.dev/c/monogon/+/526
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/build/def.bzl b/metropolis/node/build/def.bzl
index d28280b..72e548b 100644
--- a/metropolis/node/build/def.bzl
+++ b/metropolis/node/build/def.bzl
@@ -377,3 +377,76 @@
),
},
)
+
+# VerityConfig is emitted by verity_image, and contains a file enclosing a
+# singular dm-verity target table.
+VerityConfig = provider(
+ "Configuration necessary to mount a single dm-verity target.",
+ fields = {
+ "table": "A file containing the dm-verity target table. See: https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",
+ },
+)
+
+def _verity_image_impl(ctx):
+ """
+ Create a new file containing the source image data together with the Verity
+ metadata appended to it, and provide an associated DeviceMapper Verity target
+ table in a separate file, through VerityConfig provider.
+ """
+
+ # Run mkverity.
+ image = ctx.actions.declare_file(ctx.attr.name + ".img")
+ table = ctx.actions.declare_file(ctx.attr.name + ".dmt")
+ ctx.actions.run(
+ mnemonic = "GenVerityImage",
+ progress_message = "Generating a dm-verity image",
+ inputs = [ctx.file.source],
+ outputs = [
+ image,
+ table,
+ ],
+ executable = ctx.file._mkverity,
+ arguments = [
+ "-input=" + ctx.file.source.path,
+ "-output=" + image.path,
+ "-table=" + table.path,
+ "-data_alias=" + ctx.attr.rootfs_partlabel,
+ "-hash_alias=" + ctx.attr.rootfs_partlabel,
+ ]
+ )
+
+ return [
+ DefaultInfo(
+ files=depset([image]),
+ runfiles=ctx.runfiles(files=[image])
+ ),
+ VerityConfig(
+ table = table
+ )
+ ]
+
+verity_image = rule(
+ implementation = _verity_image_impl,
+ doc = """
+ Build a dm-verity target image by appending Verity metadata to the source
+ image. A corresponding dm-verity target table will be made available
+ through VerityConfig provider.
+ """,
+ attrs = {
+ "source": attr.label(
+ doc = "A source image.",
+ allow_single_file = True,
+ ),
+ "rootfs_partlabel": attr.string(
+ doc = "GPT partition label of the rootfs to be used with dm-mod.create.",
+ default = "PARTLABEL=METROPOLIS-SYSTEM",
+ ),
+ "_mkverity": attr.label(
+ doc = "The mkverity executable needed to generate the image.",
+ default = "//metropolis/node/build/mkverity",
+ allow_single_file = True,
+ executable = True,
+ cfg = "host",
+ ),
+ },
+)