containers::agents::run

Tag 0: a client asks the server to run an agent 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, registers the agent, 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 0 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#

  1. 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.

  2. The server holds every identity mount’s content before it deploys. For each entry of identity_file_mounts and identity_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.

  3. 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 kind server, the server obtains the image from a source of its own. For an image of kind registry, the server pulls the reference; which references it allows is its own.

  4. The server deploys the container. The server starts the image with memory and disk as limits; every volume mount resolved by host_name against the identity under which the connection was authorized, descended by host_relative_path, at container_path; every identity mount read-only at its container_path; the container proxy injected into the container and started; and TCP port 14979 of 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.

  5. The server connects to the proxy. The server opens /requests on 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.

  6. The server makes every FUSE mount. For each entry of fuse_file_mounts, and after the last of them for each entry of fuse_directory_mounts, in the order of the request, the server sends one /fuse/mount request 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/register request, opens no /filesystem/tree, and sends no response before the last mount is complete.

  7. 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.

  8. The server registers the agent. The server sends exactly one /agent/register request to the proxy, carrying the agent value of the request verbatim. The server sends it after the last FUSE mount is complete and before it sends the id. A registration the proxy refuses is the run’s error, and the server stops the container.

  9. 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.

  10. The server serves the scope. Concurrently, for as long as the scope lives: every ask the container makes on /requests is relayed to the client as a channel the server opens; every channel the client opens is served as its section defines.

  11. The server ends the run. When it receives the client’s stop, when the container’s /requests connection 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-rename or fuse-mkdir channel for a mount whose readonly is true. The server never writes to a volume or a mount on its own account. The server never sends a second id.