From 8b0bed7187e3103b1b66ce3997396d621bc59051 Mon Sep 17 00:00:00 2001 From: Taylor Santiago Date: Tue, 3 Sep 2024 13:30:22 -0700 Subject: [PATCH] Reapply "Clean environment variables to account for sandbox work directory." with minor edits. This reverts commit 9543d19b4b2c04e501e1e84f5d42e05af109535f. Bug: 363037195 Change-Id: I4cb10b312b7f468185bfad12a16f9b4b64e7a58a --- ui/build/config.go | 49 +++++++++++++++++++++++++---------- ui/build/path.go | 18 +++++++++++++ ui/build/sandbox_linux.go | 54 ++++++++++++++++++++++++++++++--------- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/ui/build/config.go b/ui/build/config.go index 64323487d..711f3256c 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -41,6 +41,7 @@ import ( const ( envConfigDir = "vendor/google/tools/soong_config" jsonSuffix = "json" + abfsSrcDir = "/src" ) var ( @@ -214,6 +215,10 @@ func NewConfig(ctx Context, args ...string) Config { sandboxConfig: &SandboxConfig{}, ninjaWeightListSource: DEFAULT, } + wd, err := os.Getwd() + if err != nil { + ctx.Fatalln("Failed to get working directory:", err) + } // Skip soong tests by default on Linux if runtime.GOOS == "linux" { @@ -245,17 +250,13 @@ func NewConfig(ctx Context, args ...string) Config { // Make sure OUT_DIR is set appropriately if outDir, ok := ret.environ.Get("OUT_DIR"); ok { - ret.environ.Set("OUT_DIR", filepath.Clean(outDir)) + ret.environ.Set("OUT_DIR", ret.sandboxPath(wd, filepath.Clean(outDir))) } else { outDir := "out" if baseDir, ok := ret.environ.Get("OUT_DIR_COMMON_BASE"); ok { - if wd, err := os.Getwd(); err != nil { - ctx.Fatalln("Failed to get working directory:", err) - } else { - outDir = filepath.Join(baseDir, filepath.Base(wd)) - } + outDir = filepath.Join(baseDir, filepath.Base(wd)) } - ret.environ.Set("OUT_DIR", outDir) + ret.environ.Set("OUT_DIR", ret.sandboxPath(wd, outDir)) } // loadEnvConfig needs to know what the OUT_DIR is, so it should @@ -350,6 +351,9 @@ func NewConfig(ctx Context, args ...string) Config { // Use config.useN2 instead. "SOONG_USE_N2", + + // Leaks usernames into environment. + "HOME", ) if ret.UseGoma() || ret.ForceUseGoma() { @@ -361,12 +365,12 @@ func NewConfig(ctx Context, args ...string) Config { ret.environ.Set("PYTHONDONTWRITEBYTECODE", "1") tmpDir := absPath(ctx, ret.TempDir()) - ret.environ.Set("TMPDIR", tmpDir) + ret.environ.Set("TMPDIR", ret.sandboxPath(wd, tmpDir)) // Always set ASAN_SYMBOLIZER_PATH so that ASAN-based tools can symbolize any crashes symbolizerPath := filepath.Join("prebuilts/clang/host", ret.HostPrebuiltTag(), "llvm-binutils-stable/llvm-symbolizer") - ret.environ.Set("ASAN_SYMBOLIZER_PATH", absPath(ctx, symbolizerPath)) + ret.environ.Set("ASAN_SYMBOLIZER_PATH", ret.sandboxPath(wd, absPath(ctx, symbolizerPath))) // Precondition: the current directory is the top of the source tree checkTopDir(ctx) @@ -426,9 +430,9 @@ func NewConfig(ctx Context, args ...string) Config { } ret.environ.Unset("OVERRIDE_ANDROID_JAVA_HOME") - ret.environ.Set("JAVA_HOME", absJavaHome) - ret.environ.Set("ANDROID_JAVA_HOME", javaHome) - ret.environ.Set("ANDROID_JAVA8_HOME", java8Home) + ret.environ.Set("JAVA_HOME", ret.sandboxPath(wd, absJavaHome)) + ret.environ.Set("ANDROID_JAVA_HOME", ret.sandboxPath(wd, javaHome)) + ret.environ.Set("ANDROID_JAVA8_HOME", ret.sandboxPath(wd, java8Home)) ret.environ.Set("PATH", strings.Join(newPath, string(filepath.ListSeparator))) // b/286885495, https://bugzilla.redhat.com/show_bug.cgi?id=2227130: some versions of Fedora include patches @@ -444,7 +448,7 @@ func NewConfig(ctx Context, args ...string) Config { ret.buildDateTime = strconv.FormatInt(time.Now().Unix(), 10) } - ret.environ.Set("BUILD_DATETIME_FILE", buildDateTimeFile) + ret.environ.Set("BUILD_DATETIME_FILE", ret.sandboxPath(wd, buildDateTimeFile)) if _, ok := ret.environ.Get("BUILD_USERNAME"); !ok { username := "unknown" @@ -455,6 +459,7 @@ func NewConfig(ctx Context, args ...string) Config { } ret.environ.Set("BUILD_USERNAME", username) } + ret.environ.Set("PWD", ret.sandboxPath(wd, wd)) if ret.UseRBE() { for k, v := range getRBEVars(ctx, Config{ret}) { @@ -1296,6 +1301,19 @@ func (c *configImpl) UseABFS() bool { return err == nil } +func (c *configImpl) sandboxPath(base, in string) string { + if !c.UseABFS() { + return in + } + + rel, err := filepath.Rel(base, in) + if err != nil { + return in + } + + return filepath.Join(abfsSrcDir, rel) +} + func (c *configImpl) UseRBE() bool { // These alternate modes of running Soong do not use RBE / reclient. if c.Queryview() || c.JsonModuleGraph() { @@ -1722,6 +1740,11 @@ func (c *configImpl) EmptyNinjaFile() bool { } func (c *configImpl) SkipMetricsUpload() bool { + // b/362625275 - Metrics upload sometimes prevents abfs unmount + if c.UseABFS() { + return true + } + return c.skipMetricsUpload } diff --git a/ui/build/path.go b/ui/build/path.go index 51ebff117..075bf2eb7 100644 --- a/ui/build/path.go +++ b/ui/build/path.go @@ -57,6 +57,22 @@ func parsePathDir(dir string) []string { return ret } +func updatePathForSandbox(config Config) { + wd, err := os.Getwd() + if err != nil { + return + } + + var newPath []string + if path, ok := config.Environment().Get("PATH"); ok && path != "" { + entries := strings.Split(path, string(filepath.ListSeparator)) + for _, ent := range entries { + newPath = append(newPath, config.sandboxPath(wd, ent)) + } + } + config.Environment().Set("PATH", strings.Join(newPath, string(filepath.ListSeparator))) +} + // SetupLitePath is the "lite" version of SetupPath used for dumpvars, or other // places that does not need the full logging capabilities of path_interposer, // wants the minimal performance overhead, and still get the benefits of $PATH @@ -121,6 +137,7 @@ func SetupLitePath(ctx Context, config Config, tmpDir string) { // Set $PATH to be the directories containing the host tool symlinks, and // the prebuilts directory for the current host OS. config.Environment().Set("PATH", myPath) + updatePathForSandbox(config) config.pathReplaced = true } @@ -265,5 +282,6 @@ func SetupPath(ctx Context, config Config) { // Replace the $PATH variable with the path_interposer symlinks, and // checked-in prebuilts. config.Environment().Set("PATH", myPath) + updatePathForSandbox(config) config.pathReplaced = true } diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go index d9ca85417..95b71a794 100644 --- a/ui/build/sandbox_linux.go +++ b/ui/build/sandbox_linux.go @@ -50,7 +50,6 @@ var ( const ( nsjailPath = "prebuilts/build-tools/linux-x86/bin/nsjail" - abfsSrcDir = "/src" ) var sandboxConfig struct { @@ -148,20 +147,42 @@ func (c *Cmd) sandboxSupported() bool { return sandboxConfig.working } -func (c *Cmd) srcDirArg() string { - if !c.config.UseABFS() { - return sandboxConfig.srcDir +// Assumes input path is absolute, clean, and if applicable, an evaluated +// symlink. If path is not a subdirectory of src dir or relative path +// cannot be determined, return the input untouched. +func (c *Cmd) relFromSrcDir(path string) string { + if !strings.HasPrefix(path, sandboxConfig.srcDir) { + return path } - return sandboxConfig.srcDir + ":" + abfsSrcDir + rel, err := filepath.Rel(sandboxConfig.srcDir, path) + if err != nil { + return path + } + + return rel +} + +func (c *Cmd) dirArg(path string) string { + if !c.config.UseABFS() { + return path + } + + rel := c.relFromSrcDir(path) + + return path + ":" + filepath.Join(abfsSrcDir, rel) +} + +func (c *Cmd) srcDirArg() string { + return c.dirArg(sandboxConfig.srcDir) } func (c *Cmd) outDirArg() string { - if !c.config.UseABFS() { - return sandboxConfig.outDir - } + return c.dirArg(sandboxConfig.outDir) +} - return sandboxConfig.outDir + ":" + filepath.Join(abfsSrcDir, sandboxConfig.outDir) +func (c *Cmd) distDirArg() string { + return c.dirArg(sandboxConfig.distDir) } // When configured to use ABFS, we need to allow the creation of the /src @@ -187,8 +208,17 @@ func (c *Cmd) readMountArgs() []string { return args } +func (c *Cmd) workDir() string { + if !c.config.UseABFS() { + wd, _ := os.Getwd() + return wd + } + + return abfsSrcDir +} + func (c *Cmd) wrapSandbox() { - wd, _ := os.Getwd() + wd := c.workDir() var sandboxArgs []string sandboxArgs = append(sandboxArgs, @@ -226,7 +256,7 @@ func (c *Cmd) wrapSandbox() { ) sandboxArgs = append(sandboxArgs, - c.readMountArgs()... + c.readMountArgs()..., ) sandboxArgs = append(sandboxArgs, @@ -264,7 +294,7 @@ func (c *Cmd) wrapSandbox() { if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) { //Mount dist dir as read-write if it already exists - sandboxArgs = append(sandboxArgs, "-B", sandboxConfig.distDir) + sandboxArgs = append(sandboxArgs, "-B", c.distDirArg()) } if c.Sandbox.AllowBuildBrokenUsesNetwork && c.config.BuildBrokenUsesNetwork() {