124 lines
7.1 KiB
Markdown
124 lines
7.1 KiB
Markdown
# RVBox v1 control plane
|
|
|
|
[`../protos/rvbox/v1/control.proto`](../protos/rvbox/v1/control.proto) defines
|
|
the canonical control API. `rvc` uses the `Control` gRPC service over the local
|
|
Unix-domain socket. The server also exposes the same unary operations through
|
|
an optional JSON-RPC 2.0 HTTP adapter for local debugging and batch automation.
|
|
|
|
## Endpoints
|
|
|
|
- Unix socket: enabled by default, mode `0600`, owned by the server account.
|
|
- HTTP JSON-RPC: disabled unless enabled; default bind `127.0.0.1:6900`.
|
|
It has no authentication by design. Binding it beyond loopback is an explicit
|
|
deployment choice and requires external protection.
|
|
|
|
gRPC streams command history and live events through `FollowCommand`. JSON-RPC
|
|
remains simple: callers issue work, query command state, poll event/output pages
|
|
after an event sequence, append stdin, close stdin, or signal a command. It does
|
|
not invent a separate event-stream protocol.
|
|
|
|
The JSON-RPC method names are the lower-camel protobuf operation names:
|
|
`listClients`, `getClient`, `listCommands`, `getCommand`, `runCommand`,
|
|
`appendStdin`, `closeStdin`, `signalCommand`, `getOutput`, and the three storage
|
|
incident methods documented below. Parameters and results use protobuf JSON
|
|
mapping (including base64 strings for `bytes` and UTC RFC 3339 strings for
|
|
timestamps). Control response messages contain successful results only. gRPC
|
|
failures use canonical non-OK status codes with structured RVBox details where
|
|
needed; the JSON-RPC adapter maps the same domain errors to standard JSON-RPC
|
|
error objects. `getOutput` and `getCommand` are the polling path for what gRPC
|
|
exposes as follow streams.
|
|
|
|
`rvc stat CLIENT` also shows the active durable client-instance ID and the most
|
|
recent different instance rejected while that client is live. An operator may
|
|
run `rvc client takeover CLIENT INSTANCE-ID`; this creates a one-shot 5-minute
|
|
authorization for that exact pending claim. Its matching reconnect consumes the
|
|
authorization and fences the old session. If the old session is no longer live,
|
|
the replacement connects normally without this command. The JSON-RPC method is
|
|
`authorizeClientTakeover`.
|
|
|
|
Both transports enforce the same decoded field limits. A control gRPC request
|
|
may be at most 16 MiB; a JSON-RPC HTTP body may be at most 24 MiB to accommodate
|
|
base64 expansion of the 10 MiB script maximum. `ExecutionSpec` itself may be at
|
|
most 768 KiB, which also keeps its agent dispatch below the 1 MiB envelope cap.
|
|
|
|
## CLI semantics
|
|
|
|
`rvc stat` maps to `ListClients`, `GetClient`, `ListCommands`, and `GetCommand`.
|
|
History pages default to 20 commands and may request at most 100. Historical
|
|
output uses opaque, byte-bounded cursors and may resume within an output event;
|
|
it is not numbered or paginated by lines. The server returns uncompressed output
|
|
slices with event sequence, byte offset, stream, observed timestamp, and server
|
|
receipt timestamp. `rvc` may render line-oriented human output, but line
|
|
boundaries are not storage or pagination boundaries.
|
|
|
|
`rvc run` always creates a durable command through unary `RunCommand`, which
|
|
returns the UUID. Foreground mode then calls `FollowCommand` with that UUID,
|
|
`after_event_seq=0`, and `include_existing=true`, streaming output until a
|
|
terminal event. `--background` returns immediately after `RunCommand`.
|
|
Interrupting the CLI, timing out its local wait, or losing the local control
|
|
connection never cancels remote work. The explicit `rvc kill` operation is the
|
|
only termination path. A foreground caller can resume `FollowCommand` after its
|
|
last received event sequence without missing durable history.
|
|
|
|
`FollowCommandResponse` wraps either a client-sequenced `CommandEvent` or a
|
|
server-created retention marker and exposes server receipt/recording time
|
|
separately from client observation time. A retention marker does not advance the
|
|
resume cursor. When retained history is incomplete, the server emits the relevant
|
|
marker before any terminal event on that stream, so a follower never stops on
|
|
terminal while believing truncated history was complete.
|
|
|
|
Mutating requests accept an optional `request_id`. `rvc` generates one per
|
|
mutation and reuses it for transport retries; `--request-id` lets automation
|
|
reuse it across CLI invocations. The CLI accepts that option globally and drops
|
|
it for reads. For `RunCommand`, the supplied request ID is the command's
|
|
`issue_uuid`. For stdin, close, signal, repair, and acknowledgement operations
|
|
it deduplicates that action while `issue_uuid` or `incident_id` continues to
|
|
identify the target. The server generates a request ID when omitted, preserving
|
|
simple JSON-RPC use.
|
|
|
|
The server stores the mutation kind, target, immutable request hash, and result
|
|
under that ID. An identical retry returns the original result; reuse with any
|
|
different method, target, or content returns `CONFLICT`. The record is owned by
|
|
the affected command or incident for quota and retention. A retry after that
|
|
owner has been reclaimed cannot repeat the action: it returns retained
|
|
tombstone information where available or `NOT_FOUND`.
|
|
|
|
`rvc run --queue-ttl` controls how long work may wait for server-confirmed
|
|
acceptance and defaults to 15 minutes; zero means indefinite. `rvc stat`
|
|
distinguishes terminal `Expired`, `Expired (awaiting reconciliation)`, and
|
|
actual lifecycle with a late-after-expiry warning. It renders terminal
|
|
`Rejected` with the client's structured validation/platform reason; `Failed`
|
|
means the requested code actually launched.
|
|
|
|
`rvc append` turns a string into `StdinWrite` with `append_newline=true` unless
|
|
the caller selects raw mode; `--file` supplies raw bytes; `--attach` streams
|
|
local standard input. `CloseStdin` is available separately. All stdin actions
|
|
are acknowledged and idempotent.
|
|
|
|
## Query behavior
|
|
|
|
Command details expose persisted request fields, effective execution metadata,
|
|
lifecycle, terminal result, output availability/truncation, current resource
|
|
snapshot, and `suspected_hung` diagnostics. The latter is informational and
|
|
must not be shown as a terminal state. Pagination response cursors are stable
|
|
within their declared ordering (newest issue time for command lists; increasing
|
|
`event_seq` for events/output).
|
|
|
|
Control failures are never embedded in otherwise-successful response messages.
|
|
They use canonical gRPC status codes with structured RVBox details; JSON-RPC
|
|
returns the corresponding JSON-RPC error object, and `rvc` maps the same domain
|
|
error to a stable exit code rather than parsing text.
|
|
|
|
## Storage incidents
|
|
|
|
`rvc storage incidents` lists unresolved storage incidents by default and can
|
|
include resolved history. `rvc storage repair INCIDENT` attempts only a known
|
|
safe repair. `rvc storage acknowledge INCIDENT --note ...` accepts documented
|
|
irrecoverable loss and clears that incident from dirty health. Both mutations
|
|
use the same optional `--request-id` behavior as other mutations. An
|
|
acknowledgement note is required and bounded to 4 KiB. Repair or acknowledgement
|
|
changes incident state; it does not delete history as part of that action;
|
|
resolved history later follows the independent audit/incident quota. The
|
|
JSON-RPC equivalents are `listStorageIncidents`,
|
|
`repairStorageIncident`, and `acknowledgeStorageIncident`.
|