summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Lawson <keirlawson@gmail.com>2019-05-18 02:45:24 +0100
committerDoug Tangren <d.tangren@gmail.com>2019-05-17 21:45:24 -0400
commite5258c8e63f09ef7aafc7e489bb62131eb34a74f (patch)
tree83e4d91889c8f300e2316d1529de3f0971690b12
parente97bf7175ddf063788df2fa630b4dedcd19388a0 (diff)
Add import functionality (#165)
-rw-r--r--examples/import.rs24
-rw-r--r--src/lib.rs31
2 files changed, 51 insertions, 4 deletions
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<Read>) -> 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<Read>,
+ ) -> impl Stream<Item = Value, Error = Error> {
+ 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::<iter::Empty<_>>,
+ )
+ .and_then(|bytes| {
+ serde_json::from_slice::<'_, Value>(&bytes[..])
+ .map_err(Error::from)
+ .into_future()
+ }),
+ ) as Box<Stream<Item = Value, Error = Error> + Send>,
+ Err(e) => Box::new(futures::future::err(Error::IO(e)).into_stream())
+ as Box<Stream<Item = Value, Error = Error> + Send>,
+ }
+ }
}
/// Interface for accessing and manipulating a docker container