m/test/launch: build image at runtime

Test launch now builds the node disk image from the OCI image, instead
of creating a qcow2 snapshot of the pre-built disk image. This speeds up
tests and test cluster launch.

The OCI image is uncompressed and payloads are not verified, which
enables the previously implemented copy_file_range optimization. If the
host file system supports reflinks, this has a similar effect as the
qcow2 snapshot had previously: Building the image is very fast as the
rootfs data is not copied on disk. On my machine, it takes 30 ms.

The build before launching a cluster is now faster: The MkImage step
taking 6 s is replaced by MkOCI taking 1 s. The majority of this time is
spent by Bazel computing hashes of files. For MkImage, the generated
file was a 5 GB disk image consisting mostly of zeroes, which took a
long time to hash.

Additionally, the qcow2 layer added some overhead, which is now gone.
The HA e2e test previously took 103 s on my machine, now it takes 80 s.

Change-Id: I0ce5059626cc682061c26ac3c8d11b752e641c60
Reviewed-on: https://review.monogon.dev/c/monogon/+/4294
Tested-by: Jenkins CI
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
diff --git a/osbase/oci/osimage/osimage.go b/osbase/oci/osimage/osimage.go
index 30a88ae..ac9721a 100644
--- a/osbase/oci/osimage/osimage.go
+++ b/osbase/oci/osimage/osimage.go
@@ -100,6 +100,21 @@
 	return nil, fmt.Errorf("payload %q not found", name)
 }
 
+// PayloadUnverified returns the contents of the payload of the given name.
+// Data is not verified against hashes. This only works for uncompressed images.
+func (i *Image) PayloadUnverified(name string) (structfs.Blob, error) {
+	for pi, info := range i.Config.Payloads {
+		if info.Name == name {
+			layer := &i.image.Manifest.Layers[pi]
+			if layer.MediaType != MediaTypePayloadUncompressed {
+				return nil, fmt.Errorf("unsupported media type %q for unverified payload", layer.MediaType)
+			}
+			return i.image.StructfsBlob(layer), nil
+		}
+	}
+	return nil, fmt.Errorf("payload %q not found", name)
+}
+
 type payloadBlob struct {
 	raw       structfs.Blob
 	mediaType string