summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--Cargo.toml21
-rw-r--r--examples/attach.rs32
-rw-r--r--examples/containercopyfrom.rs25
-rw-r--r--examples/containercopyinto.rs18
-rw-r--r--examples/containercreate.rs15
-rw-r--r--examples/containerdelete.rs14
-rw-r--r--examples/containerexec.rs37
-rw-r--r--examples/containerinspect.rs16
-rw-r--r--examples/containers.rs17
-rw-r--r--examples/custom_host.rs15
-rw-r--r--examples/events.rs19
-rw-r--r--examples/export.rs26
-rw-r--r--examples/imagebuild.rs25
-rw-r--r--examples/imagedelete.rs17
-rw-r--r--examples/imageinspect.rs16
-rw-r--r--examples/imagepull.rs23
-rw-r--r--examples/imagepull_auth.rs23
-rw-r--r--examples/images.rs19
-rw-r--r--examples/imagesearch.rs17
-rw-r--r--examples/imagetag.rs10
-rw-r--r--examples/import.rs21
-rw-r--r--examples/info.rs15
-rw-r--r--examples/logs.rs36
-rw-r--r--examples/networkconnect.rs14
-rw-r--r--examples/networkcreate.rs14
-rw-r--r--examples/networkdelete.rs14
-rw-r--r--examples/networkdisconnect.rs25
-rw-r--r--examples/networkinspect.rs16
-rw-r--r--examples/networks.rs20
-rw-r--r--examples/stats.rs21
-rw-r--r--examples/top.rs16
-rw-r--r--examples/version.rs15
-rw-r--r--examples/volumecreate.rs15
-rw-r--r--examples/volumedelete.rs14
-rw-r--r--examples/volumes.rs16
-rw-r--r--lib.rs0
-rw-r--r--src/errors.rs19
-rw-r--r--src/lib.rs793
-rw-r--r--src/read.rs105
-rw-r--r--src/transport.rs280
-rw-r--r--src/tty.rs372
42 files changed, 1097 insertions, 1153 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b4ad43..8e72e8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.7.0
+
+* async-await support [#229](https://github.com/softprops/shiplift/pull/229)
+
# 0.6.0
* add chrono as an optional feature, enabled by default [#190](https://github.com/softprops/shiplift/pull/190)
diff --git a/Cargo.toml b/Cargo.toml
index c85ed4e..2dad6ce 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,28 +18,31 @@ coveralls = { repository = "softprops/shipflit" }
maintenance = { status = "actively-developed" }
[dependencies]
-log = "0.4"
-mime = "0.3"
base64 = "0.11"
byteorder = "1.3"
bytes = "0.4"
chrono = { version = "0.4", optional = true, features = ["serde"] }
flate2 = "1.0"
-futures = "0.1"
-hyper = "0.12"
-hyper-openssl = { version = "0.7", optional = true }
-hyperlocal = { version = "0.6", optional = true }
+futures-util = "0.3"
+futures_codec = "0.3"
+hyper = "0.13"
+hyper-openssl = { version = "0.8", optional = true }
+hyperlocal = { version = "0.7", optional = true }
+log = "0.4"
+mime = "0.3"
openssl = { version = "0.10", optional = true }
+pin-project = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tar = "0.4"
-tokio = "0.1"
-tokio-codec = "0.1"
-tokio-io = "0.1"
+tokio = "0.2"
url = "2.1"
[dev-dependencies]
env_logger = "0.7"
+# Required for examples to run
+futures = "0.3.1"
+tokio = { version = "0.2.6", features = ["macros"] }
[features]
default = ["chrono", "unix-socket", "tls"]
diff --git a/examples/attach.rs b/examples/attach.rs
new file mode 100644
index 0000000..e4ed637
--- /dev/null
+++ b/examples/attach.rs
@@ -0,0 +1,32 @@
+use futures::StreamExt;
+use shiplift::{tty::TtyChunk, Docker};
+use std::env;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let docker = Docker::new();
+ let id = env::args()
+ .nth(1)
+ .expect("You need to specify a container id");
+
+ let tty_multiplexer = docker.containers().get(&id).attach().await?;
+
+ let (mut reader, _writer) = tty_multiplexer.split();
+
+ while let Some(tty_result) = reader.next().await {
+ match tty_result {
+ Ok(chunk) => print_chunk(chunk),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
+
+ Ok(())
+}
+
+fn print_chunk(chunk: TtyChunk) {
+ match chunk {
+ TtyChunk::StdOut(bytes) => println!("Stdout: {}", std::str::from_utf8(&bytes).unwrap()),
+ TtyChunk::StdErr(bytes) => eprintln!("Stdout: {}", std::str::from_utf8(&bytes).unwrap()),
+ TtyChunk::StdIn(_) => unreachable!(),
+ }
+}
diff --git a/examples/containercopyfrom.rs b/examples/containercopyfrom.rs
index 2ebeccf..acbfa19 100644
--- a/examples/containercopyfrom.rs
+++ b/examples/containercopyfrom.rs
@@ -1,8 +1,10 @@
+use futures::TryStreamExt;
use shiplift::Docker;
use std::{env, path};
-use tokio::prelude::{Future, Stream};
+use tar::Archive;
-fn main() {
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
let docker = Docker::new();
let id = env::args()
.nth(1)
@@ -10,17 +12,16 @@ fn main() {
let path = env::args()
.nth(2)
.expect("Usage: cargo run --example containercopyfrom -- <container> <path in container>");
- let fut = docker
+
+ let bytes = docker
.containers()
.get(&id)
.copy_from(path::Path::new(&path))
- .collect()
- .and_then(|stream| {
- let tar = stream.concat();
- let mut archive = tar::Archive::new(tar.as_slice());
- archive.unpack(env::current_dir()?)?;
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ .try_concat()
+ .await?;
+
+ let mut archive = Archive::new(&bytes[..]);
+ archive.unpack(env::current_dir()?)?;
+
+ Ok(())
}
diff --git a/examples/containercopyinto.rs b/examples/containercopyinto.rs
index 63f0a2d..689e7af 100644
--- a/examples/containercopyinto.rs
+++ b/examples/containercopyinto.rs
@@ -1,8 +1,8 @@
use shiplift::Docker;
-use std::env;
-use tokio::prelude::Future;
+use std::{env, fs::File, io::Read};
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let path = env::args()
.nth(1)
@@ -11,17 +11,17 @@ fn main() {
.nth(2)
.expect("Usage: cargo run --example containercopyinto -- <local path> <container>");
- use std::{fs::File, io::prelude::*};
-
let mut file = File::open(&path).unwrap();
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)
.expect("Cannot read file on the localhost.");
- let fut = docker
+ if let Err(e) = docker
.containers()
.get(&id)
- .copy_file_into(path, &bytes[..])
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ .copy_file_into(path, &bytes)
+ .await
+ {
+ eprintln!("Error: {}", e)
+ }
}
diff --git a/examples/containercreate.rs b/examples/containercreate.rs
index d061f70..ef579a6 100644
--- a/examples/containercreate.rs
+++ b/examples/containercreate.rs
@@ -1,16 +1,19 @@
use shiplift::{ContainerOptions, Docker};
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let image = env::args()
.nth(1)
.expect("You need to specify an image name");
- let fut = docker
+
+ match docker
.containers()
.create(&ContainerOptions::builder(image.as_ref()).build())
- .map(|info| println!("{:?}", info))
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ .await
+ {
+ Ok(info) => println!("{:?}", info),
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/containerdelete.rs b/examples/containerdelete.rs
index e3c2036..86bd9c5 100644
--- a/examples/containerdelete.rs
+++ b/examples/containerdelete.rs
@@ -1,16 +1,14 @@
use shiplift::Docker;
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let id = env::args()
.nth(1)
.expect("You need to specify an container id");
- let fut = docker
- .containers()
- .get(&id)
- .delete()
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+
+ if let Err(e) = docker.containers().get(&id).delete().await {
+ eprintln!("Error: {}", e)
+ }
}
diff --git a/examples/containerexec.rs b/examples/containerexec.rs
index 7f12f88..6c545a7 100644
--- a/examples/containerexec.rs
+++ b/examples/containerexec.rs
@@ -1,8 +1,9 @@
-use shiplift::{tty::StreamType, Docker, ExecContainerOptions};
-use std::env;
-use tokio::prelude::{Future, Stream};
+use futures::StreamExt;
+use shiplift::{tty::TtyChunk, Docker, ExecContainerOptions};
+use std::{env, str::from_utf8};
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let id = env::args()
.nth(1)
@@ -18,19 +19,19 @@ fn main() {
.attach_stdout(true)
.attach_stderr(true)
.build();
- let fut = docker
- .containers()
- .get(&id)
- .exec(&options)
- .for_each(|chunk| {
- match chunk.stream_type {
- StreamType::StdOut => println!("Stdout: {}", chunk.as_string_lossy()),
- StreamType::StdErr => eprintln!("Stderr: {}", chunk.as_string_lossy()),
- StreamType::StdIn => unreachable!(),
- }
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ while let Some(exec_result) = docker.containers().get(&id).exec(&options).next().await {
+ match exec_result {
+ Ok(chunk) => print_chunk(chunk),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
+}
+
+fn print_chunk(chunk: TtyChunk) {
+ match chunk {
+ TtyChunk::StdOut(bytes) => println!("Stdout: {}", from_utf8(&bytes).unwrap()),
+ TtyChunk::StdErr(bytes) => eprintln!("Stdout: {}", from_utf8(&bytes).unwrap()),
+ TtyChunk::StdIn(_) => unreachable!(),
+ }
}
diff --git a/examples/containerinspect.rs b/examples/containerinspect.rs
index 0f853bc..8de2a67 100644
--- a/examples/containerinspect.rs
+++ b/examples/containerinspect.rs
@@ -1,17 +1,15 @@
use shiplift::Docker;
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let id = env::args()
.nth(1)
.expect("Usage: cargo run --example containerinspect -- <container>");
- let fut = docker
- .containers()
- .get(&id)
- .inspect()
- .map(|container| println!("{:#?}", container))
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+
+ match docker.containers().get(&id).inspect().await {
+ Ok(container) => println!("{:#?}", container),
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/containers.rs b/examples/containers.rs
index 0eb51af..72de140 100644
--- a/examples/containers.rs
+++ b/examples/containers.rs
@@ -1,18 +1,15 @@
use shiplift::Docker;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
env_logger::init();
let docker = Docker::new();
- let fut = docker
- .containers()
- .list(&Default::default())
- .map(|containers| {
+ match docker.containers().list(&Default::default()).await {
+ Ok(containers) => {
for c in containers {
println!("container -> {:#?}", c)
}
- })
- .map_err(|e| eprintln!("Error: {}", e));
-
- tokio::run(fut);
+ }
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/custom_host.rs b/examples/custom_host.rs
index 3b1fd3e..8b06eae 100644
--- a/examples/custom_host.rs
+++ b/examples/custom_host.rs
@@ -1,13 +1,10 @@
-use futures::Future;
use shiplift::Docker;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::host("http://yourhost".parse().unwrap());
-
- let fut = docker
- .ping()
- .map(|pong| println!("Ping: {}", pong))
- .map_err(|e| eprintln!("Error: {}", e));
-
- tokio::run(fut);
+ match docker.ping().await {
+ Ok(pong) => println!("Ping: {}", pong),
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/events.rs b/examples/events.rs
index 0e35860..e44d68f 100644
--- a/examples/events.rs
+++ b/examples/events.rs
@@ -1,16 +1,15 @@
+use futures::StreamExt;
use shiplift::Docker;
-use tokio::prelude::{Future, Stream};
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
println!("listening for events");
- let fut = docker
- .events(&Default::default())
- .for_each(|e| {
- println!("event -> {:?}", e);
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ while let Some(event_result) = docker.events(&Default::default()).next().await {
+ match event_result {
+ Ok(event) => println!("event -> {:?}", event),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
}
diff --git a/examples/export.rs b/examples/export.rs
index 55d1b7b..34f460d 100644
--- a/examples/export.rs
+++ b/examples/export.rs
@@ -1,8 +1,10 @@
-use shiplift::{errors::Error, Docker};
+use futures::StreamExt;
use std::{env, fs::OpenOptions, io::Write};
-use tokio::prelude::{Future, Stream};
-fn main() {
+use shiplift::{errors::Error, Docker};
+
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let id = env::args().nth(1).expect("You need to specify an image id");
@@ -11,17 +13,13 @@ fn main() {
.create(true)
.open(format!("{}.tar", &id))
.unwrap();
+
let images = docker.images();
- let fut = images
- .get(&id)
- .export()
- .for_each(move |bytes| {
- export_file
- .write(&bytes[..])
- .map(|n| println!("copied {} bytes", n))
- .map_err(Error::IO)
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut)
+ while let Some(export_result) = images.get(&id).export().next().await {
+ match export_result.and_then(|bytes| export_file.write(&bytes).map_err(Error::from)) {
+ Ok(n) => println!("copied {} bytes", n),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
}
diff --git a/examples/imagebuild.rs b/examples/imagebuild.rs
index 6dbea78..80d825c 100644
--- a/examples/imagebuild.rs
+++ b/examples/imagebuild.rs
@@ -1,19 +1,22 @@
+use futures::StreamExt;
use shiplift::{BuildOptions, Docker};
use std::env;
-use tokio::prelude::{Future, Stream};
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let path = env::args().nth(1).expect("You need to specify a path");
- let fut = docker
- .images()
- .build(&BuildOptions::builder(path).tag("shiplift_test").build())
- .for_each(|output| {
- println!("{:?}", output);
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
+ let options = BuildOptions::builder(path).tag("shiplift_test").build();
- tokio::run(fut);
+ let images = docker.images();
+
+ let mut stream = images.build(&options);
+
+ while let Some(build_result) = stream.next().await {
+ match build_result {
+ Ok(output) => println!("{:?}", output),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
}
diff --git a/examples/imagedelete.rs b/examples/imagedelete.rs
index efa763c..3b9bc60 100644
--- a/examples/imagedelete.rs
+++ b/examples/imagedelete.rs
@@ -1,21 +1,18 @@
use shiplift::Docker;
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let img = env::args()
.nth(1)
.expect("You need to specify an image name");
- let fut = docker
- .images()
- .get(&img[..])
- .delete()
- .map(|statuses| {
+ match docker.images().get(&img).delete().await {
+ Ok(statuses) => {
for status in statuses {
println!("{:?}", status);
}
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ }
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/imageinspect.rs b/examples/imageinspect.rs
index 494480a..b7d2f9a 100644
--- a/examples/imageinspect.rs
+++ b/examples/imageinspect.rs
@@ -1,17 +1,15 @@
use shiplift::Docker;
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let id = env::args()
.nth(1)
.expect("Usage: cargo run --example imageinspect -- <image>");
- let fut = docker
- .images()
- .get(&id)
- .inspect()
- .map(|image| println!("{:#?}", image))
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+
+ match docker.images().get(&id).inspect().await {
+ Ok(image) => println!("{:#?}", image),
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/imagepull.rs b/examples/imagepull.rs
index 84a6149..5b3fbf4 100644
--- a/examples/imagepull.rs
+++ b/examples/imagepull.rs
@@ -1,22 +1,25 @@
// cargo run --example imagepull busybox
+use futures::StreamExt;
use shiplift::{Docker, PullOptions};
use std::env;
-use tokio::prelude::{Future, Stream};
-fn main() {
+#[tokio::main]
+async fn main() {
env_logger::init();
let docker = Docker::new();
let img = env::args()
.nth(1)
.expect("You need to specify an image name");
- let fut = docker
+
+ let mut stream = docker
.images()
- .pull(&PullOptions::builder().image(img).build())
- .for_each(|output| {
- println!("{:?}", output);
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ .pull(&PullOptions::builder().image(img).build());
+
+ while let Some(pull_result) = stream.next().await {
+ match pull_result {
+ Ok(output) => println!("{:?}", output),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
}
diff --git a/examples/imagepull_auth.rs b/examples/imagepull_auth.rs
index 1c559c7..6f0ceec 100644
--- a/examples/imagepull_auth.rs
+++ b/examples/imagepull_auth.rs
@@ -1,10 +1,11 @@
// cargo run --example imagepull_auth busybox username password
+use futures::StreamExt;
use shiplift::{Docker, PullOptions, RegistryAuth};
use std::env;
-use tokio::prelude::{Future, Stream};
-fn main() {
+#[tokio::main]
+async fn main() {
env_logger::init();
let docker = Docker::new();
let img = env::args()
@@ -16,13 +17,15 @@ fn main() {
.username(username)
.password(password)
.build();
- let fut = docker
+
+ let mut stream = docker
.images()
- .pull(&PullOptions::builder().image(img).auth(auth).build())
- .for_each(|output| {
- println!("{:?}", output);
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ .pull(&PullOptions::builder().image(img).auth(auth).build());
+
+ while let Some(pull_result) = stream.next().await {
+ match pull_result {
+ Ok(output) => println!("{:?}", output),
+ Err(e) => eprintln!("{}", e),
+ }
+ }
}
diff --git a/examples/images.rs b/examples/images.rs
index 7a8a094..1c0852e 100644
--- a/examples/images.rs
+++ b/examples/images.rs
@@ -1,13 +1,14 @@
use shiplift::Docker;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
println!("docker images in stock");
- let fut = docker
- .images()
- .list(&Default::default())
- .map(|images| {
+
+ let result = docker.images().list(&Default::default()).await;
+
+ match result {
+ Ok(images) => {
for i in images {
println!(
"{} {} {:?}",
@@ -16,7 +17,7 @@ fn main() {
i.repo_tags.unwrap_or_else(|| vec!["none".into()])
);
}
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ }
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/imagesearch.rs b/examples/imagesearch.rs
index a6d6e52..e2fd110 100644
--- a/examples/imagesearch.rs
+++ b/examples/imagesearch.rs
@@ -1,17 +1,16 @@
use shiplift::Docker;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
println!("remote docker images in stock");
- let fut = docker
- .images()
- .search("rust")
- .map(|results| {
+
+ match docker.images().search("rust").await {
+ Ok(results) => {
for result in results {
println!("{} - {}", result.name, result.description);
}
- })
- .map_err(|e| eprintln!("Error: {}", e));
- tokio::run(fut);
+ }
+ Err(e) => eprintln!("Error: {}", e),
+ }
}
diff --git a/examples/imagetag.rs b/examples/imagetag.rs
index 7ae78dd..e36af76 100644
--- a/examples/imagetag.rs
+++ b/examples/imagetag.rs
@@ -2,9 +2,9 @@
use shiplift::{Docker, Image, TagOptions};
use std::env;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
env_logger::init();
let docker = Docker::new();
let img = env::args()
@@ -21,7 +21,7 @@ fn main() {
let image = Image::new(&docker, img);
- let fut = image.tag(&tag_opts).map_err(|e| eprintln!("Error: {}", e));
-
- tokio::run(fut);
+ if let Err(e) = image.tag(&tag_opts).await {
+ eprintln!("Error: {}", e)
+ }
}
diff --git a/examples/import.rs b/examples/import.rs
index 20c61e6..7ea35bd 100644
--- a/examples/import.rs
+++ b/examples/import.rs
@@ -1,8 +1,9 @@
+use futures::StreamExt;
use shiplift::Docker;
use std::{env, fs::File};
-use tokio::prelude::{Future, Stream};
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
let path = env::args()
.nth(1)
@@ -11,14 +12,12 @@ fn main() {
let reader = Box::from(f);
- let fut = docker
- .images()
- .import(reader)
- .for_each(|output| {
- println!("{:?}", output);
- Ok(())
- })
- .map_err(|e| eprintln!("Error: {}", e));
+ let mut stream = docker.images().import(reader);
- tokio::run(fut);
+ while let Some(import_result) = stream.next().await {
+ match import_result {
+ Ok(output) => println!("{:?}", output),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
}
diff --git a/examples/info.rs b/examples/info.rs
index 05fdede..76036e6 100644
--- a/examples/info.rs
+++ b/examples/info.rs
@@ -1,12 +1,11 @@
use shiplift::Docker;
-use tokio::prelude::Future;
-fn main() {
+#[tokio::main]
+async fn main() {
let docker = Docker::new();
- tokio::run(
- docker
- .info()
- .map(|info| println!("info {:?}", info))
- .map_err