cmd/coordinator: restore partial support for -mode=dev

Set gceMode earlier in InitGCE. Its value is used by some of the code
that runs inside InitGCE.

Don't try to run gcePool.pollQuotaLoop in dev mode. Make the code more
clear and consistent about this and createBasepinDisks calls.

Merge oAuthHTTPClient into the "Initialized by InitGCE" var block above.

Remove initGCECalled, it has become unused.

For golang/go#34744.
For golang/go#38337.

Change-Id: Ic47870fa9aed0eded0cfdf14e18e63c1acda4554
Reviewed-on: https://go-review.googlesource.com/c/build/+/244398
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Alexander Rakoczy <alex@golang.org>
diff --git a/internal/coordinator/pool/gce.go b/internal/coordinator/pool/gce.go
index 5efac05..76a1b03 100644
--- a/internal/coordinator/pool/gce.go
+++ b/internal/coordinator/pool/gce.go
@@ -65,7 +65,7 @@
 // is a GCE remote buildlet.
 type IsGCERemoteBuildletFunc func(instanceName string) bool
 
-// Initialized by initGCE:
+// Initialized by InitGCE:
 // TODO(http://golang.org/issue/38337): These should be moved into a struct as
 // part of the effort to reduce package level variables.
 var (
@@ -74,16 +74,18 @@
 	// dsClient is a datastore client for the build project (symbolic-datum-552), where build progress is stored.
 	dsClient *datastore.Client
 	// goDSClient is a datastore client for golang-org, where build status is stored.
-	goDSClient     *datastore.Client
-	computeService *compute.Service
-	gcpCreds       *google.Credentials
-	errTryDeps     error // non-nil if try bots are disabled
-	gerritClient   *gerrit.Client
-	storageClient  *storage.Client
-	metricsClient  *monapi.MetricClient
-	inStaging      bool                   // are we running in the staging project? (named -dev)
-	errorsClient   *errorreporting.Client // Stackdriver errors client
-	gkeNodeIP      string
+	goDSClient *datastore.Client
+	// oAuthHTTPClient is the OAuth2 HTTP client used to make API calls to Google Cloud APIs.
+	oAuthHTTPClient *http.Client
+	computeService  *compute.Service
+	gcpCreds        *google.Credentials
+	errTryDeps      error // non-nil if try bots are disabled
+	gerritClient    *gerrit.Client
+	storageClient   *storage.Client
+	metricsClient   *monapi.MetricClient
+	inStaging       bool                   // are we running in the staging project? (named -dev)
+	errorsClient    *errorreporting.Client // Stackdriver errors client
+	gkeNodeIP       string
 
 	// values created due to seperating the buildlet pools into a seperate package
 	gceMode             string
@@ -91,23 +93,18 @@
 	testFiles           map[string]string
 	basePinErr          *atomic.Value
 	isGCERemoteBuildlet IsGCERemoteBuildletFunc
-
-	initGCECalled bool
 )
 
-// oAuthHTTPClient is the OAuth2 HTTP client used to make API calls to Google Cloud APIs.
-// It is initialized by initGCE.
-var oAuthHTTPClient *http.Client
-
 // InitGCE initializes the GCE buildlet pool.
 func InitGCE(sc *secret.Client, vmDeleteTimeout time.Duration, tFiles map[string]string, basePin *atomic.Value, fn IsGCERemoteBuildletFunc, buildEnvName, mode string) error {
-	initGCECalled = true
+	gceMode = mode
 	deleteTimeout = vmDeleteTimeout
 	testFiles = tFiles
 	basePinErr = basePin
 	isGCERemoteBuildlet = fn
-	var err error
+
 	ctx := context.Background()
+	var err error
 
 	// If the coordinator is running on a GCE instance and a
 	// buildEnv was not specified with the env flag, set the
@@ -214,14 +211,12 @@
 		log.Printf("TryBot builders enabled.")
 	}
 
-	if mode != "dev" {
+	if mode != "dev" && metadata.OnGCE() && (buildEnv == buildenv.Production || buildEnv == buildenv.Staging) {
 		go syncBuildStatsLoop(buildEnv)
+		go gcePool.pollQuotaLoop()
+		go createBasepinDisks(ctx)
 	}
 
-	gceMode = mode
-
-	go gcePool.pollQuotaLoop()
-	go createBasepinDisks(context.Background())
 	return nil
 }
 
@@ -360,14 +355,6 @@
 }
 
 func (p *GCEBuildlet) pollQuotaLoop() {
-	if computeService == nil {
-		log.Printf("pollQuotaLoop: no GCE access; not checking quota.")
-		return
-	}
-	if buildEnv.ProjectName == "" {
-		log.Printf("pollQuotaLoop: no GCE project name configured; not checking quota.")
-		return
-	}
 	for {
 		p.pollQuota()
 		time.Sleep(5 * time.Second)
@@ -827,9 +814,6 @@
 // Other than a list call, this a no-op unless new VM images were
 // added or updated recently.
 func createBasepinDisks(ctx context.Context) {
-	if !metadata.OnGCE() || (buildEnv != buildenv.Production && buildEnv != buildenv.Staging) {
-		return
-	}
 	for {
 		t0 := time.Now()
 		bgc, err := buildgo.NewClient(ctx, buildEnv)
diff --git a/internal/coordinator/pool/kube.go b/internal/coordinator/pool/kube.go
index 7900dbd..ab21575 100644
--- a/internal/coordinator/pool/kube.go
+++ b/internal/coordinator/pool/kube.go
@@ -62,7 +62,7 @@
 		return errors.New("Kubernetes builders disabled due to KubeBuild.MaxNodes == 0")
 	}
 
-	// projectID was set by initGCE
+	// projectID was set by InitGCE.
 	registryPrefix += "/" + gceBuildEnv.ProjectName
 	if !hasCloudPlatformScope() {
 		return errors.New("coordinator not running with access to the Cloud Platform scope.")