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/e2e/BUILD.bazel b/metropolis/test/e2e/BUILD.bazel
index 25a6c88..b3b2625 100644
--- a/metropolis/test/e2e/BUILD.bazel
+++ b/metropolis/test/e2e/BUILD.bazel
@@ -1,4 +1,5 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+load("//metropolis/pkg/localregistry:def.bzl", "localregistry_manifest")
 
 go_library(
     name = "e2e",
@@ -16,11 +17,20 @@
     ],
 )
 
+localregistry_manifest(
+    name = "testimages_manifest",
+    images = [
+        "//metropolis/test/e2e/selftest:selftest_image",
+        "//metropolis/vm/smoketest:smoketest_container",
+    ],
+)
+
 go_test(
     name = "e2e_test",
     size = "large",
     srcs = ["main_test.go"],
     data = [
+        ":testimages_manifest",
         "//metropolis/node:image",
         "//metropolis/node:swtpm_data",
         "//third_party/edk2:firmware",
@@ -28,9 +38,11 @@
     embed = [":e2e"],
     rundir = ".",
     deps = [
+        "//metropolis/cli/pkg/datafile",
         "//metropolis/node",
         "//metropolis/node/core/identity",
         "//metropolis/node/core/rpc",
+        "//metropolis/pkg/localregistry",
         "//metropolis/proto/api",
         "//metropolis/test/launch",
         "//metropolis/test/launch/cluster",
diff --git a/metropolis/test/e2e/kubernetes_helpers.go b/metropolis/test/e2e/kubernetes_helpers.go
index cba4ca7..ce9e78f 100644
--- a/metropolis/test/e2e/kubernetes_helpers.go
+++ b/metropolis/test/e2e/kubernetes_helpers.go
@@ -86,8 +86,8 @@
 					Containers: []corev1.Container{
 						{
 							Name:            "test",
-							ImagePullPolicy: corev1.PullNever,
-							Image:           "bazel/metropolis/test/e2e/selftest:selftest_image",
+							ImagePullPolicy: corev1.PullIfNotPresent,
+							Image:           "test.monogon.internal/metropolis/test/e2e/selftest/selftest_image",
 						},
 					},
 					RestartPolicy: corev1.RestartPolicyOnFailure,
diff --git a/metropolis/test/e2e/main_test.go b/metropolis/test/e2e/main_test.go
index a2c9eaf..812ae9d 100644
--- a/metropolis/test/e2e/main_test.go
+++ b/metropolis/test/e2e/main_test.go
@@ -39,9 +39,11 @@
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	podv1 "k8s.io/kubernetes/pkg/api/v1/pod"
 
+	"source.monogon.dev/metropolis/cli/pkg/datafile"
 	common "source.monogon.dev/metropolis/node"
 	"source.monogon.dev/metropolis/node/core/identity"
 	"source.monogon.dev/metropolis/node/core/rpc"
+	"source.monogon.dev/metropolis/pkg/localregistry"
 	apb "source.monogon.dev/metropolis/proto/api"
 	"source.monogon.dev/metropolis/test/launch"
 	"source.monogon.dev/metropolis/test/launch/cluster"
@@ -69,9 +71,15 @@
 	ctx, cancel := context.WithTimeout(context.Background(), globalTestTimeout)
 	defer cancel()
 
+	lr, err := localregistry.FromBazelManifest(datafile.MustGet("metropolis/test/e2e/testimages_manifest.prototxt"))
+	if err != nil {
+		t.Fatalf("Creating test image registry failed: %v", err)
+	}
+
 	// Launch cluster.
 	clusterOptions := cluster.ClusterOptions{
-		NumNodes: 2,
+		NumNodes:      2,
+		LocalRegistry: lr,
 	}
 	cluster, err := cluster.LaunchCluster(ctx, clusterOptions)
 	if err != nil {
@@ -182,9 +190,15 @@
 	ctx, cancel := context.WithTimeout(context.Background(), globalTestTimeout)
 	defer cancel()
 
+	lr, err := localregistry.FromBazelManifest(datafile.MustGet("metropolis/test/e2e/testimages_manifest.prototxt"))
+	if err != nil {
+		t.Fatalf("Creating test image registry failed: %v", err)
+	}
+
 	// Launch cluster.
 	clusterOptions := cluster.ClusterOptions{
-		NumNodes: 2,
+		NumNodes:      2,
+		LocalRegistry: lr,
 	}
 	cluster, err := cluster.LaunchCluster(ctx, clusterOptions)
 	if err != nil {
@@ -374,7 +388,7 @@
 					Containers: []corev1.Container{{
 						Name:            "vm-smoketest",
 						ImagePullPolicy: corev1.PullNever,
-						Image:           "bazel/metropolis/vm/smoketest:smoketest_container",
+						Image:           "test.monogon.internal/metropolis/vm/smoketest:smoketest_container",
 						Resources: corev1.ResourceRequirements{
 							Limits: corev1.ResourceList{
 								"devices.monogon.dev/kvm": *resource.NewQuantity(1, ""),
diff --git a/metropolis/test/e2e/selftest/BUILD.bazel b/metropolis/test/e2e/selftest/BUILD.bazel
index 2aa8029..7560790 100644
--- a/metropolis/test/e2e/selftest/BUILD.bazel
+++ b/metropolis/test/e2e/selftest/BUILD.bazel
@@ -12,5 +12,5 @@
     name = "selftest_image",
     embed = [":selftest"],
     pure = "on",
-    visibility = ["//metropolis/node:__pkg__"],
+    visibility = ["//metropolis/test/e2e:__pkg__"],
 )