docker-cake 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c65060c27c01fce55231395ee5ad9200948a4be7
4
- data.tar.gz: e9fc17acf691b35fbb212bb18fcd74b50d908308
3
+ metadata.gz: bb308277d72c9e12243d29048577958bcb3143fb
4
+ data.tar.gz: 0bebde5d78dddf58e42f16a86266b05fecf0f030
5
5
  SHA512:
6
- metadata.gz: da38d0dffb2c6e0eee7de50ec7f2f870e539878f67f65377da781011ad8df84985b96d6ec32e1029740e21dd2b1512985438be6fc8f9cc11b49e1c0986eee33b
7
- data.tar.gz: 31857508135384c7a536cb8ce8dc304d26d943916741827d227f81adc0cfdb069703864725230dac4d0b2f33ae7c39752ec0e124834730d5121853850d36e200
6
+ metadata.gz: 46f7c1023778cbb0d8aa626d6df4676f700d5b66ff55c0065f4f0fc2158f1efc4b3dd1410e9cb2bbd4c581e1dab80f9b1c7e72ba7c4fe0ee7f04564bcba61268
7
+ data.tar.gz: bc7334825b0e6c7c4a59ef374af115bfc76f80bc34d4bdc52fceebfba26202ec06a3e6b4525b7c8a64aebd2d19a1357a17d09408c011264608eb070968e6adac
data/docker-cake.gemspec CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |gem|
2
2
  gem.specification_version = 3
3
3
 
4
4
  gem.name = 'docker-cake'
5
- gem.version = "0.1"
5
+ gem.version = "0.2"
6
6
  gem.authors = ["Pavel Evstigneev"]
7
7
  gem.email = ["pavel.evst@gmail.com"]
8
8
  gem.license = 'MIT'
data/lib/docker_cake.rb CHANGED
@@ -7,7 +7,7 @@ class DockerCake
7
7
  attr_accessor :registry
8
8
 
9
9
  def initialize(url: nil, user: nil, password: nil)
10
- @registry ||= RegistryApiClient.new(user: user, password: password)
10
+ @registry ||= RegistryApiClient.new(user: user, password: password, url: url)
11
11
  end
12
12
 
13
13
  def repo_info(name, tag = 'latest')
@@ -17,10 +17,19 @@ class DockerCake
17
17
 
18
18
  def compare_versions(repo_name, filter: /.+/, max: 10)
19
19
  tags = registry.tags(repo_name, false)['tags']
20
+
21
+ if ENV['DEBUG']
22
+ puts "Found tags: #{tags.join(", ")}"
23
+ end
24
+
20
25
  tags.select! {|t| t =~ filter}
21
26
 
22
27
  selected_tags = tags.last(max)
23
28
 
29
+ if ENV['DEBUG']
30
+ puts "Analyzing #{selected_tags.size} tags: #{selected_tags.join(", ")}..."
31
+ end
32
+
24
33
  manifests = {}
25
34
  procs = selected_tags.map do |tag|
26
35
  lambda { manifests[tag] = registry.manifest_layers(repo_name, tag) }
@@ -1,4 +1,5 @@
1
1
  require 'optparse'
2
+ require 'socket'
2
3
  require_relative '../docker_cake'
3
4
 
4
5
  options = {}
@@ -49,13 +50,48 @@ if !repo || repo == ''
49
50
  exit(1)
50
51
  end
51
52
 
52
- connect_options = {user: options[:user], password: options[:password]}
53
- connect_options[:url] = options[:url] if options[:url]
53
+ connect_options = {
54
+ user: options[:user],
55
+ password: options[:password],
56
+ url: options[:url]
57
+ }
54
58
 
