Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
373 changes: 309 additions & 64 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ members = [
"dragonfly-client-storage",
"dragonfly-client-util",
"dragonfly-client-backend/examples/plugin",
"dragonfly-client-util/examples/request",
"dragonfly-client-metric",
]

[workspace.package]
version = "1.3.2"
version = "1.3.3"
authors = ["The Dragonfly Developers"]
homepage = "https://d7y.io/"
repository = "https://github.com/dragonflyoss/client.git"
Expand All @@ -23,14 +24,14 @@ readme = "README.md"
edition = "2021"

[workspace.dependencies]
dragonfly-client = { path = "dragonfly-client", version = "1.3.2" }
dragonfly-client-core = { path = "dragonfly-client-core", version = "1.3.2" }
dragonfly-client-config = { path = "dragonfly-client-config", version = "1.3.2" }
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "1.3.2" }
dragonfly-client-backend = { path = "dragonfly-client-backend", version = "1.3.2" }
dragonfly-client-metric = { path = "dragonfly-client-metric", version = "1.3.2" }
dragonfly-client-util = { path = "dragonfly-client-util", version = "1.3.2" }
dragonfly-client-init = { path = "dragonfly-client-init", version = "1.3.2" }
dragonfly-client = { path = "dragonfly-client", version = "1.3.3" }
dragonfly-client-core = { path = "dragonfly-client-core", version = "1.3.3" }
dragonfly-client-config = { path = "dragonfly-client-config", version = "1.3.3" }
dragonfly-client-storage = { path = "dragonfly-client-storage", version = "1.3.3" }
dragonfly-client-backend = { path = "dragonfly-client-backend", version = "1.3.3" }
dragonfly-client-metric = { path = "dragonfly-client-metric", version = "1.3.3" }
dragonfly-client-util = { path = "dragonfly-client-util", version = "1.3.3" }
dragonfly-client-init = { path = "dragonfly-client-init", version = "1.3.3" }
dragonfly-api = "=2.2.28"
thiserror = "2.0"
futures = "0.3.32"
Expand Down Expand Up @@ -120,6 +121,8 @@ cgroups-rs = "0.5"
num_cpus = "1.17"
async-trait = "0.1"
humantime-serde = "1.1.1"
oci-client = { version = "0.16.1", default-features = false, features = ["native-tls"] }
oci-spec = "0.9"

# TODO(Gaius): Remove the git dependency after the next release of mocktail, refer to https://github.com/IBM/mocktail/issues/65.
mocktail = { version = "0.3.0", git = "https://github.com/IBM/mocktail", rev = "860e75e171a8eb818083813dbeed4401d1a40b3b" }
Expand Down
2 changes: 1 addition & 1 deletion dragonfly-client-backend/examples/plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Backend for Hdfs {
}
}

/// register_plugin is a function that returns a Box<dyn Backend + Send + Sync>.
/// Register plugin is a function that returns a Box<dyn Backend + Send + Sync>.
/// This function is used to register the HDFS plugin to the Backend.
#[no_mangle]
pub fn register_plugin() -> Box<dyn Backend + Send + Sync> {
Expand Down
2 changes: 2 additions & 0 deletions dragonfly-client-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ reqwest-tracing.workspace = true
reqwest-middleware.workspace = true
num_cpus.workspace = true
humantime-serde.workspace = true
oci-client.workspace = true
oci-spec.workspace = true
rustix = { version = "1.1.3", features = ["fs"] }
base64 = "0.22.1"
pnet = "0.35.0"
Expand Down
24 changes: 24 additions & 0 deletions dragonfly-client-util/examples/request/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "request"
description = "An example of request library for the Dragonfly client"
version.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
keywords.workspace = true
license.workspace = true
edition.workspace = true
publish = false

[[bin]]
name = "get"
path = "src/bin/get.rs"

[[bin]]
name = "preheat"
path = "src/bin/preheat.rs"

[dependencies]
dragonfly-client-util.workspace = true
tokio.workspace = true
anyhow.workspace = true
23 changes: 23 additions & 0 deletions dragonfly-client-util/examples/request/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Examples of Request

An example of using the `request` module to download a file and preheat an OCI image via the Dragonfly P2P network.

## Run GET Example

Downloads a file via the Dragonfly P2P network using the `get` method.

```shell
export DRAGONFLY_SCHEDULER_ENDPOINT="http://127.0.0.1:8002"
cargo run -p request --bin get
```

## Run Preheat Example

Preheats an OCI image (`dragonflyoss/scheduler:v2.4.3`) via the Dragonfly P2P network
using the `preheat` method. All blobs (config and layers) are downloaded through the
Dragonfly seed peer proxy and cached in the P2P network.

```shell
export DRAGONFLY_SCHEDULER_ENDPOINT="http://127.0.0.1:8002"
cargo run -p request --bin preheat
```
54 changes: 54 additions & 0 deletions dragonfly-client-util/examples/request/src/bin/get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2026 The Dragonfly Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use dragonfly_client_util::request::{GetRequest, Proxy, Request};
use std::time::Duration;
use tokio::io::AsyncReadExt;

/// This example demonstrates how to use the get method of the Dragonfly request module
/// to download a file via the Dragonfly P2P network.
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let scheduler_endpoint = std::env::var("DRAGONFLY_SCHEDULER_ENDPOINT")
.unwrap_or_else(|_| "http://127.0.0.1:8002".to_string());

let proxy = Proxy::builder()
.scheduler_endpoint(scheduler_endpoint)
.scheduler_request_timeout(Duration::from_secs(5))
.health_check_interval(Duration::from_secs(60))
.max_retries(3)
.build()
.await
.map_err(|err| anyhow::anyhow!("failed to build proxy: {}", err))?;

let request = GetRequest {
url: "https://example.com/path/to/file".to_string(),
..Default::default()
};

let response = proxy
.get(&request)
.await
.map_err(|err| anyhow::anyhow!("get request failed: {}", err))?;

if let Some(mut reader) = response.reader {
let mut body = Vec::new();
reader.read_to_end(&mut body).await?;
println!("{} downloaded, size: {} bytes", &request.url, body.len());
}

Ok(())
}
49 changes: 49 additions & 0 deletions dragonfly-client-util/examples/request/src/bin/preheat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2026 The Dragonfly Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use dragonfly_client_util::request::{PreheatRequest, Proxy, Request};
use std::time::Duration;

/// This example demonstrates how to use the preheat method of the Dragonfly request module
/// to pre-cache an OCI image via the Dragonfly P2P network.
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let scheduler_endpoint = std::env::var("DRAGONFLY_SCHEDULER_ENDPOINT")
.unwrap_or_else(|_| "http://127.0.0.1:8002".to_string());

let proxy = Proxy::builder()
.scheduler_endpoint(scheduler_endpoint)
.scheduler_request_timeout(Duration::from_secs(5))
.health_check_interval(Duration::from_secs(60))
.max_retries(3)
.build()
.await
.map_err(|err| anyhow::anyhow!("failed to build proxy: {}", err))?;

let request = PreheatRequest {
image: "docker.io/dragonflyoss/scheduler:v2.4.3".to_string(),
platform: Some("linux/amd64".to_string()),
..Default::default()
};

proxy
.preheat(&request)
.await
.map_err(|err| anyhow::anyhow!("preheat failed: {}", err))?;

println!("{} has been preheated", request.image);
Ok(())
}
Loading
Loading