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

Canonical: https://provider.diverge.network/2.3.0/endpoints/containers-agents-run/
Specification revision: 2.3.0

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](/2.3.0/endpoints/containers-agents-run/request/) states its form and
  every constraint the server enforces on it.
- **The response.** [Response](/2.3.0/endpoints/containers-agents-run/response/) states the one
  response and the sequence of the main stream.
- **The channels.** The client opens the channels that
  [Client Channels](/2.3.0/endpoints/containers-agents-run/client/) defines; the server
  opens the channels that [Server Channels](/2.3.0/endpoints/containers-agents-run/server/)
  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](/2.3.0/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](/2.3.0/endpoints/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](/2.3.0/endpoints/containers-agents-run/server/fetch-file/) or
   [fetch-directory](/2.3.0/endpoints/containers-agents-run/server/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](/2.3.0/endpoints/containers-agents-run/server/oci-manifest/) channel; a blob it
   does not hold, on an [oci-blob](/2.3.0/endpoints/containers-agents-run/server/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`](/2.3.0/proxy/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`](/2.3.0/proxy/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`](/2.3.0/proxy/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](/2.3.0/endpoints/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](/2.3.0/endpoints/containers-agents-run/client/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.
