Skip to content
Permalink
Browse files

Copy a byte slice as file into a container (softprops#151)

- add function copy_file_into to container
- add example
  • Loading branch information...
schrieveslaach authored and softprops committed Feb 23, 2019
1 parent ebb2938 commit 0ae953c69ce7a336794244adc29bbc206320705d
Showing with 70 additions and 1 deletion.
  1. +28 −0 examples/containercopyinto.rs
  2. +42 −1 src/lib.rs
@@ -0,0 +1,28 @@
use shiplift::Docker;
use std::{env, path};
use tokio::prelude::Future;

fn main() {
let docker = Docker::new();
let path = env::args()
.nth(1)
.expect("Usage: cargo run --example containercopyinto -- <local path> <container>");
let id = env::args()
.nth(2)
.expect("Usage: cargo run --example containercopyinto -- <local path> <container>");


use std::fs::File;
use std::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
.containers()
.get(&id)
.copy_file_into(path::Path::new(&path), &bytes[..])
.map_err(|e| eprintln!("Error: {}", e));
tokio::run(fut);
}
@@ -497,7 +497,37 @@ impl<'a, 'b> Container<'a, 'b> {
.map(|c| c.to_vec())
}

// TODO: copy_into
/// Copy a byte slice as file into (see `bytes`) the container.
///
/// The file will be copied at the given location (see `path`) and will be owned by root
/// with access mask 644. The specified `path` parent location must exists, otherwise the
/// creation of the file fails.
pub fn copy_file_into(
&self,
path: &Path,
bytes: &[u8]
) -> impl Future<Item = (), Error = Error> {

let mut ar = tar::Builder::new(Vec::new());
let mut header = tar::Header::new_gnu();
header.set_size(bytes.len() as u64);
header.set_mode(0o0644);
ar.append_data(&mut header,
path.file_name().map(|f| f.to_str().unwrap()).unwrap(),
bytes
).unwrap();
let data = ar.into_inner().unwrap();

let body = Some((data, "application/x-tar".parse::<Mime>().unwrap()));

let path_arg = form_urlencoded::Serializer::new(String::new())
.append_pair("path", &path.parent().map(|p| p.to_string_lossy()).unwrap())
.finish();

self.docker
.put(&format!("/containers/{}/archive?{}", self.id, path_arg), body)
.map(|_| ())
}
}

/// Interface for docker containers
@@ -961,6 +991,17 @@ impl Docker {
self.transport.request(Method::POST, endpoint, body)
}

fn put<B>(
&self,
endpoint: &str,
body: Option<(B, Mime)>,
) -> impl Future<Item = String, Error = Error>
where
B: Into<Body>,
{
self.transport.request(Method::PUT, endpoint, body)
}

fn post_json<B, T>(
&self,
endpoint: &str,

0 comments on commit 0ae953c

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.