Skip to content

Commit

Permalink
Copy from container (softprops#150)
Browse files Browse the repository at this point in the history
* Add 'copy_from' function to 'Container'

* Run clippy

* Update deps
  • Loading branch information
bossmc authored and softprops committed Feb 13, 2019
1 parent 31a913b commit 2a40dc0
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 27 deletions.
40 changes: 20 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,28 @@ coveralls = { repository = "softprops/shipflit" }
maintenance = { status = "actively-developed" }

[dependencies]
byteorder = "1"
bytes = "0.4"
flate2 = "1"
futures = "0.1"
http = "0.1"
hyper = "0.12"
hyper-openssl = { version = "0.6", optional = true }
hyperlocal = { version = "0.6", optional = true }
log = "0.4"
mime = "0.3"
openssl = { version = "0.10", optional = true }
tar = "0.4"
tokio = "0.1"
tokio-codec = "0.1"
tokio-io = "0.1"
url = "1.7"
serde = "1"
serde_derive = "1"
serde_json = "1"
byteorder = "1.3.1"
bytes = "0.4.11"
flate2 = "1.0.6"
futures = "0.1.25"
http = "0.1.15"
hyper = "0.12.24"
hyper-openssl = { version = "0.7.0", optional = true }
hyperlocal = { version = "0.6.0", optional = true }
log = "0.4.6"
mime = "0.3.13"
openssl = { version = "0.10.16", optional = true }
tar = "0.4.20"
tokio = "0.1.15"
tokio-codec = "0.1.1"
tokio-io = "0.1.11"
url = "1.7.2"
serde = "1.0.87"
serde_derive = "1.0.87"
serde_json = "1.0.38"

[dev-dependencies]
env_logger = "0.5"
env_logger = "0.6.0"

[features]
default = ["unix-socket", "tls"]
Expand Down
26 changes: 26 additions & 0 deletions examples/containercopyfrom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use shiplift::Docker;
use std::{env, path};
use tokio::prelude::{Future, Stream};

fn main() {
let docker = Docker::new();
let id = env::args()
.nth(1)
.expect("Usage: cargo run --example containercopyfrom -- <container> <path in container>");
let path = env::args()
.nth(2)
.expect("Usage: cargo run --example containercopyfrom -- <container> <path in container>");
let fut = 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);
}
4 changes: 2 additions & 2 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,9 @@ impl ContainerOptionsBuilder {
for (key, val) in self
.params
.get("HostConfig.PortBindings")
.unwrap_or(&mut json!(null))
.unwrap_or(&json!(null))
.as_object()
.unwrap_or(&mut Map::new())
.unwrap_or(&Map::new())
.iter()
{
binding.insert(key.to_string(), json!(val));
Expand Down
30 changes: 28 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,27 @@ impl<'a, 'b> Container<'a, 'b> {
.flatten_stream()
}

// todo attach, attach/ws, copy, archive
/// Copy a file/folder from the container. The resulting stream is a tarball of the extracted
/// files.
///
/// If `path` is not an absolute path, it is relative to the container’s root directory. The
/// resource specified by `path` must exist. To assert that the resource is expected to be a
/// directory, `path` should end in `/` or `/`. (assuming a path separator of `/`). If `path`
/// ends in `/.` then this indicates that only the contents of the path directory should be
/// copied. A symlink is always resolved to its target.
pub fn copy_from(
&self,
path: &Path,
) -> impl Stream<Item = Vec<u8>, Error = Error> {
let path_arg = form_urlencoded::Serializer::new(String::new())
.append_pair("path", &path.to_string_lossy())
.finish();
self.docker
.stream_get(&format!("/containers/{}/archive?{}", self.id, path_arg))
.map(|c| c.to_vec())
}

// TODO: copy_into
}

/// Interface for docker containers
Expand Down Expand Up @@ -838,7 +858,7 @@ impl Docker {
"{}://{}:{}",
host.scheme_part().map(|s| s.as_str()).unwrap(),
host.host().unwrap().to_owned(),
host.port().unwrap_or(80)
host.port_u16().unwrap_or(80)
);

match host.scheme_part().map(|s| s.as_str()) {
Expand Down Expand Up @@ -1011,3 +1031,9 @@ impl Docker {
.stream_upgrade_multiplexed(Method::POST, endpoint, body)
}
}

impl Default for Docker {
fn default() -> Self {
Self::new()
}
}
4 changes: 3 additions & 1 deletion src/rep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub struct State {
pub started_at: String,
}

type PortDescription = HashMap<String, Option<Vec<HashMap<String, String>>>>;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct NetworkSettings {
Expand All @@ -116,7 +118,7 @@ pub struct NetworkSettings {
#[serde(rename = "IPPrefixLen")]
pub ip_prefix_len: u64,
pub mac_address: String,
pub ports: Option<HashMap<String, Option<Vec<HashMap<String, String>>>>>,
pub ports: Option<PortDescription>,
pub networks: HashMap<String, NetworkEntry>,
}

Expand Down
2 changes: 1 addition & 1 deletion src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ impl Transport {
B: Into<Body> + 'static,
{
self.stream_upgrade(method, endpoint, body)
.map(|u| crate::tty::Multiplexed::new(u))
.map(crate::tty::Multiplexed::new)
}

/// Extract the error message content from an HTTP response that
Expand Down
8 changes: 7 additions & 1 deletion src/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ impl TtyDecoder {
}
}

impl Default for TtyDecoder {
fn default() -> Self {
Self::new()
}
}

impl Decoder for TtyDecoder {
type Item = Chunk;
type Error = Error;
Expand Down Expand Up @@ -226,7 +232,7 @@ where
});

util::stop_on_err(stream, |e| e.kind() != io::ErrorKind::UnexpectedEof)
.map_err(|e| crate::Error::from(e))
.map_err(crate::Error::from)
}

mod util {
Expand Down

0 comments on commit 2a40dc0

Please sign in to comment.