dkregistry/
lib.rs

1//! A pure-Rust asynchronous library for Docker Registry API.
2//!
3//! This library provides support for asynchronous interaction with
4//! container registries conformant to the Docker Registry HTTP API V2.
5//!
6//! ## Example
7//!
8//! ```rust,no_run
9//! # extern crate dkregistry;
10//! # extern crate tokio;
11//! # #[tokio::main]
12//! # async fn main() {
13//! # async fn run() -> dkregistry::errors::Result<()> {
14//! #
15//! use dkregistry::v2::Client;
16//!
17//! // Check whether a registry supports API v2.
18//! let host = "quay.io";
19//! let dclient = Client::configure()
20//!                      .insecure_registry(false)
21//!                      .registry(host)
22//!                      .build()?;
23//! match dclient.is_v2_supported().await? {
24//!     false => println!("{} does NOT support v2", host),
25//!     true => println!("{} supports v2", host),
26//! };
27//! #
28//! # Ok(())
29//! # };
30//! # run().await.unwrap();
31//! # }
32//! ```
33
34#![deny(missing_debug_implementations)]
35
36#[macro_use]
37extern crate serde;
38#[macro_use]
39extern crate log;
40#[macro_use]
41extern crate strum_macros;
42
43pub mod errors;
44pub mod mediatypes;
45pub mod reference;
46pub mod render;
47pub mod v2;
48
49use errors::{Result, Error};
50use std::collections::HashMap;
51use std::io::Read;
52
53
54/// Default User-Agent client identity.
55pub static USER_AGENT: &str = "camallo-dkregistry/0.0";
56
57/// Get registry credentials from a JSON config reader.
58///
59/// This is a convenience decoder for docker-client credentials
60/// typically stored under `~/.docker/config.json`.
61pub fn get_credentials<T: Read>(
62    reader: T,
63    index: &str,
64) -> Result<(Option<String>, Option<String>)> {
65    let map: Auths = serde_json::from_reader(reader)?;
66    let real_index = match index {
67        // docker.io has some special casing in config.json
68        "docker.io" | "registry-1.docker.io" => "https://index.docker.io/v1/",
69        other => other,
70    };
71    let auth = match map.auths.get(real_index) {
72        Some(x) => base64::decode(x.auth.as_str())?,
73        None => return Err(Error::AuthInfoMissing(real_index.to_string())),
74    };
75    let s = String::from_utf8(auth)?;
76    let creds: Vec<&str> = s.splitn(2, ':').collect();
77    let up = match (creds.get(0), creds.get(1)) {
78        (Some(&""), Some(p)) => (None, Some(p.to_string())),
79        (Some(u), Some(&"")) => (Some(u.to_string()), None),
80        (Some(u), Some(p)) => (Some(u.to_string()), Some(p.to_string())),
81        (_, _) => (None, None),
82    };
83    trace!("Found credentials for user={:?} on {}", up.0, index);
84    Ok(up)
85}
86
87#[derive(Debug, Deserialize, Serialize)]
88struct Auths {
89    auths: HashMap<String, AuthObj>,
90}
91
92#[derive(Debug, Default, Deserialize, Serialize)]
93struct AuthObj {
94    auth: String,
95}