all: remove macstadium integration and monitoring

We no longer use this hosting provider.

Removes builders depending on this host type, including Windows ARM
builders.

Fixes golang/go#57562
Updates golang/go#47019

Change-Id: I1b2d3dfb0540cdf1ebc1ce2cfabbcd7d56c30145
Reviewed-on: https://go-review.googlesource.com/c/build/+/460295
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Jenny Rakoczy <jenny@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 3418085..961aa3a 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -34,7 +34,6 @@
 	"os/exec"
 	"path"
 	"path/filepath"
-	"regexp"
 	"runtime"
 	"strconv"
 	"strings"
@@ -126,9 +125,6 @@
 
 func main() {
 	builderEnv := os.Getenv("GO_BUILDER_ENV")
-	if builderEnv == "macstadium_vm" {
-		configureMacStadium()
-	}
 	onGCE := metadata.OnGCE()
 	switch runtime.GOOS {
 	case "plan9":
@@ -1737,103 +1733,6 @@
 	return p.Kill()
 }
 
-// configureMacStadium configures the buildlet flags for use on a Mac
-// VM running on MacStadium under VMWare.
-func configureMacStadium() {
-	*haltEntireOS = true
-
-	// TODO: setup RAM disk for tmp and set *workDir
-
-	disableMacScreensaver()
-	enableMacDeveloperMode()
-
-	version, err := exec.Command("sw_vers", "-productVersion").Output()
-	if err != nil {
-		log.Fatalf("failed to find sw_vers -productVersion: %v", err)
-	}
-	majorMinor := regexp.MustCompile(`^(\d+)\.(\d+)`)
-	m := majorMinor.FindStringSubmatch(string(version))
-	if m == nil {
-		log.Fatalf("unsupported sw_vers version %q", version)
-	}
-	major, minor := m[1], m[2] // "10", "12"
-
-	// As of macOS 11 (Big Sur), the major digits are used to indicate the version of
-	// macOS. This version also introduced support for multiple architectures. This
-	// takes into account the need to distinguish between versions and architectures for
-	// the later versions.
-	mj, err := strconv.Atoi(major)
-	if err != nil {
-		log.Fatalf("unable to parse major version %q", major)
-	}
-	if mj >= 13 {
-		*reverseType = fmt.Sprintf("host-darwin-%s-%s", runtime.GOARCH, major)
-	} else if mj >= 11 {
-		// The darwin-amd64-{11,12}_0 hosts have a "_0" suffix as a historical
-		// relic from when it distinguished macOS 10.15, 10.14 and older, as below.
-		*reverseType = fmt.Sprintf("host-darwin-%s-%s_0", runtime.GOARCH, major)
-	} else {
-		*reverseType = fmt.Sprintf("host-darwin-%s-%s_%s", runtime.GOARCH, major, minor)
-	}
-	*coordinator = "farmer.golang.org:443"
-
-	// guestName is set by cmd/makemac to something like
-	// "mac_10_10_host01b" or "mac_10_12_host01a", which encodes
-	// three things: the mac OS version of the guest VM, which
-	// physical machine it's on (1 to 10, currently) and which of
-	// two possible VMs on that host is running (a or b). For
-	// monitoring purposes, we want stable hostnames and don't
-	// care which OS version is currently running (which changes
-	// constantly), so normalize these to only have the host
-	// number and side (a or b), without the OS version. The
-	// buildlet will report the OS version to the coordinator
-	// anyway. We could in theory do this normalization in the
-	// coordinator, but we don't want to put buildlet-specific
-	// knowledge there, and this file already contains a bunch of
-	// buildlet host-specific configuration, so normalize it here.
-	guestName := vmwareGetInfo("guestinfo.name") // "mac_10_12_host01a"
-	hostPos := strings.Index(guestName, "_host")
-	if hostPos == -1 {
-		// Assume cmd/makemac changed its conventions.
-		// Maybe all this normalization belongs there anyway,
-		// but normalizing here is a safer first step.
-		*hostname = guestName
-	} else {
-		*hostname = "macstadium" + guestName[hostPos:] // "macstadium_host01a"
-	}
-}
-
-func disableMacScreensaver() {
-	err := exec.Command("defaults", "-currentHost", "write", "com.apple.screensaver", "idleTime", "0").Run()
-	if err != nil {
-		log.Printf("disabling screensaver: %v", err)
-	}
-}
-
-// enableMacDeveloperMode enables developer mode on macOS for the
-// runtime tests. (Issue 31123)
-//
-// It is best effort; errors are logged but otherwise ignored.
-func enableMacDeveloperMode() {
-	// Macs are configured with password-less sudo. Without sudo we get prompts
-	// that "SampleTools wants to make changes" that block the buildlet from starting.
-	// But oddly, not via gomote. Only during startup. The environment must be different
-	// enough that in one case macOS asks for permission (because it can use the GUI?)
-	// and in the gomote case (where the environment is largely scrubbed) it can't do
-	// the GUI dialog somehow and must just try to do it anyway and finds that passwordless
-	// sudo works. But using sudo seems to make it always work.
-	// For extra paranoia, use a context to not block start-up.
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-
-	out, err := exec.CommandContext(ctx, "/usr/bin/sudo", "/usr/sbin/DevToolsSecurity", "-enable").CombinedOutput()
-	if err != nil {
-		log.Printf("Error enabling developer mode: %v, %s", err, out)
-		return
-	}
-	log.Printf("DevToolsSecurity: %s", out)
-}
-
 func vmwareGetInfo(key string) string {
 	cmd := exec.Command("/Library/Application Support/VMware Tools/vmware-tools-daemon",
 		"--cmd",
diff --git a/cmd/buildlet/reverse.go b/cmd/buildlet/reverse.go
index 920a5f9..2b56a10 100644
--- a/cmd/buildlet/reverse.go
+++ b/cmd/buildlet/reverse.go
@@ -33,14 +33,6 @@
 	if isDevReverseMode() {
 		return devBuilderKey(mode), nil
 	}
-	if os.Getenv("GO_BUILDER_ENV") == "macstadium_vm" {
-		infoKey := "guestinfo.key-" + mode
-		key := vmwareGetInfo(infoKey)
-		if key == "" {
-			return "", fmt.Errorf("no build key found for VMWare info-get key %q", infoKey)
-		}
-		return key, nil
-	}
 	keyPath := filepath.Join(homedir(), ".gobuildkey-"+mode)
 	if v := os.Getenv("GO_BUILD_KEY_PATH"); v != "" {
 		keyPath = v
diff --git a/cmd/buildlet/stage0/Makefile b/cmd/buildlet/stage0/Makefile
index a72924a..6185078 100644
--- a/cmd/buildlet/stage0/Makefile
+++ b/cmd/buildlet/stage0/Makefile
@@ -4,9 +4,6 @@
 # The only reason we upload them to GCS is because that's where the
 # automated VM/container creation scripts download them from.
 #
-# The notable exception is our Mac VMs on MacStadium. In those cases,
-# the images actually do download the stage0 binary on start-up.
-#
 
 GO=go1.19
 
diff --git a/cmd/buildlet/stage0/stage0.go b/cmd/buildlet/stage0/stage0.go
index 1f3e2db..fa72fbe 100644
--- a/cmd/buildlet/stage0/stage0.go
+++ b/cmd/buildlet/stage0/stage0.go
@@ -26,7 +26,6 @@
 	"os/exec"
 	"path/filepath"
 	"runtime"
-	"strings"
 	"time"
 
 	"cloud.google.com/go/compute/metadata"
@@ -75,7 +74,6 @@
 	}
 	log.Printf("bootstrap binary running")
 
-	var isMacStadiumVM bool
 	switch osArch {
 	case "linux/arm":
 		if onGCE {
@@ -97,15 +95,6 @@
 		default:
 			panic(fmt.Sprintf("unknown/unspecified $GO_BUILDER_ENV value %q", env))
 		}
-	case "darwin/amd64":
-		// The MacStadium builders' baked-in stage0.sh
-		// bootstrap file doesn't set GO_BUILDER_ENV
-		// unfortunately, so use the filename it runs its
-		// downloaded bootstrap URL to determine whether we're
-		// in that environment.
-		isMacStadiumVM = len(os.Args) > 0 && strings.HasSuffix(os.Args[0], "run-builder")
-		log.Printf("isMacStadiumVM = %v", isMacStadiumVM)
-		os.Setenv("GO_BUILDER_ENV", "macstadium_vm")
 	}
 
 	if !awaitNetwork() {
@@ -115,7 +104,6 @@
 	netDelay := prettyDuration(timeNetwork.Sub(timeStart))
 	log.Printf("network up after %v", netDelay)
 
-Download:
 	// Note: we name it ".exe" for Windows, but the name also
 	// works fine on Linux, etc.
 	target := filepath.FromSlash("./buildlet.exe")
@@ -202,15 +190,6 @@
 	case "solaris/amd64", "illumos/amd64":
 		hostType := buildEnv
 		cmd.Args = append(cmd.Args, reverseHostTypeArgs(hostType)...)
-	case "windows/arm64":
-		switch buildEnv {
-		case "host-windows-arm64-mini", "host-windows11-arm64-mini":
-			cmd.Args = append(cmd.Args,
-				"--halt=true",
-				"--reverse-type="+buildEnv,
-				"--coordinator=farmer.golang.org:443",
-			)
-		}
 	}
 	// Release the serial port (if we opened it) so the buildlet
 	// process can open & write to it. At least on Windows, only
@@ -219,24 +198,6 @@
 		closeSerialLogOutput()
 	}
 	err := cmd.Run()
-	if isMacStadiumVM {
-		if err != nil {
-			log.Printf("error running buildlet: %v", err)
-			log.Printf("restarting in 2 seconds.")
-			time.Sleep(2 * time.Second) // in case we're spinning, slow it down
-		} else {
-			log.Printf("buildlet process exited; restarting.")
-		}
-		// Some of the MacStadium VM environments reuse their
-		// environment. Re-download the buildlet (if it
-		// changed-- httpdl does conditional downloading) and
-		// then re-run. At least on Sierra we never get this
-		// far because the buildlet will halt the machine
-		// before we get here. (and then cmd/makemac will
-		// recreate the VM)
-		// But if we get here, restart the process.
-		goto Download
-	}
 	if err != nil {
 		if configureSerialLogOutput != nil {
 			configureSerialLogOutput()
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index df95301..c068686 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -360,7 +360,6 @@
 	mux.HandleFunc("/style.css", handleStyleCSS)
 	mux.HandleFunc("/try", serveTryStatus(false))
 	mux.HandleFunc("/try.json", serveTryStatus(true))
-	mux.HandleFunc("/status/reverse.json", pool.ReversePool().ServeReverseStatusJSON)
 	mux.HandleFunc("/status/post-submit-active.json", handlePostSubmitActiveJSON)
 	mux.Handle("/dashboard", dashV2)
 	mux.HandleFunc("/queues", handleQueues)
diff --git a/cmd/coordinator/coordinator_test.go b/cmd/coordinator/coordinator_test.go
index cdec51d..edb439d 100644
--- a/cmd/coordinator/coordinator_test.go
+++ b/cmd/coordinator/coordinator_test.go
@@ -250,36 +250,36 @@
 
 	// First, determine builds without try messages. Our target SlowBot shouldn't be included.
 	ts := newTrySet(work)
-	hasWindowsARM64Builder := false
+	hasLinuxArmBuilder := false
 	for _, bs := range ts.builds {
 		v := bs.NameAndBranch()
-		if v == "windows-arm64-10" {
-			hasWindowsARM64Builder = true
+		if v == "linux-arm" {
+			hasLinuxArmBuilder = true
 		}
 	}
-	if hasWindowsARM64Builder {
-		// This test relies on windows-arm64-10 builder not being a default
+	if hasLinuxArmBuilder {
+		// This test relies on linux-arm builder not being a default
 		// TryBot to provide coverage for issue 42084. If the build policy
 		// changes, need to pick another builder to use in this test.
-		t.Fatal("windows-arm64-10 builder was included even without TRY= message")
+		t.Fatal("linux-arm builder was included even without TRY= message")
 	}
 
 	// Next, add try messages, and check that the SlowBot is now included.
 	work.TryMessage = []*apipb.TryVoteMessage{
-		{Message: "TRY=windows-amd64", AuthorId: 1234, Version: 1},
-		{Message: "TRY=windows-arm64-10", AuthorId: 1234, Version: 1},
+		{Message: "TRY=linux", AuthorId: 1234, Version: 1},
+		{Message: "TRY=linux-arm", AuthorId: 1234, Version: 1},
 	}
 	ts = newTrySet(work)
-	hasWindowsARM64Builder = false
+	hasLinuxArmBuilder = false
 	for i, bs := range ts.builds {
 		v := bs.NameAndBranch()
 		t.Logf("build[%d]: %s", i, v)
-		if v == "windows-arm64-10" {
-			hasWindowsARM64Builder = true
+		if v == "linux-arm-aws" {
+			hasLinuxArmBuilder = true
 		}
 	}
-	if !hasWindowsARM64Builder {
-		t.Error("windows-arm64-10 SlowBot was not included")
+	if !hasLinuxArmBuilder {
+		t.Error("linux-arm SlowBot was not included")
 	}
 }
 
diff --git a/cmd/coordinator/status.go b/cmd/coordinator/status.go
index 5f87d1b..f52a09a 100644
--- a/cmd/coordinator/status.go
+++ b/cmd/coordinator/status.go
@@ -13,7 +13,6 @@
 	"bytes"
 	"context"
 	_ "embed"
-	"encoding/json"
 	"errors"
 	"fmt"
 	"html"
@@ -147,7 +146,6 @@
 var basePinErr atomic.Value
 
 func addHealthCheckers(ctx context.Context, mux *http.ServeMux, sc *secret.Client) {
-	addHealthChecker(mux, newMacHealthChecker())
 	addHealthChecker(mux, newMacOSARM64Checker())
 	addHealthChecker(mux, newOSUPPC64leChecker())
 	addHealthChecker(mux, newOSUPPC64lePower9Checker())
@@ -292,81 +290,6 @@
 	}
 }
 
-func newMacHealthChecker() *healthChecker {
-	var hosts []string
-	const numMacHosts = 8 // physical Mac Pros, not reverse buildlet connections. M1 Macs will be included in separate checks.
-	for i := 1; i <= numMacHosts; i++ {
-		for _, suf := range []string{"a", "b"} {
-			name := fmt.Sprintf("macstadium_host%02d%s", i, suf)
-			hosts = append(hosts, name)
-		}
-	}
-	checkHosts := reverseHostChecker(hosts)
-
-	// And check that the makemac daemon is listening.
-	var makeMac struct {
-		sync.Mutex
-		lastCheck  time.Time // currently unused
-		lastErrors []string
-		lastWarns  []string
-	}
-	setMakeMacStatus := func(errs, warns []string) {
-		makeMac.Lock()
-		defer makeMac.Unlock()
-		makeMac.lastCheck = time.Now()
-		makeMac.lastErrors = errs
-		makeMac.lastWarns = warns
-	}
-	go func() {
-		for {
-			errs, warns := fetchMakeMacStatus()
-			setMakeMacStatus(errs, warns)
-			time.Sleep(15 * time.Second)
-		}
-	}()
-	return &healthChecker{
-		ID:     "macs",
-		Title:  "MacStadium Mac VMs",
-		DocURL: "https://github.com/golang/build/tree/master/env/darwin/macstadium",
-		Check: func(w *checkWriter) {
-			// Check hosts.
-			checkHosts(w)
-			// Check makemac daemon.
-			makeMac.Lock()
-			defer makeMac.Unlock()
-			for _, v := range makeMac.lastWarns {
-				w.warnf("makemac daemon: %v", v)
-			}
-			for _, v := range makeMac.lastErrors {
-				w.errorf("makemac daemon: %v", v)
-			}
-		},
-	}
-}
-
-func fetchMakeMacStatus() (errs, warns []string) {
-	c := &http.Client{Timeout: 15 * time.Second}
-	res, err := c.Get("http://macstadiumd.golang.org:8713")
-	if err != nil {
-		return []string{fmt.Sprintf("failed to fetch status: %v", err)}, nil
-	}
-	defer res.Body.Close()
-	if res.StatusCode != 200 {
-		return []string{fmt.Sprintf("HTTP status %v", res.Status)}, nil
-	}
-	if res.Header.Get("Content-Type") != "application/json" {
-		return []string{fmt.Sprintf("unexpected content-type %q; want JSON", res.Header.Get("Content-Type"))}, nil
-	}
-	var resj struct {
-		Errors   []string
-		Warnings []string
-	}
-	if err := json.NewDecoder(res.Body).Decode(&resj); err != nil {
-		return []string{fmt.Sprintf("reading status response body: %v", err)}, nil
-	}
-	return resj.Errors, resj.Warnings
-}
-
 func newMacOSARM64Checker() *healthChecker {
 	var expect int // Number of expected darwin/arm64 reverse builders based on x/build/dashboard.
 	for hostType, hc := range dashboard.Hosts {
diff --git a/cmd/coordinator/status_test.go b/cmd/coordinator/status_test.go
index 7374248..ee46e0a 100644
--- a/cmd/coordinator/status_test.go
+++ b/cmd/coordinator/status_test.go
@@ -95,8 +95,6 @@
 		t.Fatalf("output didn't contain %q: %s", suf, got)
 	}
 	for _, sub := range []string{
-		`<a href="/status/macs">MacStadium Mac VMs</a> [`,
-		`<li>macstadium_host06a not yet connected</li>`,
 		`<a href="/status/allgood">All Good Test</a>: ok`,
 		`<li>test-info</li>`,
 		`<li><span style='color: orange'>test-warn</span></li>`,
diff --git a/cmd/makemac/README.md b/cmd/makemac/README.md
deleted file mode 100644
index 6ab5482..0000000
--- a/cmd/makemac/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-[![Go Reference](https://pkg.go.dev/badge/golang.org/x/build/cmd/makemac.svg)](https://pkg.go.dev/golang.org/x/build/cmd/makemac)
-
-# golang.org/x/build/cmd/makemac
-
-The makemac command manages creating & destroying macOS VMs for the
-builders. See the README in x/build/env/darwin/macstadium for some
-more background.
-
-## Deploying `makemac`
-
-```
-* On Linux,
-  $ cd cmd/makemac
-  $ CGO_ENABLED=0 go build golang.org/x/build/cmd/makemac
-  $ scp -i ~/.ssh/id_ed25519_golang1 ./makemac gopher@macstadiumd.golang.org:makemac.new
-  $ ssh -i ~/.ssh/id_ed25519_golang1 gopher@macstadiumd.golang.org
-
-On that host,
-  $ cp makemac makemac.old
-  $ install makemac.new makemac
-  $ sudo systemctl restart makemac
-  $ sudo journalctl -f -u makemac     # watch it
-```
-
-## Updating `makemac.service`
-
-```
-* On Linux,
-  $ scp -i ~/.ssh/id_ed25519_golang1 cmd/makemac/makemac.service gopher@macstadiumd.golang.org:makemac.service
-
-On that host,
-  $ sudo mv makemac.service /etc/systemd/system/makemac.service
-  $ sudo systemctl daemon-reload
-  $ sudo systemctl restart makemac
-  $ sudo journalctl -f -u makemac     # watch it
-```
-
-## Checking that it's running:
-
-```
-$ curl -v http://macstadiumd.golang.org:8713
-```
-
-(Note that URL won't work in a browser due to HSTS requirements on
- *.golang.org)
diff --git a/cmd/makemac/makemac.go b/cmd/makemac/makemac.go
deleted file mode 100644
index 1d040e7..0000000
--- a/cmd/makemac/makemac.go
+++ /dev/null
@@ -1,984 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-The makemac command starts OS X VMs for the builders.
-It is currently just a thin wrapper around govc.
-
-See https://github.com/vmware/govmomi/tree/master/govc
-
-Usage:
-
-	$ makemac <macos_version>  # e.g, darwin-amd64-10_10, darwin-amd64-10_11, darwin-amd64-10_15, darwin-amd64-11_0
-*/
-package main
-
-import (
-	"bufio"
-	"context"
-	"encoding/json"
-	"errors"
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	"os/exec"
-	"path"
-	"path/filepath"
-	"regexp"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"golang.org/x/build/types"
-)
-
-func usage() {
-	fmt.Fprintf(os.Stderr, `Usage:
-    makemac <macos_version> e.g, darwin-amd64-10_10, darwin-amd64-11_0
-    makemac -status
-    makemac -auto
-`)
-	os.Exit(1)
-}
-
-var (
-	flagStatus     = flag.Bool("status", false, "print status only")
-	flagAuto       = flag.Bool("auto", false, "Automatically create & destroy as needed, reacting to https://farmer.golang.org/status/reverse.json status.")
-	flagListen     = flag.String("listen", ":8713", "HTTP status port; used by auto mode only")
-	flagNuke       = flag.Bool("destroy-all", false, "immediately destroy all running Mac VMs")
-	flagBaseDisk   = flag.String("base-disk", "", "debug mode: if set, print base disk of macOS version selected VM and exit")
-	flagDatacenter = flag.String("datacenter", "MacStadium-ATL", "target VMWare datacenter")
-	flagCluster    = flag.String("cluster", "MacPro_Cluster", "target VMWare cluster")
-)
-
-func main() {
-	flag.Parse()
-	numArg := flag.NArg()
-	ctx := context.Background()
-	if *flagBaseDisk != "" {
-		fv, err := hostTypeToVersion("host-" + *flagBaseDisk)
-		if err != nil {
-			log.Fatalf("unable to convert host=%q to VM", *flagBaseDisk)
-		}
-		baseDisk, err := findBaseDisk(ctx, fv)
-		if err != nil {
-			log.Fatal(err)
-		}
-		fmt.Println(baseDisk)
-		return
-	}
-	if *flagStatus {
-		numArg++
-	}
-	if *flagAuto {
-		numArg++
-	}
-	if *flagNuke {
-		numArg++
-	}
-	if numArg != 1 {
-		usage()
-	}
-	if *flagAuto {
-		autoLoop()
-		return
-	}
-	if *flagNuke {
-		state, err := getState(ctx)
-		if err != nil {
-			log.Fatal(err)
-		}
-		if err := state.DestroyAllMacs(ctx); err != nil {
-			log.Fatal(err)
-		}
-		return
-	}
-	v, err := hostTypeToVersion("host-" + flag.Arg(0))
-	if err != nil && !*flagStatus {
-		usage()
-	}
-
-	state, err := getState(ctx)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	if *flagStatus {
-		stj, _ := json.MarshalIndent(state, "", "  ")
-		fmt.Printf("%s\n", stj)
-		return
-	}
-
-	if _, err = state.CreateMac(ctx, v); err != nil {
-		log.Fatal(err)
-	}
-}
-
-// State is the state of the world.
-type State struct {
-	mu sync.Mutex
-
-	Hosts  map[string]int    // IP address -> running Mac VM count (including 0)
-	VMHost map[string]string // "mac_10_8_amd64_host02b" => "10.0.0.0"
-	HostIP map[string]string // "host-5" -> "10.0.0.0"
-	VMInfo map[string]VMInfo // "mac_10_8_amd64_host02b" => ...
-
-	// VMOfSlot maps from a "slot name" to the VMWare VM name.
-	//
-	// A slot name is a tuple of (host number, "a"|"b"), where "a"
-	// and "b" are the two possible guests that can run per host.
-	// This slot name of the form "macstadium_host02b" is what's
-	// reported as the host name to the coordinator.
-	//
-	// The map value is the VMWare vm name, such as "mac_10_8_amd64_host02b",
-	// and is the map key of VMHost and VMInfo above.
-	VMOfSlot map[string]string // "macstadium_host02b" => "mac_10_8_amd64_host02b"
-}
-
-type VMInfo struct {
-	IP       string
-	BootTime time.Time
-
-	// SlotName is the name of a place where we can run a VM.
-	// As of 2017-08-04 we have 20 slots total over 10 physical
-	// machines. (Two VMs per physical Mac Mini running ESXi)
-	// We use slot names of the form "macstadium_host02b"
-	// with a %02d digit host number and suffix 'a' and 'b'
-	// for which VM it is on that host.
-	//
-	// This slot name is also the name passed to the build
-	// coordinator as the coordinator's "host name". (which exists
-	// both for debugging, and for monitoring last-seen/uptime of
-	// dedicated builders.)
-	SlotName string
-}
-
-// NumCreatableVMs returns the number of VMs that can be created given
-// the current capacity.
-func (st *State) NumCreatableVMs() int {
-	st.mu.Lock()
-	defer st.mu.Unlock()
-	n := 0
-	for _, cur := range st.Hosts {
-		if cur < 2 {
-			n += 2 - cur
-		}
-	}
-	return n
-}
-
-// NumMacVMsOfVersion reports how many VMs are running the specified macOS version.
-func (st *State) NumMacVMsOfVersion(ver *Version) int {
-	st.mu.Lock()
-	defer st.mu.Unlock()
-
-	prefix := fmt.Sprintf("mac_%d_%d_%s_", ver.Major, ver.Minor, ver.Arch)
-	n := 0
-	for name := range st.VMInfo {
-		if strings.HasPrefix(name, prefix) {
-			n++
-		}
-	}
-	return n
-}
-
-// DestroyAllMacs runs "govc vm.destroy" on each running Mac VM.
-func (st *State) DestroyAllMacs(ctx context.Context) error {
-	st.mu.Lock()
-	defer st.mu.Unlock()
-	var ret error
-	for name := range st.VMInfo {
-		log.Printf("destroying %s ...", name)
-		err := govc(ctx, "vm.destroy", name)
-		log.Printf("vm.destroy(%q) = %v", name, err)
-		if err != nil && ret == nil {
-			ret = err
-		}
-	}
-	return ret
-}
-
-// guestType returns the appropriate VMWare guest type for the macOS version requested.
-func guestType(ver *Version) (string, error) {
-	switch ver.String() {
-	case "amd64_10.8":
-		return "darwin12_64Guest", nil
-	case "amd64_10.9":
-		return "darwin13_64Guest", nil
-	case "amd64_10.10":
-		return "darwin14_64Guest", nil
-	case "amd64_10.11":
-		return "darwin15_64Guest", nil
-	case "amd64_10.12":
-		return "darwin16_64Guest", nil
-	case "amd64_10.13":
-		// High Sierra. Requires vSphere 6.7.
-		// https://www.virtuallyghetto.com/2018/04/new-vsphere-6-7-apis-worth-checking-out.html
-		return "darwin17_64Guest", nil
-	case "amd64_10.14":
-		// Mojave. Requires vSphere 6.7.
-		// https://www.virtuallyghetto.com/2018/04/new-vsphere-6-7-apis-worth-checking-out.html
-		return "darwin18_64Guest", nil
-	case "amd64_10.15":
-		// Catalina. Requires vSphere 6.7 update 3.
-		// https://docs.macstadium.com/docs/vsphere-67-update-3
-		// vSphere 6.7 update 3 does not support the guestid `darwin19_64Guest` (which would be
-		// associated with macOS 10.15. It enables the creation of a macOS 10.15 vm via guestid
-		// `darwin18_64Guest`.
-		// TODO: Add a new GOS definition for darwin19_64 (macOS 10.15) in HWV >= 17
-		// https://github.com/vmware/open-vm-tools/commit/6297504ef9e139c68b65afe299136d041d690eeb
-		// TODO: investigate updating the guestid when we upgrade vSphere past version 6.7u3.
-		return "darwin18_64Guest", nil
-	case "amd64_11.0":
-		// Big Sur. Requires vSphere 6.7 update 3.
-		// https://docs.macstadium.com/docs/macos-version-in-your-vmware-cloud
-		return "darwin19_64Guest", nil
-	case "amd64_12.0":
-		// Determined experimentally to be the latest version by running:
-		// $ source govc_env_file
-		// $ govc vm.create -g darwin19_64Guest -ds GGLGTM-A-002-STV02 -net Private-1 -on=false heschi-test
-		// See also https://github.com/vmware/open-vm-tools/blob/master/open-vm-tools/lib/include/guest_os_tables.h.
-		return "darwin19_64Guest", nil
-	}
-	return "", fmt.Errorf("unsupported makemac OS X version %s", ver.String())
-}
-
-// CreateMac creates a VM running the requested macOS version.
-func (st *State) CreateMac(ctx context.Context, ver *Version) (slotName string, err error) {
-	st.mu.Lock()
-	defer st.mu.Unlock()
-
-	gt, err := guestType(ver)
-	if err != nil {
-		return "", err
-	}
-
-	hostType := fmt.Sprintf("host-darwin-%s-%d_%d", ver.Arch, ver.Major, ver.Minor)
-	key, err := ioutil.ReadFile(filepath.Join(os.Getenv("HOME"), "keys", hostType))
-	if err != nil {
-		return "", err
-	}
-	baseDisk, err := findBaseDisk(ctx, ver)
-	if err != nil {
-		return "", fmt.Errorf("failed to find osx_%s_%d_%d_frozen_nfs base disk: %v", ver.Arch, ver.Major, ver.Minor, err)
-	}
-
-	hostNum, hostWhich, err := st.pickHost()
-	if err != nil {
-		return "", err
-	}
-	name := fmt.Sprintf("mac_%d_%d_%s_host%02d%s", ver.Major, ver.Minor, ver.Arch, hostNum, hostWhich)
-	slotName = fmt.Sprintf("macstadium_host%02d%s", hostNum, hostWhich)
-
-	if err := govc(ctx, "vm.create",
-		"-m", "4096",
-		"-c", "6",
-		"-on=false",
-		"-net", "Private-1", // 172.17.20.0/24
-		"-g", gt,
-		"-pool", fmt.Sprintf("%s/Resources", *flagCluster),
-		// Put the config on the host's datastore, which
-		// forces the VM to run on that host:
-		"-ds", fmt.Sprintf("BOOT_%d", hostNum),
-		name,
-	); err != nil {
-		return "", err
-	}
-	defer func() {
-		if err != nil {
-			err := govc(ctx, "vm.destroy", name)
-			if err != nil {
-				log.Printf("failed to destroy %v: %v", name, err)
-			}
-		}
-	}()
-
-	if err := govc(ctx, "vm.change",
-		"-e", "smc.present=TRUE",
-		"-e", "ich7m.present=TRUE",
-		"-e", "firmware=efi",
-		"-e", fmt.Sprintf("guestinfo.key-%s=%s", hostType, strings.TrimSpace(string(key))),
-		"-e", "guestinfo.name="+name,
-		"-vm", name,
-	); err != nil {
-		return "", err
-	}
-
-	if err := govc(ctx, "device.usb.add", "-vm", name); err != nil {
-		return "", err
-	}
-
-	if err := govc(ctx, "vm.disk.attach",
-		"-vm", name,
-		"-link=true",
-		"-persist=false",
-		"-ds=GGLGTM-A-002-STV02",
-		"-disk", baseDisk,
-	); err != nil {
-		return "", err
-	}
-
-	if err := govc(ctx, "vm.power", "-on", name); err != nil {
-		return "", err
-	}
-	log.Printf("Success.")
-	return slotName, nil
-}
-
-// govc runs "govc <args...>" and ignores its output, unless there's an error.
-func govc(ctx context.Context, args ...string) error {
-	fmt.Fprintf(os.Stderr, "$ govc %v\n", strings.Join(args, " "))
-	out, err := exec.CommandContext(ctx, "govc", args...).CombinedOutput()
-	if err != nil {
-		if isFileSystemReadOnly() {
-			out = append(out, "; filesystem is read-only"...)
-		}
-		return fmt.Errorf("govc %s ...: %v, %s", args[0], err, out)
-	}
-	return nil
-}
-
-// esx management network IP range
-const hostIPPrefix = "10.87.58." // with fourth octet starting at 10
-
-var errNoHost = errors.New("no usable host found")
-
-// st.mu must be held.
-func (st *State) pickHost() (hostNum int, hostWhich string, err error) {
-	for ip, inUse := range st.Hosts {
-		if !strings.HasPrefix(ip, hostIPPrefix) {
-			continue
-		}
-		if inUse >= 2 {
-			// Apple policy.
-			continue
-		}
-		hostNum, err = strconv.Atoi(strings.TrimPrefix(ip, hostIPPrefix))
-		if err != nil {
-			return 0, "", err
-		}
-		hostNum -= 10   // 10.87.58.11 is "BOOT_1" datastore.
-		hostWhich = "a" // unless in use
-		if st.whichAInUse(hostNum) {
-			hostWhich = "b"
-		}
-		return
-	}
-	return 0, "", errNoHost
-}
-
-// whichAInUse reports whether a VM is running on the provided hostNum named
-// with suffix "_host<%02d>a", hostnum.
-//
-// st.mu must be held
-func (st *State) whichAInUse(hostNum int) bool {
-	suffix := fmt.Sprintf("_host%02da", hostNum)
-	for name := range st.VMHost {
-		if strings.HasSuffix(name, suffix) {
-			return true
-		}
-	}
-	return false
-}
-
-// vmNameReg is used to validate valid host names. Such as mac_11_12_amd64_host01b.
-var vmNameReg = regexp.MustCompile("^mac_[1-9][0-9]_[0-9][0-9]?_amd64_host[0-9][0-9](a|b)$")
-
-// getStat queries govc to find the current state of the hosts and VMs.
-func getState(ctx context.Context) (*State, error) {
-	st := &State{
-		VMHost:   make(map[string]string),
-		Hosts:    make(map[string]int),
-		HostIP:   make(map[string]string),
-		VMInfo:   make(map[string]VMInfo),
-		VMOfSlot: make(map[string]string),
-	}
-
-	var hosts elementList
-	p := fmt.Sprintf("/%s/host/%s", *flagDatacenter, *flagCluster)
-	if err := govcJSONDecode(ctx, &hosts, "ls", "-json", p); err != nil {
-		return nil, fmt.Errorf("getState: reading %s: %v", p, err)
-	}
-	for _, h := range hosts.Elements {
-		if h.Object.Self.Type == "HostSystem" {
-			ip := path.Base(h.Path)
-			st.Hosts[ip] = 0
-			st.HostIP[h.Object.Self.Value] = ip
-		}
-	}
-
-	var vms elementList
-	if err := govcJSONDecode(ctx, &vms, "ls", "-json", fmt.Sprintf("/%s/vm", *flagDatacenter)); err != nil {
-		return nil, fmt.Errorf("getState: reading /%s/vm: %v", *flagDatacenter, err)
-	}
-	for _, h := range vms.Elements {
-		if h.Object.Self.Type != "VirtualMachine" {
-			continue
-		}
-		name := path.Base(h.Path)
-		hostID := h.Object.Runtime.Host.Value
-		hostIP := st.HostIP[hostID]
-		st.VMHost[name] = hostIP
-		if hostIP != "" && vmNameReg.MatchString(name) {
-			st.Hosts[hostIP]++
-			var bootTime time.Time
-			if bt := h.Object.Summary.Runtime.BootTime; bt != "" {
-				bootTime, _ = time.Parse(time.RFC3339, bt)
-			}
-
-			var slotName string
-			if p := strings.Index(name, "_host"); p != -1 {
-				slotName = "macstadium" + name[p:] // macstadium_host02a
-
-				if exist := st.VMOfSlot[slotName]; exist != "" {
-					// Should never happen, but just in case.
-					log.Printf("ERROR: existing VM %q found in slot %q; destroying later VM %q", exist, slotName, name)
-					err := govc(ctx, "vm.destroy", name)
-					log.Printf("vm.destroy(%q) = %v", name, err)
-				} else {
-					st.VMOfSlot[slotName] = name // macstadium_host02a => mac_10_8_amd64_host02a
-				}
-			}
-
-			vi := VMInfo{
-				IP:       hostIP,
-				BootTime: bootTime,
-				SlotName: slotName,
-			}
-			st.VMInfo[name] = vi
-		}
-	}
-
-	return st, nil
-}
-
-// objRef is a VMWare "Managed Object Reference".
-type objRef struct {
-	Type  string // e.g. "VirtualMachine"
-	Value string // e.g. "host-12"
-}
-
-type elementList struct {
-	Elements []*elementJSON `json:"elements"`
-}
-
-type elementJSON struct {
-	Path   string
-	Object struct {
-		Self    objRef
-		Runtime struct {
-			Host objRef // for VMs; not present otherwise
-		}
-		Summary struct {
-			Runtime struct {
-				BootTime string // time.RFC3339 format, or empty if not running
-			}
-		}
-	}
-}
-
-// govcJSONDecode runs "govc <args...>" and decodes its JSON output into dst.
-func govcJSONDecode(ctx context.Context, dst interface{}, args ...string) error {
-	cmd := exec.CommandContext(ctx, "govc", args...)
-	stdout, err := cmd.StdoutPipe()
-	if err != nil {
-		return err
-	}
-	if err := cmd.Start(); err != nil {
-		return err
-	}
-	err = json.NewDecoder(stdout).Decode(dst)
-	if werr := cmd.Wait(); werr != nil && err == nil {
-		err = werr
-	}
-	return err
-}
-
-// findBaseDisk returns the path of the vmdk of the most recent
-// snapshot of the osx_$(arch)_$(major)_$(minor)_frozen_nfs VM.
-func findBaseDisk(ctx context.Context, ver *Version) (string, error) {
-	vmName := fmt.Sprintf("osx_%s_%d_%d_frozen_nfs", ver.Arch, ver.Major, ver.Minor)
-	out, err := exec.CommandContext(ctx, "govc", "vm.info", "-json", vmName).Output()
-	if err != nil {
-		return "", err
-	}
-	var ret struct {
-		VirtualMachines []struct {
-			Layout struct {
-				Snapshot []struct {
-					SnapshotFile []string
-				}
-			}
-		}
-	}
-	if err := json.Unmarshal(out, &ret); err != nil {
-		return "", fmt.Errorf("failed to parse vm.info JSON to find base disk: %v", err)
-	}
-	if n := len(ret.VirtualMachines); n != 1 {
-		if n == 0 {
-			return "", fmt.Errorf("VM %s not found", vmName)
-		}
-		return "", fmt.Errorf("len(ret.VirtualMachines) = %d; want 1 in JSON to find base disk: %v", n, err)
-	}
-	vm := ret.VirtualMachines[0]
-	if len(vm.Layout.Snapshot) < 1 {
-		return "", fmt.Errorf("VM %s does not have any snapshots; needs at least one", vmName)
-	}
-	ss := vm.Layout.Snapshot[len(vm.Layout.Snapshot)-1] // most recent snapshot is last in list
-
-	// Now find the first vmdk file, without its [datastore] prefix. The files are listed like:
-	/*
-	   "SnapshotFile": [
-	     "[GGLGLN-A-001-STV1] osx_amd64_10_14_frozen_nfs/osx_amd64_10_14_frozen_nfs-Snapshot2.vmsn",
-	     "[GGLGLN-A-001-STV1] osx_amd64_10_14_frozen_nfs/osx_amd64_10_14_frozen_nfs_15.vmdk",
-	     "[GGLGLN-A-001-STV1] osx_amd64_10_14_frozen_nfs/osx_amd64_10_14_frozen_nfs_15-000001.vmdk"
-	   ]
-	*/
-	for _, f := range ss.SnapshotFile {
-		if strings.HasSuffix(f, ".vmdk") {
-			i := strings.Index(f, "] ")
-			if i == -1 {
-				return "", fmt.Errorf("unexpected vmdk line %q in SnapshotFile", f)
-			}
-			return f[i+2:], nil
-		}
-	}
-	return "", fmt.Errorf("no VMDK found in snapshot for %v", vmName)
-}
-
-const autoAdjustTimeout = 5 * time.Minute
-
-var status struct {
-	sync.Mutex
-	lastCheck time.Time
-	lastLog   string
-	lastState *State
-	warnings  []string
-	errors    []string
-}
-
-func init() {
-	http.HandleFunc("/stage0/", handleStage0)
-	http.HandleFunc("/buildlet.darwin-amd64", handleBuildlet)
-	http.Handle("/", onlyAtRoot{http.HandlerFunc(handleStatus)}) // legacy status location
-	http.HandleFunc("/status", handleStatus)
-}
-
-func dedupLogf(format string, args ...interface{}) {
-	s := fmt.Sprintf(format, args...)
-	status.Lock()
-	defer status.Unlock()
-	if s == status.lastLog {
-		return
-	}
-	status.lastLog = s
-	log.Print(s)
-}
-
-func autoLoop() {
-	if addr := *flagListen; addr != "" {
-		go func() {
-			if err := http.ListenAndServe(*flagListen, nil); err != nil {
-				log.Fatalf("ListenAndServe: %v", err)
-			}
-		}()
-	}
-	for {
-		timer := time.AfterFunc(autoAdjustTimeout, watchdogFail)
-		autoAdjust()
-		timer.Stop()
-		time.Sleep(2 * time.Second)
-	}
-}
-
-func watchdogFail() {
-	stacks := make([]byte, 1<<20)
-	stacks = stacks[:runtime.Stack(stacks, true)]
-	log.Fatalf("timeout after %v waiting for autoAdjust(). stacks:\n%s",
-		autoAdjustTimeout, stacks)
-}
-
-func autoAdjust() {
-	status.Lock()
-	status.lastCheck = time.Now()
-	status.Unlock()
-
-	ctx, cancel := context.WithTimeout(context.Background(), autoAdjustTimeout)
-	defer cancel()
-
-	ro := isFileSystemReadOnly()
-
-	st, err := getState(ctx)
-	if err != nil {
-		status.Lock()
-		if ro {
-			status.errors = append(status.errors, "Host filesystem is read-only")
-		}
-		status.errors = []string{err.Error()}
-		status.Unlock()
-		log.Print(err)
-		return
-	}
-	var warnings, errors []string
-	if ro {
-		errors = append(errors, "Host filesystem is read-only")
-	}
-	defer func() {
-		// Set status.lastState once we're now longer using it.
-		if st != nil {
-			status.Lock()
-			status.lastState = st
-			status.warnings = warnings
-			status.errors = errors
-			status.Unlock()
-		}
-	}()
-
-	req, _ := http.NewRequestWithContext(ctx, "GET", "https://farmer.golang.org/status/reverse.json", nil)
-	res, err := http.DefaultClient.Do(req)
-	if err != nil {
-		errors = append(errors, fmt.Sprintf("getting /status/reverse.json from coordinator: %v", err))
-		log.Printf("getting reverse status: %v", err)
-		return
-	}
-	defer res.Body.Close()
-	var rstat types.ReverseBuilderStatus
-	if err := json.NewDecoder(res.Body).Decode(&rstat); err != nil {
-		errors = append(errors, fmt.Sprintf("decoding /status/reverse.json from coordinator: %v", err))
-		log.Printf("decoding reverse.json: %v", err)
-		return
-	}
-
-	revHost := make(map[string]*types.ReverseBuilder)
-	for hostType, hostStatus := range rstat.HostTypes {
-		if !hostOnMacStadium(hostType) {
-			continue
-		}
-		for name, revBuild := range hostStatus.Machines {
-			revHost[name] = revBuild
-		}
-	}
-
-	// Destroy running VMs that appear to be dead and not connected to the coordinator.
-	// TODO: do these all concurrently.
-	dirty := false
-	for name, vi := range st.VMInfo {
-		if vi.BootTime.After(time.Now().Add(-3 * time.Minute)) {
-			// Recently created. It takes about a minute
-			// to boot and connect to the coordinator, so
-			// give it 3 minutes of grace before killing
-			// it.
-			continue
-		}
-		rh := revHost[name]
-		if rh == nil {
-			// Look it up by its slot name instead.
-			rh = revHost[vi.SlotName]
-		}
-		if rh == nil {
-			log.Printf("Destroying VM %q unknown to coordinator...", name)
-			err := govc(ctx, "vm.destroy", name)
-			log.Printf("vm.destroy(%q) = %v", name, err)
-			dirty = true
-			if err != nil {
-				warnings = append(warnings, fmt.Sprintf("vm.destroy(%q) = %v", name, err))
-			}
-		}
-	}
-	for {
-		if dirty {
-			st, err = getState(ctx)
-			if err != nil {
-				errors = append(errors, err.Error())
-				log.Print(err)
-				return
-			}
-		}
-		canCreate := st.NumCreatableVMs()
-		if canCreate <= 0 {
-			dedupLogf("All Mac VMs running.")
-			return
-		}
-		ver := wantedMacVersionNext(st, &rstat)
-		if ver == nil {
-			dedupLogf("Have capacity for %d more Mac VMs, but none requested by coordinator.", canCreate)
-			return
-		}
-		dedupLogf("Have capacity for %d more Mac VMs; creating requested %d.%d_%s...", canCreate, ver.Major, ver.Minor, ver.Arch)
-		slotName, err := st.CreateMac(ctx, ver)
-		if err != nil {
-			errStr := fmt.Sprintf("Error creating %d.%d_%s: %v", ver.Major, ver.Minor, ver.Arch, err)
-			errors = append(errors, errStr)
-			log.Print(errStr)
-			return
-		}
-		log.Printf("Created %d.%d_%s VM on %q", ver.Major, ver.Minor, ver.Arch, slotName)
-		dirty = true
-	}
-}
-
-// Version represents a macOS version.
-// For example, Major=11 Minor=2 Arch=arm64 represents macOS 11.2 arm64.
-type Version struct {
-	Major int    // 10, 11, ...
-	Minor int    // 0, 1, 2, ...
-	Arch  string // amd64, arm64
-}
-
-func (v Version) String() string {
-	return fmt.Sprintf("%s_%d.%d", v.Arch, v.Major, v.Minor)
-}
-
-// hostTypeToVersion determines the version of macOS from the host type.
-// Sample host types would be: host-darwin-amd64-10_15 and host-darwin-arm64-11_0.
-func hostTypeToVersion(hostType string) (*Version, error) {
-	v := &Version{}
-	var err error
-	if !strings.HasPrefix(hostType, "host-darwin-") {
-		return nil, errors.New("unrecognized version")
-	}
-	htv := strings.TrimPrefix(hostType, "host-darwin-")
-	var majorMinor string
-	switch vs := strings.Split(htv, "-"); len(vs) {
-	case 2:
-		if vs[0] != "amd64" && vs[0] != "arm64" {
-			return nil, errors.New("unrecognized version")
-		}
-		v.Arch = vs[0]
-		majorMinor = vs[1]
-	default:
-		return nil, errors.New("unrecognized version")
-	}
-	switch mms := strings.Split(majorMinor, "_"); len(mms) {
-	case 1:
-		v.Major, err = strconv.Atoi(mms[0])
-		if err != nil {
-			return nil, err
-		}
-	case 2:
-		v.Major, err = strconv.Atoi(mms[0])
-		if err != nil {
-			return nil, err
-		}
-		v.Minor, err = strconv.Atoi(mms[1])
-		if err != nil {
-			return nil, err
-		}
-	default:
-		return nil, errors.New("unrecognized version")
-	}
-	return v, nil
-}
-
-// wantedMacVersionNext returns the macOS version to create next,
-// or nil to not make anything. It gets the latest reverse buildlet
-// status from the coordinator.
-func wantedMacVersionNext(st *State, rstat *types.ReverseBuilderStatus) *Version {
-	// TODO(go.dev/issue/35698): improve this logic now that
-	// the coordinator has a proper scheduler. Instead, don't
-	// create anything proactively until there's demand from it
-	// from the scheduler. (will need to add that to the coordinator's
-	// status JSON) And maybe add a streaming endpoint to the
-	// coordinator so we don't need to poll every N seconds. Or
-	// just poll every few seconds, perhaps at a lighter endpoint
-	// that only does darwin.
-	//
-	// For now just use the static configuration in
-	// dashboard/builders.go of how many are expected, which ends
-	// up in ReverseBuilderStatus.
-	for hostType, hostStatus := range rstat.HostTypes {
-		if !hostOnMacStadium(hostType) {
-			continue
-		}
-		ver, err := hostTypeToVersion(hostType)
-		if err != nil {
-			log.Printf("ERROR: unexpected host type %q", hostType)
-			continue
-		}
-		want := hostStatus.Expect - st.NumMacVMsOfVersion(ver)
-		if want > 0 {
-			return ver
-		}
-	}
-	return nil
-}
-
-func handleStatus(w http.ResponseWriter, r *http.Request) {
-	status.Lock()
-	defer status.Unlock()
-	w.Header().Set("Content-Type", "application/json")
-
-	// Locking the lastState shouldn't matter since we
-	// currently only set status.lastState once the
-	// *Status is no longer in use, but lock it anyway, in
-	// case usage changes in the future.
-	if st := status.lastState; st != nil {
-		st.mu.Lock()
-		defer st.mu.Unlock()
-	}
-
-	// TODO: probably more status, as needed.
-	res := &struct {
-		LastCheck string
-		LastLog   string
-		LastState *State
-		Warnings  []string
-		Errors    []string
-	}{
-		LastCheck: status.lastCheck.UTC().Format(time.RFC3339),
-		LastLog:   status.lastLog,
-		LastState: status.lastState,
-		Warnings:  status.warnings,
-		Errors:    status.errors,
-	}
-	j, _ := json.MarshalIndent(res, "", "\t")
-	w.Write(j)
-}
-
-// handleStage0 serves the shell script for buildlets to run on boot, based
-// on their macOS version.
-//
-// Starting with the macOS 10.14 (Mojave) image, their baked-in stage0.sh
-// script does:
-//
-//	while true; do (curl http://172.17.20.2:8713/stage0/$(sw_vers -productVersion)| sh); sleep 5; done
-func handleStage0(w http.ResponseWriter, r *http.Request) {
-	// ver will be like "10.14.4"
-	ver := strings.TrimPrefix(r.RequestURI, "/stage0/")
-	vs := strings.Split(ver, ".")
-	major, err := strconv.Atoi(vs[0])
-	if err != nil {
-		log.Printf("handleStage0 error converting version=%q; %s", ver, err)
-		major = 10
-	}
-
-	fmt.Fprintf(w, "set -e\nset -x\n")
-	fmt.Fprintf(w, "export GO_BUILDER_ENV=macstadium_vm\n")
-	fmt.Fprintf(w, "curl -o buildlet http://172.17.20.2:8713/buildlet.darwin-amd64\n")
-
-	// Starting with macOS 11.0, the work directory path generated by the buildlet is
-	// longer than permitted by certain net package tests. This is a workaround until
-	// a cleaner solution is implemeted.
-	if major >= 11 {
-		fmt.Fprint(w, "rm -rf /Users/gopher/workdir\n")
-		fmt.Fprint(w, "mkdir -p /Users/gopher/workdir\n")
-		fmt.Fprintf(w, "chmod +x buildlet; ./buildlet -workdir /Users/gopher/workdir")
-	} else {
-		fmt.Fprintf(w, "chmod +x buildlet; ./buildlet")
-	}
-}
-
-func handleBuildlet(w http.ResponseWriter, r *http.Request) {
-	bin, err := getLatestMacBuildlet(r.Context())
-	if err != nil {
-		log.Printf("error getting buildlet from GCS: %v", err)
-		http.Error(w, "error getting buildlet from GCS", 500)
-	}
-	w.Header().Set("Content-Length", fmt.Sprint(len(bin)))
-	w.Write(bin)
-}
-
-// buildlet binary caching by its last seen ETag from HEAD responses
-var (
-	buildletMu   sync.Mutex
-	lastEtag     string
-	lastBuildlet []byte // last buildlet binary for lastEtag
-)
-
-func getLatestMacBuildlet(ctx context.Context) (bin []byte, err error) {
-	req, _ := http.NewRequestWithContext(ctx, "HEAD", "https://storage.googleapis.com/go-builder-data/buildlet.darwin-amd64", nil)
-	res, err := http.DefaultClient.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	if res.StatusCode != 200 {
-		return nil, fmt.Errorf("%s from HEAD to %s", res.Status, req.URL)
-	}
-	etag := res.Header.Get("Etag")
-	if etag == "" {
-		return nil, fmt.Errorf("HEAD of %s lacked ETag", req.URL)
-	}
-
-	buildletMu.Lock()
-	if etag == lastEtag {
-		bin = lastBuildlet
-		log.Printf("served cached buildlet of %s", etag)
-		buildletMu.Unlock()
-		return bin, nil
-	}
-	buildletMu.Unlock()
-
-	log.Printf("fetching buildlet from GCS...")
-	req, _ = http.NewRequestWithContext(ctx, "GET", "https://storage.googleapis.com/go-builder-data/buildlet.darwin-amd64", nil)
-	res, err = http.DefaultClient.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	defer res.Body.Close()
-	if res.StatusCode != 200 {
-		return nil, fmt.Errorf("%s from GET to %s", res.Status, req.URL)
-	}
-	etag = res.Header.Get("Etag")
-	log.Printf("fetched buildlet from GCS with etag %s", etag)
-	if etag == "" {
-		return nil, fmt.Errorf("GET of %s lacked ETag", req.URL)
-	}
-	slurp, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		return nil, err
-	}
-
-	buildletMu.Lock()
-	defer buildletMu.Unlock()
-	lastEtag = etag
-	lastBuildlet = slurp
-	return lastBuildlet, nil
-}
-
-// onlyAtRoot is an http.Handler wrapper that enforces that it's
-// called at /, else it serves a 404.
-type onlyAtRoot struct{ h http.Handler }
-
-func (h onlyAtRoot) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.URL.Path != "/" {
-		http.NotFound(w, r)
-		return
-	}
-	h.h.ServeHTTP(w, r)
-}
-
-func isFileSystemReadOnly() bool {
-	f, err := os.Open("/proc/mounts")
-	if err != nil {
-		return false
-	}
-	defer f.Close()
-	// Look for line:
-	//    /dev/sda1 / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0
-	bs := bufio.NewScanner(f)
-	for bs.Scan() {
-		f := strings.Fields(bs.Text())
-		if len(f) < 4 {
-			continue
-		}
-		mountPoint, state := f[1], f[3]
-		if mountPoint == "/" {
-			return strings.HasPrefix(state, "ro,")
-		}
-	}
-	return false
-}
-
-// onMacStadiumReg matches host names for hosts that are hosted on MacStadium.
-var onMacStadiumReg = regexp.MustCompile("^host-darwin-amd64-[1-9][0-9]+_[0-9]+$")
-
-// hostOnMacstadium is true if the host type is hosted on the MacStadium cluster.
-func hostOnMacStadium(hostType string) bool {
-	return onMacStadiumReg.MatchString(hostType)
-}
diff --git a/cmd/makemac/makemac.service b/cmd/makemac/makemac.service
deleted file mode 100644
index ea009a0..0000000
--- a/cmd/makemac/makemac.service
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=Go Builders - makemac
-Documentation=https://github.com/golang/build/blob/master/cmd/makemac/makemac.go
-After=network.target
-
-[Service]
-User=gopher
-Environment="PATH=/home/gopher/bin:/usr/local/bin:/usr/bin"
-# The following file declares these variables: GOVC_URL GOVC_USERNAME GOVC_PASSWORD GOVC_INSECURE
-EnvironmentFile=/home/gopher/govc_env_file
-ExecStart=/home/gopher/makemac -auto
-Restart=always
-RestartSec=3
-
-[Install]
-WantedBy=multi-user.target
diff --git a/cmd/makemac/makemac_test.go b/cmd/makemac/makemac_test.go
deleted file mode 100644
index b1ee314..0000000
--- a/cmd/makemac/makemac_test.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-)
-
-func TestHostTypeToVersion(t *testing.T) {
-	testCases := []struct {
-		desc        string
-		hostType    string
-		wantVersion *Version
-	}{
-		{
-			desc:     "valid original darwin host type",
-			hostType: "host-darwin-amd64-10_14",
-			wantVersion: &Version{
-				Major: 10,
-				Minor: 14,
-				Arch:  "amd64",
-			},
-		},
-		{
-			desc:     "valid original darwin host type",
-			hostType: "host-darwin-amd64-10_15",
-			wantVersion: &Version{
-				Major: 10,
-				Minor: 15,
-				Arch:  "amd64",
-			},
-		},
-		{
-			desc:     "valid newer darwin host ARM64",
-			hostType: "host-darwin-arm64-11_0",
-			wantVersion: &Version{
-				Major: 11,
-				Minor: 0,
-				Arch:  "arm64",
-			},
-		},
-		{
-			desc:     "valid newer darwin host AMD64",
-			hostType: "host-darwin-amd64-11_1",
-			wantVersion: &Version{
-				Major: 11,
-				Minor: 1,
-				Arch:  "amd64",
-			},
-		},
-		{
-			desc:     "valid newer darwin host AMD64",
-			hostType: "host-darwin-amd64-13",
-			wantVersion: &Version{
-				Major: 13,
-				Minor: 0,
-				Arch:  "amd64",
-			},
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			got, err := hostTypeToVersion(tc.hostType)
-			if err != nil {
-				t.Fatalf("hostTypeToVersion(%q) = %v, %s; want no error", tc.hostType, got, err)
-			}
-			if diff := cmp.Diff(tc.wantVersion, got); diff != "" {
-				t.Errorf("hostTypeToVersion(%q) = (-want +got):\n%s", tc.hostType, diff)
-			}
-		})
-	}
-}
-
-func TestHostTypeToVersionError(t *testing.T) {
-	testCases := []struct {
-		desc     string
-		hostType string
-		wantErr  error
-	}{
-		{
-			desc:     "empty string",
-			hostType: "",
-		},
-		{
-			desc:     "invalid newer darwin host ARM64",
-			hostType: "host-darwin-amd64-11_1-toothrot",
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			if got, gotErr := hostTypeToVersion(tc.hostType); got != nil || gotErr == nil {
-				t.Errorf("hostTypeToVersion(%q) = %+v, %s; want nil, error", tc.hostType, got, gotErr)
-			}
-		})
-	}
-}
-
-func TestHostOnMacStadium(t *testing.T) {
-	testCases := []struct {
-		desc     string
-		hostType string
-		want     bool
-	}{
-		{
-			desc:     "empty string",
-			hostType: "",
-			want:     false,
-		},
-		{
-			desc:     "valid original darwin host",
-			hostType: "host-darwin-amd64-10_14",
-			want:     true,
-		},
-		{
-			desc:     "valid newer darwin host",
-			hostType: "host-darwin-amd64-11_0",
-			want:     true,
-		},
-		{
-			desc:     "invalid newer darwin host type",
-			hostType: "host-darwin-arm64-11_0-toothrot",
-			want:     false,
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			if got := hostOnMacStadium(tc.hostType); got != tc.want {
-				t.Errorf("hostOnMacStadium(%q) = %t; want %t", tc.hostType, got, tc.want)
-			}
-		})
-	}
-}
-
-func TestVMNameReg(t *testing.T) {
-	testCases := []struct {
-		desc   string
-		vmName string
-		want   bool
-	}{
-		{
-			desc:   "empty string",
-			vmName: "",
-			want:   false,
-		},
-		{
-			desc:   "invalid original darwin host",
-			vmName: "mac_10_11_host01b",
-			want:   false,
-		},
-		{
-			desc:   "valid newer darwin host",
-			vmName: "mac_11_12_amd64_host01b",
-			want:   true,
-		},
-		{
-			desc:   "valid newer darwin host",
-			vmName: "mac_11_20_amd64_host05a",
-			want:   true,
-		},
-		{
-			desc:   "invalid newer darwin host type",
-			vmName: "host-darwin-arm64-11_0-toothrot",
-			want:   false,
-		},
-		{
-			desc:   "invalid bastion host",
-			vmName: "dns_server",
-			want:   false,
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.desc, func(t *testing.T) {
-			if got := vmNameReg.MatchString(tc.vmName); got != tc.want {
-				t.Errorf("vmNameReg.MatchString(%q) = %t; want %t", tc.vmName, got, tc.want)
-			}
-		})
-	}
-}
diff --git a/dashboard/builders.go b/dashboard/builders.go
index b2f7322..7ee6548 100644
--- a/dashboard/builders.go
+++ b/dashboard/builders.go
@@ -100,7 +100,9 @@
 	"windows-386":           "windows-386-2008",
 	"windows-amd64":         "windows-amd64-2016",
 	"windows-arm":           "windows-arm-zx2c4",
-	"windows-arm64":         "windows-arm64-11",
+	// TODO:(golang/go#47019) - uncomment when builder returns and
+	//   update test.
+	// "windows-arm64":         "windows-arm64-11",
 }
 
 // Builders are the different build configurations.
@@ -569,22 +571,11 @@
 		VMImage:     "windows-amd64-server-2016-v7",
 		SSHUsername: "gopher",
 	},
-	"host-windows-arm64-mini": { // host name known to cmd/buildlet/stage0, cannot change
-		Notes:     "MacStadium mac minis hosting Windows 10 in qemu with HVM acceleration.",
-		IsReverse: true,
-		ExpectNum: 2,
-	},
 	"host-windows-arm64-zx2c4": {
 		IsReverse: true,
 		ExpectNum: 0,
 		Owners:    []*gophers.Person{gh("zx2c4")},
 	},
-	"host-windows11-arm64-mini": { // host name known to cmd/buildlet/stage0, cannot change
-		Notes:     "MacStadium mac minis hosting Windows 11 in qemu with HVM acceleration.",
-		HostArch:  "windows-arm64",
-		IsReverse: true,
-		ExpectNum: 5,
-	},
 }
 
 func gh(githubUsername string) *gophers.Person {
@@ -2481,24 +2472,6 @@
 			"GO_TEST_TIMEOUT_SCALE=3"},
 	})
 	addBuilder(BuildConfig{
-		Name:              "windows-arm64-10",
-		HostType:          "host-windows-arm64-mini",
-		numTryTestHelpers: 1,
-		env: []string{
-			"GOARCH=arm64",
-		},
-	})
-	addBuilder(BuildConfig{
-		Name:              "windows-arm64-11",
-		HostType:          "host-windows11-arm64-mini",
-		numTryTestHelpers: 1,
-		env: []string{
-			"GOARCH=arm64",
-			"GOMAXPROCS=4", // OOM problems, see go.dev/issue/51019
-		},
-		KnownIssues: []int{51019},
-	})
-	addBuilder(BuildConfig{
 		Name:           "darwin-amd64-10_14",
 		HostType:       "host-darwin-amd64-10_14-aws",
 		distTestAdjust: macTestPolicy,
diff --git a/dashboard/builders_test.go b/dashboard/builders_test.go
index 49e4554..a18f2b3 100644
--- a/dashboard/builders_test.go
+++ b/dashboard/builders_test.go
@@ -729,7 +729,10 @@
 	}
 	ports := strings.Fields(string(out))
 
-	done := map[string]bool{}
+	done := map[string]bool{
+		// TODO:(golang/go#47019) - remove when alias added
+		"windows-arm64": true,
+	}
 
 	var add bytes.Buffer
 	check := func(term string, isArch bool) {
@@ -879,23 +882,6 @@
 	}
 }
 
