use std::convert::TryInto;
use std::io;
use std::sync::mpsc::{RecvError, SendError};
use nydus_error::error::MetricsError;
use serde::Deserialize;
use serde_json::Error as SerdeError;
use crate::{BlobCacheEntryConfig, BlobCacheEntryConfigV2};
#[derive(Clone, Deserialize, Debug)]
pub struct ApiMountCmd {
pub source: String,
#[serde(default)]
pub fs_type: String,
pub config: String,
#[serde(default)]
pub prefetch_files: Option<Vec<String>>,
}
#[derive(Clone, Deserialize, Debug)]
pub struct ApiUmountCmd {
pub mountpoint: String,
}
#[derive(Clone, Deserialize, Debug)]
pub struct DaemonConf {
pub log_level: String,
}
pub const BLOB_CACHE_TYPE_META_BLOB: &str = "bootstrap";
pub const BLOB_CACHE_TYPE_DATA_BLOB: &str = "datablob";
#[derive(Debug, Deserialize, Serialize)]
pub struct BlobCacheEntry {
#[serde(rename = "type")]
pub blob_type: String,
#[serde(rename = "id")]
pub blob_id: String,
#[serde(default, rename = "config")]
pub(crate) blob_config_legacy: Option<BlobCacheEntryConfig>,
#[serde(default, rename = "config_v2")]
pub blob_config: Option<BlobCacheEntryConfigV2>,
#[serde(default)]
pub domain_id: String,
}
impl BlobCacheEntry {
pub fn prepare_configuration_info(&mut self) -> bool {
if self.blob_config.is_none() {
if let Some(legacy) = self.blob_config_legacy.as_ref() {
match legacy.try_into() {
Err(_) => return false,
Ok(v) => self.blob_config = Some(v),
}
}
}
match self.blob_config.as_ref() {
None => false,
Some(cfg) => cfg.cache.validate() && cfg.backend.validate(),
}
}
}
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct BlobCacheList {
pub blobs: Vec<BlobCacheEntry>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BlobCacheObjectId {
#[serde(default)]
pub domain_id: String,
#[serde(default)]
pub blob_id: String,
}
#[derive(Debug)]
pub enum ApiRequest {
ConfigureDaemon(DaemonConf),
GetDaemonInfo,
GetEvents,
Exit,
Start,
SendFuseFd,
TakeoverFuseFd,
Mount(String, ApiMountCmd),
Remount(String, ApiMountCmd),
Umount(String),
ExportBackendMetrics(Option<String>),
ExportBlobcacheMetrics(Option<String>),
ExportFsGlobalMetrics(Option<String>),
ExportFsAccessPatterns(Option<String>),
ExportFsBackendInfo(String),
ExportFsFilesMetrics(Option<String>, bool),
ExportFsInflightMetrics,
GetDaemonInfoV2,
CreateBlobObject(Box<BlobCacheEntry>),
GetBlobObject(BlobCacheObjectId),
DeleteBlobObject(BlobCacheObjectId),
DeleteBlobFile(String),
}
#[derive(Debug)]
pub enum DaemonErrorKind {
NotReady,
Other(String),
Serde(SerdeError),
UnexpectedEvent(String),
UpgradeManager,
Unsupported,
}
#[derive(Debug)]
pub enum MetricsErrorKind {
Daemon(DaemonErrorKind),
Stats(MetricsError),
}
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum ApiError {
DaemonAbnormal(DaemonErrorKind),
Events(String),
Metrics(MetricsErrorKind),
MountFilesystem(DaemonErrorKind),
RequestSend(SendError<Option<ApiRequest>>),
ResponsePayloadType,
ResponseRecv(RecvError),
Wakeup(io::Error),
}
pub type ApiResult<T> = std::result::Result<T, ApiError>;
#[derive(Serialize)]
pub enum ApiResponsePayload {
BackendMetrics(String),
BlobcacheMetrics(String),
DaemonInfo(String),
Empty,
Events(String),
FsGlobalMetrics(String),
FsFilesMetrics(String),
FsFilesPatterns(String),
FsBackendInfo(String),
FsInflightMetrics(String),
BlobObjectList(String),
}
pub type ApiResponse = std::result::Result<ApiResponsePayload, ApiError>;
#[derive(Debug)]
pub enum HttpError {
BadRequest,
Configure(ApiError),
DaemonInfo(ApiError),
Events(ApiError),
NoRoute,
ParseBody(SerdeError),
QueryString(String),
Mount(ApiError),
Upgrade(ApiError),
BackendMetrics(ApiError),
BlobcacheMetrics(ApiError),
FsBackendInfo(ApiError),
FsFilesMetrics(ApiError),
GlobalMetrics(ApiError),
InflightMetrics(ApiError),
Pattern(ApiError),
CreateBlobObject(ApiError),
DeleteBlobObject(ApiError),
DeleteBlobFile(ApiError),
GetBlobObjects(ApiError),
}
#[derive(Serialize, Debug)]
pub(crate) struct ErrorMessage {
pub code: String,
pub message: String,
}
impl From<ErrorMessage> for Vec<u8> {
fn from(msg: ErrorMessage) -> Self {
serde_json::to_vec(&msg).unwrap()
}
}