cloud/agent: use new OS image format for install
This switches the Agent installation method to the new OS image format
based on OCI artifacts. OS images are now fetched from an OCI registry.
Change-Id: Icd59a2c808fd607b95d8aaa8e60022a27fd2d091
Reviewed-on: https://review.monogon.dev/c/monogon/+/4091
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/cloud/agent/e2e/BUILD.bazel b/cloud/agent/e2e/BUILD.bazel
index c859c2b..7df7ad6 100644
--- a/cloud/agent/e2e/BUILD.bazel
+++ b/cloud/agent/e2e/BUILD.bazel
@@ -5,13 +5,13 @@
srcs = ["main_test.go"],
data = [
"//cloud/agent/takeover:initramfs",
- "//metropolis/installer/test/testos:testos_bundle",
+ "//metropolis/installer/test/testos:testos_image",
"//third_party/edk2:OVMF_CODE.fd",
"//third_party/edk2:OVMF_VARS.fd",
"//third_party/linux",
],
x_defs = {
- "xBundleFilePath": "$(rlocationpath //metropolis/installer/test/testos:testos_bundle )",
+ "xImagePath": "$(rlocationpath //metropolis/installer/test/testos:testos_image )",
"xOvmfVarsPath": "$(rlocationpath //third_party/edk2:OVMF_VARS.fd )",
"xOvmfCodePath": "$(rlocationpath //third_party/edk2:OVMF_CODE.fd )",
"xKernelPath": "$(rlocationpath //third_party/linux )",
@@ -21,6 +21,8 @@
"//cloud/agent/api",
"//cloud/bmaas/server/api",
"//metropolis/proto/api",
+ "//osbase/oci",
+ "//osbase/oci/registry",
"//osbase/pki",
"@com_github_cavaliergopher_cpio//:cpio",
"@com_github_klauspost_compress//zstd",
diff --git a/cloud/agent/e2e/main_test.go b/cloud/agent/e2e/main_test.go
index bcc38f3..8dbce49 100644
--- a/cloud/agent/e2e/main_test.go
+++ b/cloud/agent/e2e/main_test.go
@@ -16,7 +16,6 @@
"math/big"
"net"
"net/http"
- "net/url"
"os"
"os/exec"
"strings"
@@ -34,6 +33,8 @@
apb "source.monogon.dev/cloud/agent/api"
bpb "source.monogon.dev/cloud/bmaas/server/api"
mpb "source.monogon.dev/metropolis/proto/api"
+ "source.monogon.dev/osbase/oci"
+ "source.monogon.dev/osbase/oci/registry"
"source.monogon.dev/osbase/pki"
)
@@ -41,7 +42,7 @@
// These are filled by bazel at linking time with the canonical path of
// their corresponding file. Inside the init function we resolve it
// with the rules_go runfiles package to the real path.
- xBundleFilePath string
+ xImagePath string
xOvmfVarsPath string
xOvmfCodePath string
xKernelPath string
@@ -51,7 +52,7 @@
func init() {
var err error
for _, path := range []*string{
- &xBundleFilePath, &xOvmfVarsPath, &xOvmfCodePath,
+ &xImagePath, &xOvmfVarsPath, &xOvmfCodePath,
&xKernelPath, &xInitramfsOrigPath,
} {
*path, err = runfiles.Rlocation(*path)
@@ -95,15 +96,26 @@
Port: 3000,
}
- blobAddr := net.TCPAddr{
+ registryAddr := net.TCPAddr{
IP: net.IPv4(10, 42, 0, 6),
Port: 80,
}
+ image, err := oci.ReadLayout(xImagePath)
+ if err != nil {
+ t.Fatal(err)
+ }
+
f.installationRequest = &bpb.OSInstallationRequest{
Generation: 5,
Type: &bpb.OSInstallationRequest_Metropolis{Metropolis: &bpb.MetropolisInstallationRequest{
- BundleUrl: (&url.URL{Scheme: "http", Host: blobAddr.String(), Path: "/bundle.bin"}).String(),
+ OsImage: &mpb.OSImageRef{
+ Scheme: "http",
+ Host: registryAddr.String(),
+ Repository: "testos",
+ Tag: "latest",
+ Digest: image.ManifestDigest,
+ },
NodeParameters: &mpb.NodeParameters{},
RootDevice: "vda",
}},
@@ -165,18 +177,16 @@
go s.Serve(grpcLis)
grpcListenAddr := grpcLis.Addr().(*net.TCPAddr)
- m := http.NewServeMux()
+ registryServer := registry.NewServer()
+ registryServer.AddImage("testos", "latest", image)
- m.HandleFunc("/bundle.bin", func(w http.ResponseWriter, req *http.Request) {
- http.ServeFile(w, req, xBundleFilePath)
- })
- blobLis, err := net.Listen("tcp", "127.0.0.1:0")
+ registryLis, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
- blobListenAddr := blobLis.Addr().(*net.TCPAddr)
- go http.Serve(blobLis, m)
+ registryListenAddr := registryLis.Addr().(*net.TCPAddr)
+ go http.Serve(registryLis, registryServer)
_, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
@@ -237,7 +247,7 @@
compressedW.Close()
grpcGuestFwd := fmt.Sprintf("guestfwd=tcp:%s-tcp:127.0.0.1:%d", grpcAddr.String(), grpcListenAddr.Port)
- blobGuestFwd := fmt.Sprintf("guestfwd=tcp:%s-tcp:127.0.0.1:%d", blobAddr.String(), blobListenAddr.Port)
+ registryGuestFwd := fmt.Sprintf("guestfwd=tcp:%s-tcp:127.0.0.1:%d", registryAddr.String(), registryListenAddr.Port)
ovmfVars, err := os.CreateTemp("", "agent-ovmf-vars")
if err != nil {
@@ -257,7 +267,7 @@
"-drive", "if=pflash,format=raw,readonly=on,file=" + xOvmfCodePath,
"-drive", "if=pflash,format=raw,file=" + ovmfVars.Name(),
"-drive", "if=virtio,format=raw,cache=unsafe,file=" + rootDisk.Name(),
- "-netdev", fmt.Sprintf("user,id=net0,net=10.42.0.0/24,dhcpstart=10.42.0.10,%s,%s", grpcGuestFwd, blobGuestFwd),
+ "-netdev", fmt.Sprintf("user,id=net0,net=10.42.0.0/24,dhcpstart=10.42.0.10,%s,%s", grpcGuestFwd, registryGuestFwd),
"-device", "virtio-net-pci,netdev=net0,mac=22:d5:8e:76:1d:07",
"-device", "virtio-rng-pci",
"-serial", "stdio",