# /fuse/mount

> One FUSE mount, made on the server’s request, which names the path, the id, whether the mount is read-only, and whether it is a file or a directory; the proxy sends exactly one answer once the mount is serving, or an error, and closes the connection.

Canonical: https://provider.diverge.network/2.3.0/proxy/fuse/mount/
Specification revision: 2.3.0

The server opens `/fuse/mount` and sends exactly one message, the
request defined below as JSON, naming one mount. The proxy makes the
mount and sends exactly one message: a first byte of `0` states that
the mount is serving; a first byte of `1` is followed by a message
stating why the mount was not made. The proxy then closes the
connection. The proxy does not send the answer before the mount is
complete.

```text
server → proxy:   [request JSON]            once
proxy → server:   [0] | [1][message …]      once the mount is complete
```

- **One mount per opening.** The path accepts every opening the
  server makes. Each opening carries exactly one mount.
- **A mount not made.** A path that is empty, a path with a component
  that is empty, `.` or `..`, a path at which the proxy already holds
  a mount, a mount point the proxy could not make, a host without
  FUSE, and a session that would not start each cause the proxy to
  send `1` and a message.
- **Not served.** A close before the request, and a request that does
  not decode, cause the proxy to close the connection with no message
  before the close.
- **The life of a mount.** A mount made is held until the proxy
  ends. No party unmounts one. An abrupt end of the path leaves the
  fate of the mount unknown to the server, and no party retries the
  mount.
- **Before every other exchange.** The server makes every mount
  before it registers the agent and before it opens any filetree, so
  the program in the container finds the mount at the path and a tree
  never reports one.

The request is defined by
`diverge-provider-sdk/src/container_proxy/fuse/mount/request/request.rs`:

```rust
//! The mount to make.

use serde::{Deserialize, Serialize};

use crate::decode::Decode;
use crate::encode::{Encode, Writer};
use crate::shared::containers::fuse::Kind;

/// The first message on `/fuse/mount`, from the server: one FUSE
/// mount, as the container request named it.
///
/// One
/// [`FuseMount`](crate::shared::containers::request::FuseMount) of
/// the request, with which list it was on made explicit as the
/// [`kind`](Self::kind). The path is components from the container's
/// root, never empty, no component empty or `.` or `..`; the id is
/// the caller's, echoed on every ask the mount makes; `readonly`
/// refuses every mutation inside the container, and the mount never
/// asks one.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Request {
    /// Where the mount goes, as components from the container's
    /// root.
    pub path: Vec<String>,
    /// The mount's id, the caller's.
    pub id: String,
    /// Whether every mutation is refused.
    #[serde(default)]
    pub readonly: bool,
    /// One regular file, or a directory tree.
    pub kind: Kind,
}

impl Encode for Request {
    /// The ordinary JSON failure.
    type Error = serde_json::Error;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        serde_json::to_writer(out, self)
    }
}

impl Decode<'_> for Request {
    /// The ordinary JSON failure.
    type Error = serde_json::Error;

    fn decode(bytes: &[u8]) -> Result<Self, Self::Error> {
        serde_json::from_slice(bytes)
    }
}
```

Its `kind` is the `Kind` defined on [FUSE](/2.3.0/proxy/fuse/), as JSON:
the string `"file"` or the string `"directory"`. The answer is the ack
defined on [FUSE](/2.3.0/proxy/fuse/).
