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