cmd/buildlet: set up & clean TMPDIR and GOCACHE for child processes
Also, remove use of envutil to de-dup environment variables. Go has
done that automatically since Go 1.9.
Fixes golang/go#27182
Fixes golang/go#28041
Change-Id: I8e81e7996b5cee305465814aeb1b14df80b799dd
Reviewed-on: https://go-review.googlesource.com/c/144637
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 6b33546..45b36ad 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -43,7 +43,6 @@
"cloud.google.com/go/compute/metadata"
"golang.org/x/build/buildlet"
- "golang.org/x/build/envutil"
"golang.org/x/build/internal/httpdl"
"golang.org/x/build/pargzip"
)
@@ -73,7 +72,8 @@
// 15: ssh support
// 16: make macstadium builders always haltEntireOS
// 17: make macstadium halts use sudo
-const buildletVersion = 17
+// 18: set TMPDIR and GOCACHE
+const buildletVersion = 18
func defaultListenAddr() string {
if runtime.GOOS == "darwin" {
@@ -100,6 +100,13 @@
setOSRlimit func() error
)
+// If non-empty, the $TMPDIR and $GOCACHE environment variables to use
+// for child processes.
+var (
+ processTmpDirEnv string
+ processGoCacheEnv string
+)
+
func main() {
switch os.Getenv("GO_BUILDER_ENV") {
case "macstadium_vm":
@@ -133,8 +140,8 @@
*rebootOnHalt = true
}
- // Optimize emphemeral filesystems. Prefer speed over safety, since these machines
- // will be gone soon.
+ // Optimize emphemeral filesystems. Prefer speed over safety,
+ // since these VMs only last for the duration of one build.
switch runtime.GOOS {
case "openbsd", "freebsd", "netbsd":
makeBSDFilesystemFast()
@@ -197,6 +204,15 @@
if _, err := os.Lstat(*workDir); err != nil {
log.Fatalf("invalid --workdir %q: %v", *workDir, err)
}
+
+ // Set up and clean $TMPDIR and $GOCACHE directories.
+ if runtime.GOOS != "windows" && runtime.GOOS != "plan9" {
+ processTmpDirEnv = filepath.Join(*workDir, "tmp")
+ processGoCacheEnv = filepath.Join(*workDir, "gocache")
+ removeAllAndMkdir(processTmpDirEnv)
+ removeAllAndMkdir(processGoCacheEnv)
+ }
+
initGorootBootstrap()
http.HandleFunc("/", handleRoot)
@@ -872,29 +888,17 @@
env := append(baseEnv(goarch), r.PostForm["env"]...)
- // Set TMPDIR in the child process and clean up after it.
- // Do this at least for Solaris (golang.org/issue/22798)
- // because Solaris reuses its disk per run (for now). The other builders
- // generally run in their own containers/VMs and thus don't leak.
- // Ideally Solaris would do the same and we wouldn't need this.
- if builder := getEnv(env, "GO_BUILDER_NAME"); builder == "solaris-amd64-smartosbuildlet" {
- childTmp, err := ioutil.TempDir("", "buildlet-exec")
- if err != nil {
- // Not critical. Not worth dying over. (at least for now)
- log.Printf("failed to create a temp directory: %v", err)
- } else {
- env = append(env, "TMPDIR="+childTmp)
- defer os.RemoveAll(childTmp)
- }
+ if v := processTmpDirEnv; v != "" {
+ env = append(env, "TMPDIR="+v)
}
-
- env = envutil.Dedup(runtime.GOOS == "windows", env)
+ if v := processGoCacheEnv; v != "" {
+ env = append(env, "GOCACHE="+v)
+ }
// Prefer buildlet process's inherited GOROOT_BOOTSTRAP if
// there was one and the one we're about to use doesn't exist.
if v := getEnv(env, "GOROOT_BOOTSTRAP"); v != "" && inheritedGorootBootstrap != "" && pathNotExist(v) {
- env = envutil.Dedup(runtime.GOOS == "windows", append(env,
- "GOROOT_BOOTSTRAP="+inheritedGorootBootstrap))
+ env = append(env, "GOROOT_BOOTSTRAP="+inheritedGorootBootstrap)
}
env = setPathEnv(env, r.PostForm["path"], *workDir)
@@ -1133,7 +1137,6 @@
log.Printf("Error running reboot: %v", err)
}
os.Exit(0)
-
}
if !*haltEntireOS {
log.Printf("Ending buildlet process due to halt.")
@@ -1751,3 +1754,14 @@
os.Setenv("HOME", "/root")
}
}
+
+// removeAllAndMkdir calls os.RemoveAll and then os.Mkdir on the given
+// dir, failing the process if either step fails.
+func removeAllAndMkdir(dir string) {
+ if err := os.RemoveAll(dir); err != nil {
+ log.Fatal(err)
+ }
+ if err := os.Mkdir(dir, 0755); err != nil {
+ log.Fatal(err)
+ }
+}