Skip to content

Commit

Permalink
storage: introduce new backend localdisk
Browse files Browse the repository at this point in the history
This patch adds a new storage backend localdisk which supports reading
blobs on disk. In this scenario, each layer of the blob is stored in
partitions, and multiple partitions are addressed in the local raw
disk via the GUID partition table (GPT), which means that this disk
stores the entire image.

Signed-off-by: Qinqi Qu <[email protected]>
  • Loading branch information
adamqqqplay committed Feb 8, 2023
1 parent 2ad8675 commit 5b54510
Show file tree
Hide file tree
Showing 13 changed files with 451 additions and 3 deletions.
48 changes: 48 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ nydus-rafs = { version = "0.2.0", path = "rafs", features = [
"backend-oss",
"backend-s3",
"backend-http-proxy",
"backend-localdisk",
] }
nydus-storage = { version = "0.6.0", path = "storage" }
nydus-utils = { version = "0.4.0", path = "utils" }
Expand Down
46 changes: 44 additions & 2 deletions api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ pub struct BackendConfigV2 {
/// Type of storage backend.
#[serde(rename = "type")]
pub backend_type: String,
/// Configuration for local disk backend.
pub localdisk: Option<LocalDiskConfig>,
/// Configuration for local filesystem backend.
pub localfs: Option<LocalFsConfig>,
/// Configuration for OSS backend.
Expand All @@ -255,6 +257,14 @@ impl BackendConfigV2 {
/// Validate storage backend configuration.
pub fn validate(&self) -> bool {
match self.backend_type.as_str() {
"localdisk" => match self.localdisk.as_ref() {
Some(v) => {
if v.device_path.is_empty() {
return false;
}
}
None => return false,
},
"localfs" => match self.localfs.as_ref() {
Some(v) => {
if v.blob_file.is_empty() && v.dir.is_empty() {
Expand Down Expand Up @@ -315,6 +325,17 @@ impl BackendConfigV2 {
true
}

/// Get configuration information for localdisk
pub fn get_localdisk_config(&self) -> Result<&LocalDiskConfig> {
if &self.backend_type != "localdisk" {
Err(einval!("backend type is not 'localdisk'"))
} else {
self.localdisk
.as_ref()
.ok_or_else(|| einval!("no configuration information for localdisk"))
}
}

/// Get configuration information for localfs
pub fn get_localfs_config(&self) -> Result<&LocalFsConfig> {
if &self.backend_type != "localfs" {
Expand Down Expand Up @@ -371,6 +392,14 @@ impl BackendConfigV2 {
}
}

/// Configuration information for localdisk storage backend.
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct LocalDiskConfig {
/// Mounted block device path or original localdisk image file path.
#[serde(default)]
pub device_path: String,
}

/// Configuration information for localfs storage backend.
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct LocalFsConfig {
Expand Down Expand Up @@ -962,7 +991,7 @@ struct BackendConfig {
#[serde(rename = "type")]
pub backend_type: String,
/// Configuration for storage backend.
/// Possible value: `LocalFsConfig`, `RegistryConfig`, `OssConfig`.
/// Possible value: `LocalFsConfig`, `RegistryConfig`, `OssConfig`, `LocalDiskConfig`.
#[serde(rename = "config")]
pub backend_config: Value,
}
Expand All @@ -973,6 +1002,7 @@ impl TryFrom<&BackendConfig> for BackendConfigV2 {
fn try_from(value: &BackendConfig) -> std::result::Result<Self, Self::Error> {
let mut config = BackendConfigV2 {
backend_type: value.backend_type.clone(),
localdisk: None,
localfs: None,
oss: None,
s3: None,
Expand All @@ -981,6 +1011,9 @@ impl TryFrom<&BackendConfig> for BackendConfigV2 {
};

match value.backend_type.as_str() {
"localdisk" => {
config.localdisk = Some(serde_json::from_value(value.backend_config.clone())?);
}
"localfs" => {
config.localfs = Some(serde_json::from_value(value.backend_config.clone())?);
}
Expand Down Expand Up @@ -1200,7 +1233,7 @@ pub(crate) struct BlobCacheEntryConfig {
backend_type: String,
/// Configuration for storage backend, corresponding to `FactoryConfig::BackendConfig::backend_config`.
///
/// Possible value: `LocalFsConfig`, `RegistryConfig`, `OssConfig`.
/// Possible value: `LocalFsConfig`, `RegistryConfig`, `OssConfig`, `LocalDiskConfig`.
backend_config: Value,
/// Type of blob cache, corresponding to `FactoryConfig::CacheConfig::cache_type`.
///
Expand Down Expand Up @@ -1456,6 +1489,15 @@ mod tests {
assert_eq!(config.alt_dirs, vec!["dir1", "dir2"]);
}

#[test]
fn test_localdisk_config() {
let content = r#"{
"device_path": "device_path"
}"#;
let config: LocalDiskConfig = serde_json::from_str(content).unwrap();
assert_eq!(config.device_path, "device_path");
}

#[test]
fn test_backend_config() {
let config = BackendConfig {
Expand Down
1 change: 1 addition & 0 deletions blobfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ baekend-s3 = ["nydus-rafs/backend-s3"]
backend-oss = ["nydus-rafs/backend-oss"]
backend-registry = ["nydus-rafs/backend-registry"]
backend-http-proxy = ["nydus-rafs/backend-http-proxy"]
backend-localdisk = ["nydus-rafs/backend-localdisk"]

[package.metadata.docs.rs]
all-features = true
Expand Down
1 change: 1 addition & 0 deletions clib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ baekend-s3 = ["nydus-rafs/backend-s3"]
backend-oss = ["nydus-rafs/backend-oss"]
backend-registry = ["nydus-rafs/backend-registry"]
backend-http-proxy = ["nydus-rafs/backend-http-proxy"]
backend-localdisk = ["nydus-rafs/backend-localdisk"]
25 changes: 25 additions & 0 deletions docs/nydusd.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,31 @@ We are working on enabling cloud-hypervisor support for nydus.
}
```

##### Localdisk Backend (Experimental)
Using this backend enables Nydus to support reading blobs from block devices. This feature will be useful in Confidential Computing or Hybrid Image scenarios.

The localdisk backend adds support for storing images in disks. In this scenario, each layer of the blob is stored in partitions, and multiple partitions are addressed in the local raw disk via the GUID partition table (GPT), which means that this disk stores the entire image.

Currently, generating a localdisk image through nydusify is not supported for the time being. You need to use the nydus-localdisk tool to complete this step.
Document located at: https://github.com/adamqqqplay/nydus-localdisk/blob/master/README.md

```
{
"device": {
"backend": {
"type": "localdisk",
"config": {
// Mounted block device path or original localdisk image file path.
"device_path": "/dev/loop1"
//"device_path": "/home/user/ubuntu.img"
}
},
...
},
...
}
```

##### OSS backend with blobcache

```
Expand Down
1 change: 1 addition & 0 deletions rafs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ backend-oss = ["nydus-storage/backend-oss"]
backend-s3 = ["nydus-storage/backend-s3"]
backend-registry = ["nydus-storage/backend-registry"]
backend-http-proxy = ["nydus-storage/backend-http-proxy"]
backend-localdisk = ["nydus-storage/backend-localdisk"]

[package.metadata.docs.rs]
all-features = true
Expand Down
2 changes: 2 additions & 0 deletions storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ tokio = { version = "1.19.0", features = ["macros", "rt", "rt-multi-thread", "sy
url = { version = "2.1.1", optional = true }
vm-memory = "0.9"
fuse-backend-rs = "0.10"
gpt = { version = "3.0.0", optional = true }

nydus-api = { version = "0.2", path = "../api" }
nydus-utils = { version = "0.4", path = "../utils", features = ["zran"] }
Expand All @@ -45,6 +46,7 @@ tar = "0.4.38"
regex = "1.7.0"

[features]
backend-localdisk = ["gpt"]
backend-localfs = []
backend-oss = ["base64", "httpdate", "hmac", "sha1", "reqwest", "url"]
backend-registry = ["base64", "reqwest", "url"]
Expand Down
2 changes: 1 addition & 1 deletion storage/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# nydus-storage

The core storage subsystem for [Nydus Image Service](https://nydus.dev/) to:
- Fetch blob objects from storage backend such as Registry, OSS, S3 and file systems etc.
- Fetch blob objects from storage backend such as Registry, OSS, S3, local disk and file systems etc.
- Load data from storage backend on demand.
- Cache blob objects on local storage.

Expand Down
Loading

0 comments on commit 5b54510

Please sign in to comment.