cmd/coordinator: don't run racecompile builder on old commits

We still run some of it (at least for now, it's harmless, and in its
own goroutine), but not the -c part.

Fixes golang/go#20222

Change-Id: I37a39a41c8a5f2ebaee70aeba390c58b22399d3d
Reviewed-on: https://go-review.googlesource.com/43619
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
diff --git a/cmd/coordinator/Dockerfile.0 b/cmd/coordinator/Dockerfile.0
index 6d7a2ff..4d5095a 100644
--- a/cmd/coordinator/Dockerfile.0
+++ b/cmd/coordinator/Dockerfile.0
@@ -52,6 +52,9 @@
 RUN cd /go/src/google.golang.org/grpc && \
     git reset --hard 50955793b0183f9de69bd78e2ec251cf20aab121
 
+RUN go get go4.org/grpc && \
+    cd /go/src/go4.org/grpc && git reset --hard 32ab3eb96f50a8c0f4103aa8d149cd1f15576636
+
 # Makefile passes a string with --build-arg version
 # This becomes part of the cache key for all subsequent instructions,
 # so it must not be placed above the "go get" commands above.
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index e647453..2b469a7 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -43,6 +43,7 @@
 	"sync/atomic"
 	"time"
 
+	"go4.org/grpc"
 	"go4.org/syncutil"
 
 	"cloud.google.com/go/storage"
@@ -55,6 +56,7 @@
 	"golang.org/x/build/internal/lru"
 	"golang.org/x/build/internal/singleflight"
 	"golang.org/x/build/livelog"
+	"golang.org/x/build/maintner/maintnerd/apipb"
 	"golang.org/x/build/types"
 	"golang.org/x/crypto/acme/autocert"
 	perfstorage "golang.org/x/perf/storage"
@@ -113,6 +115,8 @@
 	subTryBuilders []dashboard.BuildConfig // for testing sub-repos
 )
 
+var maintnerClient apipb.MaintnerServiceClient
+
 func initTryBuilders() {
 	for _, name := range dashboard.TrybotBuilderNames() {
 		conf := dashboard.Builders[name]
@@ -261,6 +265,12 @@
 		log.Fatalf("Unknown mode: %q", *mode)
 	}
 
+	cc, err := grpc.NewClient(http.DefaultClient, "https://maintner.golang.org")
+	if err != nil {
+		log.Fatal(err)
+	}
+	maintnerClient = apipb.NewMaintnerServiceClient(cc)
+
 	http.HandleFunc("/", handleStatus)
 	http.HandleFunc("/debug/goroutines", handleDebugGoroutines)
 	http.HandleFunc("/debug/watcher/", handleDebugWatcher)
@@ -1843,6 +1853,39 @@
 // caller, runMake, per builder config).
 // The idea is that this might find data races in cmd/compile.
 func (st *buildStatus) runConcurrentGoBuildStdCmd(bc *buildlet.Client) (remoteErr, err error) {
+	// Only run this step if this rev has the cmd/compile -c flag.
+	// See Issue 20222.
+	qctx, cancel := context.WithTimeout(st.ctx, 30*time.Second)
+	defer cancel()
+	spanha := st.createSpan("ask_maintner_has_ancestor")
+	for {
+		const dashCRev = "22f1b56dab29d397d2bdbdd603d85e60fb678089"
+		res, err := maintnerClient.HasAncestor(qctx, &apipb.HasAncestorRequest{
+			Commit:   st.rev,
+			Ancestor: dashCRev,
+		})
+		if err != nil {
+			log.Printf("HasAncestor(%q, %q) error: %v", st.rev, dashCRev, err)
+			spanha.done(err)
+			return nil, err
+		}
+		if res.UnknownCommit {
+			select {
+			case <-qctx.Done():
+				return qctx.Err(), nil
+			case <-time.After(1 * time.Second):
+			}
+			continue
+		}
+		spanha.done(nil)
+		if !res.HasAncestor {
+			// Old commit (e.g. 1.8 branch). Don't test.
+			return nil, nil
+		}
+		// Recent commit. Break & test.
+		break
+	}
+
 	span := st.createSpan("go_build_c128_std_cmd")
 	remoteErr, err = bc.Exec("go/bin/go", buildlet.ExecOpts{
 		Output:   st,