Skip to content
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
45 changes: 26 additions & 19 deletions docs/how-engines-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,25 +196,25 @@ runtime timeout communication.
### Command format

Benchmark commands are generated by rickshaw-run.py and stored
in command files that the engine fetches during get-data. Each
command includes the iteration and sample context plus the
benchmark script with its parameters.

Parameters are passed using a Bash array mechanism:

```bash
declare -a ARGS=(
'--duration' '60'
'--protocol' 'tcp'
'--nthreads' '4'
) && mybench-client "${ARGS[@]}"
as compressed JSON files (`start.json.xz`, `stop.json.xz`,
`runtime.json.xz`, `infra.json.xz`) that the engine fetches
during get-data. Each entry pairs the iteration/sample context
with an `argv` list of already-rendered command tokens:

```json
[
{"test": "1-1", "argv": ["mybench-client", "--duration=60", "--protocol=tcp", "--nthreads=4"]}
]
```

The array preserves quoting and handles values with spaces
correctly. The engine executes the command via `invoke.run()`,
which spawns a subprocess that processes the array declaration
and runs the benchmark script. Benchmark scripts remain Bash
regardless of the engine runtime.
Parameter values are rendered as `--arg=value` tokens (`--arg`
alone when there's no value), quoted only when a value actually
needs it (e.g. embedded spaces). The engine applies `shlex.join()`
to the `argv` list immediately before executing it via
`invoke.run()` -- this is the only point where shell quoting is
introduced, so the same list can also be shipped safely through
roadblock's wait-for mechanism without any re-quoting. Benchmark
scripts remain Bash regardless of the engine runtime.

### Runtime discovery

Expand Down Expand Up @@ -242,12 +242,19 @@ Tool commands are stored as compressed JSON files:
"tools": [
{
"name": "sysstat",
"command": "declare -a ARGS=('--interval' '3') && sysstat-start \"${ARGS[@]}\""
"argv": ["sysstat-start", "--interval=3"],
"deployment": "auto",
"opt-tag": null
}
]
}
```

Tool params are rendered with the same `--arg=value` grammar and
quoting rules as benchmark params (see above) -- `argv` is
`shlex.join()`'d immediately before execution, not pre-rendered
into a shell string.

### Execution

For each tool in the JSON:
Expand Down Expand Up @@ -402,7 +409,7 @@ only knows after the engine is created (e.g., which Kubernetes
node the pod was scheduled to) and that scripts need during
execution or post-processing.

**Command files** (the ARGS array mechanism) deliver
**Command files** (the JSON argv list mechanism) deliver
benchmark and tool parameters. These are fetched from the
controller during the get-data phase and contain the actual
workload configuration — what to run, with what parameters,
Expand Down
20 changes: 11 additions & 9 deletions docs/how-tool-collection-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ tools listed in the run file will run:
```

Each tool entry specifies the tool name and optional parameters.
Parameters become `--key value` arguments passed to the tool's
Parameters become `--key=value` arguments passed to the tool's
start script. When no parameters are specified (as in the
defaults), the tool uses its own built-in defaults.

Expand Down Expand Up @@ -407,17 +407,19 @@ this path:

1. **Run file**: User specifies `tool-params` with `arg`/`val`
pairs
2. **rickshaw-run.py**: Builds a Bash command with a declared
`ARGS` array:
```bash
declare -a ARGS=('--interval' '3' '--subtools' 'mpstat,sar')
&& sysstat-start "${ARGS[@]}"
2. **rickshaw-run.py**: Renders each pair as a `--arg=value` token
(quoted only if the value needs it) and splits the result into
a plain argv list:
```json
["sysstat-start", "--interval=3", "--subtools=mpstat,sar"]
```
3. **Serialization**: Commands are written to compressed JSON files
(`tool-cmds/<collector-type>/start.json.xz`) in the run config
directory
4. **Engine execution**: The engine deserializes the JSON and
evaluates the command string
directory, one `argv` list per tool entry
4. **Engine execution**: The engine deserializes the JSON and joins
`argv` back into a shell command (`shlex.join()`) immediately
before executing it -- this is the only point where shell
quoting is introduced

This indirection allows the controller to build tool commands once
and distribute them to multiple engines, with each engine's start
Expand Down
6 changes: 3 additions & 3 deletions docs/implementing-a-new-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ A couple of things that differ from the benchmark case:

All tool scripts run inside engine containers on collection nodes.
They receive tool parameters as command-line arguments in
`--key value` format.
`--key=value` format.

### Script conventions

Expand Down Expand Up @@ -349,7 +349,7 @@ later shutdown. Typical structure:

1. Redirect output: `exec >mytool-start-stderrout.txt 2>&1`
2. Log arguments and environment for debugging
3. Parse `--key value` arguments with defaults
3. Parse `--key=value` arguments with defaults
4. Capture any baseline system state needed for post-processing
5. Launch the collection process in the background:
```bash
Expand Down Expand Up @@ -573,7 +573,7 @@ defaulted through it; if not, they're used exactly as given:
]
```

Each parameter becomes a `--key value` argument pair passed to the
Each parameter becomes a `--key=value` argument pair passed to the
start script. Parameters are optional — tools should define sensible
defaults.

Expand Down
Loading