containers::tools::run
Tag 1: a client asks the server to run a tool container from an image with limits and mounts; the server holds the content, serves the image, deploys, injects and connects to the proxy, makes every FUSE mount, sends exactly one id, and relays and serves every channel until the run ends.
A client opens the scope with a request whose payload is the tag byte
1 followed by the request as JSON. The server runs the
container the request describes for as long as the scope lives,
sends exactly one response on the scope, the container’s id or an
error, and ends the scope by the response finish. This section states
what the server does, in the order it does it. It states nothing
about the client, which may open any channel at any time.
- The request. Request states its form and every constraint the server enforces on it.
- The response. Response states the one response and the sequence of the main stream.
- The channels. The client opens the channels that Client Channels defines; the server opens the channels that Server Channels defines. Each channel is its own section.
The order#
- The server reads the request. A request whose payload does not
decode is answered by a response finish that no response precedes,
as Endpoints provides. A request the server refuses
is answered by exactly one response, the error, and the finish.
The server refuses a request that names a volume not in the
client’s volumes::list listing, a mount
whose path is the root of the container, two mounts with one path,
a mount inside a FUSE directory mount, two FUSE mounts with one
id, or an image source that its policy does not allow. - The server holds every identity mount’s content before it
deploys. For each entry of
identity_file_mountsandidentity_directory_mounts, the server either holds content it has verified against the identity, or opens a fetch-file or fetch-directory channel on the scope and stores what the client sends, verifying the size and the hash against the identity before the content counts as held. The server may hold content from an earlier run of any client. A channel the client finishes with no frame before the finish, and content that does not match its identity, are the run’s error. - The server serves the client’s image, when the image is the
client’s. For an image of kind
client, the server serves an OCI registry from which its runtime pulls the image by repository name and manifest digest. A manifest the registry does not hold, the server asks of the client on an oci-manifest channel; a blob it does not hold, on an oci-blob channel; it asks for each digest at most once per run, verifies the bytes it receives against the digest, and stores only bytes that match. A digest the client does not hold, and bytes that do not match, are the run’s error. For an image of kindserver, the server obtains the image from a source of its own. For an image of kindregistry, the server pulls the reference; which references it allows is its own. - The server deploys the container. The server starts the image
with
memoryanddiskas limits; every volume mount resolved byhost_nameagainst the identity under which the connection was authorized, descended byhost_relative_path, atcontainer_path; every identity mount read-only at itscontainer_path; the container proxy injected into the container and started; and TCP port14979of the container reachable to the server. The deploy is complete when the proxy accepts a connection at that port. The server sets no environment from the request. The server does not start the container before every identity mount’s content is held. A deploy that does not complete is the run’s error. - The server connects to the proxy. The server opens
/requestson the proxy. A proxy that does not accept the connection is a container that did not come up: the server stops the container, and the failure is the run’s error. - The server makes every FUSE mount. For each entry of
fuse_file_mounts, and after the last of them for each entry offuse_directory_mounts, in the order of the request, the server sends one/fuse/mountrequest and waits for its answer before sending the next. A mount the proxy does not make is the run’s error, and the server stops the container. The server sends no/agent/registerrequest, opens no/filesystem/tree, and sends no response before the last mount is complete. - The server holds what the client opened. A channel the client opens before the server sends the id is served after the id, in the order opened, and is neither refused nor read before the last FUSE mount is complete.
- The server mints and sends the id. The id is a string the server chooses, unique among the containers it is running, and not derivable from the request, from the identity of the connection, or from any other id. The server sends it as exactly one response. From that moment the container is running for the client, and a containers::tools::connect request naming the id finds it. The server sends no further response on the scope.
- The server serves the scope. Concurrently, for as long as the
scope lives: every ask the container makes on
/requestsis relayed to the client as a channel the server opens; every channel the client opens is served as its section defines. - The server ends the run. When it receives the client’s
stop, when the container’s
/requestsconnection ends, or when the client’s connection ends, the server ends every connect scope on the container, stops the container, releases the registry repository it served, ends every channel task, and sends the response finish. After the id, the server sends no error on the main stream: the finish that ends a running container carries none.
The rules that hold throughout#
- The means of deployment. This revision prescribes no runtime, no operating system, no virtualization, no network topology and no vendor. The server may deploy the container on hardware it operates, on infrastructure a third party supplies, or through an intermediary, and every requirement of this section holds however it deploys.
- No timeout. The server times nothing out: not a fetch, not a deploy, not a channel, not the scope. A container whose entrypoint never listens is served as a container whose exchanges the proxy cannot serve.
- The conduit. The server relays the bytes of every relayed exchange verbatim. It does not read them, does not alter them, does not reorder frames within one channel, and does not send an ask a second time. A channel the client finishes with no frame before the finish is relayed to the proxy as an ask not served.
- What the server never does. The server never opens a
fuse-write,fuse-remove,fuse-renameorfuse-mkdirchannel for a mount whosereadonlyistrue. The server never writes to a volume or a mount on its own account. The server never sends a second id.