*: reflow comments to 80 characters

This reformats the entire Metropolis codebase to have comments no longer
than 80 characters, implementing CR/66.

This has been done half manually, as we don't have a good integration
between commentwrap/Bazel, but that can be implemented if we decide to
go for this tool/limit.

Change-Id: If1fff0b093ef806f5dc00551c11506e8290379d0
diff --git a/metropolis/test/e2e/k8s_cts/main.go b/metropolis/test/e2e/k8s_cts/main.go
index e419b2f..026ca8a 100644
--- a/metropolis/test/e2e/k8s_cts/main.go
+++ b/metropolis/test/e2e/k8s_cts/main.go
@@ -14,8 +14,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// This package launches a Metropolis cluster with two nodes and spawns in the CTS container. Then it streams its output
-// to the console. When the CTS has finished it exits with the appropriate error code.
+// This package launches a Metropolis cluster with two nodes and spawns in the
+// CTS container. Then it streams its output to the console. When the CTS has
+// finished it exits with the appropriate error code.
 package main
 
 import (
@@ -37,18 +38,22 @@
 	"source.monogon.dev/metropolis/test/launch"
 )
 
-// makeCTSPodSpec generates a spec for a standalone pod running the Kubernetes CTS. It also sets the test configuration
-// for the Kubernetes E2E test suite to only run CTS tests and excludes known-broken ones.
+// makeCTSPodSpec generates a spec for a standalone pod running the Kubernetes
+// CTS. It also sets the test configuration for the Kubernetes E2E test suite
+// to only run CTS tests and excludes known-broken ones.
 func makeCTSPodSpec(name string, saName string) *corev1.Pod {
 	skipRegexes := []string{
-		// hostNetworking cannot be supported since we run different network stacks for the host and containers
+		// hostNetworking cannot be supported since we run different network
+		// stacks for the host and containers
 		"should function for node-pod communication",
-		// gVisor misreports statfs() syscalls: https://github.com/google/gvisor/issues/3339
+		// gVisor misreports statfs() syscalls:
+		//   https://github.com/google/gvisor/issues/3339
 		`should support \((non-)?root,`,
 		"volume on tmpfs should have the correct mode",
 		"volume on default medium should have the correct mode",
-		// gVisor doesn't support the full Linux privilege machinery including SUID and NewPrivs
-		// https://github.com/google/gvisor/issues/189#issuecomment-481064000
+		// gVisor doesn't support the full Linux privilege machinery including
+		// SUID and NewPrivs:
+		//   https://github.com/google/gvisor/issues/189#issuecomment-481064000
 		"should run the container as unprivileged when false",
 	}
 	return &corev1.Pod{
@@ -73,10 +78,12 @@
 					ImagePullPolicy: corev1.PullNever,
 				},
 			},
