all: add illumos/amd64 builder on Joyent

Fixes golang/go#32308

Change-Id: I6934c7de4bf2e73b0f816cd512765b6152e4b170
Reviewed-on: https://go-review.googlesource.com/c/build/+/179418
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/cmd/buildlet/Makefile b/cmd/buildlet/Makefile
index 6b88564..31ee99c 100644
--- a/cmd/buildlet/Makefile
+++ b/cmd/buildlet/Makefile
@@ -14,6 +14,7 @@
 	GOOS=dragonfly GOARCH=amd64 go install golang.org/x/build/cmd/buildlet
 	GOOS=freebsd GOARCH=arm go install golang.org/x/build/cmd/buildlet
 	GOOS=freebsd GOARCH=amd64 go install golang.org/x/build/cmd/buildlet
+	GOOS=illumos GOARCH=amd64 go install golang.org/x/build/cmd/buildlet
 	GOOS=linux GOARCH=amd64 go install golang.org/x/build/cmd/buildlet
 	GOOS=linux GOARCH=arm go install golang.org/x/build/cmd/buildlet
 	GOOS=linux GOARCH=arm64 go install golang.org/x/build/cmd/buildlet
@@ -34,7 +35,7 @@
 	GOOS=windows GOARCH=amd64 go install golang.org/x/build/cmd/buildlet
 
 # buildlet.all is compiles & uploads all targets.
-buildlet.all: FORCE buildlet.aix-ppc64 buildlet.darwin-amd64 buildlet.freebsd-amd64 buildlet.linux-amd64 buildlet.netbsd-386 buildlet.netbsd-amd64 buildlet.netbsd-arm buildlet.openbsd-amd64 buildlet.openbsd-386 buildlet.plan9-386 buildlet.windows-amd64 buildlet.windows-arm buildlet.linux-arm buildlet.linux-arm-arm5 buildlet.linux-arm64 buildlet.linux-mips buildlet.linux-mipsle buildlet.linux-mips64 buildlet.linux-mips64le buildlet.linux-ppc64 buildlet.linux-ppc64le buildlet.linux-s390x buildlet.solaris-amd64
+buildlet.all: FORCE buildlet.aix-ppc64 buildlet.darwin-amd64 buildlet.freebsd-amd64 buildlet.linux-amd64 buildlet.netbsd-386 buildlet.netbsd-amd64 buildlet.netbsd-arm buildlet.openbsd-amd64 buildlet.openbsd-386 buildlet.plan9-386 buildlet.windows-amd64 buildlet.windows-arm buildlet.linux-arm buildlet.linux-arm-arm5 buildlet.linux-arm64 buildlet.linux-mips buildlet.linux-mipsle buildlet.linux-mips64 buildlet.linux-mips64le buildlet.linux-ppc64 buildlet.linux-ppc64le buildlet.linux-s390x buildlet.solaris-amd64 buildlet.illumos-amd64
 	echo "done"
 
 buildlet.aix-ppc64: FORCE
@@ -157,6 +158,10 @@
 	go install golang.org/x/build/cmd/upload
 	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet --public --cacheable=false go-builder-data/$@
 
+buildlet.illumos-amd64: FORCE
+	go install golang.org/x/build/cmd/upload
+	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet --public --cacheable=false go-builder-data/$@
+
 dev-buildlet.linux-arm: FORCE
 	go install golang.org/x/build/cmd/upload
 	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet --public --cacheable=false dev-go-builder-data/buildlet.linux-arm
diff --git a/cmd/buildlet/stage0/Makefile b/cmd/buildlet/stage0/Makefile
index 899c644..1405fe1 100644
--- a/cmd/buildlet/stage0/Makefile
+++ b/cmd/buildlet/stage0/Makefile
@@ -42,6 +42,10 @@
 	go install golang.org/x/build/cmd/upload
 	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet/stage0 --public --cacheable=false go-builder-data/$@
 
+buildlet-stage0.illumos-amd64: FORCE
+	go install golang.org/x/build/cmd/upload
+	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet/stage0 --public --cacheable=false go-builder-data/$@
+
 buildlet-stage0.linux-s390x: FORCE
 	go install golang.org/x/build/cmd/upload
 	upload --verbose --osarch=$@ --file=go:golang.org/x/build/cmd/buildlet/stage0 --public --cacheable=false go-builder-data/$@
