Krikri::BatchScript
Wire protocol for task batching (on by default; --no-batching disables it): builds the bash script that runs several plugin invocations in one SSH round trip, and parses the results back out.
Both directions use base64 framing, never marker strings mixed into a plugin's own stdout/stderr - a shell/command task's captured output could in principle contain anything, including a string that collides with a hand-picked delimiter. Base64's own alphabet structurally can't produce that collision, so this is immune to it rather than merely unlikely to hit it.
The generated script is meant to be piped via a single ssh ... bash -s invocation's stdin. Each step's config is embedded in the script
itself (also base64) rather than streamed separately over that same
stdin - interleaving "script source" and "step data" on one stdin
stream is a well-known footgun (bash's own script-reading can read
ahead in blocks, not strictly line-by-line, corrupting the boundary
between where the script ends and data begins). A single
self-contained script sidesteps that entirely.
Assumes GNU coreutils base64 (supports -w0, no line wrapping) on
the target - consistent with this project's existing assumption of a
Debian/RHEL-family Linux target elsewhere (dpkg/rpm detection, etc.).
Constants
/var/tmp, not /tmp - see PluginManager.remote_plugin_dir for
why (some hardening roles remount /tmp as a fresh, empty tmpfs
mid-play, which would silently wipe this batch's own per-step
output files out from under it).
awk program (POSIX awk, run against one step's stdout file) that answers "does this result JSON have a TOP-LEVEL "failed": true?"
- exits 0 when it does. Tracks JSON string/escape state and brace depth so "failed" keys nested inside result values (uri:'s parsed response body, string-valued fields carrying escaped copies) never trip it. The result is always a single-line compact JSON object, so per-line state resets are harmless.
Class methods
Builds the full script for one batch. batch_id should be unique per invocation (avoids any risk of colliding with a leftover directory from an earlier batch against the same host).
Parses a batch script's stdout (as captured from the single SSH invocation that ran it) back into per-step results, keyed by the step's original index. A step whose index is missing never ran (the script halted before reaching it, or the whole batch never started)
- callers must not treat a missing entry as an error on its own.