cmd/coordinator: start up in dev mode without crashing again

Change-Id: I24b48a33e9f32e74f532aa234608e2ebb3aefa31
Reviewed-on: https://go-review.googlesource.com/21011
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index 3997718..0ef8b5d 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -165,7 +165,7 @@
 func listenAndServeTLS() {
 	addr := ":443"
 	if *mode == "dev" {
-		addr = ":8119"
+		addr = "localhost:8119"
 	}
 	ln, err := net.Listen("tcp", addr)
 	if err != nil {
diff --git a/cmd/coordinator/gce.go b/cmd/coordinator/gce.go
index 2865172..d8f2894 100644
--- a/cmd/coordinator/gce.go
+++ b/cmd/coordinator/gce.go
@@ -73,8 +73,15 @@
 	// If the coordinator is running on a GCE instance and a
 	// buildEnv was not specified with the env flag, set the
 	// buildEnvName to the project ID
-	if metadata.OnGCE() && *buildEnvName == "" {
-		*buildEnvName, _ = metadata.ProjectID()
+	if *buildEnvName == "" {
+		if *mode == "dev" {
+			*buildEnvName = "dev"
+		} else if metadata.OnGCE() {
+			*buildEnvName, err = metadata.ProjectID()
+			if err != nil {
+				log.Fatalf("metadata.ProjectID: %v", err)
+			}
+		}
 	}
 
 	buildEnv = buildenv.ByProjectID(*buildEnvName)
@@ -108,10 +115,12 @@
 		log.Fatalf("failed to get a token source: %v", err)
 	}
 	httpClient := oauth2.NewClient(oauth2.NoContext, tokenSource)
-	serviceCtx = cloud.NewContext(buildEnv.ProjectName, httpClient)
-	storageClient, err = storage.NewClient(serviceCtx, cloud.WithBaseHTTP(httpClient))
-	if err != nil {
-		log.Fatalf("storage.NewClient: %v", err)
+	if *mode != "dev" {
+		serviceCtx = cloud.NewContext(buildEnv.ProjectName, httpClient)
+		storageClient, err = storage.NewClient(serviceCtx, cloud.WithBaseHTTP(httpClient))
+		if err != nil {
+			log.Fatalf("storage.NewClient: %v", err)
+		}
 	}
 
 	computeService, _ = compute.New(httpClient)
@@ -130,6 +139,9 @@
 	if !hasStorageScope() {
 		return errors.New("coordinator's GCE instance lacks the storage service scope")
 	}
+	if *mode == "dev" {
+		return errors.New("running in dev mode")
+	}
 	wr := storageClient.Bucket(buildEnv.LogBucket).Object("hello.txt").NewWriter(serviceCtx)
 	fmt.Fprintf(wr, "Hello, world! Coordinator start-up at %v", time.Now())
 	if err := wr.Close(); err != nil {
@@ -174,6 +186,14 @@
 }
 
 func (p *gceBuildletPool) pollQuotaLoop() {
+	if computeService == nil {
+		log.Printf("pollQuotaLoop: no GCE access; not checking quota.")
+		return
+	}
+	if buildEnv.ProjectName == "" {
+		log.Printf("pollQuotaLoop: no GCE project name confingured; not checking quota.")
+		return
+	}
 	for {
 		p.pollQuota()
 		time.Sleep(5 * time.Second)