awful 0.0.127 → 0.0.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/awful/ecr.rb +96 -14
  3. data/lib/awful/version.rb +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c8364b35aadf90541c75aa587ccc009496834dd
4
- data.tar.gz: b63549108ca09ddfbf654044a35d2e004446c6e0
3
+ metadata.gz: a0da7e8c9d19b6ce0b6188f1e1c32c81c9c75eaa
4
+ data.tar.gz: 97a8e87f2f1e5e83e1e1d5ec3e1c8fae26a83727
5
5
  SHA512:
6
- metadata.gz: a2d583981434a5e4f75ec1591f7b64ef52af6a9717fb263879056e585dc42d96976d851968213fea0030d49b15b90b6dc52636b13415fd41feef3849108dcdd7
7
- data.tar.gz: fcd76c096089ccabd2bbf9791ffba0cd023c2110a3eece41b2eeb06aaf56e4ee4dbb643a786548e0cb1e6ea33cc10cfeae45e0482d0d15d1370ee0115c36f263
6
+ metadata.gz: 135c8ae7944cdd637c553000d5997e282b682c8b65db6d45f940d12a9c1c7b582868f789126e1cd704113ea8f7ed5c9d890ef081ed0fb4a46935a4b209bd1ff6
7
+ data.tar.gz: 8360d46cd3a3ab4caac731d72a289b4811063727ed689bd474f7bef4e78b52fada39af9b80d0bac6efa675a5061231540f47d16cacb9249f918b24fb3eb49083
@@ -12,12 +12,24 @@ module Awful
12
12
  def ecr
13
13
  @ecr ||= Aws::ECR::Client.new
14
14
  end
15
+
16
+ ## get array of image_tag hashes in form expected by get methods
17
+ def image_tags(*tags)
18
+ tags.map do |tag|
19
+ {image_tag: tag}
20
+ end
21
+ end
22
+
23
+ ## parse created date from manifest of Aws::ECR::Types::Image object
24
+ def parse_created(image)
25
+ JSON.parse(JSON.parse(image.image_manifest)['history'].first['v1Compatibility'])['created']
26
+ end
15
27
  end
16
28
 
17
29
  desc 'ls', 'list commands'
18
30
  method_option :long, aliases: '-l', type: :boolean, default: false, desc: 'Long listing'
19
31
  def ls
20
- ecr.describe_repositories.repositories.tap do |repos|
32
+ ecr.describe_repositories.repositories.output do |repos|
21
33
  if options[:long]
22
34
  print_table repos.map { |r| [r.repository_name, r.registry_id, r.repository_arn] }
23
35
  else
@@ -29,7 +41,7 @@ module Awful
29
41
  desc 'dump [REPOS]', 'describe given or all repositories as yaml'
30
42
  def dump(*repos)
31
43
  repos = nil if repos.empty? # omit this arg to show all repos
32
- ecr.describe_repositories(repository_names: repos).repositories.tap do |list|
44
+ ecr.describe_repositories(repository_names: repos).repositories.output do |list|
33
45
  list.each do |repo|
34
46
  puts YAML.dump(stringify_keys(repo.to_h))
35
47
  end
@@ -52,7 +64,7 @@ module Awful
52
64
  desc 'auth [REGISTRIES]', 'dump authorization details for registries (or default)'
53
65
  def auth(*registries)
54
66
  registries = nil if registries.empty?
55
- ecr.get_authorization_token(registry_ids: registries).authorization_data.tap do |auths|
67
+ ecr.get_authorization_token(registry_ids: registries).authorization_data.output do |auths|
56
68
  auths.each do |auth|
57
69
  puts YAML.dump(stringify_keys(auth.to_h))
58
70
  end
@@ -65,7 +77,7 @@ module Awful
65
77
  def login(*registries)
66
78
  cmd = options[:print] ? :puts : :system
67
79
  registries = nil if registries.empty?
68
- ecr.get_authorization_token(registry_ids: registries).authorization_data.tap do |auths|
80
+ ecr.get_authorization_token(registry_ids: registries).authorization_data.output do |auths|
69
81
  auths.each do |auth|
70
82
  user, pass = Base64.decode64(auth.authorization_token).split(':')
71
83
  send(cmd, "docker login -u #{user} -p #{pass} -e #{options[:email]} #{auth.proxy_endpoint}")
@@ -75,32 +87,102 @@ module Awful
75
87
 
76
88
  desc 'images REPO', 'list images for repo'
77
89
  method_option :long, aliases: '-l', type: :boolean, default: false, desc: 'Long listing'
