1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::distribution::{Registry, RegistryError};
mod go;
pub mod manifest;
pub mod spec;
use manifest::Digest;
pub use manifest::ManifestV2;
#[derive(Debug)]
pub struct Image<'a> {
registry: &'a Registry,
name: String,
manifest: ManifestV2,
}
impl<'a> Image<'a> {
pub fn new(registry: &'a Registry, name: &str, reference: &str) -> Result<Self, RegistryError> {
let name = name.to_owned();
let url = format!("{}/v2/{}/manifests/{}", registry.url, name, reference);
let accept_types = vec![
"application/vnd.oci.distribution.manifest.v2+json",
"application/vnd.docker.distribution.manifest.v2+json",
];
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(
reqwest::header::ACCEPT,
accept_types.join(",").parse().unwrap(),
);
let manifest = registry
.get(&url, Some(&headers))?
.text()
.map_err(RegistryError::ReqwestError)?
.parse()
.map_err(RegistryError::ManifestError)?;
Ok(Self {
registry,
name,
manifest,
})
}
pub fn manifest(&self) -> &ManifestV2 {
&self.manifest
}
pub fn get_blob(&self, digest: &Digest) -> Result<String, RegistryError> {
let url = format!("{}/v2/{}/blobs/{}", self.registry.url, self.name, digest);
self.registry
.get(&url, None)?
.text()
.map_err(RegistryError::ReqwestError)
}
pub fn config(&self) -> Result<spec::ImageV1, RegistryError> {
match manifest::ManifestV2Schema::from(self.manifest()) {
manifest::ManifestV2Schema::Schema2 => {}
other => return Err(RegistryError::UnsupportedManifestSchema(other)),
};
let config_digest = match self.manifest() {
ManifestV2::Schema2(m) => m.config.digest(),
_ => unreachable!(),
};
self.get_blob(config_digest)?
.parse()
.map_err(RegistryError::ImageSpecError)
}
}