Add nanoswitch and cluster testing

Adds nanoswitch and the `switched-multi2` launch target to launch two Smalltown instances on a switched
network and enroll them into a single cluster. Nanoswitch contains a Linux bridge and a minimal DHCP server
and connects to the two Smalltown instances over virtual Ethernet cables. Also moves out the DHCP client into
a package since nanoswitch needs it.

Test Plan:
Manually tested using `bazel run //:launch -- switched-multi2` and observing that the second VM
(whose serial port is mapped to stdout) prints that it is enrolled. Also validated by `bazel run //core/cmd/dbg -- kubectl get node -o wide` returning two ready nodes.

X-Origin-Diff: phab/D572
GitOrigin-RevId: 9f6e2b3d8268749dd81588205646ae3976ad14b3
diff --git a/core/cmd/launch/main.go b/core/cmd/launch/main.go
index 100d350..ff5c4d5 100644
--- a/core/cmd/launch/main.go
+++ b/core/cmd/launch/main.go
@@ -18,7 +18,7 @@
 
 import (
 	"context"
-	"fmt"
+	"log"
 	"os"
 	"os/signal"
 	"syscall"
@@ -38,6 +38,6 @@
 		if err == ctx.Err() {
 			return
 		}
-		fmt.Printf("Failed to execute: %v\n", err)
+		log.Fatalf("Failed to execute: %v\n", err)
 	}
 }