//! Shiplift is a multi-transport utility for maneuvering [docker](https://www.docker.com/) containers
//!
//! # examples
//!
//! ```no_run
//! extern crate shiplift;
//!
//! let docker = shiplift::Docker::new();
//! let images = docker.images().list(&Default::default()).unwrap();
//! println!("docker images in stock");
//! for i in images {
//! println!("{:?}", i.repo_tags);
//! }
//! ```
#[macro_use]
extern crate log;
extern crate byteorder;
extern crate flate2;
extern crate http;
extern crate hyper;
extern crate hyper_openssl;
#[cfg(feature = "unix-socket")]
extern crate hyperlocal;
extern crate mime;
extern crate openssl;
extern crate tar;
extern crate url;
#[macro_use]
extern crate serde_derive;
extern crate serde;
#[macro_use]
extern crate serde_json;
extern crate tokio;
pub mod builder;
pub mod errors;
pub mod rep;
pub mod transport;
pub mod tty;
mod tarball;
pub use builder::{
BuildOptions, ContainerConnectionOptions, ContainerFilter, ContainerListOptions,
ContainerOptions, EventsOptions, ExecContainerOptions, ImageFilter, ImageListOptions,
LogsOptions, NetworkCreateOptions, NetworkListOptions, PullOptions, RmContainerOptions,
};
pub use errors::Error;
use hyper::client::HttpConnector;
use hyper::Body;
use hyper::{Client, Method, Uri};
use hyper_openssl::HttpsConnector;
#[cfg(feature = "unix-socket")]
use hyperlocal::UnixConnector;
use mime::Mime;
use openssl::ssl::{SslConnector, SslFiletype, SslMethod};
use rep::Image as ImageRep;
use rep::{
Change, Container as ContainerRep, ContainerCreateInfo, ContainerDetails, Event, Exit, History,
ImageDetails, Info, SearchResult, Stats, Status, Top, Version,
};
use rep::{NetworkCreateInfo, NetworkDetails as NetworkInfo};
use serde_json::Value;
use std::borrow::Cow;
use std::cell::RefCell;
use std::env;
use std::io::prelude::*;
use std::path::Path;
use std::time::Duration;
use transport::{tar, Transport};
use tty::Tty;
use url::form_urlencoded;
/// Represents the result of all docker operations
pub type Result<T> = std::result::Result<T, Error>;
/// Entrypoint interface for communicating with docker daemon
pub struct Docker {
transport: Transport,
}
/// Interface for accessing and manipulating a named docker image
pub struct Image<'a, 'b> {
docker: &'a Docker,
name: Cow<'b, str>,
}
impl<'a, 'b> Image<'a, 'b> {
/// Exports an interface for operations that may be performed against a named image
pub fn new<S>(
docker: &'a Docker,
name: S,
) -> Image<'a, 'b>
where
S: Into<Cow<'b, str>>,
{
Image {
docker,
name: name.into(),
}
}
/// Inspects a named image's details
pub fn inspect(&self) -> Result<ImageDetails> {
let raw = self
.docker
.get(&format!("/images/{}/json", self.name)[..])?;
Ok(serde_json::from_str::<ImageDetails>(&raw)?)
}
/// Lists the history of the images set of changes
pub fn history(&self) -> Result<Vec<History>> {
let raw = self
.docker
.get(&format!("/images/{}/history", self.name)[..])?;
Ok(serde_json::from_str::<Vec<History>>(&raw)?)
}
/// Delete's an image
pub fn delete(&self) -> Result<Vec<Status>> {
let raw = self.docker.delete(&format!("/images/{}", self.name)[..])?;
Ok(match serde_json::from_str(&raw)? {
Value::Array(ref xs) => xs.iter().map(|j| {
let obj = j.as_object().expect("expected json object");
obj.get("Untagged")
.map(|sha| {
Status::Untagged(
sha.as_str()
.expect("expected Untagged to be a string")
.to_owned(),
)
})
.or_else(|| {
obj.get("Deleted").map(|sha| {
Status::Deleted(
sha.as_str()
.expect("expected Deleted to be a string")
.to_owned(),
)
})
})
.expect("expected Untagged or Deleted")
}),
_ => unreachable!(),
}
.collect())
}
/// Export this image to a tarball
pub fn export(&self) -> Result<Box<Read>> {
self.docker
.stream_get(&format!("/images/{}/get", self.name)[..])
}
}
/// Interface for docker images
pub struct Images<'a> {
docker: &'a Docker,
}
impl<'a> Images<'a> {
/// Exports an interface for interacting with docker images
pub fn new(docker: &'a Docker) -> Images<'a> {
Images { docker }
}
/// Builds a new image build by reading a Dockerfile in a target directory
pub fn build(