metropolis: implement and use A/B preloader

This switches over from using the EFI built-in bootloader for A/B
updates to using our own EFI preloader due to significant issues with
in-the-wild EFI implementations.  It is a very minimal design relying
on a single Protobuf state file instead of EFI variables.

Change-Id: Ieebd0a8172ebe3f44c69b3e8c278c53d3fe2eeb4
Reviewed-on: https://review.monogon.dev/c/monogon/+/2203
Tested-by: Jenkins CI
Reviewed-by: Serge Bazanski <serge@monogon.tech>
diff --git a/cloud/agent/install.go b/cloud/agent/install.go
index c8583ac..f209ce3 100644
--- a/cloud/agent/install.go
+++ b/cloud/agent/install.go
@@ -3,6 +3,7 @@
 import (
 	"archive/zip"
 	"bytes"
+	_ "embed"
 	"errors"
 	"fmt"
 	"io/fs"
@@ -20,6 +21,9 @@
 	npb "source.monogon.dev/net/proto"
 )
 
+//go:embed metropolis/node/core/abloader/abloader_bin.efi
+var abloader []byte
+
 // FileSizedReader is a small adapter from fs.File to fs.SizedReader
 // Panics on Stat() failure, so should only be used with sources where Stat()
 // cannot fail.
@@ -134,6 +138,7 @@
 		},
 		SystemImage:    systemImage,
 		EFIPayload:     FileSizedReader{efiPayload},
+		ABLoader:       bytes.NewReader(abloader),
 		NodeParameters: bytes.NewReader(nodeParamsRaw),
 		Output:         rootDev,
 	}