dashboard, buildlet: add a disabled builder with nested virt, for testing

This adds a linux-amd64 COS builder that should be just like our
existing linux-amd64 COS builder except that it's using a forked image
that has the VMX license bit enabled for nested virtualization. (GCE
appears to be using the license mechanism as some sort of opt-in
mechanism for features that aren't yet GA; might go away?)

Once this is in, it won't do any new builds as regular+trybot builders
are disabled. But it means I can then use gomote + debugnewvm to work
on preparing the other four image types.

Updates golang/go#15581 (solaris)
Updates golang/go#23060 (dragonfly)
Updates golang/go#30262 (riscv)
Updates golang/go#30267 (fuchsia)
Updates golang/go#23824 (android)

Change-Id: Ic55f17eea17908dba7f58618d8cd162a2ed9b015
Reviewed-on: https://go-review.googlesource.com/c/162959
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/buildlet/gce.go b/buildlet/gce.go
index 1a1c0a0..2bacf7d 100644
--- a/buildlet/gce.go
+++ b/buildlet/gce.go
@@ -142,11 +142,26 @@
 	}
 
 	srcImage := "https://www.googleapis.com/compute/v1/projects/" + projectID + "/global/images/" + hconf.VMImage
+	minCPU := hconf.MinCPUPlatform
 	if hconf.IsContainer() {
-		var err error
-		srcImage, err = cosImage(ctx, computeService)
-		if err != nil {
-			return nil, fmt.Errorf("error find Container-Optimized OS image: %v", err)
+		if hconf.NestedVirt {
+			minCPU = "Intel Haswell" // documented minimum from https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances
+			// TODO: use some variant of cosImage that finds our local
+			// forked copy of cos-stable with the VMX license added. For
+			// now, I just manually once ran:
+			//   gcloud compute images create cos-stable-72-11316-136-0-vmx --source-image=cos-stable-72-11316-136-0 --source-image-project=cos-cloud --licenses=https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx
+			// And we'll use that version for now. Perhaps when Nested
+			// Virtualization reaches GA it'll just become a boolean we
+			// can set in our compute.Instance creation request and this
+			// license opt-in mechanism will be unnecessary.
+			const coxVMXImage = "cos-stable-72-11316-136-0-vmx"
+			srcImage = "https://www.googleapis.com/compute/v1/projects/" + projectID + "/global/images/" + coxVMXImage
+		} else {
+			var err error
+			srcImage, err = cosImage(ctx, computeService)
+			if err != nil {
+				return nil, fmt.Errorf("error find Container-Optimized OS image: %v", err)
+			}
 		}
 	}
 
@@ -154,7 +169,7 @@
 		Name:           instName,
 		Description:    opts.Description,
 		MachineType:    machType,
-		MinCpuPlatform: hconf.MinCPUPlatform,
+		MinCpuPlatform: minCPU,
 		Disks: []*compute.AttachedDisk{
 			{
 				AutoDelete: true,
diff --git a/dashboard/builders.go b/dashboard/builders.go
index 4616c98..6400f48 100644
--- a/dashboard/builders.go
+++ b/dashboard/builders.go
@@ -41,6 +41,14 @@
 		env:             []string{"GOROOT_BOOTSTRAP=/go1.4"},
 		SSHUsername:     "root",
 	},
+	"host-linux-stretch-vmx": &HostConfig{
+		Notes:           "Debian Stretch w/ Nested Virtualization (VMX CPU bit) enabled, for testing",
+		ContainerImage:  "linux-x86-stretch:latest",
+		NestedVirt:      true,
+		buildletURLTmpl: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
+		env:             []string{"GOROOT_BOOTSTRAP=/go1.4"},
+		SSHUsername:     "root",
+	},
 	"host-linux-armhf-cross": &HostConfig{
 		Notes:           "Debian Jessie with armhf cross-compiler, built from env/crosscompile/linux-armhf-jessie",
 		ContainerImage:  "linux-armhf-jessie:latest",
@@ -576,6 +584,9 @@
 	ExpectNum       int  // expected number of reverse buildlets of this type
 	HermeticReverse bool // whether reverse buildlet has fresh env per conn
 
+	// Container image options, if ContainerImage != "":
+	NestedVirt bool // container requires VMX nested virtualization
+
 	// Optional base env. GOROOT_BOOTSTRAP should go here if the buildlet
 	// has Go 1.4+ baked in somewhere.
 	env []string
@@ -1204,6 +1215,13 @@
 		numTryTestHelpers: 4,
 		RunBench:          true,
 	})
+	addBuilder(BuildConfig{
+		Name:      "linux-amd64-vmx",
+		HostType:  "host-linux-stretch-vmx",
+		MaxAtOnce: 1,
+		TryOnly:   true, // don't run regular build
+		tryBot:    nil,  // and don't run trybots (only gomote)
+	})
 
 	const testAlpine = false // Issue 22689 (hide all red builders), Issue 19938 (get Alpine passing)
 	if testAlpine {