/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.
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.
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 send1and 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:
//! 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, as JSON:
the string "file" or the string "directory". The answer is the ack
defined on FUSE.