Skip to content

Commit

Permalink
Merge pull request #32 from lucab/ups/errors-module
Browse files Browse the repository at this point in the history
lib: general cleanup and docs
  • Loading branch information
lucab authored Jun 18, 2017
2 parents 4c410d3 + fb333f6 commit d14db92
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 87 deletions.
2 changes: 1 addition & 1 deletion examples/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn main() {
}

fn run(dkr_ref: &reference::Reference, user: Option<String>, passwd: Option<String>) -> Result<()> {
let image = dkr_ref.image();
let image = dkr_ref.repository();
let version = dkr_ref.version();

let mut tcore = try!(Core::new());
Expand Down
2 changes: 1 addition & 1 deletion examples/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn run(dkr_ref: &reference::Reference,
env_logger::LogBuilder::new().filter(Some("dkregistry"), log::LogLevelFilter::Trace)
.filter(Some("trace"), log::LogLevelFilter::Trace)
.init()?;
let image = dkr_ref.image();
let image = dkr_ref.repository();
let version = dkr_ref.version();

let mut tcore = try!(Core::new());
Expand Down
2 changes: 2 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Error chains, types and traits.
use hyper;
use serde_json;
use std::{io, string};
Expand Down
28 changes: 15 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! # extern crate dkregistry;
//! # extern crate tokio_core;
//! # fn main() {
//! # fn run() -> dkregistry::Result<()> {
//! # fn run() -> dkregistry::errors::Result<()> {
//! #
//! use tokio_core::reactor::Core;
//! use dkregistry::v2::Client;
Expand All @@ -33,7 +33,6 @@
//! # }
//! ```

extern crate base64;
extern crate futures;
extern crate hyper;
Expand All @@ -53,13 +52,15 @@ extern crate strum;
#[macro_use]
extern crate strum_macros;

mod errors;
pub use errors::*;

pub mod errors;
pub mod mediatypes;
pub mod v2;
pub mod reference;
pub mod render;
pub mod v2;

use std::collections::HashMap;
use std::io::Read;
use errors::Result;

/// Default User-Agent client identity.
pub static USER_AGENT: &'static str = "camallo-dkregistry/0.0";
Expand All @@ -68,9 +69,10 @@ pub static USER_AGENT: &'static str = "camallo-dkregistry/0.0";
///
/// This is a convenience decoder for docker-client credentials
/// typically stored under `~/.docker/config.json`.
pub fn get_credentials<T: ::std::io::Read>(reader: T,
index: &str)
-> Result<(Option<String>, Option<String>)> {
pub fn get_credentials<T: Read>(
reader: T,
index: &str,
) -> Result<(Option<String>, Option<String>)> {
let map: Auths = try!(serde_json::from_reader(reader));
let real_index = match index {
// docker.io has some special casing in config.json
Expand All @@ -79,7 +81,7 @@ pub fn get_credentials<T: ::std::io::Read>(reader: T,
other => other,
};
let auth = match map.auths.get(real_index) {
Some(x) => try!(::base64::decode(x.auth.as_str())),
Some(x) => try!(base64::decode(x.auth.as_str())),
None => bail!("no auth for index"),
};
let s = try!(String::from_utf8(auth));
Expand All @@ -94,12 +96,12 @@ pub fn get_credentials<T: ::std::io::Read>(reader: T,
Ok(up)
}

#[derive(Debug,Deserialize,Serialize)]
#[derive(Debug, Deserialize, Serialize)]
struct Auths {
auths: ::std::collections::HashMap<String, AuthObj>,
auths: HashMap<String, AuthObj>,
}

#[derive(Debug,Default,Deserialize,Serialize)]
#[derive(Debug, Default, Deserialize, Serialize)]
struct AuthObj {
auth: String,
}
97 changes: 54 additions & 43 deletions src/reference.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
//! Parser for `docker://` URLs.
//!
//! This module provides support for parsing image references.
//!
//! ## Example
//!
//! ```rust
//! # extern crate dkregistry;
//! # fn main() {
//! # fn run() -> dkregistry::errors::Result<()> {
//! #
//! use std::str::FromStr;
//! use dkregistry::reference::Reference;
//!
//! // Parse an image reference
//! let dkref = Reference::from_str("docker://busybox")?;
//! assert_eq!(dkref.registry(), "registry-1.docker.io");
//! assert_eq!(dkref.repository(), "library/busybox");
//! assert_eq!(dkref.version(), "latest");
//! #
//! # Ok(())
//! # };
//! # run().unwrap();
//! # }
//! ```
//!
//!
// The `docker://` schema is not officially documented, but has a reference implementation:
// https://github.com/docker/distribution/blob/v2.6.1/reference/reference.go

use std::{fmt, str};
use std::str::FromStr;

/// Image version, either a tag or a digest.
#[derive(Clone)]
pub enum Version {
Tag(String),
Expand Down Expand Up @@ -57,31 +84,25 @@ impl fmt::Display for Version {
}
}

/// A registry image reference.
#[derive(Clone, Debug, Default)]
pub struct Reference {
has_schema: bool,
raw_input: String,
registry: String,
repository: String,
image: String,
version: Version,
}

impl Reference {
pub fn new(registry: Option<String>,
repository: Option<String>,
image: String,
version: Option<Version>)
-> Self {
pub fn new(registry: Option<String>, repository: String, version: Option<Version>) -> Self {
let reg = registry.unwrap_or("registry-1.docker.io".to_string());
let repo = repository.unwrap_or("library".to_string());
let ver = version.unwrap_or(Version::Tag("latest".to_string()));
Self {
has_schema: false,
raw_input: "".into(),
registry: reg,
repository: repo,
image: image,
repository: repository,
version: ver,
}
}
Expand All @@ -90,8 +111,8 @@ impl Reference {
self.registry.clone()
}

pub fn image(&self) -> String {
self.repository.clone() + "/" + self.image.as_str()
pub fn repository(&self) -> String {
self.repository.clone()
}

pub fn version(&self) -> String {
Expand All @@ -104,22 +125,18 @@ impl Reference {

//TODO(lucab): move this to a real URL type
pub fn to_url(&self) -> String {
format!("docker://{}/{}/{}{:?}",
self.registry,
self.repository,
self.image,
self.version)
format!(
"docker://{}/{}{:?}",
self.registry,
self.repository,
self.version
)
}
}

impl fmt::Display for Reference {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f,
"{}/{}/{}{:?}",
self.registry,
self.repository,
self.image,
self.version)
write!(f, "{}/{}{:?}", self.registry, self.repository, self.version)
}
}

Expand All @@ -144,33 +161,27 @@ fn parse_url(s: &str) -> Result<Reference, ::errors::Error> {
}
(None, None) => (rest, Version::default()),
};
if rest.len() < 1 {
bail!("name too short");
}
let mut reg = "registry-1.docker.io";
let mut repo = "library";
let rest: Vec<&str> = rest.rsplitn(3, '/').collect();
let image = match rest.len() {
1 => rest[0],
2 => {
repo = rest[1];
rest[0]
}
let split: Vec<&str> = rest.rsplitn(3, '/').collect();
let image = match split.len() {
1 => "library/".to_string() + rest,
2 => rest.to_string(),
_ => {
reg = rest[2];
repo = rest[1];
rest[0]
reg = split[2];
split[1].to_string() + "/" + split[0]
}
};
if image.len() < 1 {
bail!("name too short");
}
if image.len() > 127 {
bail!("name too long");
}
Ok(Reference {
has_schema: has_schema,
raw_input: s.to_string(),
registry: reg.to_string(),
repository: repo.to_string(),
image: image.to_string(),
version: ver,
})
has_schema: has_schema,
raw_input: s.to_string(),
registry: reg.to_string(),
repository: image,
version: ver,
})
}
4 changes: 4 additions & 0 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ use libflate::gzip;
use std::{fs, path};
use tar;

/// Unpack an ordered list of layers to a target directory.
///
/// Layers must be provided as gzip-compressed tar archives, with lower layers
/// coming first. Target directory must be an existing absolute path.
pub fn unpack(layers: &[Vec<u8>], target_dir: &path::Path) -> Result<()> {
if !target_dir.is_absolute() || !target_dir.exists() || !target_dir.is_dir() {
bail!("wrong target path");
Expand Down
5 changes: 5 additions & 0 deletions src/v2/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ impl Client {
return Ok(Box::new(www_auth));
}

/// Set the token to be used for further registry requests.
pub fn set_token(&mut self, token: Option<&str>) -> &Self {
if let Some(ref t) = token {
self.token = Some(t.to_string());
}
self
}

/// Perform registry authentication and return an authenticated token.
///
/// On success, the returned token will be valid for all requested scopes.
pub fn login(&self, scopes: Vec<&str>) -> Result<FutureTokenAuth> {
let subclient = self.hclient.clone();
let creds = self.credentials.clone();
Expand Down Expand Up @@ -115,6 +119,7 @@ impl Client {
return Ok(Box::new(auth));
}

/// Check whether the client is authenticated with the registry.
pub fn is_auth(&self, token: Option<&str>) -> Result<FutureBool> {
let url = try!(hyper::Uri::from_str((self.base_url.clone() + "/v2/").as_str()));
let mut req = self.new_request(hyper::Method::Get, url.clone());
Expand Down
2 changes: 1 addition & 1 deletion src/v2/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use futures::Stream;
pub type StreamCatalog = Box<futures::Stream<Item = String, Error = Error>>;

#[derive(Debug,Default,Deserialize,Serialize)]
pub struct Catalog {
struct Catalog {
pub repositories: Vec<String>,
}

Expand Down
10 changes: 6 additions & 4 deletions src/v2/manifest/manifest_schema1.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use v2::*;

/// Manifest version 2 schema 1, signed.
#[derive(Debug,Default,Deserialize,Serialize)]
pub struct ManifestSchema1Signed {
#[serde(rename = "schemaVersion")]
Expand All @@ -8,28 +9,29 @@ pub struct ManifestSchema1Signed {
pub tag: String,
pub architecture: String,
#[serde(rename = "fsLayers")]
fs_layers: Vec<Layer>,
fs_layers: Vec<S1Layer>,
history: Vec<V1Compat>,
signatures: Vec<Signature>,
}

#[derive(Debug,Default,Deserialize,Serialize)]
pub struct Signature {
struct Signature {
// TODO(lucab): switch to jsonwebtokens crate
// https://github.com/Keats/rust-jwt/pull/23
header: serde_json::Value,
signature: String,
protected: String,
}

/// Compatibility entry for version 1 manifest interoperability.
#[derive(Debug,Deserialize,Serialize)]
pub struct V1Compat {
struct V1Compat {
#[serde(rename = "v1Compatibility")]
v1_compat: String,
}

#[derive(Debug,Deserialize,Serialize)]
pub struct Layer {
struct S1Layer {
#[serde(rename = "blobSum")]
blob_sum: String,
}
Expand Down
Loading

0 comments on commit d14db92

Please sign in to comment.