Skip to content

Commit

Permalink
Merge pull request #59 from cgwalters/add-example-client
Browse files Browse the repository at this point in the history
Add an example client
  • Loading branch information
jmarrero committed Oct 26, 2023
2 parents a9aae43 + ebec044 commit 929070b
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ tracing = "0.1"
# We support both versions
cap-std-ext = ">= 2.0, <= 3.0"

[dev-dependencies]
bytes = "1.5"
clap = { version = "4.4", features = ["derive"] }

[lib]
path = "src/imageproxy.rs"

Expand Down
84 changes: 84 additions & 0 deletions examples/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::io::Write;

use anyhow::Result;
use clap::Parser;
use oci_spec::image::ImageManifest;
use tokio::io::AsyncReadExt;

#[derive(clap::Parser, Debug)]
struct GetMetadataOpts {
/// The skopeo-style transport:image reference
reference: String,
}

#[derive(clap::Parser, Debug)]
struct GetBlobOpts {
/// The skopeo-style transport:image reference
reference: String,

/// The digest of the target blob to fetch
digest: String,

/// The size of the blob to fetch
size: u64,
}

/// Simple program to greet a person
#[derive(clap::Parser, Debug)]
#[command(version, about, long_about = None)]
enum Opt {
GetMetadata(GetMetadataOpts),
GetBlob(GetBlobOpts),
}

#[derive(serde::Serialize, Debug)]
struct Metadata {
digest: String,
manifest: ImageManifest,
}

async fn get_metadata(o: GetMetadataOpts) -> Result<()> {
let proxy = containers_image_proxy::ImageProxy::new().await?;
let img = proxy.open_image(&o.reference).await?;
let (digest, manifest) = proxy.fetch_manifest(&img).await?;
let metadata = Metadata { digest, manifest };
serde_json::to_writer_pretty(&mut std::io::stdout().lock(), &metadata)?;
Ok(())
}

async fn get_blob(o: GetBlobOpts) -> Result<()> {
let proxy = containers_image_proxy::ImageProxy::new().await?;
let img = proxy.open_image(&o.reference).await?;
let (mut blob, driver) = proxy.get_blob(&img, &o.digest, o.size).await?;

let mut stdout = std::io::stdout().lock();
let reader = async move {
let mut buffer = [0u8; 8192];
loop {
let n = blob.read(&mut buffer).await?;
if n == 0 {
return anyhow::Ok(());
}
stdout.write_all(&buffer[..n])?;
}
};

let (a, b) = tokio::join!(reader, driver);
a?;
b?;
Ok(())
}

async fn run() -> Result<()> {
match Opt::parse() {
Opt::GetMetadata(o) => get_metadata(o).await,
Opt::GetBlob(o) => get_blob(o).await,
}
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
if let Err(e) = run().await {
eprintln!("{:#}", e);
}
}

0 comments on commit 929070b

Please sign in to comment.