# rexplorer

View information about an action and it's associated action-result in a JSON format, suitable for consumption by `jq`. It also supports a human-readable format directly by using the `--pretty` option.

## Usage
For basic usage with the CAS and Action Cache located at different endpoints, the following will print the Action and ActionResult (if available).
```
./rexplorer --cas-remote=http://foobar:50051 --cas-instance=foobar --ac-remote=http://ac:60051 --ac-instance=ac --action deadbeef/1337
```
If the CAS and Action Cache are located together, the `--remote`/`--instance`/... options can be specified instead.
```
Usage: ./rexplorer
   --help                          Display usage and exit.
   --version                       Print version information and exit. [optional]
   --action                        Action digest to view. Must be of the form <hash>/<size> [required]
   --depth                         How many levels of the input root to fetch, a negative value means print the entire root [optional, default = 1]
   --digest-function               Set a custom digest function. Supported functions: SHA384, SHA512, SHA256, SHA1, MD5 [optional, default = "SHA256"]
   --log-level                     Log level (debug, error, info, trace, warning) [optional, default = "error"]
   --verbose                       Set log level to 'debug' [optional]
   --pretty                        Print human readable JSON [optional]
   --remote                        URL for all services [optional]
   --instance                      Instance for all services [optional]
   --server-cert                   Server TLS certificate for all services (PEM-encoded) [optional]
   --client-key                    Client private TLS key far all services (PEM-encoded) [optional]
   --client-cert                   Client TLS certificate for all services (PEM-encoded) [optional]
   --access-token                  Authentication token for all services (JWT, OAuth token etc), will be included as an HTTP  Authorization bearer token [optional]
   --token-reload-interval         Default access token refresh timeout [optional]
   --googleapi-auth                Use GoogleAPIAuth for all services [optional]
   --retry-limit                   Retry limit for gRPC errors for all services [optional]
   --retry-delay                   Retry delay for gRPC errors for all services [optional]
   --retry-on-code                 gRPC status code(s) as string(s) to retry on for all services, e.g. 'UNKNOWN', 'INTERNAL' [optional]
   --request-timeout               Timeout for gRPC requests for all services  (set to 0 to disable timeout) [optional]
   --min-throughput                Minimum throughput for gRPC requests for all services, bytes per seconds. The value may be suffixed with K, M, G or T. [optional]
   --keepalive-time                gRPC keepalive pings period for all services (set to 0 to disable keepalive pings) [optional]
   --load-balancing-policy         gRPC load balancing policy for all services (valid options are 'round_robin' and 'grpclb') [optional]
   --cas-remote                    URL for the CAS service [optional]
   --cas-instance                  Name of the CAS instance [optional]
   --cas-server-cert               Server TLS certificate for CAS (PEM-encoded) [optional]
   --cas-client-key                Client private TLS key for CAS (PEM-encoded) [optional]
   --cas-client-cert               Client TLS certificate for CAS (PEM-encoded) [optional]
   --cas-access-token              Authentication token for CAS (JWT, OAuth token etc), will be included as an HTTP  Authorization bearer token [optional]
   --cas-token-reload-interval     Access token refresh timeout for CAS service [optional]
   --cas-googleapi-auth            Use GoogleAPIAuth for CAS service [optional]
   --cas-retry-limit               Retry limit for gRPC errors for CAS service [optional]
   --cas-retry-delay               Retry delay for gRPC errors for CAS service [optional]
   --cas-retry-on-code             gRPC status code(s) as string(s) to retry on for CAS service e.g., 'UNKNOWN', 'INTERNAL' [optional]
   --cas-request-timeout           Timeout for gRPC requests for CAS service (set to 0 to disable timeout) [optional]
   --cas-min-throughput            Minimum throughput for gRPC requests for CAS service, bytes per seconds. The value may be suffixed with K, M, G or T. [optional]
   --cas-keepalive-time            gRPC keepalive pings period for CAS service (set to 0 to disable keepalive pings) [optional]
   --cas-load-balancing-policy     gRPC load balancing policy for CAS service (valid options are 'round_robin' and 'grpclb') [optional]
   --ac-remote                     URL for the Action Cache service [optional]
   --ac-instance                   Name of the Action Cache instance [optional]
   --ac-server-cert                Server TLS certificate for Action Cache (PEM-encoded) [optional]
   --ac-client-key                 Client private TLS key for Action Cache (PEM-encoded) [optional]
   --ac-client-cert                Client TLS certificate for Action Cache (PEM-encoded) [optional]
   --ac-access-token               Authentication token for Action Cache (JWT, OAuth token etc), will be included as an HTTP  Authorization bearer token [optional]
   --ac-token-reload-interval      Access token refresh timeout for Action Cache service [optional]
   --ac-googleapi-auth             Use GoogleAPIAuth for Action Cache service [optional]
   --ac-retry-limit                Retry limit for gRPC errors for Action Cache service [optional]
   --ac-retry-delay                Retry delay for gRPC errors for Action Cache service [optional]
   --ac-retry-on-code              gRPC status code(s) as string(s) to retry on for Action Cache service e.g., 'UNKNOWN', 'INTERNAL' [optional]
   --ac-request-timeout            Timeout for gRPC requests for Action Cache service (set to 0 to disable timeout) [optional]
   --ac-min-throughput             Minimum throughput for gRPC requests for Action Cache service, bytes per seconds. The value may be suffixed with K, M, G or T. [optional]
   --ac-keepalive-time             gRPC keepalive pings period for Action Cache service (set to 0 to disable keepalive pings) [optional]
   --ac-load-balancing-policy      gRPC load balancing policy for Action Cache service (valid options are 'round_robin' and 'grpclb') [optional]```

