Skip to content

Commit

Permalink
Download compressed gz image from remote source
Browse files Browse the repository at this point in the history
Accept url arguments for remote image download and copy.
Implements async support for use of reqwest.

Signed-off-by: Rafael Garcia Ruiz <rafael.garcia@collabora.com>
  • Loading branch information
Razaloc committed Oct 24, 2022
1 parent 90a3ff4 commit b4bdc49
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
3 changes: 3 additions & 0 deletions bmap-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ anyhow = "1"
structopt = "0.3"
nix = "0.25"
flate2 = "1"
tokio = { version = "1.21.2", features = ["full"] }
reqwest = { version = "0.11.12"}
bytes = "1.2.1"
37 changes: 30 additions & 7 deletions bmap-rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use anyhow::{anyhow, bail, Context, Result};
use bmap::{Bmap, Discarder, SeekForward};
use bytes::Buf;
use flate2::read::GzDecoder;
use nix::unistd::ftruncate;
use reqwest::Url;
use std::ffi::OsStr;
use std::fs::File;
use std::io::Read;
Expand All @@ -14,7 +16,11 @@ struct Copy {
image: PathBuf,
dest: PathBuf,
}

#[derive(PartialEq)]
enum InputType {
Local,
Remote(Url),
}
#[derive(StructOpt, Debug)]
enum Command {
Copy(Copy),
Expand Down Expand Up @@ -75,7 +81,7 @@ impl SeekForward for Decoder {
}
}

fn setup_input(path: &Path) -> Result<Decoder> {
fn setup_local_input(path: &Path) -> Result<Decoder> {
let f = File::open(path)?;
match path.extension().and_then(OsStr::to_str) {
Some("gz") => {
Expand All @@ -86,8 +92,21 @@ fn setup_input(path: &Path) -> Result<Decoder> {
}
}

fn copy(c: Copy) -> Result<()> {
if !c.image.exists() {
async fn setup_remote_input(url: &Url) -> Result<Decoder> {
if url.to_file_path().unwrap().extension().unwrap() != "gz" {
bail!("Image file format not implemented")
}
let data = reqwest::get(url.clone()).await?.bytes().await?;
let reader = GzDecoder::new(data.reader());
Ok(Decoder::new(Discarder::new(reader)))
}

async fn copy(c: Copy) -> Result<()> {
let input_type = match Url::parse(c.image.to_str().unwrap()) {
Ok(url) => InputType::Remote(url),
Err(_) => InputType::Local,
};
if !c.image.exists() && input_type == InputType::Local {
bail!("Image file doesn't exist")
}

Expand All @@ -109,18 +128,22 @@ fn copy(c: Copy) -> Result<()> {
.context("Failed to truncate file")?;
}

let mut input = setup_input(&c.image)?;
let mut input = match input_type {
InputType::Local => setup_local_input(&c.image)?,
InputType::Remote(url) => setup_remote_input(&url).await?,
};
bmap::copy(&mut input, &mut output, &bmap)?;
println!("Done: Syncing...");
output.sync_all().expect("Sync failure");

Ok(())
}

fn main() -> Result<()> {
#[tokio::main]
async fn main() -> Result<()> {
let opts = Opts::from_args();

match opts.command {
Command::Copy(c) => copy(c),
Command::Copy(c) => copy(c).await,
}
}

0 comments on commit b4bdc49

Please sign in to comment.