metropolis/test: use localregistry

This removes everything but the preseed test image from the preseed
image pool, instead opting to serve all test image via localregistry.

The registry API is served from a dedicated IP inside the virtual
network and forwarded to an ephemeral listener on the host. The relevant
infrastructure is added to the launch package.

As it is required to add configuration to containerd for this registry
anyways as it does not and should not have TLS we take that opportunity
to give it a descriptive name (test.monogon.internal).

Visibilities of images are also adjusted as they are now referenced much
closer to their point of use.

Against main this saves 51MiB in bundle size (289MiB -> 238MiB).

Change-Id: I31f732eb8c4ccec486204f35e3635b588fd9c85b
Reviewed-on: https://review.monogon.dev/c/monogon/+/1927
Tested-by: Jenkins CI
Reviewed-by: Leopold Schabel <leo@monogon.tech>
diff --git a/metropolis/test/launch/launch.go b/metropolis/test/launch/launch.go
index cd51549..a048cef 100644
--- a/metropolis/test/launch/launch.go
+++ b/metropolis/test/launch/launch.go
@@ -114,6 +114,21 @@
 	return portMap, nil
 }
 
+// GuestServiceMap maps an IP/port combination inside the virtual guest network
+// to a TCPAddr reachable by the host. If the guest connects to the virtual
+// address/port, this connection gets forwarded to the host.
+type GuestServiceMap map[*net.TCPAddr]net.TCPAddr
+
+// ToQemuForwards generates QEMU guestfwd values (https://qemu.weilnetz.de/doc/qemu-
+// doc.html#:~:text=guestfwd=) for all mapped addresses.
+func (p GuestServiceMap) ToQemuForwards() []string {
+	var guestfwdOptions []string
+	for guestAddr, hostAddr := range p {
+		guestfwdOptions = append(guestfwdOptions, fmt.Sprintf("tcp:%s-tcp:%s", guestAddr.String(), hostAddr.String()))
+	}
+	return guestfwdOptions
+}
+
 // NewSocketPair creates a new socket pair. By connecting both ends to different
 // instances you can connect them with a virtual "network cable". The ends can be
 // passed into the ConnectToSocket option.
@@ -165,6 +180,10 @@
 	// network interface.
 	PortMap PortMap
 
+	// GuestServiceMap contains TCP services made available in the guest virtual
+	// network which are running on the host.
+	GuestServiceMap GuestServiceMap
+
 	// DisableHostNetworkInterface disables the SLIRP-backed host network interface
 	// that is normally the first network interface. If this is set PortMap is ignored.
 	// Mostly useful for speeding up QEMU's startup time for tests.
@@ -257,6 +276,9 @@
 		if opts.PortMap != nil {
 			qemuNetConfig["hostfwd"] = opts.PortMap.ToQemuForwards()
 		}
+		if opts.GuestServiceMap != nil {
+			qemuNetConfig["guestfwd"] = opts.GuestServiceMap.ToQemuForwards()
+		}
 
 		baseArgs = append(baseArgs, "-netdev", qemuNetConfig.ToOption(qemuNetType),
 			"-device", "virtio-net-device,netdev=usernet0,mac="+HostInterfaceMAC.String())