### Docker

`rexplorer` can be used via the [`Dockerfile`](Dockerfile)

```
$ cd cpp/rexplorer
$ docker build . -t rexplorer
...
$ docker run -it rexplorer bash
```

## Output format
`protos/rexplorer.proto` contains the proto representation of the JSON output used by `rexplorer`. The main reason for using a custom format
is to inline parts of the Action which are normally referenced by digest, such as the `Command` or `InputRoot`. A basic action looks like the following (some empty fields left out/abbreviated for readability):

```
{
   "action": {
      "command": {
         "arguments": [
            "/bin/echo",
            "hi"
         ],
         "platform": {
            "properties": [
               {
                  "name": "ISA",
                  "value": "x86-64"
               }
            ]
         },
         "workingDirectory": "tmp",
         "outputPaths": [
            "my/output/file"
         ]
      },
      "inputRoot": [
         {
            "type": "directory",
            "name": "tmp"
         },
         {
            "type": "file",
            "name": "examplefile.txt"
         }
      ],
      "timeout": "0s"
   },
   "actionResult": {
      "outputFiles": [
         {
            "path": "my/output/file",
            "digest": {
               "hash": "deadbeefdeadbeef...",
               "sizeBytes": "9001"
            },
            "nodeProperties": {}
         }
      ],
      "exitCode": 0
      "stdoutDigest": {
         "hash": "abcdefabcdef...",
         "sizeBytes": "246810",
      },
      "executionMetadata": {
         "worker": "myworker1",
         ...
      }
   }
}
```

This can be easily filtered down using `jq`. For example to only print the `ActionResult` you can pipe the output of `rexplorer` to `jq` like so:

```
./rexplorer ... | jq .actionResult
```

### Output gotchas

There are some bits of weirdness with this output which might not be intuitive at first glance.

* The inputRoot is by default only fetched 1 level deep. More levels of the input root can be fetched using the `--depth` parameter.
* If an Action doesn't have an associated ActionResult, the `actionResult` key isn't returned at all, instead of having an "empty" value like `[]`
