nydus_api/
http.rs

1// Copyright 2022 Alibaba Cloud. All rights reserved.
2// Copyright 2020 Ant Group. All rights reserved.
3// Copyright © 2019 Intel Corporation
4//
5// SPDX-License-Identifier: Apache-2.0
6
7use std::io;
8use std::sync::mpsc::{RecvError, SendError};
9
10use serde::Deserialize;
11use serde_json::Error as SerdeError;
12use thiserror::Error;
13
14use crate::BlobCacheEntry;
15
16/// Errors related to Metrics.
17#[derive(Error, Debug)]
18pub enum MetricsError {
19    #[error("no counter found for the metric")]
20    NoCounter,
21    #[error("failed to serialize metric: {0:?}")]
22    Serialize(#[source] SerdeError),
23}
24
25/// Mount a filesystem.
26#[derive(Clone, Deserialize, Debug)]
27pub struct ApiMountCmd {
28    /// Path to source of the filesystem.
29    pub source: String,
30    /// Type of filesystem.
31    #[serde(default)]
32    pub fs_type: String,
33    /// Configuration for the filesystem.
34    pub config: String,
35    /// List of files to prefetch.
36    #[serde(default)]
37    pub prefetch_files: Option<Vec<String>>,
38}
39
40/// Umount a mounted filesystem.
41#[derive(Clone, Deserialize, Debug)]
42pub struct ApiUmountCmd {
43    /// Path of mountpoint.
44    pub mountpoint: String,
45}
46
47/// Set/update daemon configuration.
48#[derive(Clone, Deserialize, Debug)]
49pub struct DaemonConf {
50    /// Logging level: Off, Error, Warn, Info, Debug, Trace.
51    pub log_level: String,
52}
53
54/// Identifier for cached blob objects.
55///
56/// Domains are used to control the blob sharing scope. All blobs associated with the same domain
57/// will be shared/reused, but blobs associated with different domains are isolated.
58#[derive(Clone, Debug, Default, Deserialize, Serialize)]
59pub struct BlobCacheObjectId {
60    /// Domain identifier for the object.
61    #[serde(default)]
62    pub domain_id: String,
63    /// Blob identifier for the object.
64    #[serde(default)]
65    pub blob_id: String,
66}
67
68#[derive(Debug)]
69pub enum ApiRequest {
70    /// Set daemon configuration.
71    ConfigureDaemon(DaemonConf),
72    /// Get daemon information.
73    GetDaemonInfo,
74    /// Get daemon global events.
75    GetEvents,
76    /// Stop the daemon.
77    Exit,
78    /// Start the daemon.
79    Start,
80    /// Send fuse fd to new daemon.
81    SendFuseFd,
82    /// Take over fuse fd from old daemon instance.
83    TakeoverFuseFd,
84
85    // Filesystem Related
86    /// Mount a filesystem.
87    Mount(String, ApiMountCmd),
88    /// Remount a filesystem.
89    Remount(String, ApiMountCmd),
90    /// Unmount a filesystem.
91    Umount(String),
92
93    /// Get storage backend metrics.
94    ExportBackendMetrics(Option<String>),
95    /// Get blob cache metrics.
96    ExportBlobcacheMetrics(Option<String>),
97
98    // Nydus API v1 requests
99    /// Get filesystem global metrics.
100    ExportFsGlobalMetrics(Option<String>),
101    /// Get filesystem access pattern log.
102    ExportFsAccessPatterns(Option<String>),
103    /// Get filesystem backend information.
104    ExportFsBackendInfo(String),
105    /// Get filesystem file metrics.
106    ExportFsFilesMetrics(Option<String>, bool),
107    /// Get information about filesystem inflight requests.
108    ExportFsInflightMetrics,
109
110    // Nydus API v2
111    /// Get daemon information excluding filesystem backends.
112    GetDaemonInfoV2,
113    /// Create a blob cache entry
114    CreateBlobObject(Box<BlobCacheEntry>),
115    /// Get information about blob cache entries
116    GetBlobObject(BlobCacheObjectId),
117    /// Delete a blob cache entry
118    DeleteBlobObject(BlobCacheObjectId),
119    /// Delete a blob cache file
120    DeleteBlobFile(String),
121}
122
123/// Kinds for daemon related error messages.
124#[derive(Debug)]
125pub enum DaemonErrorKind {
126    /// Service not ready yet.
127    NotReady,
128    /// Generic errors.
129    Other(String),
130    /// Message serialization/deserialization related errors.
131    Serde(SerdeError),
132    /// Unexpected event type.
133    UnexpectedEvent(String),
134    /// Can't upgrade the daemon.
135    UpgradeManager(String),
136    /// Unsupported requests.
137    Unsupported,
138}
139
140/// Kinds for metrics related error messages.
141#[derive(Debug)]
142pub enum MetricsErrorKind {
143    /// Generic daemon related errors.
144    Daemon(DaemonErrorKind),
145    /// Errors related to metrics implementation.
146    Stats(MetricsError),
147}
148
149#[derive(Error, Debug)]
150#[allow(clippy::large_enum_variant)]
151pub enum ApiError {
152    #[error("daemon internal error: {0:?}")]
153    DaemonAbnormal(DaemonErrorKind),
154    #[error("daemon events error: {0}")]
155    Events(String),
156    #[error("metrics error: {0:?}")]
157    Metrics(MetricsErrorKind),
158    #[error("failed to mount filesystem: {0:?}")]
159    MountFilesystem(DaemonErrorKind),
160    #[error("failed to send request to the API service: {0:?}")]
161    RequestSend(#[from] SendError<Option<ApiRequest>>),
162    #[error("failed to parse response payload type")]
163    ResponsePayloadType,
164    #[error("failed to receive response from the API service: {0:?}")]
165    ResponseRecv(#[from] RecvError),
166    #[error("failed to wake up the daemon: {0:?}")]
167    Wakeup(#[source] io::Error),
168}
169
170/// Specialized `std::result::Result` for API replies.
171pub type ApiResult<T> = std::result::Result<T, ApiError>;
172
173#[derive(Serialize)]
174pub enum ApiResponsePayload {
175    /// Filesystem backend metrics.
176    BackendMetrics(String),
177    /// Blobcache metrics.
178    BlobcacheMetrics(String),
179    /// Daemon version, configuration and status information in json.
180    DaemonInfo(String),
181    /// No data is sent on the channel.
182    Empty,
183    /// Global error events.
184    Events(String),
185
186    /// Filesystem global metrics, v1.
187    FsGlobalMetrics(String),
188    /// Filesystem per-file metrics, v1.
189    FsFilesMetrics(String),
190    /// Filesystem access pattern trace log, v1.
191    FsFilesPatterns(String),
192    // Filesystem Backend Information, v1.
193    FsBackendInfo(String),
194    // Filesystem Inflight Requests, v1.
195    FsInflightMetrics(String),
196
197    /// List of blob objects, v2
198    BlobObjectList(String),
199}
200
201/// Specialized version of [`std::result::Result`] for value returned by backend services.
202pub type ApiResponse = std::result::Result<ApiResponsePayload, ApiError>;
203
204/// HTTP error messages sent back to the clients.
205///
206/// The `HttpError` object will be sent back to client with `format!("{:?}", http_error)`.
207/// So unfortunately it implicitly becomes parts of the API, please keep it stable.
208#[derive(Debug)]
209pub enum HttpError {
210    // Daemon common related errors
211    /// Invalid HTTP request
212    BadRequest,
213    /// Failed to configure the daemon.
214    Configure(ApiError),
215    /// Failed to query information about daemon.
216    DaemonInfo(ApiError),
217    /// Failed to query global events.
218    Events(ApiError),
219    /// No handler registered for HTTP request URI
220    NoRoute,
221    /// Failed to parse HTTP request message body
222    ParseBody(SerdeError),
223    /// Query parameter is missed from the HTTP request.
224    QueryString(String),
225
226    /// Failed to mount filesystem.
227    Mount(ApiError),
228    /// Failed to remount filesystem.
229    Upgrade(ApiError),
230
231    // Metrics related errors
232    /// Failed to get backend metrics.
233    BackendMetrics(ApiError),
234    /// Failed to get blobcache metrics.
235    BlobcacheMetrics(ApiError),
236
237    // Filesystem related errors (v1)
238    /// Failed to get filesystem backend information
239    FsBackendInfo(ApiError),
240    /// Failed to get filesystem per-file metrics.
241    FsFilesMetrics(ApiError),
242    /// Failed to get global metrics.
243    GlobalMetrics(ApiError),
244    /// Failed to get information about inflight request
245    InflightMetrics(ApiError),
246    /// Failed to get filesystem file access trace.
247    Pattern(ApiError),
248
249    // Blob cache management related errors (v2)
250    /// Failed to create blob object
251    CreateBlobObject(ApiError),
252    /// Failed to delete blob object
253    DeleteBlobObject(ApiError),
254    /// Failed to delete blob file
255    DeleteBlobFile(ApiError),
256    /// Failed to list existing blob objects
257    GetBlobObjects(ApiError),
258}
259
260#[derive(Serialize, Debug)]
261pub(crate) struct ErrorMessage {
262    pub code: String,
263    pub message: String,
264}
265
266impl From<ErrorMessage> for Vec<u8> {
267    fn from(msg: ErrorMessage) -> Self {
268        // Safe to unwrap since `ErrorMessage` must succeed in serialization
269        serde_json::to_vec(&msg).unwrap()
270    }
271}