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}