Revert "Remove env config fetcher code"
This reverts commit 6324647bcce4a05568e9a5cb1237c2ca7f6781b3.
Reason for revert: This change negatively impacts users running builds on gLinux laptops. Reverting to limit impact and reland with appropriate fix.
Bug: b/284985772
Change-Id: I04a3d0107bb3ea680ba6641240620736a2ef5f17
diff --git a/ui/build/config.go b/ui/build/config.go
index 45735ad..8ec9680 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -15,6 +15,7 @@
package build
import (
+ "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -38,6 +39,9 @@
const (
envConfigDir = "vendor/google/tools/soong_config"
jsonSuffix = "json"
+
+ configFetcher = "vendor/google/tools/soong/expconfigfetcher"
+ envConfigFetchTimeout = 10 * time.Second
)
var (
@@ -166,6 +170,87 @@
}
}
+// fetchEnvConfig optionally fetches a configuration file that can then subsequently be
+// loaded into Soong environment to control certain aspects of build behavior (e.g., enabling RBE).
+// If a configuration file already exists on disk, the fetch is run in the background
+// so as to NOT block the rest of the build execution.
+func fetchEnvConfig(ctx Context, config *configImpl, envConfigName string) error {
+ configName := envConfigName + "." + jsonSuffix
+ expConfigFetcher := &smpb.ExpConfigFetcher{Filename: &configName}
+ defer func() {
+ ctx.Metrics.ExpConfigFetcher(expConfigFetcher)
+ }()
+ if !config.GoogleProdCredsExist() {
+ status := smpb.ExpConfigFetcher_MISSING_GCERT
+ expConfigFetcher.Status = &status
+ return nil
+ }
+
+ s, err := os.Stat(configFetcher)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+ if s.Mode()&0111 == 0 {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
+ return fmt.Errorf("configuration fetcher binary %v is not executable: %v", configFetcher, s.Mode())
+ }
+
+ configExists := false
+ outConfigFilePath := filepath.Join(config.OutDir(), configName)
+ if _, err := os.Stat(outConfigFilePath); err == nil {
+ configExists = true
+ }
+
+ tCtx, cancel := context.WithTimeout(ctx, envConfigFetchTimeout)
+ fetchStart := time.Now()
+ cmd := exec.CommandContext(tCtx, configFetcher, "-output_config_dir", config.OutDir(),
+ "-output_config_name", configName)
+ if err := cmd.Start(); err != nil {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
+ return err
+ }
+
+ fetchCfg := func() error {
+ if err := cmd.Wait(); err != nil {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
+ return err
+ }
+ fetchEnd := time.Now()
+ expConfigFetcher.Micros = proto.Uint64(uint64(fetchEnd.Sub(fetchStart).Microseconds()))
+ expConfigFetcher.Filename = proto.String(outConfigFilePath)
+
+ if _, err := os.Stat(outConfigFilePath); err != nil {
+ status := smpb.ExpConfigFetcher_NO_CONFIG
+ expConfigFetcher.Status = &status
+ return err
+ }
+ status := smpb.ExpConfigFetcher_CONFIG
+ expConfigFetcher.Status = &status
+ return nil
+ }
+
+ // If a config file does not exist, wait for the config file to be fetched. Otherwise
+ // fetch the config file in the background and return immediately.
+ if !configExists {
+ defer cancel()
+ return fetchCfg()
+ }
+
+ go func() {
+ defer cancel()
+ if err := fetchCfg(); err != nil {
+ ctx.Verbosef("Failed to fetch config file %v: %v\n", configName, err)
+ }
+ }()
+ return nil
+}
+
func loadEnvConfig(ctx Context, config *configImpl, bc string) error {
if bc == "" {
return nil
@@ -265,6 +350,9 @@
bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
if bc != "" {
+ if err := fetchEnvConfig(ctx, ret, bc); err != nil {
+ ctx.Verbosef("Failed to fetch config file: %v\n", err)
+ }
if err := loadEnvConfig(ctx, ret, bc); err != nil {
ctx.Fatalln("Failed to parse env config files: %v", err)
}