diff --git a/cmd/buildlet/stage0/stage0.go b/cmd/buildlet/stage0/stage0.go
index 9f268ce..65d02ff 100644
--- a/cmd/buildlet/stage0/stage0.go
+++ b/cmd/buildlet/stage0/stage0.go
@@ -193,15 +193,17 @@
 		// GO_BUILD_HOST_TYPE (see above) and check that.
 		cmd.Args = append(cmd.Args, reverseHostTypeArgs("host-linux-ppc64le-osu")...)
 	case "solaris/amd64":
-		if buildEnv != "" {
-			// Explicit value given. Treat it like a host type.
-			cmd.Args = append(cmd.Args, reverseHostTypeArgs(buildEnv)...)
-		} else {
-			// If there's no value, assume it's the old Joyent builders,
-			// which are currently GOOS=solaris, but will be illumos after
-			// golang.org/issue/20603.
-			cmd.Args = append(cmd.Args, reverseHostTypeArgs("host-solaris-amd64")...)
+		hostType := buildEnv
+		if hostType == "" {
+			hostType = "host-solaris-amd64"
 		}
+		cmd.Args = append(cmd.Args, reverseHostTypeArgs(hostType)...)
+	case "illumos/amd64":
+		hostType := buildEnv
+		if hostType == "" {
+			hostType = "host-illumos-amd64-joyent"
+		}
+		cmd.Args = append(cmd.Args, reverseHostTypeArgs(hostType)...)
 	}
 	// Release the serial port (if we opened it) so the buildlet
 	// process can open & write to it. At least on Windows, only
@@ -325,6 +327,8 @@
 		return "https://storage.googleapis.com/go-builder-data/buildlet.linux-ppc64le"
 	case "solaris/amd64":
 		return "https://storage.googleapis.com/go-builder-data/buildlet.solaris-amd64"
+	case "illumos/amd64":
+		return "https://storage.googleapis.com/go-builder-data/buildlet.illumos-amd64"
 	case "darwin/amd64":
 		return "https://storage.googleapis.com/go-builder-data/buildlet.darwin-amd64"
 	}
diff --git a/cmd/coordinator/status.go b/cmd/coordinator/status.go
index e77f681..34466df 100644
--- a/cmd/coordinator/status.go
+++ b/cmd/coordinator/status.go
@@ -127,7 +127,8 @@
 	addHealthChecker(newPacketHealthChecker())
 	addHealthChecker(newOSUPPC64Checker())
 	addHealthChecker(newOSUPPC64leChecker())
-	addHealthChecker(newJoyentChecker())
+	addHealthChecker(newJoyentSolarisChecker())
+	addHealthChecker(newJoyentIllumosChecker())
 	addHealthChecker(newBasepinChecker())
 }
 
@@ -209,27 +210,39 @@
 	}
 }
 
