all: consolidate configuration for coordinator and gomote
buildenv.Environment type defines configuration options:
- Coordinator uses the GCE project name to lookup config. A custom
config name can be provided at runtime to override.
- The conventional prod and stage project names ('symbolic-datum-552'
and 'go-dashboard-dev') map to prod and staging configuration structs.
- Production and staging status is explicitly defined in configuration.
- GCS bucket names for buildlet, logs, and snapshots are
configurable.
Change-Id: I7e6d7874eb0bdfe35dbdd5fcf6212ab50d576b88
Reviewed-on: https://go-review.googlesource.com/19502
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/buildenv/envs.go b/buildenv/envs.go
index b6b664e..48c446a 100644
--- a/buildenv/envs.go
+++ b/buildenv/envs.go
@@ -6,6 +6,11 @@
// environments the Go build system can run in.
package buildenv
+import (
+ "fmt"
+ "strings"
+)
+
const (
prefix = "https://www.googleapis.com/compute/v1/projects/"
)
@@ -18,6 +23,12 @@
// This field may be overridden as necessary without impacting other fields.
ProjectName string
+ // The IsProd flag indicates whether production functionality should be
+ // enabled. When true, GCE and Kubernetes builders are enabled and the
+ // coordinator serves on 443. Otherwise, GCE and Kubernetes builders are
+ // disabled and the coordinator serves on 8119.
+ IsProd bool
+
// Zone is the GCE zone that the coordinator instance and Kubernetes cluster
// will run in. This field may be overridden as necessary without impacting
// other fields.
@@ -60,24 +71,59 @@
// CoordinatorName is the hostname of the coordinator instance.
CoordinatorName string
+
+ // BuildletBucket is the GCS bucket that stores buildlet binaries.
+ BuildletBucket string
+
+ // The GCS bucket that logs are written to.
+ LogBucket string
+
+ // The GCS bucket that snapshots are written to.
+ SnapBucket string
}
-// This method returns the URI for the environment's Machine Type.
+// MachineTypeURI returns the URI for the environment's Machine Type.
func (e Environment) MachineTypeURI() string {
return e.ComputePrefix() + "/zones/" + e.Zone + "/machineTypes/" + e.MachineType
}
-// This method returns the URI prefix for Compute Engine resources in a project.
+// ComputePrefix returns the URI prefix for Compute Engine resources in a project.
func (e Environment) ComputePrefix() string {
return prefix + e.ProjectName
}
+// Region returns the GCE region, derived from its zone.
+func (e Environment) Region() string {
+ return e.Zone[:strings.LastIndex(e.Zone, "-")]
+}
+
+// ByProjectID returns an Environment for the specified
+// project ID. It is currently limited to the symbolic-datum-552
+// and go-dashboard-dev projects.
+// ByProjectID will panic if the project ID is not known.
+func ByProjectID(projectID string) *Environment {
+ var envKeys []string
+
+ for k := range possibleEnvs {
+ envKeys = append(envKeys, k)
+ }
+
+ var env *Environment
+ env, ok := possibleEnvs[projectID]
+ if !ok {
+ panic(fmt.Sprintf("Can't get buildenv for unknown project %q. Possible envs are %s", projectID, envKeys))
+ }
+
+ return env
+}
+
// Staging defines the environment that the coordinator and build
// infrastructure is deployed to before it is released to production.
// For local dev, override the project with the program's flag to set
// a custom project.
var Staging = &Environment{
ProjectName: "go-dashboard-dev",
+ IsProd: true,
Zone: "us-central1-f",
ZonesToClean: []string{"us-central1-a", "us-central1-b", "us-central1-f"},
StaticIP: "104.154.113.235",
@@ -85,15 +131,19 @@
KubeMinNodes: 1,
KubeMaxNodes: 5,
KubeName: "buildlets",
- KubeMachineType: "n1-standard-8",
+ KubeMachineType: "n1-standard-32",
CoordinatorURL: "https://storage.googleapis.com/dev-go-builder-data/coordinator",
CoordinatorName: "farmer",
+ BuildletBucket: "dev-go-builder-data",
+ LogBucket: "dev-go-build-log",
+ SnapBucket: "dev-go-build-snap",
}
// Production defines the environment that the coordinator and build
// infrastructure is deployed to for production usage at build.golang.org.
var Production = &Environment{
ProjectName: "symbolic-datum-552",
+ IsProd: true,
Zone: "us-central1-f",
ZonesToClean: []string{"us-central1-f"},
StaticIP: "107.178.219.46",
@@ -101,7 +151,16 @@
KubeMinNodes: 1,
KubeMaxNodes: 10,
KubeName: "buildlets",
- KubeMachineType: "n1-standard-8",
+ KubeMachineType: "n1-standard-32",
CoordinatorURL: "https://storage.googleapis.com/go-builder-data/coordinator",
CoordinatorName: "farmer",
+ BuildletBucket: "go-builder-data",
+ LogBucket: "go-build-log",
+ SnapBucket: "go-build-snap",
+}
+
+// possibleEnvs enumerate the known buildenv.Environment definitions.
+var possibleEnvs = map[string]*Environment{
+ "symbolic-datum-552": Production,
+ "go-dashboard-dev": Staging,
}
diff --git a/buildlet/gce.go b/buildlet/gce.go
index df5d166..be99551 100644
--- a/buildlet/gce.go
+++ b/buildlet/gce.go
@@ -13,6 +13,7 @@
"strings"
"time"
+ "golang.org/x/build/buildenv"
"golang.org/x/build/dashboard"
"golang.org/x/oauth2"
"google.golang.org/api/compute/v1"
@@ -158,7 +159,7 @@
// which the VMs are configured to download at boot and run.
// This lets us/ update the buildlet more easily than
// rebuilding the whole VM image.
- addMeta("buildlet-binary-url", conf.BuildletBinaryURL())
+ addMeta("buildlet-binary-url", conf.BuildletBinaryURL(buildenv.ByProjectID(opts.ProjectID)))
addMeta("builder-type", builderType)
if !opts.TLS.IsZero() {
addMeta("tls-cert", opts.TLS.CertPEM)
diff --git a/buildlet/kube.go b/buildlet/kube.go
index 0a89d82..1d57351 100644
--- a/buildlet/kube.go
+++ b/buildlet/kube.go
@@ -12,6 +12,7 @@
"strings"
"time"
+ "golang.org/x/build/buildenv"
"golang.org/x/build/dashboard"
"golang.org/x/build/kubernetes"
"golang.org/x/build/kubernetes/api"
@@ -28,6 +29,9 @@
// PodOpts control how new pods are started.
type PodOpts struct {
+ // ProjectID is the GCE project ID. Required.
+ ProjectID string
+
// ImageRegistry specifies the Docker registry Kubernetes
// will use to create the pod. Required.
ImageRegistry string
@@ -122,7 +126,7 @@
// which the pods are configured to download at boot and run.
// This lets us/ update the buildlet more easily than
// rebuilding the whole pod image.
- addEnv("META_BUILDLET_BINARY_URL", conf.BuildletBinaryURL())
+ addEnv("META_BUILDLET_BINARY_URL", conf.BuildletBinaryURL(buildenv.ByProjectID(opts.ProjectID)))
addEnv("META_BUILDER_TYPE", builderType)
if !opts.TLS.IsZero() {
addEnv("META_TLS_CERT", opts.TLS.CertPEM)
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index 3140629..b71db145 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -62,28 +62,19 @@
const devPause = false
var (
- role = flag.String("role", "coordinator", "Which role this binary should run as. Valid options: coordinator, watcher")
-
+ role = flag.String("role", "coordinator", "Which role this binary should run as. Valid options: coordinator, watcher")
masterKeyFile = flag.String("masterkey", "", "Path to builder master key. Else fetched using GCE project attribute 'builder-master-key'.")
// TODO(bradfitz): remove this list and just query it from the compute API:
// http://godoc.org/google.golang.org/api/compute/v1#RegionsService.Get
// and Region.Zones: http://godoc.org/google.golang.org/api/compute/v1#Region
- cleanZones = flag.String("zones", "us-central1-a,us-central1-b,us-central1-f", "Comma-separated list of zones to periodically clean of stale build VMs (ones that failed to shut themselves down)")
-
- mode = flag.String("mode", "", "valid modes are 'dev', 'prod', or '' for auto-detect. dev means localhost development, not be confused with staging on go-dashboard-dev, which is still the 'prod' mode.")
+ cleanZones = flag.String("zones", "us-central1-a,us-central1-b,us-central1-f", "Comma-separated list of zones to periodically clean of stale build VMs (ones that failed to shut themselves down)")
+ mode = flag.String("mode", "", "Valid modes are 'dev', 'prod', or '' for auto-detect. dev means localhost development, not be confused with staging on go-dashboard-dev, which is still the 'prod' mode.")
+ buildEnvName = flag.String("env", "", "The build environment configuration to use. Not required if running on GCE, but will override GCE default config if set.")
devEnableGCE = flag.Bool("dev_gce", false, "Whether or not to enable the GCE pool when in dev mode. The pool is enabled by default in prod mode.")
enableDebugProd = flag.Bool("debug_prod", false, "Enable the /dosomework URL to manually schedule a build on a prod coordinator. Enabled by default in dev mode.")
)
-func buildLogBucket() string {
- return stagingPrefix() + "go-build-log"
-}
-
-func snapBucket() string {
- return stagingPrefix() + "go-build-snap"
-}
-
// LOCK ORDER:
// statusMu, buildStatus.mu, trySet.mu
// (Other locks, such as subrepoHead.Mutex or the remoteBuildlet mutex should
@@ -160,7 +151,7 @@
return []byte(b), nil
}
- r, err := storageClient.Bucket(stagingPrefix() + "go-builder-data").Object(name).NewReader(serviceCtx)
+ r, err := storageClient.Bucket(buildEnv.BuildletBucket).Object(name).NewReader(serviceCtx)
if err != nil {
return nil, err
}
@@ -315,7 +306,6 @@
}
if inStaging {
- dashboard.BuildletBucket = "dev-go-builder-data"
dashboard.Builders = stagingClusterBuilders()
}
initTryBuilders()
@@ -1031,7 +1021,7 @@
s1 := sha1.New()
io.WriteString(s1, buildLog)
objName := fmt.Sprintf("%s/%s_%x.log", bs.rev[:8], bs.name, s1.Sum(nil)[:4])
- wr := storageClient.Bucket(buildLogBucket()).Object(objName).NewWriter(serviceCtx)
+ wr := storageClient.Bucket(buildEnv.LogBucket).Object(objName).NewWriter(serviceCtx)
wr.ContentType = "text/plain; charset=utf-8"
wr.ACL = append(wr.ACL, storage.ACLRule{Entity: storage.AllUsers, Role: storage.RoleReader})
if _, err := io.WriteString(wr, buildLog); err != nil {
@@ -1042,7 +1032,7 @@
log.Printf("Failed to write to GCS: %v", err)
return
}
- failLogURL := fmt.Sprintf("https://storage.googleapis.com/%s/%s", buildLogBucket(), objName)
+ failLogURL := fmt.Sprintf("https://storage.googleapis.com/%s/%s", buildEnv.LogBucket, objName)
bs.mu.Lock()
bs.failURL = failLogURL
@@ -1669,7 +1659,7 @@
// snapshotURL is the absolute URL of the snapshot object (see above).
func (br *builderRev) snapshotURL() string {
- return fmt.Sprintf("https://storage.googleapis.com/%s/%s", snapBucket(), br.snapshotObjectName())
+ return fmt.Sprintf("https://storage.googleapis.com/%s/%s", buildEnv.SnapBucket, br.snapshotObjectName())
}
func (st *buildStatus) writeSnapshot() error {
@@ -1682,7 +1672,7 @@
}
defer tgz.Close()
- wr := storageClient.Bucket(snapBucket()).Object(st.snapshotObjectName()).NewWriter(serviceCtx)
+ wr := storageClient.Bucket(buildEnv.SnapBucket).Object(st.snapshotObjectName()).NewWriter(serviceCtx)
wr.ContentType = "application/octet-stream"
wr.ACL = append(wr.ACL, storage.ACLRule{Entity: storage.AllUsers, Role: storage.RoleReader})
if _, err := io.Copy(wr, tgz); err != nil {
diff --git a/cmd/coordinator/gce.go b/cmd/coordinator/gce.go
index 2e9213c..f9163bd 100644
--- a/cmd/coordinator/gce.go
+++ b/cmd/coordinator/gce.go
@@ -9,6 +9,7 @@
import (
"crypto/rand"
+ "encoding/json"
"errors"
"fmt"
"io"
@@ -20,6 +21,7 @@
"sync"
"time"
+ "golang.org/x/build/buildenv"
"golang.org/x/build/buildlet"
"golang.org/x/build/dashboard"
"golang.org/x/build/gerrit"
@@ -48,16 +50,10 @@
<-apiCallTicker.C
}
-const (
- stagingProjectID = "go-dashboard-dev"
- stagingProjectZone = "us-central1-f"
-)
-
// Initialized by initGCE:
var (
- projectID string
- projectZone string
- projectRegion string
+ buildEnv *buildenv.Environment
+
computeService *compute.Service
externalIP string
tokenSource oauth2.TokenSource
@@ -70,57 +66,49 @@
initGCECalled bool
)
-func stagingPrefix() string {
- if !initGCECalled {
- panic("stagingPrefix called before initGCE")
- }
- if inStaging {
- return "dev-" // legacy prefix; must match resource names
- }
- return ""
-}
-
func initGCE() error {
initGCECalled = true
var err error
- // Use the staging project if not on GCE. This assumes the DefaultTokenSource
- // credential used below has access to that project.
- if !metadata.OnGCE() {
- projectID = stagingProjectID
- projectZone = stagingProjectZone
- } else {
- projectID, err = metadata.ProjectID()
- if err != nil {
- return fmt.Errorf("failed to get current GCE ProjectID: %v", err)
- }
- projectZone, err = metadata.Get("instance/zone")
+
+ // 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()
+ }
+
+ buildEnv := buildenv.ByProjectID(*buildEnvName)
+
+ // If running on GCE, override the zone and static IP, and check service account permissions.
+ if metadata.OnGCE() {
+ projectZone, err := metadata.Get("instance/zone")
if err != nil || projectZone == "" {
return fmt.Errorf("failed to get current GCE zone: %v", err)
}
// Convert the zone from "projects/1234/zones/us-central1-a" to "us-central1-a".
projectZone = path.Base(projectZone)
+ buildEnv.Zone = projectZone
+
+ buildEnv.StaticIP, err = metadata.ExternalIP()
+ if err != nil {
+ return fmt.Errorf("ExternalIP: %v", err)
+ }
+
if !hasComputeScope() {
return errors.New("The coordinator is not running with access to read and write Compute resources. VM support disabled.")
}
- externalIP, err = metadata.ExternalIP()
- if err != nil {
- return fmt.Errorf("ExternalIP: %v", err)
- }
}
- inStaging = projectID == stagingProjectID
- if inStaging {
- log.Printf("Running in staging cluster (%q)", projectID)
- }
- projectRegion = projectZone[:strings.LastIndex(projectZone, "-")] // "us-central1"
+ cfgDump, _ := json.MarshalIndent(buildEnv, "", " ")
+ log.Printf("Loaded configuration %q for project %q:\n%s", *buildEnvName, buildEnv.ProjectName, cfgDump)
tokenSource, err = google.DefaultTokenSource(oauth2.NoContext, compute.CloudPlatformScope, monitoring.MonitoringScope)
if err != nil {
log.Fatalf("failed to get a token source: %v", err)
}
httpClient := oauth2.NewClient(oauth2.NoContext, tokenSource)
- serviceCtx = cloud.NewContext(projectID, httpClient)
+ serviceCtx = cloud.NewContext(buildEnv.ProjectName, httpClient)
storageClient, err = storage.NewClient(serviceCtx, cloud.WithBaseHTTP(httpClient))
if err != nil {
log.Fatalf("storage.NewClient: %v", err)
@@ -142,10 +130,10 @@
if !hasStorageScope() {
return errors.New("coordinator's GCE instance lacks the storage service scope")
}
- wr := storageClient.Bucket(buildLogBucket()).Object("hello.txt").NewWriter(serviceCtx)
+ 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 {
- return fmt.Errorf("test write of a GCS object to bucket %q failed: %v", buildLogBucket(), err)
+ return fmt.Errorf("test write of a GCS object to bucket %q failed: %v", buildEnv.LogBucket, err)
}
if inStaging {
// Don't expect to write to Gerrit in staging mode.
@@ -194,9 +182,9 @@
func (p *gceBuildletPool) pollQuota() {
gceAPIGate()
- reg, err := computeService.Regions.Get(projectID, projectRegion).Do()
+ reg, err := computeService.Regions.Get(buildEnv.ProjectName, buildEnv.Region()).Do()
if err != nil {
- log.Printf("Failed to get quota for %s/%s: %v", projectID, projectRegion, err)
+ log.Printf("Failed to get quota for %s/%s: %v", buildEnv.ProjectName, buildEnv.Region(), err)
return
}
p.mu.Lock()
@@ -253,8 +241,8 @@
el.logEventTime("creating_gce_instance", instName)
log.Printf("Creating GCE VM %q for %s at %s", instName, typ, rev)
bc, err := buildlet.StartNewVM(tokenSource, instName, typ, buildlet.VMOpts{
- ProjectID: projectID,
- Zone: projectZone,
+ ProjectID: buildEnv.ProjectName,
+ Zone: buildEnv.Zone,
Description: fmt.Sprintf("Go Builder for %s at %s", typ, rev),
DeleteIn: deleteIn,
OnInstanceRequested: func() {
@@ -282,7 +270,7 @@
el.logEventTime("gce_buildlet_create_failure", fmt.Sprintf("%s: %v", instName, err))
log.Printf("Failed to create VM for %s, %s: %v", typ, rev, err)
if needDelete {
- deleteVM(projectZone, instName)
+ deleteVM(buildEnv.Zone, instName)
p.putVMCountQuota(conf.GCENumCPU())
}
p.setInstanceUsed(instName, false)
@@ -305,7 +293,7 @@
// buildlet client library between Close, Destroy/Halt, and
// tracking execution errors. That was all half-baked before
// and thus removed. Now Close always destroys everything.
- deleteVM(projectZone, instName)
+ deleteVM(buildEnv.Zone, instName)
p.setInstanceUsed(instName, false)
conf, ok := dashboard.Builders[typ]
@@ -474,7 +462,7 @@
// TODO(bradfitz): revist this code if we ever start running
// thousands of VMs.
gceAPIGate()
- list, err := computeService.Instances.List(projectID, zone).Do()
+ list, err := computeService.Instances.List(buildEnv.ProjectName, zone).Do()
if err != nil {
return fmt.Errorf("listing instances: %v", err)
}
@@ -523,7 +511,7 @@
func deleteVM(zone, instName string) (operation string, err error) {
deletedVMCache.Add(instName, token{})
gceAPIGate()
- op, err := computeService.Instances.Delete(projectID, zone, instName).Do()
+ op, err := computeService.Instances.Delete(buildEnv.ProjectName, zone, instName).Do()
apiErr, ok := err.(*googleapi.Error)
if ok {
if apiErr.Code == 404 {
diff --git a/cmd/coordinator/kube.go b/cmd/coordinator/kube.go
index 3dd1ec3..a913d13 100644
--- a/cmd/coordinator/kube.go
+++ b/cmd/coordinator/kube.go
@@ -60,7 +60,7 @@
initKubeCalled = true
// projectID was set by initGCE
- registryPrefix += "/" + projectID
+ registryPrefix += "/" + buildEnv.ProjectName
if !hasCloudPlatformScope() {
return errors.New("coordinator not running with access to the Cloud Platform scope.")
}
@@ -79,9 +79,9 @@
tsService = monitoring.NewTimeseriesService(monService)
metricDescService = monitoring.NewMetricDescriptorsService(monService)
- kubeCluster, err = containerService.Projects.Zones.Clusters.Get(projectID, projectZone, clusterName).Do()
+ kubeCluster, err = containerService.Projects.Zones.Clusters.Get(buildEnv.ProjectName, buildEnv.Zone, clusterName).Do()
if err != nil {
- return fmt.Errorf("cluster %q could not be found in project %q, zone %q: %v", clusterName, projectID, projectZone, err)
+ return fmt.Errorf("cluster %q could not be found in project %q, zone %q: %v", clusterName, buildEnv.ProjectName, buildEnv.Zone, err)
}
// Decode certs
@@ -163,18 +163,18 @@
{Key: clusterNameLabelKey},
{Key: serviceLabelKey},
},
- Project: projectID,
+ Project: buildEnv.ProjectName,
TypeDescriptor: &monitoring.MetricDescriptorTypeDescriptor{
MetricType: "gauge",
ValueType: "double",
},
}
- _, err := metricDescService.Create(projectID, metric).Do()
+ _, err := metricDescService.Create(buildEnv.ProjectName, metric).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 403 {
log.Printf("Error creating CPU metric: could not authenticate to Google Cloud Monitoring. If you are running the coordinator on a local machine in dev mode, configure service account credentials for authentication as described at https://cloud.google.com/monitoring/api/authentication#service_account_authorization. Error message: %v\n", err)
} else {
- log.Fatalf("Failed to create CPU metric for project. Ensure the Google Cloud Monitoring API is enabled for project %v: %v.", projectID, err)
+ log.Fatalf("Failed to create CPU metric for project. Ensure the Google Cloud Monitoring API is enabled for project %v: %v.", buildEnv.ProjectName, err)
}
}
@@ -185,18 +185,18 @@
{Key: clusterNameLabelKey},
{Key: serviceLabelKey},
},
- Project: projectID,
+ Project: buildEnv.ProjectName,
TypeDescriptor: &monitoring.MetricDescriptorTypeDescriptor{
MetricType: "gauge",
ValueType: "double",
},
}
- _, err = metricDescService.Create(projectID, metric).Do()
+ _, err = metricDescService.Create(buildEnv.ProjectName, metric).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 403 {
log.Printf("Error creating memory metric: could not authenticate to Google Cloud Monitoring. If you are running the coordinator on a local machine in dev mode, configure service account credentials for authentication as described at https://cloud.google.com/monitoring/api/authentication#service_account_authorization. Error message: %v\n", err)
} else {
- log.Fatalf("Failed to create memory metric for project. Ensure the Google Cloud Monitoring API is enabled for project %v: %v.", projectID, err)
+ log.Fatalf("Failed to create memory metric for project. Ensure the Google Cloud Monitoring API is enabled for project %v: %v.", buildEnv.ProjectName, err)
}
}
}
@@ -212,12 +212,12 @@
func (p *kubeBuildletPool) pollCapacity(ctx context.Context) {
nodes, err := kubeClient.GetNodes(ctx)
if err != nil {
- log.Printf("failed to retrieve nodes to calculate cluster capacity for %s/%s: %v", projectID, projectRegion, err)
+ log.Printf("failed to retrieve nodes to calculate cluster capacity for %s/%s: %v", buildEnv.ProjectName, buildEnv.Region(), err)
return
}
pods, err := kubeClient.GetPods(ctx)
if err != nil {
- log.Printf("failed to retrieve pods to calculate cluster capacity for %s/%s: %v", projectID, projectRegion, err)
+ log.Printf("failed to retrieve pods to calculate cluster capacity for %s/%s: %v", buildEnv.ProjectName, buildEnv.Region(), err)
return
}
@@ -261,7 +261,7 @@
},
TimeseriesDesc: &monitoring.TimeseriesDescriptor{
Metric: cpuUsedMetric,
- Project: projectID,
+ Project: buildEnv.ProjectName,
Labels: map[string]string{
clusterNameLabelKey: clusterName,
serviceLabelKey: "container",
@@ -276,7 +276,7 @@
},
TimeseriesDesc: &monitoring.TimeseriesDescriptor{
Metric: memoryUsedMetric,
- Project: projectID,
+ Project: buildEnv.ProjectName,
Labels: map[string]string{
clusterNameLabelKey: clusterName,
serviceLabelKey: "container",
@@ -286,7 +286,7 @@
},
}
- _, err = tsService.Write(projectID, &wtr).Do()
+ _, err = tsService.Write(buildEnv.ProjectName, &wtr).Do()
if err != nil {
log.Printf("custom cluster utilization metric could not be written to Google Cloud Monitoring: %v", err)
}
@@ -327,6 +327,7 @@
log.Printf("Creating Kubernetes pod %q for %s at %s", podName, typ, rev)
bc, err := buildlet.StartPod(ctx, kubeClient, podName, typ, buildlet.PodOpts{
+ ProjectID: buildEnv.ProjectName,
ImageRegistry: registryPrefix,
Description: fmt.Sprintf("Go Builder for %s at %s", typ, rev),
DeleteIn: deleteIn,
diff --git a/cmd/gomote/gomote.go b/cmd/gomote/gomote.go
index e1499fb..5d175eb 100644
--- a/cmd/gomote/gomote.go
+++ b/cmd/gomote/gomote.go
@@ -26,14 +26,16 @@
"sort"
"golang.org/x/build"
+ "golang.org/x/build/buildenv"
"golang.org/x/build/buildlet"
- "golang.org/x/build/dashboard"
)
var (
user = flag.String("user", username(), "gomote server username. You must have the token for user-$USER. The error message will say where to put it.")
staging = flag.Bool("staging", false, "if true, use the staging build coordinator and buildlets")
+
+ buildEnv = buildenv.Production
)
type command struct {
@@ -111,8 +113,7 @@
flag.Usage = usage
flag.Parse()
if *staging {
- // TODO(cmang): make this configurable.
- dashboard.BuildletBucket = "dev-go-builder-data"
+ buildEnv = buildenv.Staging
}
args := flag.Args()
if len(args) == 0 {
diff --git a/dashboard/builders.go b/dashboard/builders.go
index 3cbdd7c..1759cb9 100644
--- a/dashboard/builders.go
+++ b/dashboard/builders.go
@@ -9,6 +9,8 @@
import (
"strconv"
"strings"
+
+ "golang.org/x/build/buildenv"
)
// Builders are the different build configurations.
@@ -80,28 +82,13 @@
return strings.Join(x, "/")
}
-// BuildletBucket is the GCS storage bucket which holds the buildlet binaries.
-// Tools working in the dev project may change this.
-var BuildletBucket = "go-builder-data"
-
-func fixBuildletBucket(u string) string {
- if BuildletBucket == "go-builder-data" {
- // Prod. Default case.
- return u
- }
- // Dev project remapping:
- return strings.Replace(u,
- "//storage.googleapis.com/go-builder-data/",
- "//storage.googleapis.com/"+BuildletBucket+"/",
- 1)
-}
-
// BuildletBinaryURL returns the public URL of this builder's buildlet.
-func (c *BuildConfig) BuildletBinaryURL() string {
- if c.buildletURL != "" {
- return fixBuildletBucket(c.buildletURL)
+func (c *BuildConfig) BuildletBinaryURL(e *buildenv.Environment) string {
+ tmpl := c.buildletURL
+ if tmpl == "" {
+ return "http://storage.googleapis.com/" + e.BuildletBucket + "/buildlet." + c.GOOS() + "-" + c.GOARCH()
}
- return fixBuildletBucket("http://storage.googleapis.com/go-builder-data/buildlet." + c.GOOS() + "-" + c.GOARCH())
+ return strings.Replace(tmpl, "$BUCKET", e.BuildletBucket, 1)
}
// SetBuildletBinaryURL sets the public URL of this builder's buildlet.
@@ -262,7 +249,7 @@
Name: "freebsd-amd64-gce93",
VMImage: "freebsd-amd64-gce93",
machineType: "n1-highcpu-2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-freebsd-amd64.tar.gz",
NumTestHelpers: 3,
})
addBuilder(BuildConfig{
@@ -270,7 +257,7 @@
Notes: "FreeBSD 10.1; GCE VM is built from script in build/env/freebsd-amd64",
VMImage: "freebsd-amd64-gce101",
machineType: "n1-highcpu-2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-freebsd-amd64.tar.gz",
env: []string{"CC=clang"},
NumTestHelpers: 3,
})
@@ -278,7 +265,7 @@
Name: "freebsd-amd64-race",
VMImage: "freebsd-amd64-gce101",
machineType: "n1-highcpu-4",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-freebsd-amd64.tar.gz",
env: []string{"CC=clang"},
})
addBuilder(BuildConfig{
@@ -286,8 +273,8 @@
VMImage: "freebsd-amd64-gce101",
//BuildletType: "freebsd-amd64-gce101",
machineType: "n1-highcpu-2",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.freebsd-amd64",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-freebsd-amd64.tar.gz",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.freebsd-amd64",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-freebsd-amd64.tar.gz",
env: []string{"GOARCH=386", "GOHOSTARCH=386", "CC=clang"},
NumTestHelpers: 3,
})
@@ -295,7 +282,7 @@
Name: "linux-386",
VMImage: "linux-buildlet-std",
//BuildletType: "linux-amd64",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOARCH=386", "GOHOSTARCH=386"},
NumTestHelpers: 3,
})
@@ -304,7 +291,7 @@
Notes: "GO386=387",
VMImage: "linux-buildlet-std",
//BuildletType: "linux-amd64",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOARCH=386", "GOHOSTARCH=386", "GO386=387"},
})
addBuilder(BuildConfig{
@@ -316,6 +303,7 @@
addBuilder(BuildConfig{
Name: "linux-amd64-kube",
KubeImage: "linux-x86-std:latest",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4"},
NumTestHelpers: 3,
})
@@ -325,7 +313,7 @@
VMImage: "linux-buildlet-std",
machineType: "n1-highcpu-16", // CPU-bound, uses it well.
Notes: "Runs buildall.sh to compile stdlib for GOOS/GOARCH pairs not otherwise covered by trybots, but doesn't run any tests.",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4"},
allScriptArgs: []string{
// Filtering pattern to buildall.bash:
@@ -363,7 +351,7 @@
Name: "linux-386-clang",
VMImage: "linux-buildlet-clang",
//BuildletType: "linux-amd64-clang",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "CC=/usr/bin/clang", "GOHOSTARCH=386"},
})
addBuilder(BuildConfig{
@@ -375,7 +363,7 @@
addBuilder(BuildConfig{
Name: "linux-386-sid",
VMImage: "linux-buildlet-sid",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOHOSTARCH=386"},
})
addBuilder(BuildConfig{
@@ -402,26 +390,26 @@
addBuilder(BuildConfig{
Name: "nacl-386",
VMImage: "linux-buildlet-nacl-v2",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOOS=nacl", "GOARCH=386", "GOHOSTOS=linux", "GOHOSTARCH=amd64"},
//BuildletType: "nacl-amd64p32",
})
addBuilder(BuildConfig{
Name: "nacl-amd64p32",
VMImage: "linux-buildlet-nacl-v2",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOOS=nacl", "GOARCH=amd64p32", "GOHOSTOS=linux", "GOHOSTARCH=amd64"},
})
addBuilder(BuildConfig{
Name: "nacl-386-kube",
KubeImage: "linux-x86-nacl:latest",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOOS=nacl", "GOARCH=386", "GOHOSTOS=linux", "GOHOSTARCH=amd64"},
})
addBuilder(BuildConfig{
Name: "nacl-amd64p32-kube",
KubeImage: "linux-x86-nacl:latest",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.linux-amd64",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.linux-amd64",
env: []string{"GOROOT_BOOTSTRAP=/go1.4", "GOOS=nacl", "GOARCH=amd64p32", "GOHOSTOS=linux", "GOHOSTARCH=amd64"},
})
addBuilder(BuildConfig{
@@ -429,7 +417,7 @@
Notes: "OpenBSD 5.8; GCE VM is built from script in build/env/openbsd-amd64",
VMImage: "openbsd-amd64-58",
machineType: "n1-highcpu-2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-openbsd-amd64-gce58.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-openbsd-amd64-gce58.tar.gz",
NumTestHelpers: 3,
})
addBuilder(BuildConfig{
@@ -437,14 +425,14 @@
Notes: "OpenBSD 5.8; GCE VM is built from script in build/env/openbsd-386",
VMImage: "openbsd-386-58",
machineType: "n1-highcpu-2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-openbsd-386-gce58.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-openbsd-386-gce58.tar.gz",
NumTestHelpers: 3,
})
addBuilder(BuildConfig{
Name: "plan9-386",
Notes: "Plan 9 from 0intro; GCE VM is built from script in build/env/plan9-386",
VMImage: "plan9-386-v2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-plan9-386.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-plan9-386.tar.gz",
// We *were* using n1-standard-1 because Plan 9 can only
// reliably use a single CPU. Using 2 or 4 and we see
@@ -476,7 +464,7 @@
Name: "windows-amd64-gce",
VMImage: "windows-buildlet-v2",
machineType: "n1-highcpu-2",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-windows-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-windows-amd64.tar.gz",
RegularDisk: true,
env: []string{"GOARCH=amd64", "GOHOSTARCH=amd64"},
NumTestHelpers: 3,
@@ -486,7 +474,7 @@
Notes: "Only runs -race tests (./race.bat)",
VMImage: "windows-buildlet-v2",
machineType: "n1-highcpu-4",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-windows-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-windows-amd64.tar.gz",
RegularDisk: true,
env: []string{"GOARCH=amd64", "GOHOSTARCH=amd64"},
})
@@ -495,8 +483,8 @@
VMImage: "windows-buildlet-v2",
machineType: "n1-highcpu-2",
// TODO(bradfitz): once buildlet type vs. config type is split: BuildletType: "windows-amd64-gce",
- buildletURL: "http://storage.googleapis.com/go-builder-data/buildlet.windows-amd64",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-windows-386.tar.gz",
+ buildletURL: "http://storage.googleapis.com/$BUCKET/buildlet.windows-amd64",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-windows-386.tar.gz",
RegularDisk: true,
env: []string{"GOARCH=386", "GOHOSTARCH=386"},
NumTestHelpers: 3,
@@ -504,14 +492,14 @@
addBuilder(BuildConfig{
Name: "darwin-amd64-10_10",
Notes: "Mac Mini running OS X 10.10 (Yosemite)",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
NumTestHelpers: 0, // disabled per golang.org/issue/12979
})
addBuilder(BuildConfig{
Name: "darwin-386-10_10",
Notes: "Mac Mini running OS X 10.10 (Yosemite)",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOARCH=386", "GOHOSTARCH=386"},
NumTestHelpers: 0, // disabled per golang.org/issue/12979
@@ -519,7 +507,7 @@
addBuilder(BuildConfig{
Name: "android-arm-sdk19",
Notes: "Android ARM device running android-19 (KitKat 4.4), attatched to Mac Mini",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOOS=android", "GOARCH=arm"},
NumTestHelpers: 1, // limited resources
@@ -527,7 +515,7 @@
addBuilder(BuildConfig{
Name: "android-arm64-sdk21",
Notes: "Android arm64 device using the android-21 toolchain, attatched to Mac Mini",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOOS=android", "GOARCH=arm64"},
NumTestHelpers: 1, // limited resources
@@ -535,7 +523,7 @@
addBuilder(BuildConfig{
Name: "android-386-sdk21",
Notes: "Android 386 device using the android-21 toolchain, attatched to Mac Mini",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOOS=android", "GOARCH=386"},
NumTestHelpers: 1, // limited resources
@@ -543,7 +531,7 @@
addBuilder(BuildConfig{
Name: "android-amd64-sdk21",
Notes: "Android amd64 device using the android-21 toolchain, attatched to Mac Mini",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOOS=android", "GOARCH=amd64"},
NumTestHelpers: 1, // limited resources
@@ -552,7 +540,7 @@
Name: "darwin-arm-a5ios",
Notes: "iPhone 4S (A5 processor), via a Mac Mini",
Owner: "crawshaw@golang.org",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOARCH=arm", "GOHOSTARCH=amd64"},
})
@@ -560,7 +548,7 @@
Name: "darwin-arm64-a7ios",
Notes: "iPad Mini 3 (A7 processor), via a Mac Mini",
Owner: "crawshaw@golang.org",
- Go14URL: "https://storage.googleapis.com/go-builder-data/go1.4-darwin-amd64.tar.gz",
+ Go14URL: "https://storage.googleapis.com/$BUCKET/go1.4-darwin-amd64.tar.gz",
IsReverse: true,
env: []string{"GOARCH=arm64", "GOHOSTARCH=amd64"},
})