Skip to main content

jax_daemon/http_server/api/v0/mounts/
update.rs

1//! Update mount API endpoint
2
3use axum::extract::{Json, Path, State};
4use axum::response::{IntoResponse, Response};
5use reqwest::{Client, RequestBuilder, Url};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9use super::create::MountInfo;
10use crate::http_server::api::client::ApiRequest;
11use crate::ServiceState;
12
13/// Request body for updating a mount (used by handler)
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct UpdateMountBody {
16    pub mount_point: Option<String>,
17    pub enabled: Option<bool>,
18    pub auto_mount: Option<bool>,
19    pub read_only: Option<bool>,
20    pub cache_size_mb: Option<u32>,
21    pub cache_ttl_secs: Option<u32>,
22}
23
24/// Full request for updating a mount (used by client)
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct UpdateMountRequest {
27    pub mount_id: Uuid,
28    #[serde(flatten)]
29    pub body: UpdateMountBody,
30}
31
32/// Response containing the updated mount
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct UpdateMountResponse {
35    pub mount: MountInfo,
36}
37
38pub async fn handler(
39    State(state): State<ServiceState>,
40    Path(id): Path<Uuid>,
41    Json(req): Json<UpdateMountBody>,
42) -> Result<impl IntoResponse, UpdateMountError> {
43    let mount_manager = state.mount_manager().read().await;
44    let mount_manager = mount_manager
45        .as_ref()
46        .ok_or(UpdateMountError::MountManagerUnavailable)?;
47
48    let mount = mount_manager
49        .update(
50            &id,
51            req.mount_point.as_deref(),
52            req.enabled,
53            req.auto_mount,
54            req.read_only,
55            req.cache_size_mb,
56            req.cache_ttl_secs,
57        )
58        .await?
59        .ok_or(UpdateMountError::NotFound(id))?;
60
61    Ok((
62        http::StatusCode::OK,
63        Json(UpdateMountResponse {
64            mount: mount.into(),
65        }),
66    )
67        .into_response())
68}
69
70#[derive(Debug, thiserror::Error)]
71pub enum UpdateMountError {
72    #[error("Mount manager unavailable")]
73    MountManagerUnavailable,
74    #[error("Mount not found: {0}")]
75    NotFound(Uuid),
76    #[error("Mount error: {0}")]
77    Mount(#[from] crate::fuse::MountError),
78}
79
80impl IntoResponse for UpdateMountError {
81    fn into_response(self) -> Response {
82        match self {
83            UpdateMountError::MountManagerUnavailable => (
84                http::StatusCode::SERVICE_UNAVAILABLE,
85                "Mount manager not available",
86            )
87                .into_response(),
88            UpdateMountError::NotFound(id) => (
89                http::StatusCode::NOT_FOUND,
90                format!("Mount not found: {}", id),
91            )
92                .into_response(),
93            UpdateMountError::Mount(e) => {
94                (http::StatusCode::BAD_REQUEST, format!("Mount error: {}", e)).into_response()
95            }
96        }
97    }
98}
99
100impl ApiRequest for UpdateMountRequest {
101    type Response = UpdateMountResponse;
102
103    fn build_request(self, base_url: &Url, client: &Client) -> RequestBuilder {
104        let full_url = base_url
105            .join(&format!("/api/v0/mounts/{}", self.mount_id))
106            .unwrap();
107        client.patch(full_url).json(&self.body)
108    }
109}