-			Tolerations: []corev1.Toleration{{ // Tolerate all taints, otherwise the CTS likes to self-evict
+			// Tolerate all taints, otherwise the CTS likes to self-evict.
+			Tolerations: []corev1.Toleration{{
 				Operator: "Exists",
 			}},
-			PriorityClassName:  "system-cluster-critical", // Don't evict the CTS pod
+			// Don't evict the CTS pod.
+			PriorityClassName:  "system-cluster-critical",
 			RestartPolicy:      corev1.RestartPolicyNever,
 			ServiceAccountName: saName,
 		},
@@ -145,7 +152,8 @@
 	}
 	var logs io.ReadCloser
 	go func() {
-		// This loops the whole .Stream()/io.Copy process because the API sometimes returns streams that immediately return EOF
+		// This loops the whole .Stream()/io.Copy process because the API
+		// sometimes returns streams that immediately return EOF
 		for {
 			logs, err = clientSet.CoreV1().Pods("default").GetLogs(podName, &corev1.PodLogOptions{Follow: true}).Stream(ctx)
 			if err == nil {
diff --git a/metropolis/test/e2e/kubernetes_helpers.go b/metropolis/test/e2e/kubernetes_helpers.go
index 71e8c3a..3c1f95a 100644
--- a/metropolis/test/e2e/kubernetes_helpers.go
+++ b/metropolis/test/e2e/kubernetes_helpers.go
@@ -33,8 +33,9 @@
 	apb "source.monogon.dev/metropolis/proto/api"
 )
 
-// GetKubeClientSet gets a Kubeconfig from the debug API and creates a K8s ClientSet using it. The identity used has
-// the system:masters group and thus has RBAC access to everything.
+// GetKubeClientSet gets a Kubeconfig from the debug API and creates a K8s
+// ClientSet using it. The identity used has the system:masters group and thus
+// has RBAC access to everything.
 func GetKubeClientSet(ctx context.Context, client apb.NodeDebugServiceClient, port uint16) (kubernetes.Interface, error) {
 	var lastErr = errors.New("context canceled before any operation completed")
 	for {
@@ -67,9 +68,11 @@
 	}
 }
 
-// makeTestDeploymentSpec generates a Deployment spec for a single pod running NGINX with a readiness probe. This allows
-// verifying that the control plane is capable of scheduling simple pods and that kubelet works, its runtime is set up
-// well enough to run a simple container and the network to the pod can pass readiness probe traffic.
+// makeTestDeploymentSpec generates a Deployment spec for a single pod running
+// NGINX with a readiness probe. This allows verifying that the control plane
+// is capable of scheduling simple pods and that kubelet works, its runtime is
+// set up well enough to run a simple container and the network to the pod can
+// pass readiness probe traffic.
 func makeTestDeploymentSpec(name string) *appsv1.Deployment {
 	return &appsv1.Deployment{
 		ObjectMeta: metav1.ObjectMeta{Name: name},
diff --git a/metropolis/test/e2e/main_test.go b/metropolis/test/e2e/main_test.go
index 0463fc4..6d9b1db 100644
--- a/metropolis/test/e2e/main_test.go
+++ b/metropolis/test/e2e/main_test.go
@@ -44,8 +44,8 @@
 const (
 	// Timeout for the global test context.
 	//
-	// Bazel would eventually time out the test after 900s ("large") if, for some reason,
-	// the context cancellation fails to abort it.
+	// Bazel would eventually time out the test after 900s ("large") if, for
+	// some reason, the context cancellation fails to abort it.
 	globalTestTimeout = 600 * time.Second
 
 	// Timeouts for individual end-to-end tests of different sizes.
@@ -53,8 +53,10 @@
 	largeTestTimeout = 120 * time.Second
 )
 
-// TestE2E is the main E2E test entrypoint for single-node freshly-bootstrapped E2E tests. It starts a full Metropolis node
-// in bootstrap mode and then runs tests against it. The actual tests it performs are located in the RunGroup subtest.
+// TestE2E is the main E2E test entrypoint for single-node freshly-bootstrapped
+// E2E tests. It starts a full Metropolis node in bootstrap mode and then runs
+// tests against it. The actual tests it performs are located in the RunGroup
+// subtest.
 func TestE2E(t *testing.T) {
 	// Run pprof server for debugging
 	go func() {
@@ -102,8 +104,9 @@
 	}
 	debugClient := apb.NewNodeDebugServiceClient(grpcClient)
 
-	// This exists to keep the parent around while all the children race
-	// It currently tests both a set of OS-level conditions and Kubernetes Deployments and StatefulSets
+	// This exists to keep the parent around while all the children race.
+	// It currently tests both a set of OS-level conditions and Kubernetes
+	// Deployments and StatefulSets
 	t.Run("RunGroup", func(t *testing.T) {
 		t.Run("Get Kubernetes Debug Kubeconfig", func(t *testing.T) {
 			t.Parallel()
diff --git a/metropolis/test/e2e/utils.go b/metropolis/test/e2e/utils.go
index f888189..dcc9eac 100644
--- a/metropolis/test/e2e/utils.go
+++ b/metropolis/test/e2e/utils.go
@@ -23,8 +23,9 @@
 	"time"
 )
 
-// testEventual creates a new subtest looping the given function until it either doesn't return an error anymore or
-// the timeout is exceeded. The last returned non-context-related error is being used as the test error.
+// testEventual creates a new subtest looping the given function until it
+// either doesn't return an error anymore or the timeout is exceeded. The last
+// returned non-context-related error is being used as the test error.
 func testEventual(t *testing.T, name string, ctx context.Context, timeout time.Duration, f func(context.Context) error) {
 	ctx, cancel := context.WithTimeout(ctx, timeout)
 	t.Helper()
diff --git a/metropolis/test/ktest/init/main.go b/metropolis/test/ktest/init/main.go
index 0236531..5523432 100644
--- a/metropolis/test/ktest/init/main.go
+++ b/metropolis/test/ktest/init/main.go
@@ -14,10 +14,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// ktestinit is an init designed to run inside a lightweight VM for running tests in there.
-// It performs basic platform initialization like mounting kernel filesystems and launches the
-// test executable at /tester, passes the exit code back out over the control socket to ktest and
-// then terminates the VM kernel.
+// ktestinit is an init designed to run inside a lightweight VM for running
+// tests in there.  It performs basic platform initialization like mounting
+// kernel filesystems and launches the test executable at /tester, passes the
+// exit code back out over the control socket to ktest and then terminates the
+// default VM kernel.
 package main
 
 import (
diff --git a/metropolis/test/ktest/main.go b/metropolis/test/ktest/main.go
index 17a9f71..f082671 100644
--- a/metropolis/test/ktest/main.go
+++ b/metropolis/test/ktest/main.go
@@ -14,8 +14,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// ktest is a test launcher for running tests inside a custom kernel and passes the results
-// back out.
+// ktest is a test launcher for running tests inside a custom kernel and passes
+// the results back out.
 package main
 
 import (
diff --git a/metropolis/test/launch/launch.go b/metropolis/test/launch/launch.go
index df36685..f440adb 100644
--- a/metropolis/test/launch/launch.go
+++ b/metropolis/test/launch/launch.go
@@ -46,8 +46,8 @@
 
 type qemuValue map[string][]string
 
-// toOption encodes structured data into a QEMU option.
-// Example: "test", {"key1": {"val1"}, "key2": {"val2", "val3"}} returns "test,key1=val1,key2=val2,key2=val3"
+// toOption encodes structured data into a QEMU option. Example: "test", {"key1":
+// {"val1"}, "key2": {"val2", "val3"}} returns "test,key1=val1,key2=val2,key2=val3"
 func (value qemuValue) toOption(name string) string {
 	var optionValues []string
 	if name != "" {
@@ -84,11 +84,12 @@
 	return out.Close()
 }
 
-// PortMap represents where VM ports are mapped to on the host. It maps from the VM port number to the host port number.
+// PortMap represents where VM ports are mapped to on the host. It maps from the VM
+// port number to the host port number.
 type PortMap map[uint16]uint16
 
-// toQemuForwards generates QEMU hostfwd values (https://qemu.weilnetz.de/doc/qemu-doc.html#:~:text=hostfwd=) for all
-// mapped ports.
+// toQemuForwards generates QEMU hostfwd values (https://qemu.weilnetz.de/doc/qemu-
+// doc.html#:~:text=hostfwd=) for all mapped ports.
 func (p PortMap) toQemuForwards() []string {
 	var hostfwdOptions []string
 	for vmPort, hostPort := range p {
@@ -97,8 +98,8 @@
 	return hostfwdOptions
 }
 
-// DialGRPC creates a gRPC client for a VM port that's forwarded/mapped to the host. The given port is automatically
-// resolved to the host-mapped port.
+// DialGRPC creates a gRPC client for a VM port that's forwarded/mapped to the
+// host. The given port is automatically resolved to the host-mapped port.
 func (p PortMap) DialGRPC(port uint16, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
 	mappedPort, ok := p[port]
 	if !ok {
@@ -113,24 +114,29 @@
 
 // Options contains all options that can be passed to Launch()
 type Options struct {
-	// Ports contains the port mapping where to expose the internal ports of the VM to the host. See IdentityPortMap()
-	// and ConflictFreePortMap(). Ignored when ConnectToSocket is set.
+	// Ports contains the port mapping where to expose the internal ports of the VM to
+	// the host. See IdentityPortMap() and ConflictFreePortMap(). Ignored when
+	// ConnectToSocket is set.
 	Ports PortMap
 
-	// If set to true, reboots are honored. Otherwise all reboots exit the Launch() command. Metropolis nodes
-	// generally restarts on almost all errors, so unless you want to test reboot behavior this should be false.
+	// If set to true, reboots are honored. Otherwise all reboots exit the Launch()
+	// command. Metropolis nodes generally restarts on almost all errors, so unless you
+	// want to test reboot behavior this should be false.
 	AllowReboot bool
 
-	// By default the VM is connected to the Host via SLIRP. If ConnectToSocket is set, it is instead connected
-	// to the given file descriptor/socket. If this is set, all port maps from the Ports option are ignored.
-	// Intended for networking this instance together with others for running  more complex network configurations.
+	// By default the VM is connected to the Host via SLIRP. If ConnectToSocket is set,
+	// it is instead connected to the given file descriptor/socket. If this is set, all
+	// port maps from the Ports option are ignored. Intended for networking this
+	// instance together with others for running  more complex network configurations.
 	ConnectToSocket *os.File
 
-	// SerialPort is a io.ReadWriter over which you can communicate with the serial port of the machine
-	// It can be set to an existing file descriptor (like os.Stdout/os.Stderr) or any Go structure implementing this interface.
+	// SerialPort is a io.ReadWriter over which you can communicate with the serial
+	// port of the machine It can be set to an existing file descriptor (like
+	// os.Stdout/os.Stderr) or any Go structure implementing this interface.
 	SerialPort io.ReadWriter
 
-	// NodeParameters is passed into the VM and subsequently used for bootstrapping or registering into a cluster.
+	// NodeParameters is passed into the VM and subsequently used for bootstrapping or
+	// registering into a cluster.
 	NodeParameters *apb.NodeParameters
 }
 
@@ -138,8 +144,9 @@
 var NodePorts = []uint16{node.ConsensusPort, node.NodeServicePort, node.MasterServicePort,
 	node.ExternalServicePort, node.DebugServicePort, node.KubernetesAPIPort, node.DebuggerPort}
 
-// IdentityPortMap returns a port map where each given port is mapped onto itself on the host. This is mainly useful
-// for development against Metropolis. The dbg command requires this mapping.
+// IdentityPortMap returns a port map where each given port is mapped onto itself
+// on the host. This is mainly useful for development against Metropolis. The dbg
+// command requires this mapping.
 func IdentityPortMap(ports []uint16) PortMap {
 	portMap := make(PortMap)
 	for _, port := range ports {
@@ -148,10 +155,11 @@
 	return portMap
 }
 
-// ConflictFreePortMap returns a port map where each given port is mapped onto a random free port on the host. This is
-// intended for automated testing where multiple instances of Metropolis nodes might be running. Please call this
-// function for each Launch command separately and as close to it as possible since it cannot guarantee that the ports
-// will remain free.
+// ConflictFreePortMap returns a port map where each given port is mapped onto a
+// random free port on the host. This is intended for automated testing where
+// multiple instances of Metropolis nodes might be running. Please call this
+// function for each Launch command separately and as close to it as possible since
+// it cannot guarantee that the ports will remain free.
 func ConflictFreePortMap(ports []uint16) (PortMap, error) {
 	portMap := make(PortMap)
 	for _, port := range ports {
@@ -159,7 +167,8 @@
 		if err != nil {
 			return portMap, fmt.Errorf("failed to get free host port: %w", err)
 		}
-		// Defer closing of the listening port until the function is done and all ports are allocated
+		// Defer closing of the listening port until the function is done and all ports are
+		// allocated
 		defer listenCloser.Close()
 		portMap[port] = mappedPort
 	}
@@ -181,21 +190,26 @@
 	return &mac, nil
 }
 
-// Launch launches a Metropolis node instance with the given options. The instance runs mostly paravirtualized but
-// with some emulated hardware similar to how a cloud provider might set up its VMs. The disk is fully writable but
-// is run in snapshot mode meaning that changes are not kept beyond a single invocation.
+// Launch launches a Metropolis node instance with the given options. The instance
+// runs mostly paravirtualized but with some emulated hardware similar to how a
+// cloud provider might set up its VMs. The disk is fully writable but is run in
+// snapshot mode meaning that changes are not kept beyond a single invocation.
 func Launch(ctx context.Context, options Options) error {
-	// Pin temp directory to /tmp until we can use abstract socket namespace in QEMU (next release after 5.0,
-	// https://github.com/qemu/qemu/commit/776b97d3605ed0fc94443048fdf988c7725e38a9). swtpm accepts already-open FDs
-	// so we can pass in an abstract socket namespace FD that we open and pass the name of it to QEMU. Not pinning this
-	// crashes both swtpm and qemu because we run into UNIX socket length limitations (for legacy reasons 108 chars).
+	// Pin temp directory to /tmp until we can use abstract socket namespace in QEMU
+	// (next release after 5.0,
+	// https://github.com/qemu/qemu/commit/776b97d3605ed0fc94443048fdf988c7725e38a9).
+	// swtpm accepts already-open FDs so we can pass in an abstract socket namespace FD
+	// that we open and pass the name of it to QEMU. Not pinning this crashes both
+	// swtpm and qemu because we run into UNIX socket length limitations (for legacy
+	// reasons 108 chars).
 	tempDir, err := ioutil.TempDir("/tmp", "launch*")
 	if err != nil {
 		return fmt.Errorf("failed to create temporary directory: %w", err)
 	}
 	defer os.RemoveAll(tempDir)
 
-	// Copy TPM state into a temporary directory since it's being modified by the emulator
+	// Copy TPM state into a temporary directory since it's being modified by the
+	// emulator
 	tpmTargetDir := filepath.Join(tempDir, "tpm")
 	tpmSrcDir := "metropolis/node/tpm"
 	if err := os.Mkdir(tpmTargetDir, 0755); err != nil {
@@ -315,8 +329,9 @@
 	return err
 }
 
-// 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.
+// 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.
 func NewSocketPair() (*os.File, *os.File, error) {
 	fds, err := unix.Socketpair(unix.AF_UNIX, syscall.SOCK_STREAM, 0)
 	if err != nil {
@@ -328,8 +343,8 @@
 	return fd1, fd2, nil
 }
 
-// HostInterfaceMAC is the MAC address the host SLIRP network interface has if it is not disabled (see
-// DisableHostNetworkInterface in MicroVMOptions)
+// HostInterfaceMAC is the MAC address the host SLIRP network interface has if it
+// is not disabled (see DisableHostNetworkInterface in MicroVMOptions)
 var HostInterfaceMAC = net.HardwareAddr{0x02, 0x72, 0x82, 0xbf, 0xc3, 0x56}
 
 // MicroVMOptions contains all options to start a MicroVM
@@ -343,39 +358,47 @@
 	// Cmdline contains additional kernel commandline options
 	Cmdline string
 
-	// SerialPort is a File(descriptor) over which you can communicate with the serial port of the machine
-	// It can be set to an existing file descriptor (like os.Stdout/os.Stderr) or you can use NewSocketPair() to get one
-	// end to talk to from Go.
+	// SerialPort is a File(descriptor) over which you can communicate with the serial
+	// port of the machine It can be set to an existing file descriptor (like
+	// os.Stdout/os.Stderr) or you can use NewSocketPair() to get one end to talk to
+	// from Go.
 	SerialPort *os.File
 
-	// ExtraChardevs can be used similar to SerialPort, but can contain an arbitrary number of additional serial ports
+	// ExtraChardevs can be used similar to SerialPort, but can contain an arbitrary
+	// number of additional serial ports
 	ExtraChardevs []*os.File
 
-	// ExtraNetworkInterfaces can contain an arbitrary number of file descriptors which are mapped into the VM as virtio
-	// network interfaces. The first interface is always a SLIRP-backed interface for communicating with the host.
+	// ExtraNetworkInterfaces can contain an arbitrary number of file descriptors which
+	// are mapped into the VM as virtio network interfaces. The first interface is
+	// always a SLIRP-backed interface for communicating with the host.
 	ExtraNetworkInterfaces []*os.File
 
-	// PortMap contains ports that are mapped to the host through the built-in SLIRP network interface.
+	// PortMap contains ports that are mapped to the host through the built-in SLIRP
+	// network interface.
 	PortMap PortMap
 
-	// 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.
+	// 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.
 	DisableHostNetworkInterface bool
 }
 
-// RunMicroVM launches a tiny VM mostly intended for testing. Very quick to boot (<40ms).
+// RunMicroVM launches a tiny VM mostly intended for testing. Very quick to boot
+// (<40ms).
 func RunMicroVM(ctx context.Context, opts *MicroVMOptions) error {
-	// Generate options for all the file descriptors we'll be passing as virtio "serial ports"
+	// Generate options for all the file descriptors we'll be passing as virtio "serial
+	// ports"
 	var extraArgs []string
 	for idx, _ := range opts.ExtraChardevs {
 		idxStr := strconv.Itoa(idx)
 		id := "extra" + idxStr
-		// That this works is pretty much a hack, but upstream QEMU doesn't have a bidirectional chardev backend not
-		// based around files/sockets on the disk which are a giant pain to work with.
-		// We're using QEMU's fdset functionality to make FDs available as pseudo-files and then "ab"using the pipe
-		// backend's fallback functionality to get a single bidirectional chardev backend backed by a passed-down
-		// RDWR fd.
-		// Ref https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg01256.html
+		// That this works is pretty much a hack, but upstream QEMU doesn't have a
+		// bidirectional chardev backend not based around files/sockets on the disk which
+		// are a giant pain to work with. We're using QEMU's fdset functionality to make
+		// FDs available as pseudo-files and then "ab"using the pipe backend's fallback
+		// functionality to get a single bidirectional chardev backend backed by a passed-
+		// down RDWR fd. Ref https://lists.gnu.org/archive/html/qemu-devel/2015-
+		// 12/msg01256.html
 		addFdConf := qemuValue{
 			"set": {idxStr},
 			"fd":  {strconv.Itoa(idx + 3)},
@@ -400,23 +423,29 @@
 		extraArgs = append(extraArgs, "-netdev", netdevConf.toOption("socket"), "-device", "virtio-net-device,netdev="+id)
 	}
 
-	// This sets up a minimum viable environment for our Linux kernel.
-	// It clears all standard QEMU configuration and sets up a MicroVM machine
-	// (https://github.com/qemu/qemu/blob/master/docs/microvm.rst) with all legacy emulation turned off. This means
-	// the only "hardware" the Linux kernel inside can communicate with is a single virtio-mmio region. Over that MMIO
-	// interface we run a paravirtualized RNG (since the kernel in there has nothing to gather that from and it
-	// delays booting), a single paravirtualized console and an arbitrary number of extra serial ports for talking to
-	// various things that might run inside. The kernel, initramfs and command line are mapped into VM memory at boot
-	// time and not loaded from any sort of disk. Booting and shutting off one of these VMs takes <100ms.
+	// This sets up a minimum viable environment for our Linux kernel. It clears all
+	// standard QEMU configuration and sets up a MicroVM machine
+	// (https://github.com/qemu/qemu/blob/master/docs/microvm.rst) with all legacy
+	// emulation turned off. This means the only "hardware" the Linux kernel inside can
+	// communicate with is a single virtio-mmio region. Over that MMIO interface we run
+	// a paravirtualized RNG (since the kernel in there has nothing to gather that from
+	// and it delays booting), a single paravirtualized console and an arbitrary number
+	// of extra serial ports for talking to various things that might run inside. The
+	// kernel, initramfs and command line are mapped into VM memory at boot time and
+	// not loaded from any sort of disk. Booting and shutting off one of these VMs
+	// takes <100ms.
 	baseArgs := []string{"-nodefaults", "-no-user-config", "-nographic", "-no-reboot",
 		"-accel", "kvm", "-cpu", "host",
-		// Needed until QEMU updates their bundled qboot version (needs https://github.com/bonzini/qboot/pull/28)
+		// Needed until QEMU updates their bundled qboot version (needs
+		// https://github.com/bonzini/qboot/pull/28)
 		"-bios", "external/com_github_bonzini_qboot/bios.bin",
 		"-M", "microvm,x-option-roms=off,pic=off,pit=off,rtc=off,isa-serial=off",
 		"-kernel", opts.KernelPath,
-		// We force using a triple-fault reboot strategy since otherwise the kernel first tries others (like ACPI) which
-		// are not available in this very restricted environment. Similarly we need to override the boot console since
-		// there's nothing on the ISA bus that the kernel could talk to. We also force quiet for performance reasons.
+		// We force using a triple-fault reboot strategy since otherwise the kernel first
+		// tries others (like ACPI) which are not available in this very restricted
+		// environment. Similarly we need to override the boot console since there's
+		// nothing on the ISA bus that the kernel could talk to. We also force quiet for
+		// performance reasons.
 		"-append", "reboot=t console=hvc0 quiet " + opts.Cmdline,
 		"-initrd", opts.InitramfsPath,
 		"-device", "virtio-rng-device,max-bytes=1024,period=1000",
@@ -457,8 +486,8 @@
 	return err
 }
 
-// QEMUError is a special type of ExitError used when QEMU fails. In addition to normal ExitError features it
-// prints stderr for debugging.
+// QEMUError is a special type of ExitError used when QEMU fails. In addition to
+// normal ExitError features it prints stderr for debugging.
 type QEMUError exec.ExitError
 
 func (e *QEMUError) Error() string {
@@ -478,7 +507,8 @@
 	NumNodes int
 }
 
-// LaunchCluster launches a cluster of Metropolis node VMs together with a Nanoswitch instance to network them all together.
+// LaunchCluster launches a cluster of Metropolis node VMs together with a
+// Nanoswitch instance to network them all together.
 func LaunchCluster(ctx context.Context, opts ClusterOptions) (apb.NodeDebugServiceClient, PortMap, error) {
 	var switchPorts []*os.File
 	var vmPorts []*os.File
@@ -509,9 +539,10 @@
 			},
 		}); err != nil {
 
-			// Launch() only terminates when QEMU has terminated. At that point our function probably doesn't run anymore
-			// so we have no way of communicating the error back up, so let's just log it. Also a failure in launching
-			// VMs should be very visible by the unavailability of the clients we return.
+			// Launch() only terminates when QEMU has terminated. At that point our function
+			// probably doesn't run anymore so we have no way of communicating the error back
+			// up, so let's just log it. Also a failure in launching VMs should be very visible
+			// by the unavailability of the clients we return.
 			log.Printf("Failed to launch vm0: %v", err)
 		}
 	}()
diff --git a/metropolis/test/nanoswitch/nanoswitch.go b/metropolis/test/nanoswitch/nanoswitch.go
index 3ab662b..21a526e 100644
--- a/metropolis/test/nanoswitch/nanoswitch.go
+++ b/metropolis/test/nanoswitch/nanoswitch.go
@@ -15,9 +15,11 @@
 // limitations under the License.
 
 // nanoswitch is a virtualized switch/router combo intended for testing.
-// It uses the first interface as an external interface to connect to the host and pass traffic in and out. All other
-// interfaces are switched together and served by a built-in DHCP server. Traffic from that network to the
-// SLIRP/external network is SNATed as the host-side SLIRP ignores routed packets.
+// It uses the first interface as an external interface to connect to the host
+// and pass traffic in and out. All other interfaces are switched together and
+// served by a built-in DHCP server. Traffic from that network to the
+// SLIRP/external network is SNATed as the host-side SLIRP ignores routed
+// packets.
 // It also has built-in userspace proxying support for debugging.
 package main
 
@@ -49,17 +51,21 @@
 var switchIP = net.IP{10, 1, 0, 1}
 var switchSubnetMask = net.CIDRMask(24, 32)
 
-// defaultLeaseOptions sets the lease options needed to properly configure connectivity to nanoswitch
+// defaultLeaseOptions sets the lease options needed to properly configure
+// connectivity to nanoswitch.
 func defaultLeaseOptions(reply *dhcpv4.DHCPv4) {
 	reply.GatewayIPAddr = switchIP
-	reply.UpdateOption(dhcpv4.OptDNS(net.IPv4(10, 42, 0, 3))) // SLIRP fake DNS server
+	// SLIRP fake DNS server.
+	reply.UpdateOption(dhcpv4.OptDNS(net.IPv4(10, 42, 0, 3)))
 	reply.UpdateOption(dhcpv4.OptRouter(switchIP))
-	reply.UpdateOption(dhcpv4.OptIPAddressLeaseTime(30 * time.Second)) // Make sure we exercise our DHCP client in E2E tests
+	// Make sure we exercise our DHCP client in E2E tests.
+	reply.UpdateOption(dhcpv4.OptIPAddressLeaseTime(30 * time.Second))
 	reply.UpdateOption(dhcpv4.OptSubnetMask(switchSubnetMask))
 }
 
-// runDHCPServer runs an extremely minimal DHCP server with most options hardcoded, a wrapping bump allocator for the
-// IPs, 30 second lease timeout and no support for DHCP collision detection.
+// runDHCPServer runs an extremely minimal DHCP server with most options
+// hardcoded, a wrapping bump allocator for the IPs, 30 second lease timeout
+// and no support for DHCP collision detection.
 func runDHCPServer(link netlink.Link) supervisor.Runnable {
 	currentIP := net.IP{10, 1, 0, 1}
 
@@ -114,7 +120,8 @@
 	}
 }
 
-// userspaceProxy listens on port and proxies all TCP connections to the same port on targetIP
+// userspaceProxy listens on port and proxies all TCP connections to the same
+// port on targetIP
 func userspaceProxy(targetIP net.IP, port uint16) supervisor.Runnable {
 	return func(ctx context.Context) error {
 		logger := supervisor.Logger(ctx)
@@ -172,7 +179,8 @@
 	return nil
 }
 
-// nfifname converts an interface name into 16 bytes padded with zeroes (for nftables)
+// nfifname converts an interface name into 16 bytes padded with zeroes (for
+// nftables)
 func nfifname(n string) []byte {
 	b := make([]byte, 16)
 	copy(b, []byte(n+"\x00"))