Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update doc for how to re-run an action with another RBE instance. #590

Merged
merged 2 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ Flags that describe the RBE instance used and the authentication method are comm

`--alsologtostderr` and `-v VERBOSITY_LEVEL` can be used to tune the verbosity and location of the output, e.g. `--alsologtosrderr -v 1`.

For example, the common flags could be:

```
--service remotebuildexecution.googleapis.com:443 \
--use_application_default_credentials=true \
--alsologtostderr \
--v 1
```
#### Downloading an action's inputs and metadata
```
bazelisk run //go/cmd/remotetool -- \
Expand Down Expand Up @@ -42,6 +50,36 @@ bazelisk run //go/cmd/remotetool -- \
- An action digest formatted as `"{hash}/{size}"` can be provided directly using the `--digest` flag, or a previously downloaded action can be used with `--action_root`. The `--action_root` path should point to the `--path` of a previous `download_action` invocation. Specifically, the `--action_root` folder must contain a `cmd.textproto` and `ac.textproto` files.
- `--path` is the destination where the outputs of the action will be downloaded

#### Re-running a downloaded action remotely on a different RBE instance

If you want to download an action from an RBE instance `FOO`, and remotely
execute it on another RBE instance `BAR` (probably because you only have the
permission to download actions from `FOO`, but don't have the permission to
execute that instance). In this case, you want to download the action first, and
then re-run it on another RBE instance with
`--instance` and `--action_root` flags.

1. download the action from instance `FOO` to dir `/tmp/out/downloaded_action`

```
bazelisk run //go/cmd/remotetool -- \
--operation download_action \
--instance=FOO \
--digest=DIGEST
COMMON_FLAGS
--path /tmp/out/downloaded_action
```
2. run the downloaded action with another RBE instance `BAR`
```
bazelisk run //go/cmd/remotetool -- \
--operation execute_action \
--instance=BAR \
--action_root /tmp/out/downloaded_action \
COMMON_FLAGS
--path /tmp/output_file_path
```


#### Running a modified version of a downloaded action

1. Download an action to a given `PATH` following the [instructions for downloading an action](#downloading-an-actions-inputs-and-metadata),
Expand Down
19 changes: 15 additions & 4 deletions go/pkg/tool/embeddedtool.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ var (

// RegisterFlags registers the flags necessary for the embedded tool to work.
func RegisterFlags() {
flag.StringVar(&inputDigest, "digest", "", "Digest in <digest/size_bytes> format.")
flag.StringVar(&inputDigest, "digest", "", "Digest in <digest/size_bytes> format. This flag should not be provided if action_root is set.")
flag.StringVar(&pathPrefix, "path", "", "Path to which outputs should be downloaded to.")
flag.BoolVar(&overwrite, "overwrite", false, "Overwrite the output path if it already exist.")
flag.StringVar(&actionRoot, "action_root", "", "For execute_action: the root of the action spec, containing ac.textproto (Action proto), cmd.textproto (Command proto), and input/ (root of the input tree).")
flag.StringVar(&actionRoot, "action_root", "", "For execute_action: the root of the action spec, containing ac.textproto (Action proto), cmd.textproto (Command proto), and input/ (root of the input tree). This flag should not be provided if digest is set.")
flag.IntVar(&execAttempts, "exec_attempts", 10, "For check_determinism: the number of times to remotely execute the action and check for mismatches.")
flag.StringVar(&jsonOutput, "json", "", "Path to output operation result as JSON. Currently supported for \"upload_dir\", and includes various upload metadata (see UploadStats).")
}
Expand Down Expand Up @@ -99,12 +99,14 @@ var RemoteToolOperations = map[OpType]func(ctx context.Context, c *Client){
fmt.Printf("Action downloaded to %v\n", getPathFlag())
},
executeAction: func(ctx context.Context, c *Client) {
if _, err := c.ExecuteAction(ctx, getDigestFlag(), actionRoot, getPathFlag(), outerr.SystemOutErr); err != nil {
validateActionRootAndDg()
if _, err := c.ExecuteAction(ctx, inputDigest, actionRoot, getPathFlag(), outerr.SystemOutErr); err != nil {
log.Exitf("error executing action: %v", err)
}
},
checkDeterminism: func(ctx context.Context, c *Client) {
if err := c.CheckDeterminism(ctx, getDigestFlag(), actionRoot, execAttempts); err != nil {
validateActionRootAndDg()
if err := c.CheckDeterminism(ctx, inputDigest, actionRoot, execAttempts); err != nil {
log.Exitf("error checking determinism: %v", err)
}
},
Expand Down Expand Up @@ -157,3 +159,12 @@ func getPathFlag() string {
}
return pathPrefix
}

func validateActionRootAndDg() {
if inputDigest != "" && actionRoot != "" {
log.Exitf("either specify --digest or --action_root, should not set both of them together.")
}
if inputDigest == "" && actionRoot == "" {
log.Exitf("either specify --digest or --action_root, one of these flags must be set, but not both.")
}
}
5 changes: 3 additions & 2 deletions go/pkg/tool/tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"time"

"errors"
log "github.com/golang/glog"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/encoding/prototext"
Expand Down Expand Up @@ -98,7 +98,7 @@ func (c *Client) prepCommand(ctx context.Context, client *rexec.Client, actionDi
return nil, err
}

log.Infof("Reading command from action digest..")
log.Infof("Reading command from action digest: %v", acDg)
if _, err := c.GrpcClient.ReadProto(ctx, cmdDg, commandProto); err != nil {
return nil, err
}
Expand Down Expand Up @@ -656,6 +656,7 @@ func (c *Client) ExecuteAction(ctx context.Context, actionDigest, actionRoot, ou
case command.LocalErrorResultStatus:
oe.WriteErr([]byte(fmt.Sprintf("Local error: %v.\n", ec.Result.Err)))
}
fmt.Printf("Result: %+v\n", ec.Result)
ywmei-brt1 marked this conversation as resolved.
Show resolved Hide resolved
if ec.Result.Err == nil && outDir != "" {
ec.DownloadOutputs(outDir)
fmt.Printf("Output written to %v\n", outDir)
Expand Down
Loading