78
- def images(repository)
79
- ecr.list_images(repository_name: repository).image_ids.tap do |images|
90
+ def images(repository, token: nil)
91
+ next_token = token
92
+ images = []
93
+ loop do
94
+ response = ecr.list_images(repository_name: repository, next_token: next_token)
95
+ images = images + response.image_ids
96
+ next_token = response.next_token
97
+ break unless next_token
98
+ end
99
+
100
+ images.output do |list|
80
101
  if options[:long]
81
- print_table images.map { |i| [i.image_tag, i.image_digest] }
102
+ print_table list.map { |i|
103
+ [i.image_tag, i.image_digest]
104
+ }
82
105
  else
83
- puts images.map(&:image_tag)
106
+ puts list.map(&:image_tag)
84
107
  end
85
108
  end
86
109
  end
87
110
 
88
111
  desc 'get REPO TAG[S]', 'get image details for all given TAGS'
89
112
  def get(repository, *tags)
90
- ids = tags.map do |tag|
91
- {image_tag: tag}
92
- end
93
- ecr.batch_get_image(repository_name: repository, image_ids: ids).images.tap do |imgs|
113
+ ecr.batch_get_image(repository_name: repository, image_ids: image_tags(*tags)).images.output do |imgs|
94
114
  imgs.each do |img|
95
115
  puts YAML.dump(stringify_keys(img.to_h))
96
116
  end
97
117
  end
98
118
  end
99
119
 
120
+ desc 'inspect REPO TAGS', 'get first history element from manifest'
121
+ def inspect(repository, *tags)
122
+ ecr.batch_get_image(repository_name: repository, image_ids: image_tags(*tags)).images.output do |imgs|
123
+ imgs.map do |img|
124
+ JSON.parse(JSON.parse(img.image_manifest)['history'].first['v1Compatibility'])
125
+ end.output do |list|
126
+ puts YAML.dump(list)
127
+ end
128
+ end
129
+ end
130
+
131
+ desc 'date REPO TAGS', 'get created date for given tags'
132
+ def date(repository, *tags)
133
+ ecr.batch_get_image(repository_name: repository, image_ids: image_tags(*tags)).images.output do |imgs|
134
+ imgs.map do |img|
135
+ parse_created(img)
136
+ end.output do |dates|
137
+ puts dates
138
+ end
139
+ end
140
+ end
141
+
100
142
  desc 'exists REPO TAG', 'test if repo with given tag exists in registry'
101
143
  def exists(repository, tag)
102
- imgs = ecr.batch_get_image(repository_name: repository, image_ids: [{image_tag: tag}]).images
103
- (imgs.empty? ? false : true).tap(&method(:puts))
144
+ imgs = ecr.batch_get_image(repository_name: repository, image_ids: image_tags(tag)).images
145
+ (imgs.empty? ? false : true).output(&method(:puts))
146
+ end
147
+
148
+ desc 'reap REPO', 'reap old images for repo'
149
+ method_option :batch, aliases: '-b', type: :numeric, default: 10, desc: 'batch size to get and delete'
150
+ method_option :dry_run, aliases: '-d', type: :boolean, default: false, desc: 'dry run, do not delete, implies verbose'
151
+ method_option :verbose, aliases: '-v', type: :boolean, default: false, desc: 'print images to be deleted'
152
+ def reap(repository, days, token: nil)
153
+ verbose = options[:verbose] || options[:dry_run]
154
+ next_token = token
155
+ now = Time.now.utc
156
+
157
+ deleted = failures = 0
158
+ loop do
159
+ ## get a batch of image ids
160
+ response = ecr.list_images(repository_name: repository, next_token: next_token, max_results: options[:batch])
161
+
162
+ ## get details for the batch of images and calculate age
163
+ old_images = ecr.batch_get_image(repository_name: repository, image_ids: response.image_ids).images.select do |image|
164
+ date = Time.parse(parse_created(image)).utc
165
+ age = ((now - date)/(24*60*60)).to_i
166
+ if age > days.to_i
167
+ puts "#{date} #{age} #{image.image_id.image_tag}" if verbose
168
+ true
169
+ else
170
+ false
171
+ end
172
+ end
173
+
174
+ ## delete old images
175
+ unless options[:dry_run] || old_images.empty?
176
+ r = ecr.batch_delete_image(repository_name: repository, image_ids: old_images.map(&:image_id))
177
+ deleted += r.image_ids.count
178
+ failures += r.failures.count
179
+ end
180
+
181
+ next_token = response.next_token
182
+ break unless next_token
183
+ end
184
+
185
+ puts "deleted: #{deleted}, failures: #{failures}"
104
186
  end
105
187
  end
106
188
  end
@@ -1,3 +1,3 @@
1
1
  module Awful
2
- VERSION = '0.0.127'
2
+ VERSION = '0.0.128'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.127
4
+ version: 0.0.128
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ric Lister
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-12 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler