Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac985b9c authored by Kousik Kumar's avatar Kousik Kumar Committed by Gerrit Code Review
Browse files

Merge "Revert "Remove env config fetcher code""

parents 1ef69c75 d93c67f6
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package build

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
@@ -39,6 +40,9 @@ import (
const (
	envConfigDir = "vendor/google/tools/soong_config"
	jsonSuffix   = "json"

	configFetcher         = "vendor/google/tools/soong/expconfigfetcher"
	envConfigFetchTimeout = 10 * time.Second
)

var (
@@ -170,6 +174,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 {
	if bc == "" {
		return nil
@@ -283,6 +368,9 @@ func NewConfig(ctx Context, args ...string) Config {
	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)
		}