summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml71
-rw-r--r--CHANGELOG.md31
-rw-r--r--Cargo.toml28
-rw-r--r--README.md6
-rw-r--r--examples/containerlogs.rs (renamed from examples/logs.rs)0
-rw-r--r--examples/execinspect.rs32
-rw-r--r--examples/execresize.rs30
-rw-r--r--examples/export.rs4
-rw-r--r--examples/imagebuild.rs5
-rw-r--r--examples/networkdisconnect.rs5
-rw-r--r--examples/servicedelete.rs14
-rw-r--r--examples/serviceinspect.rs15
-rw-r--r--examples/servicelogs.rs31
-rw-r--r--examples/services.rs19
-rw-r--r--examples/volumecreate.rs6
-rw-r--r--examples/volumedelete.rs3
-rw-r--r--examples/volumes.rs4
-rw-r--r--lib.rs0
-rw-r--r--rustfmt.toml4
-rw-r--r--src/builder.rs1900
-rw-r--r--src/container.rs1819
-rw-r--r--src/datetime.rs26
-rw-r--r--src/docker.rs651
-rw-r--r--src/errors.rs11
-rw-r--r--src/exec.rs379
-rw-r--r--src/image.rs956
-rw-r--r--src/lib.rs1266
-rw-r--r--src/network.rs412
-rw-r--r--src/rep.rs559
-rw-r--r--src/service.rs538
-rw-r--r--src/transport.rs42
-rw-r--r--src/tty.rs7
-rw-r--r--src/volume.rs257
33 files changed, 5418 insertions, 3713 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 80c2290..e84d448 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,6 +1,24 @@
name: Main
-on: push
+on:
+ workflow_dispatch:
+ push:
+ paths-ignore:
+ - "*.md"
+ branches:
+ - main
+ - master
+ tags:
+ - "**"
+ pull_request:
+ paths-ignore:
+ - "*.md"
+ branches:
+ - main
+ - master
+
+env:
+ CARGO_TERM_COLOR: always
jobs:
codestyle:
@@ -40,26 +58,26 @@ jobs:
runs-on: ubuntu-latest
steps:
- - name: Setup Rust
- uses: hecrj/setup-rust-action@v1
- with:
- rust-version: ${{ matrix.rust }}
- - name: Checkout
- uses: actions/checkout@v1
- - name: Test
- run: cargo test
- - name: Coverage
- if: matrix.rust == 'stable'
- run: |
- # tarpaulin knows how to extract data from ci
- # ci services and GitHub actions is not one of them
- # work around that by masquerading as travis
- # https://github.com/xd009642/coveralls-api/blob/6da4ccd7c6eaf1df04cfd1e560362de70fa80605/src/lib.rs#L247-L262
- export TRAVIS_JOB_ID=${GITHUB_SHA}
- export TRAVIS_PULL_REQUEST=false
- export TRAVIS_BRANCH=${GITHUB_REF##*/}
- cargo install cargo-tarpaulin
- cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID
+ - name: Setup Rust
+ uses: hecrj/setup-rust-action@v1
+ with:
+ rust-version: ${{ matrix.rust }}
+ - name: Checkout
+ uses: actions/checkout@v1
+ - name: Test
+ run: cargo test
+ - name: Coverage
+ if: matrix.rust == 'stable'
+ run: |
+ # tarpaulin knows how to extract data from ci
+ # ci services and GitHub actions is not one of them
+ # work around that by masquerading as travis
+ # https://github.com/xd009642/coveralls-api/blob/6da4ccd7c6eaf1df04cfd1e560362de70fa80605/src/lib.rs#L247-L262
+ export TRAVIS_JOB_ID=${GITHUB_SHA}
+ export TRAVIS_PULL_REQUEST=false
+ export TRAVIS_BRANCH=${GITHUB_REF##*/}
+ cargo install cargo-tarpaulin
+ cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID
publish-docs:
if: github.ref == 'refs/heads/master'
@@ -75,13 +93,10 @@ jobs:
cargo doc --no-deps
echo "<meta http-equiv=refresh content=0;url=`echo ${{ github.repository }} | cut -d / -f 2 | tr '-' '_'`/index.html>" > target/doc/index.html
- name: Publish
- uses: docker://peaceiris/gh-pages:v2.3.1
- env:
- PUBLISH_BRANCH: gh-pages
- PUBLISH_DIR: ./target/doc
- PERSONAL_TOKEN: ${{ secrets.GH_PAGES_TOKEN }}
+ uses: peaceiris/actions-gh-pages@v3
with:
- emptyCommits: true
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./target/doc
publish-crate:
if: startsWith(github.ref, 'refs/tags/')
@@ -93,4 +108,4 @@ jobs:
- uses: actions/checkout@v1
- name: Publish
shell: bash
- run: cargo publish --token ${{ secrets.CRATES_TOKEN }} \ No newline at end of file
+ run: cargo publish --token ${{ secrets.CRATES_TOKEN }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e72e8c..2898200 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,37 @@
+# 0.8.0
+
+* `ContainerOptionsBuilder::entrypoint` now correctly takes an `IntoIterator<Item = AsRef<str>>` instead of `&str` [#269](https://github.com/softprops/shiplift/pull/269)
+* make `config` field of `ImageDetails` optional [#264](https://github.com/softprops/shiplift/pull/264)
+* add `container`, `container_config`, `os_version`, `graph_driver`, `root_fs`, `metadata` fields to `ImageDetails` [#264](https://github.com/softprops/shiplift/pull/264)
+* rename `shiplift::rep::Config` to `shiplift::rep::ContainerConfig` [#264](https://github.com/softprops/shiplift/pull/264)
+* add missing fields ([API version 1.41](https://docs.docker.com/engine/api/v1.41/#operation/ImageInspect)) to `ContainerConfig` [#264](https://github.com/softprops/shiplift/pull/264)
+* add missing fields ([API version 1.41](https://docs.docker.com/engine/api/v1.41/#operation/ImageHistory)) to `History` [#264](https://github.com/softprops/shiplift/pull/264)
+* add missing fields to `NetworkEntry` [#254](https://github.com/softprops/shiplift/pull/254)
+* PullOptionsBuilder now adds a `latest` tag by default [#261](https://github.com/softprops/shiplift/pull/261)
+* `Image::pull`, `Image::build` and `Image::import` now return a stream of `ImageBuildChunk` instead of `json::Value`[#262](https://github.com/softprops/shiplift/262)
+* rename `Config` to `ContainerConfig` [#266](https://github.com/softprops/shiplift/pull/266)
+* `HostConfig.port_bindings` inner elements now have a clear type `PortBinding` instead of `HashMap<String, String>` [#266](https://github.com/softprops/shiplift/pull/266)
+* `ContainerDetails` contains new fields [#266](https://github.com/softprops/shiplift/pull/266)
+* Units of `ContainerInfo` `size_rw` and `size_root_fs` units changed to match API [#266](https://github.com/softprops/shiplift/pull/266)
+
# 0.7.0
* async-await support [#229](https://github.com/softprops/shiplift/pull/229)
+* add multiple fields to `shiplift::rep::Version` [#212](https://github.com/softprops/shiplift/pull/212)
+* add `image_id` and `state` fields to `shiplift::rep::Container` [#213](https://github.com/softprops/shiplift/pull/213)
+* add `ContainerOptionsBuilder::publish_all_ports()` [#215](https://github.com/softprops/shiplift/pull/215)
+* re-export `hyper::Uri` as `shiplift::Uri` [#209](https://github.com/softprops/shiplift/pull/209)
+* `shiplift::builder::ImageListOptionsBuilder::all()` no longer accepts an argument and always sets the option to true [#211](https://github.com/softprops/shiplift/pull/211)
+* add `repo_tags`, `repo_digests` fields to `ImageDetails` [#222](https://github.com/softprops/shiplift/pull/222)
+* add `status` field to container State [#221](https://github.com/softprops/shiplift/pull/221)
+* support for specifying user when creating container [#220](https://github.com/softprops/shiplift/pull/220)
+* add `nano_cpus` and `memory_swap` to `ContainerOptions` [#230](https://github.com/softprops/shiplift/pull/230)
+* `ContainerOptionsBuilder::env()` signature changed [#237](https://github.com/softprops/shiplift/pull/237)
+* allow attaching to containers when connecting to Docker daemon via UNIX socket [#238](https://github.com/softprops/shiplift/pull/238)
+* support for uploading tar to container [#239](https://github.com/softprops/shiplift/pull/239)
+* fix registry authentication to use URL-safe base64 encoding [#245](https://github.com/softprops/shiplift/pull/245)
+* add StopSignal and StopTimeout to ContainerOptionsBuilder [#248](https://github.com/softprops/shiplift/pull/248)
+* update lifetimes of various methods to avoid `temporary value dropped while borrowed` errors [#272](https://github.com/softprops/shiplift/pull/272)
# 0.6.0
diff --git a/Cargo.toml b/Cargo.toml
index 2dad6ce..bc0054b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "shiplift"
-version = "0.6.0"
+version = "0.7.0"
authors = ["softprops <d.tangren@gmail.com>"]
description = "A Rust interface for maneuvering Docker containers"
documentation = "https://docs.rs/shiplift"
@@ -18,31 +18,35 @@ coveralls = { repository = "softprops/shipflit" }
maintenance = { status = "actively-developed" }
[dependencies]
-base64 = "0.11"
-byteorder = "1.3"
-bytes = "0.4"
+base64 = "0.13"
+byteorder = "1.4"
+bytes = "1.0"
chrono = { version = "0.4", optional = true, features = ["serde"] }
flate2 = "1.0"
futures-util = "0.3"
-futures_codec = "0.3"
-hyper = "0.13"
-hyper-openssl = { version = "0.8", optional = true }
-hyperlocal = { version = "0.7", optional = true }
+futures_codec = "0.4"
+hyper = { version = "0.14", features = ["client", "http1", "tcp", "stream"] }
+hyper-openssl = { version = "0.9", optional = true }
+hyperlocal = { version = "0.8", optional = true }
log = "0.4"
mime = "0.3"
openssl = { version = "0.10", optional = true }
-pin-project = "0.4"
+pin-project = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tar = "0.4"
-tokio = "0.2"
+tokio = "1.0"
url = "2.1"
+# XXX: This is a temporary dependency for the reexport! macro in lib.rs. Remove
+# me before 0.9.0 is released.
+paste = "1.0"
+
[dev-dependencies]
-env_logger = "0.7"
+env_logger = "0.8"
# Required for examples to run
futures = "0.3.1"
-tokio = { version = "0.2.6", features = ["macros"] }
+tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
[features]
default = ["chrono", "unix-socket", "tls"]
diff --git a/README.md b/README.md
index 41f9c1d..3fe3ca1 100644
--- a/README.md
+++ b/README.md
@@ -10,15 +10,11 @@ Add the following to your `Cargo.toml` file
```toml
[dependencies]
-shiplift = "0.6"
+shiplift = "0.7"
```
## usage
Many small runnable example programs can be found in this repository's [examples directory](https://github.com/softprops/shiplift/tree/master/examples).
-## planned changes
-
-* give image pull chunked json a proper type
-
Doug Tangren (softprops) 2015-2018
diff --git a/examples/logs.rs b/examples/containerlogs.rs
index 73c8045..73c8045 100644
--- a/examples/logs.rs
+++ b/examples/containerlogs.rs
diff --git a/examples/execinspect.rs b/examples/execinspect.rs
new file mode 100644
index 0000000..de92ec7
--- /dev/null
+++ b/examples/execinspect.rs
@@ -0,0 +1,32 @@
+use futures::StreamExt;
+use shiplift::{Docker, Exec, ExecContainerOptions};
+use std::env;
+
+#[tokio::main]
+async fn main() {
+ let docker = Docker::new();
+ let mut args = env::args().skip(1);
+
+ // First argument is container id
+ let id = args.next().expect("You need to specify a container id");
+ // Rest is command to run in the container
+ let cmd = args.collect::<Vec<String>>();
+ println!("{} {:?}", id, cmd);
+
+ // Create options with specified command
+ let opts = ExecContainerOptions::builder()
+ .cmd(cmd.iter().map(String::as_str).collect())
+ .attach_stdout(true)
+ .attach_stderr(true)
+ .build();
+
+ let exec = Exec::create(&docker, &id, &opts).await.unwrap();
+
+ println!("{:#?}", exec.inspect().await.unwrap());
+
+ let mut stream = exec.start();
+
+ stream.next().await;
+
+ println!("{:#?}", exec.inspect().await.unwrap());
+}
diff --git a/examples/execresize.rs b/examples/execresize.rs
new file mode 100644
index 0000000..7c9cf11
--- /dev/null
+++ b/examples/execresize.rs
@@ -0,0 +1,30 @@
+use shiplift::{Docker, Exec, ExecContainerOptions, ExecResizeOptions};
+use std::env;
+
+#[tokio::main]
+async fn main() {
+ let docker = Docker::new();
+ let mut args = env::args().skip(1);
+
+ // First argument is container id
+ let id = args.next().expect("You need to specify a container id");
+ // Second is width
+ let width: u64 = args.next().map_or(Ok(0), |s| s.parse::<u64>()).unwrap();
+ // Third is height
+ let height: u64 = args.next().map_or(Ok(0), |s| s.parse::<u64>()).unwrap();
+
+ // Create an exec instance
+ let exec_opts = ExecContainerOptions::builder()
+ .cmd(vec!["echo", "123"])
+ .attach_stdout(true)
+ .attach_stderr(true)
+ .build();
+ let exec = Exec::create(&docker, &id, &exec_opts).await.unwrap();
+
+ // Resize its window with given parameters
+ let resize_opts = ExecResizeOptions::builder()
+ .width(width)
+ .height(height)
+ .build();
+ exec.resize(&resize_opts).await.unwrap();
+}
diff --git a/examples/export.rs b/examples/export.rs
index 34f460d..22c543e 100644
--- a/examples/export.rs
+++ b/examples/export.rs
@@ -14,9 +14,7 @@ async fn main() {
.open(format!("{}.tar", &id))
.unwrap();
- let images = docker.images();
-
- while let Some(export_result) = images.get(&id).export().next().await {
+ while let Some(export_result) = docker.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 80d825c..01647d4 100644
--- a/examples/imagebuild.rs
+++ b/examples/imagebuild.rs
@@ -9,10 +9,7 @@ async fn main() {
let options = BuildOptions::builder(path).tag("shiplift_test").build();
- let images = docker.images();
-
- let mut stream = images.build(&options);
-
+ let mut stream = docker.images().build(&options);
while let Some(build_result) = stream.next().await {
match build_result {
Ok(output) => println!("{:?}", output),
diff --git a/examples/networkdisconnect.rs b/examples/networkdisconnect.rs
index 8d58b35..78f33c6 100644
--- a/examples/networkdisconnect.rs
+++ b/examples/networkdisconnect.rs
@@ -6,9 +6,8 @@ async fn network_disconnect(
network_id: &str,
) {
let docker = Docker::new();
- let networks = docker.networks();
-
- if let Err(e) = networks
+ if let Err(e) = docker
+ .networks()
.get(network_id)
.disconnect(&ContainerConnectionOptions::builder(container_id).build())
.await
diff --git a/examples/servicedelete.rs b/examples/servicedelete.rs
new file mode 100644
index 0000000..e962276
--- /dev/null
+++ b/examples/servicedelete.rs
@@ -0,0 +1,14 @@
+use shiplift::Docker;
+use std::env;
+
+#[tokio::main]
+async fn main() {
+ let docker = Docker::new();
+ let id = env::args()
+ .nth(1)
+ .expect("You need to specify an service name");
+
+ if let Err(e) = docker.services().get(&id).delete().await {
+ eprintln!("Error: {}", e)
+ }
+}
diff --git a/examples/serviceinspect.rs b/examples/serviceinspect.rs
new file mode 100644
index 0000000..c281632
--- /dev/null
+++ b/examples/serviceinspect.rs
@@ -0,0 +1,15 @@
+use shiplift::Docker;
+use std::env;
+
+#[tokio::main]
+async fn main() {
+ let docker = Docker::new();
+ let id = env::args()
+ .nth(1)
+ .expect("Usage: cargo run --example serviceinspect -- <service>");
+
+ match docker.services().get(&id).inspect().await {
+ Ok(service) => println!("{:#?}", service),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+}
diff --git a/examples/servicelogs.rs b/examples/servicelogs.rs
new file mode 100644
index 0000000..e5f97c0
--- /dev/null
+++ b/examples/servicelogs.rs
@@ -0,0 +1,31 @@
+use futures::StreamExt;
+use shiplift::{tty::TtyChunk, Docker, LogsOptions};
+use std::env;
+
+#[tokio::main]
+async fn main() {
+ let docker = Docker::new();
+ let id = env::args()
+ .nth(1)
+ .expect("You need to specify a service name");
+
+ let mut logs_stream = docker
+ .services()
+ .get(&id)
+ .logs(&LogsOptions::builder().stdout(true).stderr(true).build());
+
+ while let Some(log_result) = logs_stream.next().await {
+ match log_result {
+ Ok(chunk) => print_chunk(chunk),
+ Err(e) => eprintln!("Error: {}", e),
+ }
+ }
+}
+
+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/services.rs b/examples/services.rs
new file mode 100644
index 0000000..713c5f8
--- /dev/null
+++ b/examples/services.rs
@@ -0,0 +1,19 @@
+use shiplift::{Docker, ServiceListOptions};
+
+#[tokio::main]
+async fn main() {
+ env_logger::init();
+ let docker = Docker::new();
+ match docker
+ .services()
+ .list(&ServiceListOptions::builder().enable_status().build())
+ .await
+ {
+ Ok(services) => {
+ for s in services {
+ println!("service -> {:#?}", s)
+ }
+ }
+ Err(e) => eprintln!("Error: {}", e),
+ }
+}
diff --git a/examples/volumecreate.rs b/examples/volumecreate.rs
index a243be6..a95bb12 100644
--- a/examples/volumecreate.rs
+++ b/examples/volumecreate.rs
@@ -1,10 +1,9 @@
-use shiplift::{builder::VolumeCreateOptions, Docker};
+use shiplift::{Docker, VolumeCreateOptions};
use std::{collections::HashMap, env};
#[tokio::main]
async fn main() {
let docker = Docker::new();
- let volumes = docker.volumes();
let volume_name = env::args()
.nth(1)
@@ -13,7 +12,8 @@ async fn main() {
let mut labels = HashMap::new();
labels.insert("com.github.softprops", "shiplift");
- match volumes
+ match docker
+ .volumes()
.create(
&VolumeCreateOptions::builder()
.name(volume_name.as_ref())
diff --git a/examples/volumedelete.rs b/examples/volumedelete.rs
index ec1da7e..46b37f6 100644
--- a/examples/volumedelete.rs
+++ b/examples/volumedelete.rs
@@ -4,13 +4,12 @@ use std::env;
#[tokio::main]
async fn main() {
let docker = Docker::new();
- let volumes = docker.volumes();
let volume_name = env::args()
.nth(1)
.expect("You need to specify an volume name");
- if let Err(e) = volumes.get(&volume_name).delete().await {
+ if let Err(e) = docker.volumes().get(&volume_name).delete().await {
eprintln!("Error: {}", e)
}
}
diff --git a/examples/volumes.rs b/examples/volumes.rs
index d45c00a..0bb82aa 100644
--- a/examples/volumes.rs
+++ b/examples/volumes.rs
@@ -3,9 +3,7 @@ use shiplift::Docker;
#[tokio::main]
async fn main() {
let docker = Docker::new();
- let volumes = docker.volumes();
-
- match volumes.list().await {
+ match docker.volumes().list().await {
Ok(volumes) => {
for v in volumes {
println!("volume -> {:#?}", v)
diff --git a/lib.rs b/lib.rs
deleted file mode 100644
index e69de29..0000000
--- a/lib.rs
+++ /dev/null
diff --git a/rustfmt.toml b/rustfmt.toml
index 899a094..35ca786 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,4 +1,4 @@
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#fn_args_layout
fn_args_layout = "Vertical"
-# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#merge_imports
-merge_imports = true \ No newline at end of file
+# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#imports_granularity
+imports_granularity="Crate" \ No newline at end of file
diff --git a/src/builder.rs b/src/builder.rs
deleted file mode 100644
index c14cbb7..0000000
--- a/src/builder.rs
+++ /dev/null
@@ -1,1900 +0,0 @@
-//! Interfaces for building various structures
-
-use crate::{errors::Error, Result};
-use serde::Serialize;
-use serde_json::{self, json, map::Map, Value};
-use std::{
- cmp::Eq,
- collections::{BTreeMap, HashMap},
- hash::Hash,
- iter::{IntoIterator, Peekable},
-};
-use url::form_urlencoded;
-
-#[derive(Clone, Serialize, Debug)]
-#[serde(untagged)]
-pub enum RegistryAuth {
- Password {
- username: String,
- password: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- email: Option<String>,
-
- #[serde(rename = "serveraddress")]
- #[serde(skip_serializing_if = "Option::is_none")]
- server_address: Option<String>,
- },
- Token {
- #[serde(rename = "identitytoken")]
- identity_token: String,
- },
-}
-
-impl RegistryAuth {
- /// return a new instance with token authentication
- pub fn token<S>(token: S) -> RegistryAuth
- where
- S: Into<String>,
- {
- RegistryAuth::Token {
- identity_token: token.into(),
- }
- }
-
- /// return a new instance of a builder for authentication
- pub fn builder() -> RegistryAuthBuilder {
- RegistryAuthBuilder::default()
- }
-
- /// serialize authentication as JSON in base64
- pub fn serialize(&self) -> String {
- serde_json::to_string(self)
- .map(|c| base64::encode(&c))
- .unwrap()
- }
-}
-
-#[derive(Default)]
-pub struct RegistryAuthBuilder {
- username: Option<String>,
- password: Option<String>,
- email: Option<String>,
- server_address: Option<String>,
-}
-
-impl RegistryAuthBuilder {
- pub fn username<I>(
- &mut self,
- username: I,
- ) -> &mut Self
- where
- I: Into<String>,
- {
- self.username = Some(username.into());
- self
- }
-
- pub fn password<I>(
- &mut self,
- password: I,
- ) -> &mut Self
- where
- I: Into<String>,
- {
- self.password = Some(password.into());
- self
- }
-
- pub fn email<I>(
- &mut self,
- email: I,
- ) -> &mut Self
- where
- I: Into<String>,
- {
- self.email = Some(email.into());
- self
- }
-
- pub fn server_address<I>(
- &mut self,
- server_address: I,
- ) -> &mut Self
- where
- I: Into<String>,
- {
- self.server_address = Some(server_address.into());
- self
- }
-
- pub fn build(&self) -> RegistryAuth {
- RegistryAuth::Password {
- username: self.username.clone().unwrap_or_else(String::new),
- password: self.password.clone().unwrap_or_else(String::new),
- email: self.email.clone(),
- server_address: self.server_address.clone(),
- }
- }
-}
-
-#[derive(Default, Debug)]
-pub struct TagOptions {
- pub params: HashMap<&'static str, String>,
-}
-
-impl TagOptions {
- /// return a new instance of a builder for options
- pub fn builder() -> TagOptionsBuilder {
- TagOptionsBuilder::default()
- }
-
- /// serialize options as a string. returns None if no options are defined
- pub fn serialize(&self) -> Option<String> {
- if self.params.is_empty() {
- None
- } else {
- Some(
- form_urlencoded::Serializer::new(String::new())
- .extend_pairs(&self.params)
- .finish(),
- )
- }
- }
-}
-
-#[derive(Default)]
-pub struct TagOptionsBuilder {
- params: HashMap<&'static str, String>,
-}
-
-impl TagOptionsBuilder {
- pub fn repo<R>(
- &mut self,
- r: R,
- ) -> &mut Self
- where
- R: Into<String>,
- {
- self.params.insert("repo", r.into());
- self
- }
-
- pub fn tag<T>(
- &mut self,
- t: T,
- ) -> &mut Self
- where
- T: Into<String>,
- {
- self.params.insert("tag", t.into());
- self
- }
-
- pub fn build(&self) -> TagOptions {
- TagOptions {
- params: self.params.clone(),
- }
- }
-}
-
-#[derive(Default, Debug)]
-pub struct PullOptions {
- auth: Option<RegistryAuth>,
- params: HashMap<&'static str, String>,
-}
-
-impl PullOptions {
- /// return a new instance of a builder for options
- pub fn builder() -> PullOptionsBuilder {
- PullOptionsBuilder::default()
- }
-
- /// serialize options as a string. returns None if no options are defined
- pub fn serialize(&self) -> Option<String> {
- if self.params.is_empty() {
- None
- } else {
- Some(
- form_urlencoded::Serializer::new(String::new())
- .extend_pairs(&self.params)
- .finish(),
- )
- }
- }
-
- pub(crate) fn auth_header(&self) -> Option<String> {
- self.auth.clone().map(|a| a.serialize())
- }
-}
-
-#[derive(Default)]
-pub struct PullOptionsBuilder {
- auth: Option<RegistryAuth>,
- params: HashMap<&'static str, String>,
-}
-
-impl PullOptionsBuilder {
- /// Name of the image to pull. The name may include a tag or digest.
- /// This parameter may only be used when pulling an image.
- /// If an untagged value is provided and no `tag` is provided, _all_
- /// tags will be pulled
- /// The pull is cancelled if the HTTP connection is closed.
- pub fn image<I>(
- &mut self,
- img: I,
- ) -> &mut Self
- where
- I: Into<String>,
- {
- self.params.insert("fromImage", img.into());
- self
- }
-
- pub fn src<S>(
- &mut self,
- s: S,
- ) -> &mut Self
- where
- S: Into<String>,
- {
- self.params.insert("fromSrc", s.into());
- self
- }
-
- /// Repository name given to an image when it is imported. The repo may include a tag.
- /// This parameter may only be used when importing an image.
- pub fn repo<R>(
- &mut self,
- r: R,
- ) -> &mut Self
- where
- R: Into<String>,
- {
- self.params.insert("repo", r.into());
- self
- }
-
- /// Tag or digest. If empty when pulling an image,
- /// this causes all tags for the given image to be pulled.
- pub fn tag<T>(
- &mut self,
- t: T,
- ) -> &mut Self
- where
- T: Into<String>,
- {
- self.params.insert("tag", t.into());
- self
- }
-
- pub fn auth(
- &mut self,
- auth: RegistryAuth,
- ) -> &mut Self {
- self.auth = Some(auth);
- self
- }
-
- pub fn build(&mut self) -> PullOptions {
- PullOptions {
- auth: self.auth.take(),
- params: self.params.clone(),
- }
- }
-}
-
-#[derive(Default, Debug)]
-pub struct BuildOptions {
- pub path: String,
- params: HashMap<&'static str, String>,
-}
-
-impl BuildOptions {
- /// return a new instance of a builder for options
- /// path is expected to be a file path to a directory containing a Dockerfile
- /// describing how to build a Docker image
- pub fn builder<S>(path: S) -> BuildOptionsBuilder
- where
- S: Into<String>,
- {
- BuildOptionsBuilder::new(path)
- }
-
- /// serialize options as a string. returns None if no options are defined
- pub fn serialize(&self) -> Option<String> {
- if self.params.is_empty() {
- None
- } else {
- Some(
- form_urlencoded::Serializer::new(String::new())
- .extend_pairs(&self.params)
- .finish(),
- )
- }
- }
-}
-
-#[derive(Default)]
-pub struct BuildOptionsBuilder {
- path: String,
- params: HashMap<&'static str, String>,
-}
-
-impl BuildOptionsBuilder {
- /// path is expected to be a file path to a directory containing a Dockerfile
- /// describing how to build a Docker image
- pub(crate) fn new<S>(path: S) -> Self
- where
- S: Into<String>,