From e5258c8e63f09ef7aafc7e489bb62131eb34a74f Mon Sep 17 00:00:00 2001 From: Keir Lawson Date: Sat, 18 May 2019 02:45:24 +0100 Subject: Add import functionality (#165) --- examples/import.rs | 24 ++++++++++++++++++++++++ src/lib.rs | 31 +++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 examples/import.rs diff --git a/examples/import.rs b/examples/import.rs new file mode 100644 index 0000000..20c61e6 --- /dev/null +++ b/examples/import.rs @@ -0,0 +1,24 @@ +use shiplift::Docker; +use std::{env, fs::File}; +use tokio::prelude::{Future, Stream}; + +fn main() { + let docker = Docker::new(); + let path = env::args() + .nth(1) + .expect("You need to specify an image path"); + let f = File::open(path).expect("Unable to open file"); + + let reader = Box::from(f); + + let fut = docker + .images() + .import(reader) + .for_each(|output| { + println!("{:?}", output); + Ok(()) + }) + .map_err(|e| eprintln!("Error: {}", e)); + + tokio::run(fut); +} diff --git a/src/lib.rs b/src/lib.rs index e999ba7..687a0e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,7 @@ use mime::Mime; #[cfg(feature = "tls")] use openssl::ssl::{SslConnector, SslFiletype, SslMethod}; use serde_json::Value; -use std::{borrow::Cow, env, iter, path::Path, time::Duration}; +use std::{borrow::Cow, env, io::Read, iter, path::Path, time::Duration}; use tokio_codec::{FramedRead, LinesCodec}; use url::form_urlencoded; @@ -230,9 +230,32 @@ impl<'a> Images<'a> { .map(|c| c.to_vec()) } - // pub fn import(self, tarball: Box) -> Result<()> { - // self.docker.post - // } + /// imports an image or set of images from a given tarball source + /// source can be uncompressed on compressed via gzip, bzip2 or xz + pub fn import( + self, + mut tarball: Box, + ) -> impl Stream { + let mut bytes = Vec::new(); + + match tarball.read_to_end(&mut bytes) { + Ok(_) => Box::new( + self.docker + .stream_post( + "/images/load", + Some((Body::from(bytes), tar())), + None::>, + ) + .and_then(|bytes| { + serde_json::from_slice::<'_, Value>(&bytes[..]) + .map_err(Error::from) + .into_future() + }), + ) as Box + Send>, + Err(e) => Box::new(futures::future::err(Error::IO(e)).into_stream()) + as Box + Send>, + } + } } /// Interface for accessing and manipulating a docker container -- cgit v1.2.3