-func newJoyentChecker() *healthChecker {
-	const hostType = "host-solaris-amd64"
-	want := expectedHosts(hostType)
+func newJoyentSolarisChecker() *healthChecker {
 	return &healthChecker{
-		ID:     "joyent",
+		ID:     "joyent-solaris",
 		Title:  "Joyent solaris/amd64 machines",
 		EnvURL: "https://github.com/golang/build/tree/master/env/solaris-amd64/joyent",
-		Check: func(cw *checkWriter) {
-			p := reversePool
-			p.mu.Lock()
-			defer p.mu.Unlock()
-			n := 0
-			for _, b := range p.buildlets {
-				if b.hostType == hostType {
-					n++
-				}
+		Check:  hostTypeChecker("host-solaris-amd64"),
+	}
+}
+
+func newJoyentIllumosChecker() *healthChecker {
+	return &healthChecker{
+		ID:     "joyent-illumos",
+		Title:  "Joyent illumos/amd64 machines",
+		EnvURL: "https://github.com/golang/build/tree/master/env/illumos-amd64-joyent",
+		Check:  hostTypeChecker("host-illumos-amd64-joyent"),
+	}
+}
+
+func hostTypeChecker(hostType string) func(cw *checkWriter) {
+	want := expectedHosts(hostType)
+	return func(cw *checkWriter) {
+		p := reversePool
+		p.mu.Lock()
+		defer p.mu.Unlock()
+		n := 0
+		for _, b := range p.buildlets {
+			if b.hostType == hostType {
+				n++
 			}
-			if n < want {
-				cw.errorf("%d connected; want %d", n, want)
-			}
-		},
+		}
+		if n < want {
+			cw.errorf("%d connected; want %d", n, want)
+		}
 	}
 }
 
diff --git a/dashboard/builders.go b/dashboard/builders.go
index e070233..a485a4b 100644
--- a/dashboard/builders.go
+++ b/dashboard/builders.go
@@ -448,6 +448,12 @@
 		env:            []string{"GOROOT_BOOTSTRAP=/root/go-solaris-amd64-bootstrap", "HOME=/root"},
 		ReverseAliases: []string{"solaris-amd64-smartosbuildlet"},
 	},
+	"host-illumos-amd64-joyent": &HostConfig{
+		Notes:     "run by Go team on Joyent, on a SmartOS 'infrastructure container'",
+		IsReverse: true,
+		ExpectNum: 1,
+		env:       []string{"GOROOT_BOOTSTRAP=/root/goboot", "HOME=/root"},
+	},
 	"host-solaris-oracle-amd64-oraclerel": &HostConfig{
 		Notes:       "Oracle Solaris amd64 Release System",
 		Owner:       "", // TODO: find current owner
@@ -2035,6 +2041,10 @@
 		HostType: "host-solaris-amd64",
 	})
 	addBuilder(BuildConfig{
+		Name:     "illumos-amd64-joyent",
+		HostType: "host-illumos-amd64-joyent",
+	})
+	addBuilder(BuildConfig{
 		Name:     "linux-ppc64-buildlet",
 		HostType: "host-linux-ppc64-osu",
 		FlakyNet: true,
diff --git a/env/illumos-amd64-joyent/README.md b/env/illumos-amd64-joyent/README.md
new file mode 100644
index 0000000..cf61a11
--- /dev/null
+++ b/env/illumos-amd64-joyent/README.md
@@ -0,0 +1,77 @@
+# Illumos Builder
+
+This instructions for the Illumos builder that the Go team runs on Joyent.
+
+# Prep files from Linux
+
+```
+bradfitz@go:~/go/src$ GOOS=illumos GOARCH=amd64 BOOTSTRAP_FORMAT=mintgz ./bootstrap.bash
+...
+...
+Writing gobootstrap-illumos-amd64-e883d000f4.tar.gz ...
+-rw-r--r-- 1 bradfitz bradfitz 51647155 May 29 17:24 /home/bradfitz/gobootstrap-illumos-amd64-e883d000f4.tar.gz
+
+bradfitz@go:~/go/src$ go install golang.org/x/build/cmd/upload
+bradfitz@go:~/go/src$ upload --file=/home/bradfitz/gobootstrap-illumos-amd64-e883d000f4.tar.gz --public go-builder-data/gobootstrap-illumos-amd64-e883d000f4.tar.gz
+
+$ cd $GOPATH/src/golang.org/x/build/cmd/buildlet
+$ make buildlet.illumos-amd64
+$ cd $GOPATH/src/golang.org/x/build/cmd/buildlet/stage0
+$ make buildlet-stage0.illumos-amd64
+
+```
+
+# Create VM on Joyent
+
+* at least 2 CPUs, at least 1 GB ram. (I used `g4-highcpu-4G` somewhat arbitrarily)
+
+# Prep VM
+
+```
+bradfitz@go:~$ ssh -i ~/.ssh/id_rsa_golang2 root@$IP
+...
+# curl -O https://storage.googleapis.com/go-builder-data/gobootstrap-illumos-amd64-e883d000f4.tar.gz
+# mkdir goboot
+# cd goboot
+# tar -zxvf ../gobootstrap-illumos-amd64-e883d000f4.tar.gz
+# pkgin in gcc47
+# rm /opt/local/sbin/mysqld
+# rm /opt/local/sbin/httpd
+# cat > /root/.gobuildkey-host-illumos-amd64-joyent
+xxxx
+^D
+# curl -o /opt/buildlet-stage0 https://storage.googleapis.com/go-builder-data/buildlet-stage0.illumos-amd64
+# chmod +x /opt/buildlet-stage0
+# curl -O https://raw.githubusercontent.com/golang/build/master/env/solaris-amd64/joyent/buildlet.xml
+# svccfg import buildlet.xml
+```
+
+The service should be running now. Shut down the machine and create an
+image from the Joyent web console.
+
+If you need to debug, you can check status with:
+
+```
+svcs -x buildlet.xml
+```
+
+This will also give you the location to the log file.
+
+If you need to change an environment variable, place this inside the start
+exec_method element:
+
+```
+<method_context>
+    <method_environment>
+       <envvar name="EXAMPLE" value="foo"/>
+    </method_environment>
+</method_context>
+```
+
+To debug an instance once it's running, you can ssh as:
+
+```
+$ ssh -i ~/.ssh/id_rsa_golang2 root@$IP
+```
+
+The key is at http://go/id_rsa_golang2