Remote Run Library ================== Location -------- - ``config/remote_run.sh`` Purpose ------- This library provides a ``rr_run`` entry point which executes a local shell script on a remote host via SSH **without writing any file to the remote filesystem**. The main script and every library it ``source``\s are kept on the local machine; the remote side receives file content on demand through a private TCP channel established by SSH port-forwarding. The library is designed for scripts that are already validated locally and use ``source`` as their composition mechanism (e.g. ``handle_state.sh``, ``command_guard.sh``). Dependencies ------------ +------------------+----------+-------------------------------------------+ | Dependency | Side | Notes | +==================+==========+===========================================+ | Bash ≥ 4.3 | Both | Nameref (``local -n``) in | | | | ``handle_state.sh``; auto-assigned FDs | | | | (``exec {var}<>file``) in remote_run.sh | +------------------+----------+-------------------------------------------+ | OpenSSH client | Local | ``ssh``, ``-T``, ``-R`` required | +------------------+----------+-------------------------------------------+ | OpenSSH server | Remote | ``sshd`` must be running and reachable | +------------------+----------+-------------------------------------------+ | ``nc`` | Local | OpenBSD nc (``-lU socket``); other | | | | variants are not supported | +------------------+----------+-------------------------------------------+ | ``base64`` | Remote | Standard on all major Linux distributions | +------------------+----------+-------------------------------------------+ All local-side dependencies are checked when the library is sourced via ``cg_guard``. If any required tool is absent the library fails to load, emits a diagnostic, and returns ``RR_ERR_DEPENDENCY_MISSING``. Architecture Overview --------------------- ``rr_run`` establishes a ControlMaster connection and multiplexes two operations over it. Each concurrent ``rr_resolve`` call adds a third channel for the duration of its file transfer, then closes it at EOF: **Bootstrap channel (SSH stdin via** ``-T``\ **)** — delivers the bootstrap shell fragment to the remote bash. The fragment is piped via process substitution; the write end closes when the generator exits, signalling EOF to remote bash stdin after the last bootstrap command. No PTY is allocated; ``ssh -T`` is always used. **Protocol channel (TCP via SSH** ``-R``\ **)** — carries the file-serving protocol after the bootstrap is running. Each ``rr_run`` call starts a ``nc`` listener on an ephemeral Unix-domain socket. SSH forwards an auto-allocated remote TCP port to that socket. The remote bash opens that port directly using Bash's built-in ``/dev/tcp/localhost/`` path with ``exec {fd}<>/dev/tcp/…``; no SSH client and no additional tool is required on the remote side. All subsequent ``GET`` / ``RESOLVE`` / ``OK`` / ``ERR`` messages travel over that single bidirectional file descriptor. :: local bootstrap pipe ──► SSH -T stdin ──► remote bash stdin (bootstrap) local nc server ◄── SSH -R tunnel ◄── remote bash fd (protocol) (GET / RESOLVE / OK / ERR) The remote bootstrap, delivered via SSH stdin, performs the following steps before any user code runs: 1. Allocates the protocol file descriptor dynamically (``exec {fd}<>``). 2. Generates and evaluates the ``source`` override with the fd value inscribed literally, so that ``source`` works correctly regardless of what the user script does to shell variables. 3. Propagates the local shell flags (``$-``) from the ``rr_run`` call site so that ``set -x``, ``set -e``, ``set -u``, ``set -o pipefail`` etc. are active on the remote if and only if they were active locally. Note that the remote script may subsequently change these flags at any time, exactly as it would when run locally. ``PS4`` is configured to display real source paths rather than internal wrapper names when tracing is active. 4. Runs the user script inside the double wrapper (see below). Quick Start ----------- .. code-block:: bash # Source the library once source "$(dirname "$0")/config/remote_run.sh" # Run a local script on a remote host (no prior initialisation needed) rr_run user@host deploy.sh --env production # Capture default options once, then run in parallel on multiple hosts local state rr_init -S state --ssh-opt "-i ~/.ssh/deploy_key" --allow /opt/shared/libs for host in "${servers[@]}"; do rr_run -S state "root@$host" deploy.sh --env production & done wait Inside ``deploy.sh`` or any script it sources, ``source`` works exactly as locally: .. code-block:: bash #!/usr/bin/env bash source config/handle_state.sh # fetched from local machine on demand source config/command_guard.sh # nested source — also fetched locally guard curl jq init_deployment() { local endpoint="$1" # ... deployment logic ... } init_deployment "$1" Public API ---------- rr_init ~~~~~~~ .. code-block:: text rr_init [-S ] [--allow ] [--ssh-opt ] Optional. Captures default options into a ``handle_state`` vector by name. Calling ``rr_run`` without a prior ``rr_init`` is valid; built-in defaults are used. ``-S `` Name of the caller-owned variable that will receive the updated state vector. Declare ``local `` before calling ``rr_init``. ``--allow `` Default whitelist entry. May be repeated. ``--ssh-opt `` Default SSH option. May be repeated. rr_run ~~~~~~ .. code-block:: text rr_run [-S ] [--allow ] [--ssh-opt ] [--] [args...] Executes ```` on ```` via SSH. All ``source`` calls inside the script resolve against the local filesystem. Each call allocates its own fd and ``nc`` instance; multiple ``rr_run`` calls may run in parallel against different hosts. ``-S `` State vector produced by ``rr_init``. Options in the vector are used as defaults and may be overridden by per-call ``--allow`` / ``--ssh-opt``. ``--allow `` Permit access to ```` in addition to the whitelist. May be repeated. Relative paths are resolved against the local working directory at invocation time. ``--ssh-opt `` Pass an extra option to every ``ssh`` invocation. May be repeated: .. code-block:: bash rr_run --ssh-opt "-p 2222" \ --ssh-opt "-i ~/.ssh/deploy_key" \ --ssh-opt "-o StrictHostKeyChecking=no" \ user@host deploy.sh ```` SSH target. Any format accepted by ``ssh`` is valid. ```` Path to the local script to execute, or a ``/dev/fd/N`` path produced by ``rr_resolve`` for relay scenarios. ``[args...]`` Positional arguments forwarded to the script as ``$1``, ``$2``, … **Exit code** Returns the exit code of the remote script, or one of the named error constants defined in the **Error Codes** section below: +------------------------------------+-------------------------------------------+ | Constant | Condition | +====================================+===========================================+ | ``RR_ERR_UNKNOWN_ARGUMENT`` | Unrecognised option in the option loop | +------------------------------------+-------------------------------------------+ | ``RR_ERR_MISSING_ARGUMENT`` | ```` or ``