summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsoftprops <d.tangren@gmail.com>2015-03-25 23:15:58 -0400
committersoftprops <d.tangren@gmail.com>2015-03-25 23:15:58 -0400
commita22cc5f3204d0825ccdd86faa098c0f6ab63d30d (patch)
tree839115d64b804198aeb1a273c7533acb631f029b
sketch
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock156
-rw-r--r--Cargo.toml13
-rw-r--r--src/lib.rs127
-rw-r--r--src/main.rs10
5 files changed, 307 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb5a316
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..c9cc035
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,156 @@
+[root]
+name = "shiplift"
+version = "0.0.1"
+dependencies = [
+ "hyper 0.3.2",
+ "openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unix_socket 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cookie"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gcc"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "httparse"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "hyper"
+version = "0.3.2"
+dependencies = [
+ "cookie 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "httparse 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 0.2.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libressl-pnacl-sys"
+version = "2.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "pnacl-build-helper 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "log"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "mime"
+version = "0.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num_cpus"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "openssl"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "openssl-sys"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libressl-pnacl-sys 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "pnacl-build-helper"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc-serialize"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "time"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicase"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unix_socket"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "url"
+version = "0.2.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..73d17c8
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+
+name = "shiplift"
+version = "0.0.1"
+authors = ["softprops <d.tangren@gmail.com>"]
+
+[dependencies.hyper]
+path="/Users/dougtangren/code/rust/hyper"
+
+[dependencies]
+openssl = "0.5.0"
+unix_socket = "0.2.1"
+url = "0.2.26" \ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..5ec2d6d
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,127 @@
+extern crate hyper;
+extern crate openssl;
+extern crate unix_socket;
+extern crate url;
+
+use hyper::{ Client, Url };
+use hyper::method::Method;
+use hyper::net::NetworkConnector;
+use openssl::x509::X509FileType;
+use std::io::{ Read, Write };
+use std::{ env, result };
+use std::path::Path;
+use std::io::Error;
+use unix_socket::UnixStream;
+use url::{ Host, RelativeSchemeData, SchemeData };
+
+pub type Result<T> = result::Result<T, Error>;
+
+trait Transport {
+ fn request(&mut self, method: Method, endpoint: &str) -> Result<String>;
+}
+
+pub struct Docker {
+ transport: Box<Transport>
+}
+
+impl Transport for UnixStream {
+ fn request(&mut self, method: Method, endpoint: &str) -> Result<String> {
+ let method_str = match method {
+ Method::Put => "PUT",
+ Method::Post => "POST",
+ Method::Delete => "DELETE",
+ _ => "GET"
+ };
+ let req = format!("{} {} HTTP/1.0\r\n\r\n", method_str, endpoint);
+ try!(self.write_all(req.as_bytes()));
+ let mut result = String::new();
+ self.read_to_string(&mut result).map(|_| result)
+ }
+}
+
+impl<C: NetworkConnector> Transport for (Client<C>, String) {
+ fn request(&mut self, method: Method, endpoint: &str) -> Result<String> {
+ let uri = format!("{}{}", self.1, endpoint);
+ let req = match method {
+ Method::Put => self.0.put(&uri[..]),
+ Method::Post => self.0.post(&uri[..]),
+ Method::Delete => self.0.delete(&uri[..]),
+ _ => self.0.get(&uri[..])
+ };
+ let mut res = match req.send() {
+ Ok(r) => r,
+ Err(e) => panic!("failed request {:?}", e)
+ };
+ let mut body = String::new();
+ res.read_to_string(&mut body).map(|_| body)
+ }
+}
+
+
+
+// https://docs.docker.com/reference/api/docker_remote_api_v1.17/
+impl Docker {
+ pub fn new() -> Docker {
+ let host = env::var("DOCKER_HOST")
+ .map(|h| Url::parse(&h).ok()
+ .expect("invalid url"))
+ .ok()
+ .expect("expected host");
+ let domain = match host.scheme_data {
+ SchemeData::NonRelative(s) => s,
+ SchemeData::Relative(RelativeSchemeData { host: host, .. }) =>
+ match host {
+ Host::Domain(s) => s,
+ Host::Ipv6(a) => a.to_string()
+ }
+ };
+ match &host.scheme[..] {
+ "unix" => {
+ let stream =
+ match UnixStream::connect(domain) {
+ Err(_) => panic!("failed to connect to socket"),
+ Ok(s) => s
+ };
+ Docker { transport: Box::new(stream) }
+ },
+ _ => {
+ let mut client = Client::new();
+ client.set_ssl_verifier(Box::new(|ssl_ctx| {
+ match env::var("DOCKER_CERT_PATH").ok() {
+ Some(ref certs) => {
+ let cert = &format!("{}/cert.pem", certs);
+ let key = &format!("{}/key.pem", certs);
+ ssl_ctx.set_certificate_file(&Path::new(cert), X509FileType::PEM);
+ ssl_ctx.set_private_key_file(&Path::new(key), X509FileType::PEM);
+ match env::var("DOCKER_TLS_VERIFY").ok() {
+ Some(_) => {
+ let ca = &format!("{}/ca.pem", certs);
+ ssl_ctx.set_CA_file(&Path::new(ca));
+ }, _ => ()
+ };
+ ()
+ }, _ => ()
+ }
+ }));
+ let tup = (client, format!("https:{}", domain.to_string()));
+ Docker { transport: Box::new(tup) }
+ }
+ }
+ }
+
+ pub fn images(&mut self) -> Result<String> {
+ self.get("/images/json")
+ }
+
+ pub fn version(&mut self) -> Result<String> {
+ self.get("/version")
+ }
+
+ pub fn info(&mut self) -> Result<String> {
+ self.get("/info")
+ }
+
+ fn get(&mut self, endpoint: &str) -> Result<String> {
+ (*self.transport).request(Method::Get, endpoint)
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..6a6ed77
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,10 @@
+extern crate shiplift;
+
+use shiplift::Docker;
+
+fn main() {
+ match Docker::new().info() {
+ Ok(e) => println!("-> {:?}", e),
+ Err(e) => panic!("<- {:?}", e)
+ };
+}