Skip to content

Commit

Permalink
Update tokio and use async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
schrieveslaach committed Jan 3, 2020
1 parent acfaf3e commit 5290199
Show file tree
Hide file tree
Showing 20 changed files with 565 additions and 708 deletions.
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[package]
name = "dkregistry"
version = "0.3.2-alpha.0"
edition = "2018"
authors = ["Luca Bruno <lucab@debian.org>", "Stefan Junker <sjunker@redhat.com>"]
license = "MIT/Apache-2.0"
documentation = "https://docs.rs/dkregistry"
Expand All @@ -24,27 +25,27 @@ tag-prefix = ""
[dependencies]
base64 = "0.11"
error-chain = { version = "0.12", default-features = false }
futures = "0.1"
futures = "0.3"
http = "0.2"
libflate = "0.1"
log = "0.4"
mime = "0.3"
mockito = { version = "0.22", optional = true }
regex = "^1.1.0"
serde = "1"
serde_derive = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
strum = "0.16"
strum_macros = "0.16"
tar = "0.4"
tokio = "0.1"
tokio = "0.2"
dirs = "2.0"
reqwest = { version = "^0.9.6", default-features = false }
reqwest = { version = "0.10", default-features = false, features = ["json"] }
sha2 = "^0.8.0"

[dev-dependencies]
env_logger = "0.7"
spectral = "0.6"
tokio = { version = "0.2", features = ["macros"] }