55
- if options[:layers]
56
- DockerCake.new(connect_options).repo_info(repo, tag || 'latest')
57
- else
58
- opts = {}
59
- opts[:max] = options[:max].to_i if options[:max]
60
- DockerCake.new(connect_options).compare_versions(repo, opts)
61
- end
59
+ begin
60
+ if options[:layers]
61
+ DockerCake.new(connect_options).repo_info(repo, tag || 'latest')
62
+ else
63
+ opts = {}
64
+ opts[:max] = options[:max].to_i if options[:max]
65
+ DockerCake.new(connect_options).compare_versions(repo, opts)
66
+ end
67
+ rescue RegistryApiClient::RegistryAuthenticationException => e
68
+ puts "Permission denied, make sure username and password are correct"
69
+ puts "Server response: #{e.message}"
70
+ puts "Example:"
71
+ puts " docker-cake bob/private_repo -u bob -p ***"
72
+ exit 1
73
+ rescue RegistryApiClient::HTTP::NotFound => e
74
+ if options[:layers]
75
+ puts "Repository or tag not found"
76
+ else
77
+ puts "Repository not found"
78
+ end
79
+ puts "Example:"
80
+ puts " docker-cake library/ruby"
81
+ exit 1
82
+ rescue RegistryApiClient::JsonError => error
83
+ message = error.message.size > 300 ? error.message[0..300] + "..." : error.message
84
+ puts "Error parsing JSON response: #{message} (#{(error.parent || error).class})"
85
+ body = error.response.size > 300 ? error.response[0..300] + "..." : error.response
86
+ puts "Server response body: #{body}"
87
+ if ENV['DEBUG']
88
+ headers = error.response.headers.to_a.map {|pair| pair.join(": ")}.join("\n ")
89
+ puts "Headers:\n #{headers}"
90
+ end
91
+ exit 1
92
+ rescue SocketError => e
93
+ puts "Can not connect to registery:"
94
+ puts "#{e.class}: #{e.message}"
95
+ puts e.backtrace if ENV['DEBUG']
96
+ exit 1
97
+ end
@@ -26,6 +26,16 @@ class RegistryApiClient
26
26
  class InvalidMethod < Exception
27
27
  end
28
28
 
29
+ class JsonError < Exception
30
+ attr_reader :response
31
+ attr_reader :parent
32
+ def initialize(message, response = nil)
33
+ super(message)
34
+ @parent = message if message.is_a?(Exception)
35
+ @response = response
36
+ end
37
+ end
38
+
29
39
  class Waiter
30
40
  def initialize
31
41
  @queue = Queue.new
@@ -70,6 +80,7 @@ class RegistryApiClient
70
80
  # @option options [#to_s] :user User name for basic authentication
71
81
  # @option options [#to_s] :password Password for basic authentication
72
82
  def initialize(url: DEFAULT_REGISTRY, user: nil, password: nil)
83
+ url = url || DEFAULT_REGISTRY
73
84
  @url = url
74
85
  uri = URI.parse(url)
75
86
  @base_uri = "#{uri.scheme}://#{uri.host}:#{uri.port}"
@@ -112,7 +123,11 @@ class RegistryApiClient
112
123
  def tags(repo, withHashes = false)
113
124
  response = http_get("/v2/#{repo}/tags/list")
114
125
  # parse the response
115
- resp = JSON.parse(response)
126
+ resp = begin
127
+ JSON.parse(response)
128
+ rescue JSON::ParserError => e
129
+ raise JsonError.new(e, response)
130
+ end
116
131
  # do we include the hashes?
117
132
  if withHashes then
118
133
  useGet = false
@@ -200,7 +215,9 @@ class RegistryApiClient
200
215
  end
201
216
  end
202
217
 
203
- threads.map(&:join)
218
+ threads.each do |t|
219
+ t.alive? && t.join
220
+ end
204
221
 
205
222
  if errors.size > 0
206
223
  raise errors.first
@@ -232,9 +249,9 @@ class RegistryApiClient
232
249
  else
233
250
  return req_no_auth(type, url, stream: stream, manifest: manifest)
234
251
  end
235
- rescue SocketError => e
236
- p e
237
- raise RegistryUnknownException
252
+ # rescue SocketError => e
253
+ # p e
254
+ # raise RegistryUnknownException
238
255
  rescue HTTP::Unauthorized => e
