remoteexec.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2020 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package remoteexec
  15. import (
  16. "sort"
  17. "strings"
  18. )
  19. const (
  20. // ContainerImageKey is the key identifying the container image in the platform spec.
  21. ContainerImageKey = "container-image"
  22. // PoolKey is the key identifying the pool to use for remote execution.
  23. PoolKey = "Pool"
  24. // DefaultImage is the default container image used for Android remote execution. The
  25. // image was built with the Dockerfile at
  26. // https://android.googlesource.com/platform/prebuilts/remoteexecution-client/+/refs/heads/master/docker/Dockerfile
  27. DefaultImage = "docker://gcr.io/androidbuild-re-dockerimage/android-build-remoteexec-image@sha256:582efb38f0c229ea39952fff9e132ccbe183e14869b39888010dacf56b360d62"
  28. // DefaultWrapperPath is the default path to the remote execution wrapper.
  29. DefaultWrapperPath = "prebuilts/remoteexecution-client/live/rewrapper"
  30. // DefaultPool is the name of the pool to use for remote execution when none is specified.
  31. DefaultPool = "default"
  32. // LocalExecStrategy is the exec strategy to indicate that the action should be run locally.
  33. LocalExecStrategy = "local"
  34. // RemoteExecStrategy is the exec strategy to indicate that the action should be run
  35. // remotely.
  36. RemoteExecStrategy = "remote"
  37. // RemoteLocalFallbackExecStrategy is the exec strategy to indicate that the action should
  38. // be run remotely and fallback to local execution if remote fails.
  39. RemoteLocalFallbackExecStrategy = "remote_local_fallback"
  40. )
  41. var (
  42. defaultLabels = map[string]string{"type": "tool"}
  43. defaultExecStrategy = LocalExecStrategy
  44. defaultEnvironmentVariables = []string{
  45. // This is a subset of the allowlist in ui/build/ninja.go that makes sense remotely.
  46. "LANG",
  47. "LC_MESSAGES",
  48. "PYTHONDONTWRITEBYTECODE",
  49. }
  50. )
  51. // REParams holds information pertinent to the remote execution of a rule.
  52. type REParams struct {
  53. // Platform is the key value pair used for remotely executing the action.
  54. Platform map[string]string
  55. // Labels is a map of labels that identify the rule.
  56. Labels map[string]string
  57. // ExecStrategy is the remote execution strategy: remote, local, or remote_local_fallback.
  58. ExecStrategy string
  59. // Inputs is a list of input paths or ninja variables.
  60. Inputs []string
  61. // RSPFiles is the name of the files used by the rule as a placeholder for an rsp input.
  62. RSPFiles []string
  63. // OutputFiles is a list of output file paths or ninja variables as placeholders for rule
  64. // outputs.
  65. OutputFiles []string
  66. // OutputDirectories is a list of output directories or ninja variables as placeholders for
  67. // rule output directories.
  68. OutputDirectories []string
  69. // ToolchainInputs is a list of paths or ninja variables pointing to the location of
  70. // toolchain binaries used by the rule.
  71. ToolchainInputs []string
  72. // EnvironmentVariables is a list of environment variables whose values should be passed through
  73. // to the remote execution.
  74. EnvironmentVariables []string
  75. }
  76. func init() {
  77. }
  78. // Template generates the remote execution wrapper template to be added as a prefix to the rule's
  79. // command.
  80. func (r *REParams) Template() string {
  81. return "${android.RBEWrapper}" + r.wrapperArgs()
  82. }
  83. // NoVarTemplate generates the remote execution wrapper template without variables, to be used in
  84. // RuleBuilder.
  85. func (r *REParams) NoVarTemplate(wrapper string) string {
  86. return wrapper + r.wrapperArgs()
  87. }
  88. func (r *REParams) wrapperArgs() string {
  89. args := ""
  90. var kvs []string
  91. labels := r.Labels
  92. if len(labels) == 0 {
  93. labels = defaultLabels
  94. }
  95. for k, v := range labels {
  96. kvs = append(kvs, k+"="+v)
  97. }
  98. sort.Strings(kvs)
  99. args += " --labels=" + strings.Join(kvs, ",")
  100. var platform []string
  101. for k, v := range r.Platform {
  102. if v == "" {
  103. continue
  104. }
  105. platform = append(platform, k+"="+v)
  106. }
  107. if _, ok := r.Platform[ContainerImageKey]; !ok {
  108. platform = append(platform, ContainerImageKey+"="+DefaultImage)
  109. }
  110. if platform != nil {
  111. sort.Strings(platform)
  112. args += " --platform=\"" + strings.Join(platform, ",") + "\""
  113. }
  114. strategy := r.ExecStrategy
  115. if strategy == "" {
  116. strategy = defaultExecStrategy
  117. }
  118. args += " --exec_strategy=" + strategy
  119. if len(r.Inputs) > 0 {
  120. args += " --inputs=" + strings.Join(r.Inputs, ",")
  121. }
  122. if len(r.RSPFiles) > 0 {
  123. args += " --input_list_paths=" + strings.Join(r.RSPFiles, ",")
  124. }
  125. if len(r.OutputFiles) > 0 {
  126. args += " --output_files=" + strings.Join(r.OutputFiles, ",")
  127. }
  128. if len(r.OutputDirectories) > 0 {
  129. args += " --output_directories=" + strings.Join(r.OutputDirectories, ",")
  130. }
  131. if len(r.ToolchainInputs) > 0 {
  132. args += " --toolchain_inputs=" + strings.Join(r.ToolchainInputs, ",")
  133. }
  134. envVarAllowlist := append(r.EnvironmentVariables, defaultEnvironmentVariables...)
  135. if len(envVarAllowlist) > 0 {
  136. args += " --env_var_allowlist=" + strings.Join(envVarAllowlist, ",")
  137. }
  138. return args + " -- "
  139. }