-// TestExpectedMacstadiumVMCount ensures that the right number of
-// instances of macOS virtual machines are expected at MacStadium.
-//
-// TODO(go.dev/issue/35698): remove once the scheduler allocates VMs based on demand.
-func TestExpectedMacstadiumVMCount(t *testing.T) {
-	t.Skip("MacStadium turndown")
-	got := 0
-	for host, config := range Hosts {
-		if strings.HasPrefix(host, "host-darwin-amd64-") && !strings.HasSuffix(host, "-aws") {
-			got += config.ExpectNum
-		}
-	}
-	if got != 16 {
-		t.Fatalf("macstadium host count: got %d; want 16", got)
-	}
-}
-
 // Test that we have longtest builders and
 // that their environment configurations are okay.
 func TestLongTestBuilder(t *testing.T) {
diff --git a/env/darwin/macstadium/10_11/Makefile b/env/darwin/macstadium/10_11/Makefile
deleted file mode 100644
index f763396..0000000
--- a/env/darwin/macstadium/10_11/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-usage: FORCE
-	# See Makefile targets.
-	exit 1
-
-FORCE:
-
-upload: FORCE
-	go install golang.org/x/build/cmd/upload
-	upload --verbose --gzip --file=run-builder-darwin-10_11.sh -cacheable=false -public=true go-builder-data/run-builder-darwin-10_11.gz
diff --git a/env/darwin/macstadium/10_11/stage0.sh b/env/darwin/macstadium/10_11/stage0.sh
deleted file mode 100755
index 0894e8e..0000000
--- a/env/darwin/macstadium/10_11/stage0.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-# Copyright 2022 Go Authors All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-
-# This is the file baked into the OS X 10.11 VM image. It is ALSO
-# baked into the macOS 10.12 Sierra image. (That is, both 10.11 and
-# 10.12 download and run the run-builder-darwin-10_11.gz URL)
-#
-# It is not used on modern OS X versions.
-#
-# Normally our VMs & containers actually have the cmd/buildlet/stage0
-# binary baked-in, but the Mac VM images are extra painful to
-# configure, so there's an extra level of indirection in their boot
-# process to give us this point of flexibility. This shell script then
-# downloads run-builder-darwin-10_11.gz which is the cmd/buildlet/stage0
-# binary, compressed.
-
-set -e
-url="https://storage.googleapis.com/go-builder-data/run-builder-darwin-10_11.gz"
-while ! curl -f -o run-builder.gz "$url"; do
-    echo
-    echo "curl failed to fetch $url"
-    echo "Sleeping before retrying..."
-    sleep 2
-done
-
-set -x
-gunzip -f run-builder.gz
-chmod +x run-builder
-exec ./run-builder
diff --git a/env/darwin/macstadium/README.md b/env/darwin/macstadium/README.md
deleted file mode 100644
index d93055f..0000000
--- a/env/darwin/macstadium/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Overview
-
-Go's Mac builders run at Mac hosting provider,
-[MacStadium](https://macstadium.com). We have a VMware cluster with 8
-physical Mac Pros on which we run two VMs each. There is also a single M1 Mac Mini.
-
-In addition to the Mac VMs and M1 Mac mini, we also run one a Linux VM that's our
-bastion host & runs various services.
-
-## Bastion Host
-
-The bastion host is **macstadiumd.golang.org** and can be accessed
-via:
-
-    $ ssh -D :1080 -i ~/keys/id_ed25519_golang1 gopher@macstadiumd.golang.org
-
-(Where `id_ed255519_golang1` is available from go/go-builders-ssh)
-
-It also runs:
-
-* a DHCP server for the 16 Mac VMs to get IP addresses from (systemd
-  unit `isc-dhcp-server.service`, so watch with `journalctl -f -u
-  isc-dhcp-server.service`)
-
-* the [**makemac** daemon](../../../cmd/makemac/) daemon (systemd
-  unit `makemac.service`, so watch with `journalctl -f -u makemac`).
-  This monitors the build coordinator (farmer.golang.org) as well as
-  the VMware cluster (via the [`govc` CLI
-  tool](https://github.com/vmware/govmomi/tree/master/govc)) and makes
-  and destroys Mac VMs as needed. It also serves plaintext HTTP status
-  at http://macstadiumd.golang.org:8713 which used to be accessible in
-  a browser, but recent HSTS configuration on `*.golang.org` means you
-  need to use curl now. But that's a good way to see what it's doing
-  remotely, without authentication.
-
-* [WireGuard](https://www.wireguard.com/) listening on port 51820,
-  because OpenVPN + Mac's built-in VPN client is painful and buggy.
-  See config in `/etc/wireguard/wg0.conf`. This doesn't yet come up on
-  boot. It's a recent addition.
-
-## OpenVPN
-
-The method of last resort to access the cluster, which works even if
-the bastion host VM is down, is to VPN to our Cisco gateway via go/go-how-to-vpn-into-macstadium.
-
-## VMware web UI
-
-Connect with OpenVPN, WireGuard, or configure your browser to use
-localhost:1080 as a SOCKS proxy. Add:
-
-10.87.58.9      vcenter.gglgtm-a-002.macstadium.com
-
-to your hosts file, then access the UI at https://vcenter.gglgtm-a-002.macstadium.com.
-
-VMware web UI at:
-
-   https://10.87.58.9/ui/
-
-## Adding a New Image
-
-When a new version of macOS is released:
-
-* Ensure that the version of vSphere deployed on MacStadium supports the
-  new version of macOS. If it doesn't, either request that MacStadium
-  upgrade the cluster or seek guidance from them about the upgrade path.
-
-* Clone the latest macOS version on vSphere and upgrade that version
-  to the desired macOS version as per the [instructions](vmware-notes.md).
-
-* If a completely new image is required, follow the [images setup notes](../setup-notes.md)
-  in order to add a new image.
-
-## Debugging
-
-Common techniques to debug:
-
-* Can you get to the bastion host?
-
-* What does `journalctl -f -u makemac` say? Is it error looping?
-
-* Look at https://10.87.58.9/ui/ and see if VMware is unhappy about
-  things. Did hosts die? Did storage disappear?
-
-* Need to hard reboot machines? Eventually we'll fix
-  https://github.com/golang/go/issues/32033 but for now you can use
-  https://portal.macstadium.com/subscriptions and power cycle
-  machines that VMware reports dead (or that you see missing from
-  [https://farmer.golang.org](https://farmer.golang.org)'s reverse pool info).
-
-* Worst case, file a ticket: https://portal.macstadium.com/tickets
diff --git a/env/darwin/macstadium/vmware-notes.md b/env/darwin/macstadium/vmware-notes.md
deleted file mode 100644
index 2618549..0000000
--- a/env/darwin/macstadium/vmware-notes.md
+++ /dev/null
@@ -1,36 +0,0 @@
-* Create a new virtual machine stored in GGLGTM*, with the most recent 
-  supported version of macOS as the guest OS. Configure it with 2 CPUs,
-  4 GB RAM, 60+ GiB of disk, and mount the installer ISO from ISO/OSX.
-* Setup OS X following setup-notes.md.
-* Shut it down.
-* Clone to Virtual Machine (convention: "osx_amd64_11_0_frozen" for macOS
-  11.0")
-* Snapshot that new frozen VM once to make its vmdk in COW format.
-* Clone it again to _frozen_nfs; nobody quite knows why we do this
-  but it's the required format for makemac.
-
-Then change makemac to know about the new OS, and add the new reverse builders
-and build to the coordinator.
-
-Other misc notes:
-
-```bash
-$ source govc_env_file
-$ govc vm.info -json mac_11_0_amd64_host07a | jq . | grep MacAdd
-              "MacAddress": "00:50:56:b4:05:57",
-```
-
-if sleep failing,
-```bash
-sudo pmset -a hibernatemode 25
-sudo pmset sleepnow
-```
-
-```bash
-pmset -g assertions     # RemovableMedia mounted
-system_profiler  # to see which
-```
-
-https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1012225
-  ... doesn't seem to work
-  ... but changing from SATA to IDE does make the RemovableMedia assertion go away (but `pmset sleepnow` stil doesn't work)
diff --git a/env/darwin/setup-notes.md b/env/darwin/setup-notes.md
index 8db0273..8ff3c6b 100644
--- a/env/darwin/setup-notes.md
+++ b/env/darwin/setup-notes.md
@@ -1,18 +1,3 @@
-# For VMWare VMs only #
-
-The Disk should be formatted with a case insensitive file system (default).
-
-Install VMWare tools daemon.
-
-  - The UI is supposed to be able to do this automatically, but it's broken as of writing.
-  - Instead, mount darwin.iso from ISO/VMWARE TOOLS and run the installer from there.
-  - open security preferences and click "Allow" on blocked software install from VMware
-  - reboot
-  - make sure you can run and see:
-
-    $ /Library/Application Support/VMware Tools/vmware-tools-daemon --cmd "info-get guestinfo.name"
-    No value found
-
 # For all machine types
 
 - Turn on the computer.
@@ -37,12 +22,6 @@
 
 Create `$HOME/stage0.sh`.
 
-**For VMWare VMs**
-```
-#!/bin/bash
-while true; do (curl -v http://172.17.20.2:8713/stage0/$(sw_vers -productVersion) | sh); sleep 5; done
-```
-
 **For physical machines**
 ```
 #!/bin/bash
diff --git a/env/windows-arm64/macstadium/image-setup-notes.txt b/env/windows-arm64/macstadium/image-setup-notes.txt
deleted file mode 100644
index d876fb5..0000000
--- a/env/windows-arm64/macstadium/image-setup-notes.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-The Disk should be formatted with a case insensitive file system (default).
-
-System Preferences > Software Update > off
-
-System Preferences > Desktop & Screensaver > never screensaver
-
-System Preferences > Energy Saver > never sleep
-
-System Preferences > Energy Saver > start up automatically after power failure
-
-System Preferences > Sharing > enable ssh (enable for administrators)
-
-windows image:
-
-  gsutil cp gs://go-builder-data/windows-arm64.20210629.tar.xz ./windows-arm64.20210629.tar.xz
-  scp windows-arm64.20210629.tar.xz your-macmini-instance:~/
-  ssh your-macmini-instance
-  # The following will create a directory called macmini-windows with image and qemu binaries inside:
-  tar xf windows-arm64-20210629.tar.xz
-
-Automator:
-
-  scp env/windows-arm64/macstadium/winloop.sh your-macmini-instance:~/macmini-windows/winloop.sh
-  # On buildlet host:
-  chmod u+x ~/macmini-windows/winloop.sh
-  File > New > Application
-  [+] Run shell script
-  [ open -a Terminal.app $HOME/macmini-windows/winloop.sh ]
-  Save to desktop as "run-builder"
-
-System Preferences > Users & Groups > auto-login "gopher" user, run Desktop/run-builder (automator app)
-
-passwordless sudo:
-
-  sudo visudo
-  Change line from:
-   %admin ALL=(ALL) ALL
-  to:
-   %admin ALL=(ALL) NOPASSWD: ALL
-
-verbose boot: (text instead of apple image)
-
-  sudo nvram boot-args="-v"
diff --git a/env/windows-arm64/macstadium/winloop.sh b/env/windows-arm64/macstadium/winloop.sh
deleted file mode 100755
index 164a89f..0000000
--- a/env/windows-arm64/macstadium/winloop.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-# Copyright 2022 Go Authors All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-
-while true; do
-  DYLD_LIBRARY_PATH="$HOME/macmini-windows/sysroot-macos-arm64/lib" "$HOME/macmini-windows/sysroot-macos-arm64/bin/qemu-system-aarch64" \
-    -L ./UTM.app/Contents/Resources/qemu \
-    -device ramfb \
-    -cpu max \
-    -smp cpus=8,sockets=1,cores=8,threads=1 \
-    -machine virt,highmem=off \
-    -accel hvf \
-    -accel tcg,tb-size=1536 \
-    -boot menu=on \
-    -m 8192 \
-    -name "Virtual Machine" \
-    -device qemu-xhci,id=usb-bus \
-    -device usb-tablet,bus=usb-bus.0 \
-    -device usb-mouse,bus=usb-bus.0 \
-    -device usb-kbd,bus=usb-bus.0 \
-    -bios "$HOME/macmini-windows/Images/QEMU_EFI.fd" \
-    -device nvme,drive=drive0,serial=drive0,bootindex=0 \
-    -drive "if=none,media=disk,id=drive0,file=$HOME/macmini-windows/Images/win10.qcow2,cache=writethrough" \
-    -device usb-storage,drive=drive2,removable=true,bootindex=1 \
-    -drive "if=none,media=cdrom,id=drive2,file=$HOME/macmini-windows/Images/virtio.iso,cache=writethrough" \
-    -device virtio-net-pci,netdev=net0 \
-    -netdev user,id=net0 \
-    -uuid 41E1CBA2-8837-4224-801B-277336D58A3D \
-    -snapshot \
-    -vnc :3
-  sleep 5
-done
diff --git a/internal/coordinator/pool/reverse.go b/internal/coordinator/pool/reverse.go
index a58fb43..7645483 100644
--- a/internal/coordinator/pool/reverse.go
+++ b/internal/coordinator/pool/reverse.go
@@ -35,7 +35,6 @@
 	"context"
 	"crypto/hmac"
 	"crypto/md5"
-	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
@@ -51,7 +50,6 @@
 	"golang.org/x/build/dashboard"
 	"golang.org/x/build/internal/coordinator/pool/queue"
 	"golang.org/x/build/revdial/v2"
-	"golang.org/x/build/types"
 )
 
 const minBuildletVersion = 23
@@ -117,56 +115,6 @@
 	return t, ok
 }
 
-// ServeReverseStatusJSON is an HTTP handler implementation which serves the status in
-// JSON format.
-func (p *ReverseBuildletPool) ServeReverseStatusJSON(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "application/json")
-	status := p.BuildReverseStatusJSON()
-	j, _ := json.MarshalIndent(status, "", "\t")
-	w.Write(j)
-}
-
-// BuildReverseStatusJSON is an HTTP handler implementation which builds the reverse
-// status reverse buildlets.
-func (p *ReverseBuildletPool) BuildReverseStatusJSON() *types.ReverseBuilderStatus {
-	status := &types.ReverseBuilderStatus{}
-
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	for _, b := range p.buildlets {
-		hs := status.Host(b.hostType)
-		if hs.Machines == nil {
-			hs.Machines = make(map[string]*types.ReverseBuilder)
-		}
-		hs.Connected++
-		bs := &types.ReverseBuilder{
-			Name:         b.hostname,
-			HostType:     b.hostType,
-			ConnectedSec: time.Since(b.regTime).Seconds(),
-			Version:      b.version,
-		}
-		if b.inUse && !b.inHealthCheck {
-			hs.Busy++
-			bs.Busy = true
-			bs.BusySec = time.Since(b.inUseTime).Seconds()
-		} else {
-			hs.Idle++
-			bs.IdleSec = time.Since(b.inUseTime).Seconds()
-		}
-
-		hs.Machines[b.hostname] = bs
-	}
-	for hostType, queue := range p.hostQueue {
-		status.Host(hostType).Waiters = queue.Len()
-	}
-	for hostType, hc := range dashboard.Hosts {
-		if hc.ExpectNum > 0 {
-			status.Host(hostType).Expect = hc.ExpectNum
-		}
-	}
-	return status
-}
-
 // tryToGrab returns non-nil bc on success if a buildlet is free.
 //
 // Otherwise it returns how many were busy, which might be 0 if none