239
256
  header = e.response.headers[:www_authenticate]
240
257
  method = header.downcase.split(' ')[0]
@@ -279,11 +296,11 @@ class RegistryApiClient
279
296
  headers: {Accept: manifest || @manifest_format},
280
297
  block_response: block
281
298
  )
282
- rescue SocketError
283
- raise RegistryUnknownException
284
- rescue HTTP::Unauthorized
285
- raise RegistryAuthenticationException
286
- rescue MethodNotAllowed
299
+ # rescue SocketError
300
+ # raise RegistryUnknownException
301
+ rescue HTTP::Unauthorized => error
302
+ raise RegistryAuthenticationException.new(error)
303
+ rescue HTTP::MethodNotAllowed
287
304
  raise InvalidMethod
288
305
  end
289
306
  return response
@@ -303,11 +320,11 @@ class RegistryApiClient
303
320
  headers: {Authorization: 'Bearer ' + token, Accept: manifest || @manifest_format},
304
321
  block_response: block
305
322
  )
306
- rescue SocketError
307
- raise RegistryUnknownException
308
- rescue HTTP::Unauthorized
309
- raise RegistryAuthenticationException
310
- rescue MethodNotAllowed
323
+ # rescue SocketError
324
+ # raise RegistryUnknownException
325
+ rescue HTTP::Unauthorized => e
326
+ raise RegistryAuthenticationException.new(e)
327
+ rescue HTTP::MethodNotAllowed
311
328
  raise InvalidMethod
312
329
  end
313
330
 
@@ -324,7 +341,12 @@ class RegistryApiClient
324
341
  if AUTH_CACHE[scope].is_a?(String)
325
342
  return AUTH_CACHE[scope]
326
343
  elsif AUTH_CACHE[scope].is_a?(PubSub)
327
- return AUTH_CACHE[scope].wait
344
+ result = AUTH_CACHE[scope].wait
345
+ if result.is_a?(Exception)
346
+ raise result
347
+ else
348
+ return result
349
+ end
328
350
  else
329
351
  AUTH_CACHE[scope] = PubSub.new
330
352
  end
@@ -343,9 +365,10 @@ class RegistryApiClient
343
365
  user: @user,
344
366
  password: @password
345
367
  )
346
- rescue HTTP::Unauthorized
368
+ rescue HTTP::Unauthorized => error
347
369
  # bad authentication
348
- raise RegistryAuthenticationException
370
+ AUTH_CACHE[scope].notify(error)
371
+ raise RegistryAuthenticationException.new(error)
349
372
  end
350
373
  # now save the web token
351
374
  token = JSON.parse(response)["token"]
@@ -373,7 +396,7 @@ class RegistryApiClient
373
396
  module HTTP
374
397
  extend self
375
398
 
376
- class Unauthorized < Exception
399
+ class ResponseError < Exception
377
400
  attr_accessor :response
378
401
  def initialize(message, response)
379
402
  super(message)
@@ -381,12 +404,13 @@ class RegistryApiClient
381
404
  end
382
405
  end
383
406
 
384
- class MethodNotAllowed < Exception
385
- attr_accessor :response
386
- def initialize(message, response)
387
- super(message)
388
- @response = response
389
- end
407
+ class Unauthorized < ResponseError
408
+ end
409
+
410
+ class MethodNotAllowed < ResponseError
411
+ end
412
+
413
+ class NotFound < ResponseError
390
414
  end
391
415
 
392
416
  def execute(method:, url:, headers: {}, user: nil, password: nil, block_response: nil, body: nil, query: nil)
@@ -439,6 +463,10 @@ class RegistryApiClient
439
463
  raise MethodNotAllowed.new(http_resp.body, response)
440
464
  end
441
465
 
466
+ if http_resp.code.to_s == '404'
467
+ raise NotFound.new(http_resp.body, response)
468
+ end
469
+
442
470
  return response
443
471
  end
444
472
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-cake
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Evstigneev