Revert "Remove env config fetcher code"

This reverts commit 6324647bcc.

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
This commit is contained in:
Kousik Kumar 2023-05-30 20:23:57 +00:00
parent 6324647bcc
commit d93c67f64c

View file

@ -15,6 +15,7 @@
package build package build
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -38,6 +39,9 @@ import (
const ( const (
envConfigDir = "vendor/google/tools/soong_config" envConfigDir = "vendor/google/tools/soong_config"
jsonSuffix = "json" jsonSuffix = "json"
configFetcher = "vendor/google/tools/soong/expconfigfetcher"
envConfigFetchTimeout = 10 * time.Second
) )
var ( var (
@ -166,6 +170,87 @@ func checkTopDir(ctx Context) {
} }
} }
// 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 { func loadEnvConfig(ctx Context, config *configImpl, bc string) error {
if bc == "" { if bc == "" {
return nil return nil
@ -265,6 +350,9 @@ func NewConfig(ctx Context, args ...string) Config {
bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG") bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
if bc != "" { 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 { if err := loadEnvConfig(ctx, ret, bc); err != nil {
ctx.Fatalln("Failed to parse env config files: %v", err) ctx.Fatalln("Failed to parse env config files: %v", err)
} }