[features]
default = ["reqwest-default-tls"]
Expand Down
4 changes: 2 additions & 2 deletions examples/checkregistry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ fn main() {

fn run(host: &str) -> Result<bool, boxed::Box<dyn error::Error>> {
let mut runtime = Runtime::new()?;
let dclient = try!(dkregistry::v2::Client::configure()
let dclient = dkregistry::v2::Client::configure()
.registry(host)
.insecure_registry(false)
.build());
.build()?;
let futcheck = dclient.is_v2_supported();

let supported = runtime.block_on(futcheck)?;
Expand Down
57 changes: 18 additions & 39 deletions examples/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,24 @@
extern crate dkregistry;
extern crate futures;

use futures::prelude::*;

pub fn authenticate_client(
pub async fn authenticate_client(
mut client: dkregistry::v2::Client,
login_scope: String,
) -> impl Future<Item = dkregistry::v2::Client, Error = dkregistry::errors::Error> {
futures::future::ok::<_, dkregistry::errors::Error>(client.clone())
.and_then(|dclient| {
dclient.is_v2_supported().and_then(|v2_supported| {
if !v2_supported {
Err("API v2 not supported".into())
} else {
Ok(dclient)
}
})
})
.and_then(|dclient| {
dclient.is_auth(None).and_then(move |is_auth| {
if is_auth {
Ok(dclient)
} else {
Err("login required".into())
}
})
})
.or_else(move |_| {
client
.login(&[login_scope.as_str()])
.and_then(move |token| {
client
.is_auth(Some(token.token()))
.and_then(move |is_auth| {
if !is_auth {
Err("login failed".into())
} else {
println!("logged in!");
Ok(client.set_token(Some(token.token())).clone())
}
})
})
})
) -> Result<dkregistry::v2::Client, dkregistry::errors::Error> {
if !client.is_v2_supported().await? {
return Err("API v2 not supported".into());
}

if client.is_auth(None).await? {
return Ok(client);
}

let token = client.login(&[login_scope.as_str()]).await?;

if !client.is_auth(Some(token.token())).await? {
Err("login failed".into())
} else {
println!("logged in!");
Ok(client.set_token(Some(token.token())).clone())
}
}
26 changes: 7 additions & 19 deletions examples/login.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
extern crate dkregistry;
extern crate futures;
extern crate tokio;

mod common;

use futures::prelude::*;
use std::result::Result;
use std::{boxed, error};
use tokio::runtime::current_thread::Runtime;

fn main() {
#[tokio::main]
async fn main() {
let registry = match std::env::args().nth(1) {
Some(x) => x,
None => "registry-1.docker.io".into(),
Expand All @@ -29,15 +24,15 @@ fn main() {
println!("[{}] no $DKREG_PASSWD for login password", registry);
}

let res = run(&registry, user, password, login_scope);
let res = run(&registry, user, password, login_scope).await;

if let Err(e) = res {
println!("[{}] {}", registry, e);
std::process::exit(1);
};
}

fn run(
async fn run(
host: &str,
user: Option<String>,
passwd: Option<String>,
Expand All @@ -48,21 +43,14 @@ fn run(
.filter(Some("trace"), log::LevelFilter::Trace)
.try_init()?;

let mut runtime = Runtime::new()?;

let client = dkregistry::v2::Client::configure()
.registry(host)
.insecure_registry(false)
.username(user)
.password(passwd)
.build()?;

let futures = common::authenticate_client(client, login_scope)
.and_then(|dclient| dclient.is_v2_supported());

match runtime.block_on(futures) {
Ok(login_successful) if login_successful => Ok(()),
Err(e) => Err(Box::new(e)),
_ => Err("Login unsucessful".into()),
}
let dclient = common::authenticate_client(client, login_scope).await?;
dclient.is_v2_supported().await?;
Ok(())
}
47 changes: 15 additions & 32 deletions examples/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ extern crate tokio;
mod common;

use dkregistry::reference;
use futures::prelude::*;
use std::str::FromStr;
use std::{boxed, env, error, fs, io};
use tokio::runtime::current_thread::Runtime;

fn main() {
#[tokio::main]
async fn main() {
let dkr_ref = match std::env::args().nth(1) {
Some(ref x) => reference::Reference::from_str(x),
None => reference::Reference::from_str("quay.io/coreos/etcd"),
Expand Down Expand Up @@ -45,15 +44,15 @@ fn main() {
}
};

let res = run(&dkr_ref, user, password);
let res = run(&dkr_ref, user, password).await;

if let Err(e) = res {
println!("[{}] {:?}", registry, e);
std::process::exit(1);
};
}

fn run(
async fn run(
dkr_ref: &reference::Reference,
user: Option<String>,
passwd: Option<String>,
Expand All @@ -65,7 +64,6 @@ fn run(

let image = dkr_ref.repository();
let version = dkr_ref.version();
let mut runtime = Runtime::new()?;

let client = dkregistry::v2::Client::configure()
.registry(&dkr_ref.registry())
Expand All @@ -76,33 +74,18 @@ fn run(

let login_scope = "";

let futures = common::authenticate_client(client, login_scope.to_string())
.and_then(|dclient| {
dclient
.get_manifest(&image, &version)
.and_then(|manifest| Ok((dclient, manifest.layers_digests(None)?)))
})
.and_then(|(dclient, layers_digests)| {
let image = image.clone();

println!("{} -> got {} layer(s)", &image, layers_digests.len(),);

futures::stream::iter_ok::<_, dkregistry::errors::Error>(layers_digests)
.and_then(move |layer_digest| {
let get_blob_future = dclient.get_blob(&image, &layer_digest);
get_blob_future.inspect(move |blob| {
println!("Layer {}, got {} bytes.\n", layer_digest, blob.len());
})
})
.collect()
});

let blobs = match runtime.block_on(futures) {
Ok(blobs) => blobs,
Err(e) => return Err(Box::new(e)),
};
let dclient = common::authenticate_client(client, login_scope.to_string()).await?;
let manifest = dclient.get_manifest(&image, &version).await?;

let layers_digests = manifest.layers_digests(None)?;
println!("{} -> got {} layer(s)", &image, layers_digests.len(),);

for layer_digest in &layers_digests {
let blob = dclient.get_blob(&image, &layer_digest).await?;
println!("Layer {}, got {} bytes.\n", layer_digest, blob.len());
}

println!("Downloaded {} layers", blobs.len());
println!("Downloaded {} layers", layers_digests.len());

Ok(())
}
1 change: 0 additions & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use base64;
use http;
use regex;
use reqwest;
use serde_json;
use std::{io, string};

error_chain! {
Expand Down
10 changes: 4 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ extern crate base64;
extern crate futures;
extern crate http;
extern crate mime;
#[macro_use]
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate log;
extern crate libflate;
extern crate regex;
Expand Down Expand Up @@ -77,17 +75,17 @@ 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 map: Auths = serde_json::from_reader(reader)?;
let real_index = match index {
// docker.io has some special casing in config.json
"docker.io" | "registry-1.docker.io" => "https://index.docker.io/v1/",
other => other,
};
let auth = match map.auths.get(real_index) {
Some(x) => try!(base64::decode(x.auth.as_str())),
Some(x) => base64::decode(x.auth.as_str())?,
None => bail!("no auth for index {}", real_index),
};
let s = try!(String::from_utf8(auth));
let s = String::from_utf8(auth)?;
let creds: Vec<&str> = s.splitn(2, ':').collect();
let up = match (creds.get(0), creds.get(1)) {
(Some(&""), Some(p)) => (None, Some(p.to_string())),
Expand Down
5 changes: 2 additions & 3 deletions src/mediatypes.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
//! Media-types for API objects.

use errors::*;
use crate::errors::{Error, Result};
use futures;
use mime;
use strum::EnumProperty;

pub type FutureMediaType =
Box<dyn futures::Future<Item = Option<MediaTypes>, Error = Error> + Send>;
pub type FutureMediaType = Box<dyn futures::Future<Output = Result<Option<MediaTypes>>> + Send>;

// For schema1 types, see https://docs.docker.com/registry/spec/manifest-v2-1/
// For schema2 types, see https://docs.docker.com/registry/spec/manifest-v2-2/
Expand Down
6 changes: 3 additions & 3 deletions src/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
// 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 errors::Error;
use crate::errors::Error;
use regex;
use std::collections::VecDeque;
use std::str::FromStr;
Expand All @@ -47,7 +47,7 @@ pub enum Version {
}

impl str::FromStr for Version {
type Err = ::errors::Error;
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let v = match s.chars().nth(0) {
Some(':') => Version::Tag(s.trim_start_matches(':').to_string()),
Expand Down Expand Up @@ -146,7 +146,7 @@ impl fmt::Display for Reference {
}

impl str::FromStr for Reference {
type Err = ::errors::Error;
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
parse_url(s)
}
Expand Down
2 changes: 1 addition & 1 deletion src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Docker image format is specified at
// https://github.com/moby/moby/blob/v17.05.0-ce/image/spec/v1.md

use errors::*;
use crate::errors::*;
use libflate::gzip;
use std::{fs, path};
use tar;
Expand Down
Loading

0 comments on commit 5290199

Please sign in to comment.