cmd/coordinator: provide a GOPROXY for vetall and all subrepo builds
Also allow individual builders to override GOPROXY explicitly.
The vetall builder expects to build golang.org/x/tools from a specific
revision, and in module mode that implies that it needs access to all
of the module dependencies of that revision.
The individual subrepo builders may need a GOPROXY to resolve
dependencies when the default value of GO111MODULE changes to "on",
since they will enter module mode automatically even though they are
running within GOPATH.
Updates golang/go#30228
Change-Id: I40f6f2ea3c5ed05eaaaf3503ba97e6ccd3f20e1f
Reviewed-on: https://go-review.googlesource.com/c/build/+/165738
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index 55ef6d8..319d220 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -2479,51 +2479,52 @@
sp := st.CreateSpan("running_subrepo_tests", st.SubName)
defer func() { sp.Done(err) }()
- goProxy, err := st.moduleProxy()
- if err != nil {
- return nil, err
- }
- var go111Module, dir string
- if goProxy != "" {
- go111Module = "on"
- dir = "gopath/src/golang.org/x/" + st.SubName
+ env := append(st.conf.Env(),
+ "GOROOT="+goroot,
+ "GOPATH="+gopath,
+ "GOPROXY="+moduleProxy(),
+ )
+ if v, ok := st.go111Module(); ok {
+ env = append(env, "GO111MODULE="+v)
}
return st.bc.Exec(path.Join("go", "bin", "go"), buildlet.ExecOpts{
- Debug: true, // make buildlet print extra debug in output for failures
- Output: st,
- Dir: dir,
- ExtraEnv: append(st.conf.Env(),
- "GOROOT="+goroot,
- "GOPATH="+gopath,
- "GO111MODULE="+go111Module,
- "GOPROXY="+goProxy,
- ),
- Path: []string{"$WORKDIR/go/bin", "$PATH"},
- Args: []string{"test", "-short", subrepoPrefix + st.SubName + "/..."},
+ Debug: true, // make buildlet print extra debug in output for failures
+ Output: st,
+ Dir: "gopath/src/golang.org/x/" + st.SubName,
+ ExtraEnv: env,
+ Path: []string{"$WORKDIR/go/bin", "$PATH"},
+ Args: []string{"test", "-short", subrepoPrefix + st.SubName + "/..."},
})
}
-// moduleProxy returns the GOPROXY environment value to use for this
-// build's tests. If non-empty, GO111MODULE=on is included in the
-// environment as well. Returning two zero values means to not
-// configure the environment values.
+// go111Module() returns the GO111MODULE environment value to use for this
+// build's tests.
+//
+// If ok=false, the tests should use whatever is set in the builder's
+// environment.
+func (st *buildStatus) go111Module() (value string, ok bool) {
+ switch st.SubName {
+ case "oauth2", "build":
+ return "on", true // Force module mode.
+ default:
+ return "", false // Use the builder's default behavior, whatever that is.
+ }
+}
+
+// moduleProxy returns the GOPROXY environment value to use for module-enabled
+// tests.
//
// We go through a GCP-project-internal module proxy ("GOPROXY") to
// eliminate load on the origin servers. Our builder VMs are ephemeral
// and only run for the duration of one build. They also often don't
// have all the VCS tools installed (or even available: there is no
// git for plan9).
-func (bs *buildStatus) moduleProxy() (string, error) {
- switch bs.SubName {
- case "oauth2", "build":
- // The two repos we're starting with for testing.
- default:
- return "", nil
- }
+func moduleProxy() string {
// If we're running on localhost, just use the current environment's value.
if buildEnv == nil || !buildEnv.IsProd {
- return os.Getenv("GOPROXY"), nil
+ // If empty, use installed VCS tools as usual to fetch modules.
+ return os.Getenv("GOPROXY")
}
// We run a NodePort service on each GKE node
@@ -2537,10 +2538,13 @@
// scheme that supports internal static IPs.
gkeNodeIP, err := metadata.Get("instance/network-interfaces/0/ip")
if err != nil || gkeNodeIP == "" {
+ // Explicitly disable module downloads: otherwise, we end up trying to run
+ // 'git' on hosts that don't have it installed, and the failure messages are
+ // unpleasant.
log.Printf("WARNING: failed to discover local GCE node's IP: %v; disabling GOPROXY", err)
- return "", nil
+ return "off"
}
- return "http://" + gkeNodeIP + ":30156", nil
+ return "http://" + gkeNodeIP + ":30156"
}
// affectedPkgs returns the name of every package affected by this commit.
@@ -2616,6 +2620,7 @@
mainBuildletGoroot := st.conf.FilePathJoin(workDir, "go")
mainBuildletGopath := st.conf.FilePathJoin(workDir, "gopath")
+ goproxy := set.goProxy()
// We use our original buildlet to run the tests in order, to
// make the streaming somewhat smooth and not incredibly
@@ -2637,7 +2642,7 @@
}
continue
}
- st.runTestsOnBuildlet(st.bc, tis, mainBuildletGoroot, mainBuildletGopath)
+ st.runTestsOnBuildlet(st.bc, tis, mainBuildletGoroot, mainBuildletGopath, goproxy)
}
st.LogEventTime("main_buildlet_broken", st.bc.Name())
}()
@@ -2676,7 +2681,7 @@
st.LogEventTime("no_new_tests_remain", bc.Name())
return
}
- st.runTestsOnBuildlet(bc, tis, goroot, gopath)
+ st.runTestsOnBuildlet(bc, tis, goroot, gopath, goproxy)
}
st.LogEventTime("test_helper_is_broken", bc.Name())
}(helper)
@@ -2850,7 +2855,7 @@
const maxTestExecErrors = 3
// runTestsOnBuildlet runs tis on bc, using the optional goroot & gopath environment variables.
-func (st *buildStatus) runTestsOnBuildlet(bc *buildlet.Client, tis []*testItem, goroot, gopath string) {
+func (st *buildStatus) runTestsOnBuildlet(bc *buildlet.Client, tis []*testItem, goroot, gopath, goproxy string) {
names := make([]string, len(tis))
for i, ti := range tis {
names[i] = ti.name
@@ -2888,6 +2893,13 @@
remoteErr, err = ti.bench.Run(buildEnv, st, st.conf, bc, &buf, []buildgo.BuilderRev{st.BuilderRev, pbr})
}
} else {
+ env := append(st.conf.Env(),
+ "GOROOT="+goroot,
+ "GOPATH="+gopath,
+ )
+ if goproxy != "" {
+ env = append(env, "GOPROXY="+goproxy)
+ }
remoteErr, err = bc.Exec(path.Join("go", "bin", "go"), buildlet.ExecOpts{
// We set Dir to "." instead of the default ("go/bin") so when the dist tests
// try to run os/exec.Command("go", "test", ...), the LookPath of "go" doesn't
@@ -2895,15 +2907,12 @@
// fail when dist tries to run the binary in dir "$GOROOT/src", since
// "$GOROOT/src" + "./go.exe" doesn't exist. Perhaps LookPath should return
// an absolute path.
- Dir: ".",
- Output: &buf, // see "maybe stream lines" TODO below
- ExtraEnv: append(st.conf.Env(),
- "GOROOT="+goroot,
- "GOPATH="+gopath,
- ),
- Timeout: timeout,
- Path: []string{"$WORKDIR/go/bin", "$PATH"},
- Args: args,
+ Dir: ".",
+ Output: &buf, // see "maybe stream lines" TODO below
+ ExtraEnv: env,
+ Timeout: timeout,
+ Path: []string{"$WORKDIR/go/bin", "$PATH"},
+ Args: args,
})
}
execDuration := time.Since(t0)
@@ -2970,6 +2979,15 @@
return nil
}
+// goProxy returns the GOPROXY environment value to set for tests in the main
+// repo.
+func (s *testSet) goProxy() string {
+ if len(s.needsXRepo) == 0 {
+ return "off"
+ }
+ return moduleProxy()
+}
+
// cancelAll cancels all pending tests.
func (s *testSet) cancelAll() {
for _, ti := range s.items {