Class: RegistryApiClient
- Inherits:
-
Object
show all
- Defined in:
- lib/docker_cake/registry_api_client.rb
Defined Under Namespace
Modules: HTTP
Classes: InvalidMethod, JsonError, PubSub, ReauthenticatedException, RegistryAuthenticationException, RegistryAuthorizationException, RegistrySSLException, RegistryUnknownException, UnknownRegistryException, Waiter
Constant Summary
collapse
- DEFAULT_REGISTRY =
"https://registry.hub.docker.com"
- DEFAULT_MANIFEST =
"application/vnd.docker.distribution.manifest.v2+json"
- FAT_MANIFEST =
"application/vnd.docker.distribution.manifest.list.v2+json"
Instance Method Summary
collapse
-
#blob_size(repo, blobSum) ⇒ Object
gets the size of a particular blob, given the repo and the content-addressable hash usually unneeded, since manifest includes it.
-
#http_delete(url) ⇒ Object
-
#http_get(url, manifest: nil, auth: nil, auth_header: nil) ⇒ Object
-
#http_head(url) ⇒ Object
-
#in_parallel(procs = {}) ⇒ Object
-
#initialize(url: DEFAULT_REGISTRY, user: nil, password: nil) ⇒ RegistryApiClient
constructor
A new instance of RegistryApiClient.
-
#manifest(repo, tag, manifest: nil) ⇒ Object
combines small output and fat output to get layer names and sizes.
-
#manifest_layers(repo, tag) ⇒ Object
-
#manifest_sum(manifest) ⇒ Object
-
#ping ⇒ Object
-
#search(query = '') ⇒ Object
-
#tags(repo, withHashes = false) ⇒ Object
Constructor Details
#initialize(url: DEFAULT_REGISTRY, user: nil, password: nil) ⇒ RegistryApiClient
Returns a new instance of RegistryApiClient.
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/docker_cake/registry_api_client.rb', line 82
def initialize(url: DEFAULT_REGISTRY, user: nil, password: nil)
url = url || DEFAULT_REGISTRY
@url = url
uri = URI.parse(url)
@base_uri = "#{uri.scheme}://#{uri.host}:#{uri.port}"
@user = user
@password = password
@manifest_format = "application/vnd.docker.distribution.manifest.v2+json"
end
|
Instance Method Details
#blob_size(repo, blobSum) ⇒ Object
gets the size of a particular blob, given the repo and the content-addressable hash usually unneeded, since manifest includes it
231
232
233
234
|
# File 'lib/docker_cake/registry_api_client.rb', line 231
def blob_size(repo, blobSum)
response = http_head("/v2/#{repo}/blobs/#{blobSum}")
Integer(response.[:content_length], 10)
end
|
#http_delete(url) ⇒ Object
100
101
102
|
# File 'lib/docker_cake/registry_api_client.rb', line 100
def http_delete(url)
http_req("delete", url)
end
|
#http_get(url, manifest: nil, auth: nil, auth_header: nil) ⇒ Object
96
97
98
|
# File 'lib/docker_cake/registry_api_client.rb', line 96
def http_get(url, manifest: nil, auth: nil, auth_header: nil)
http_req("get", url, manifest: manifest, auth: auth, auth_header: )
end
|
#http_head(url) ⇒ Object
104
105
106
|
# File 'lib/docker_cake/registry_api_client.rb', line 104
def http_head(url)
http_req("head", url)
end
|
#in_parallel(procs = {}) ⇒ Object
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# File 'lib/docker_cake/registry_api_client.rb', line 196
def in_parallel(procs = {})
threads = []
result = {}
errors = []
procs.each do |key, fun|
if fun == nil && key.is_a?(Proc)
fun = key
key = result.size
end
result[key] = nil
threads << Thread.new do
begin
result[key] = fun.call
rescue => error
puts "#{error.class}: #{error.message}"
puts error.backtrace
errors << error
end
end
end
threads.each do |t|
t.alive? && t.join
end
if errors.size > 0
raise errors.first
end
result
end
|
#manifest(repo, tag, manifest: nil) ⇒ Object
combines small output and fat output to get layer names and sizes
155
156
157
158
159
160
|
# File 'lib/docker_cake/registry_api_client.rb', line 155
def manifest(repo, tag, manifest: nil)
if @url == DEFAULT_REGISTRY
= %{Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:#{repo}:pull"}
end
JSON.parse(http_get("/v2/#{repo}/manifests/#{tag}", manifest: manifest, auth: :bearer, auth_header: ))
end
|
#manifest_layers(repo, tag) ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
# File 'lib/docker_cake/registry_api_client.rb', line 162
def manifest_layers(repo, tag)
basic_response = nil
fat_response = nil
resp = in_parallel(
basic: lambda { manifest(repo, tag) },
fat: lambda { manifest(repo, tag, manifest: FAT_MANIFEST) }
)
unless resp[:basic]['layers']
puts "Strange response"
p resp[:basic]
end
basic = resp[:basic]['layers'] || []
fat_response = resp[:fat]
result = []
fat_response['history'].each_with_index do |info, index|
result[index] = JSON.parse(info['v1Compatibility'])
result[index]['blobSum'] = fat_response['fsLayers'][index]['blobSum']
result[index]['size'] = basic.detect do |layer|
layer['digest'] == result[index]['blobSum']
end
result[index]['size'] = result[index]['size']['size'] if result[index]['size']
end
result.reverse
end
|
#manifest_sum(manifest) ⇒ Object
236
237
238
239
240
241
242
|
# File 'lib/docker_cake/registry_api_client.rb', line 236
def manifest_sum(manifest)
size = 0
manifest["layers"].each do |layer|
size += layer["size"]
end
size
end
|
#ping ⇒ Object
108
109
110
|
# File 'lib/docker_cake/registry_api_client.rb', line 108
def ping
response = http_get('/v2/')
end
|
#search(query = '') ⇒ Object
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/docker_cake/registry_api_client.rb', line 112
def search(query = '')
response = http_get "/v2/_catalog"
repos = JSON.parse(response)["repositories"]
if query.strip.length > 0
re = Regexp.new query
repos = repos.find_all {|e| re =~ e }
end
return repos
end
|
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# File 'lib/docker_cake/registry_api_client.rb', line 123
def tags(repo, withHashes = false)
response = http_get("/v2/#{repo}/tags/list")
resp = begin
JSON.parse(response)
rescue JSON::ParserError => e
raise JsonError.new(e, response)
end
if withHashes then
useGet = false
resp["hashes"] = {}
resp["tags"].each {|tag|
if useGet then
head = http_get "/v2/#{repo}/manifests/#{tag}"
else
begin
head = http_head("/v2/#{repo}/manifests/#{tag}")
rescue InvalidMethod
useGet = true
head = http_get("/v2/#{repo}/manifests/#{tag}")
end
end
resp["hashes"][tag] = head.[:docker_content_digest]
}
end
return resp
end
|