Skip to content

Commit

Permalink
[RB] Support remote header overrides (#7823)
Browse files Browse the repository at this point in the history
This will let customers pass credentials for private docker images for
the remote runner
  • Loading branch information
maggie-lou authored Oct 30, 2024
1 parent 68b433a commit ea0cbbd
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cli/remotebazel/remotebazel.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ var (
remoteRunner = RemoteFlagset.String("remote_runner", defaultRemoteExecutionURL, "The Buildbuddy grpc target the remote runner should run on.")
timeout = RemoteFlagset.Duration("timeout", 0, "If set, requests that have exceeded this timeout will be canceled automatically. (Ex. --timeout=15m; --timeout=2h)")
execPropsFlag = bbflag.New(RemoteFlagset, "runner_exec_properties", []string{}, "Exec properties that will apply to the *ci runner execution*. Key-value pairs should be separated by '=' (Ex. --runner_exec_properties=NAME=VALUE). Can be specified more than once. NOTE: If you want to apply an exec property to the bazel command that's run on the runner, just pass at the end of the command (Ex. bb remote build //... --remote_default_exec_properties=OSFamily=linux).")
remoteHeaders = bbflag.New(RemoteFlagset, "remote_run_header", []string{}, "Remote headers to be applied to the execution request for the remote run. Can be used to set platform properties containing secrets (Ex. --remote_run_header=x-buildbuddy-platform.SECRET_NAME=SECRET_VALUE). Can be specified more than once.")
runRemotely = RemoteFlagset.Bool("run_remotely", true, "For `run` commands, whether the target should be run remotely. If false, the target will be built remotely, and then fetched and run locally.")
useSystemGitCredentials = RemoteFlagset.Bool("use_system_git_credentials", false, "Whether to use github auth pre-configured on the remote runner. If false, require https and an access token for git access.")
runFromBranch = RemoteFlagset.String("run_from_branch", "", "A GitHub branch to base the remote run off. If unset, the remote workspace will mirror your local workspace.")
Expand Down Expand Up @@ -792,6 +793,7 @@ func Run(ctx context.Context, opts RunOpts, repoConfig *RepoConfig) (int, error)
ContainerImage: *containerImage,
Env: envVars,
ExecProperties: platform.Properties,
RemoteHeaders: *remoteHeaders,
RunRemotely: *runRemotely,
}
req.GetRepoState().Patch = append(req.GetRepoState().Patch, repoConfig.Patches...)
Expand Down
25 changes: 25 additions & 0 deletions docs/remote-bazel-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ The following configuration options are supported:
- `--runner_exec_properties`: Platform properties to configure the remote runner.
- Ex. To run on a self-hosted executor pool, you could use
`--runner_exec_properties=use-self-hosted-executors=true --runner_exec_properties=Pool=custom-pool`
- `--remote_run_header`: Remote headers to be applied to the execution request for the remote runner.
- These are useful for passing platform properties containing secrets. Platform
properties set via remote header will not be displayed on the UI and will not
be included in the snapshot key (which contains regular platform properties).
This is helpful when passing short-lived credentials that you don't want invalidating
your snapshots.
- See `Private Docker images` below for an example.
- `--timeout` (Ex. '30m', '1h'): If set, remote runs that have been running for longer
than this duration will be canceled automatically. This only applies to a single attempt,
and does not include multiple retry attempts.
Expand Down Expand Up @@ -220,6 +227,24 @@ https://app.buildbuddy.io/api/v1/Run
If your GitHub repo is private, you must first link it at https://app.buildbuddy.io/workflows/
to authorize the remote runner to access it.

### Private Docker images

If you would like the remote runner to start from a private container image, you
can pass credentials via remote headers.

See https://www.buildbuddy.io/docs/rbe-platforms/#passing-credentials-for-docker-images
for more details on passing credentials for private images.

See `Configuring the remote runner` above for more information about remote headers.

```bash
bb remote \
--container_image=docker://<private-image-url> \
--remote_run_header=x-buildbuddy-platform.container-registry-username=USERNAME \
--remote_run_header=x-buildbuddy-platform.container-registry-password=PASSWORD \
build //...
```

### GitHub Enterprise

In order to use Remote Bazel with GitHub Enterprise, you must set `--use_system_git_credentials`
Expand Down
1 change: 1 addition & 0 deletions enterprise/server/api/api_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ func (s *APIServer) Run(ctx context.Context, req *apipb.RunRequest) (*apipb.RunR
Env: req.GetEnv(),
Timeout: req.GetTimeout(),
ExecProperties: execProps,
RemoteHeaders: req.GetRemoteHeaders(),
RunRemotely: true,
})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions enterprise/server/hostedrunner/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ go_library(
"@com_github_google_uuid//:uuid",
"@in_gopkg_yaml_v2//:yaml_v2",
"@org_golang_google_genproto//googleapis/longrunning",
"@org_golang_google_grpc//metadata",
"@org_golang_google_grpc//status",
"@org_golang_google_protobuf//types/known/durationpb",
],
Expand Down
12 changes: 12 additions & 0 deletions enterprise/server/hostedrunner/hostedrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/buildbuddy-io/buildbuddy/server/util/status"
"github.com/google/uuid"
"google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/types/known/durationpb"
"gopkg.in/yaml.v2"

Expand Down Expand Up @@ -375,6 +376,17 @@ func (r *runnerService) Run(ctx context.Context, req *rnpb.RunRequest) (*rnpb.Ru
if err != nil {
return nil, status.WrapError(err, "add request metadata to ctx")
}
// Apply remote headers
for _, h := range req.GetRemoteHeaders() {
parts := strings.SplitN(h, "=", 2)
if len(parts) != 2 {
return nil, status.InvalidArgumentErrorf("malformed remote header %s: key-value pairs should be separated by '='", h)
}
headerKey := parts[0]
headerVal := parts[1]
execCtx = metadata.AppendToOutgoingContext(execCtx, headerKey, headerVal)
}

execCtx, err = r.withCredentials(execCtx, req)
if err != nil {
return nil, status.WrapError(err, "authenticate ctx")
Expand Down
1 change: 1 addition & 0 deletions enterprise/server/test/integration/remote_bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package(default_visibility = ["//enterprise:__subpackages__"])

go_test(
name = "remote_bazel_test",
size = "enormous",
srcs = ["remote_bazel_test.go"],
exec_properties = {
"include-secrets": "true",
Expand Down
7 changes: 7 additions & 0 deletions proto/api/v1/remote_runner.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ message RunRequest {
// Ex. {"OSFamily":"linux", "Arch":"amd64"}
map<string, string> platform_properties = 6;

// Remote headers to be applied to the execution request for the remote
// runner.
//
// Can be used to set platform properties containing secrets.
// Ex. --remote_headers=x-buildbuddy-platform.SECRET_NAME=SECRET_VALUE
repeated string remote_headers = 10;

// Max time before run should be canceled.
// Ex. "15s", "2h"
string timeout = 7;
Expand Down
7 changes: 7 additions & 0 deletions proto/runner.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ message RunRequest {
repeated build.bazel.remote.execution.v2.Platform.Property exec_properties =
13;

// Remote headers to be applied to the execution request for the remote
// runner.
//
// Can be used to set platform properties containing secrets.
// Ex. --remote_headers=x-buildbuddy-platform.SECRET_NAME=SECRET_VALUE
repeated string remote_headers = 17;

// If true, binaries generated by a `bazel run` command will be executed
// remotely. If false or unset, run metadata (runtime flags, files, etc) will
// be collected so the binary can be run elsewhere.
Expand Down

0 comments on commit ea0cbbd

Please sign in to comment.