dockly 3.3.0 → 4.2.0

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODI3Y2E3MmU4NzIzNGM3Y2Q5MzA5MzQ0MTU0MmM5OTA5N2VjZTc3Mg==
5
- data.tar.gz: !binary |-
6
- M2RkM2IzMjJlNzhiMGMwZTdjNGI2NDIzYTliMDEyOGRhNThkOTQ3ZQ==
2
+ SHA1:
3
+ metadata.gz: 817b3a75ce89c73e9ad40e97913c7e694f6d5d39
4
+ data.tar.gz: 7a0a50ba3a0c833f77deefda46eace5917b0b1d2
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OTBmZjQ3OWUwOTU2N2RkYjk4ODYyY2M2ZmQ2ZDM5YmUzNjhkNGUwNWUzNmQ1
10
- MWNlYmE4ZjlmZmYyMTczZDQ1MTRmODhhNjBhNjc3YzA2Nzg4NDdkODMwOWYw
11
- ZjgyOTMxZWRjZDc4YmU2YzdiZmIxZTc3Nzg1Zjg1YWI4NDVmYjc=
12
- data.tar.gz: !binary |-
13
- YTZjYjU2OTYzZDc2ZmViM2IyNmUwZTE4NzQ3ZmYyNmM4OGQwMWM1NDc4NGE3
14
- N2FjZjIzZjNiYWI4ZGNiNTJlODg3MmRjMjRjZTcxMDcyMTQwODg1OGQ4MjYz
15
- ZWI4NWQ4NDNhMmJlYTFjNDA3ODdjNGIyOTFmMjI5ZGM1ZWUwNzg=
6
+ metadata.gz: d3e29e2b40e5dede34e76d19a7635b2e8d051fc799b41961871a5fee4e2011c1616954518aef46cae0f591561452180816e786aa0a919a9b0713c9c94b6c61a3
7
+ data.tar.gz: d4f4dc7bd97cbca3071ef9099ae8150b77b826daa4ba62c999d88ddb15dd62f175523f0c802d0e949d361c933179c987cb887fe1066917a8ad10f9387ed5bbef
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 1.9.3-p547
1
+ 2.3.1
data/.travis.yml CHANGED
@@ -1,14 +1,13 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9
4
- - 2.0
5
- - 2.1
6
- - 2.2
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ - 2.3
7
7
  script:
8
8
  - git fetch --tags
9
9
  - CI=true bundle exec rake
10
10
  before_install:
11
11
  - sudo apt-get update -qq
12
12
  - sudo apt-get install -qq rpm
13
- - gem install bundler
14
-
13
+ - gem install bundler -v 1.17.3
data/README.md CHANGED
@@ -174,6 +174,11 @@ In addition to the above attributes, `docker` has the following references:
174
174
  - allows one
175
175
  - class: `Dockly::Docker::Registry`
176
176
  - description: a registry to push to in lieu of exporting as a tar -- the registry will be automatically pulled upon installing the package
177
+ - `ecr`
178
+ - required: `false`
179
+ - allows one
180
+ - class: `Dockly::Docker::ECR`
181
+ - description: an AWS ECR Docker registry to push to in lieu of exporting as a tar -- the registry will be automatically pulled upon installing the package
177
182
 
178
183
  Need finer control of Docker packages? We also wrote [docker-api](https://github.com/swipely/docker-api).
179
184
 
@@ -200,6 +205,23 @@ The `registry` DSL is used to define Docker Registries. It has the following att
200
205
  - default: `https://index.docker.io/v1`
201
206
  - description: the server where the registry lives
202
207
 
208
+ `ecr`
209
+ --------
210
+
211
+ The `ecr` DSL is used to define AWS ECR Docker registries. It has the following attributes:
212
+
213
+ - `server_address`
214
+ - required: `true`
215
+ - description: the server where the registry lives without the repo name, eg `accountid.dkr.ecr.region.amazonaws.com`
216
+ - `username`
217
+ - required: `false`
218
+ - default: pulled from auth data obtained using assumed role's credentials
219
+ - description: the username to authenticate
220
+ - `password`
221
+ - required: `false`
222
+ - default: pulled from auth data obtained using assumed role's credentials
223
+ - description: the password to authenticate
224
+
203
225
  `foreman`
204
226
  ---------
205
227
 
data/dockly.gemspec CHANGED
@@ -18,14 +18,17 @@ Gem::Specification.new do |gem|
18
18
  gem.add_dependency 'docker-api', '>= 1.14.0'
19
19
  gem.add_dependency 'dockly-util', '>= 0.0.9', '< 1.0'
20
20
  gem.add_dependency 'excon'
21
- gem.add_dependency 'aws-sdk', '~> 2.0'
21
+ gem.add_dependency 'aws-sdk-core', '~> 3'
22
+ gem.add_dependency 'aws-sdk-s3', '~> 1'
23
+ gem.add_dependency 'aws-sdk-ecr', '~> 1'
22
24
  gem.add_dependency 'foreman'
23
25
  gem.add_dependency 'fpm', '~> 1.2.0'
24
26
  gem.add_dependency 'minigit', '~> 0.0.4'
25
27
  gem.add_development_dependency 'cane'
26
28
  gem.add_development_dependency 'pry'
27
- gem.add_development_dependency 'rake'
29
+ gem.add_development_dependency 'rake', '< 11.0'
28
30
  gem.add_development_dependency 'rspec', '~> 2.14.1'
29
31
  gem.add_development_dependency 'vcr'
30
- gem.add_development_dependency 'webmock'
32
+ gem.add_development_dependency 'webmock', '<= 1.18.0'
33
+ gem.add_development_dependency 'addressable', '<= 2.3.6'
31
34
  end
data/lib/dockly.rb CHANGED
@@ -4,7 +4,9 @@ require 'dockly/util/git'
4
4
  require 'foreman/cli_fix'
5
5
  require 'foreman/export/base_fix'
6
6
  require 'minigit'
7
- require 'aws-sdk'
7
+ require 'aws-sdk-core'
8
+ require 'aws-sdk-s3'
9
+ require 'aws-sdk-ecr'
8
10
  require 'open3'
9
11
 
10
12
  module Dockly
@@ -24,7 +24,8 @@ module Dockly
24
24
  generate_snippet_for :s3_docker_import, [:s3_url, :repo, :tag]
25
25
  generate_snippet_for :s3_diff_docker_import, [:base_image, :diff_image, :repo, :tag]
26
26
  generate_snippet_for :registry_import, [:repo, :tag], { :tag => "latest" }
27
+ generate_snippet_for :auth_ecr, [:server_address]
27
28
 
28
- generate_snippet_for :docker_tag_latest, [:repo, :tag]
29
+ generate_snippet_for :docker_tag_latest, [:repo, :tag, :new_name]
29
30
  end
30
31
  end
@@ -77,7 +77,7 @@ class Dockly::BuildCache::Docker < Dockly::BuildCache::Base
77
77
  debug 'Restarting the container to copy the cache\'s output'
78
78
  # Restart the container so we can copy its output
79
79
  container = container.commit.run('sleep 3600')
80
- container.copy(output_directory) { |chunk| file.write(chunk.to_s) }
80
+ container.archive_out(output_directory) { |chunk| file.write(chunk.to_s) }
81
81
  container.kill
82
82
  file.tap(&:rewind)
83
83
  end
data/lib/dockly/deb.rb CHANGED
@@ -77,7 +77,6 @@ class Dockly::Deb
77
77
  end
78
78
 
79
79
  def upload_to_s3
80
- info "uploading to s3"
81
80
  return if s3_bucket.nil?
82
81
  raise "Package wasn't created!" unless File.exist?(build_path)
83
82
  info "uploading package to s3"
@@ -126,7 +125,14 @@ private
126
125
  add_files(@dir_package)
127
126
  add_docker_auth_config(@dir_package)
128
127
  add_docker(@dir_package)
129
- add_startup_script(@dir_package) if package_startup_script
128
+
129
+ if package_startup_script.is_a?(String)
130
+ raise ArgumentError,
131
+ 'package_startup_script filename must not be empty if specified' if package_startup_script.empty?
132
+ add_startup_script(@dir_package, package_startup_script)
133
+ elsif package_startup_script
134
+ add_startup_script(@dir_package)
135
+ end
130
136
 
131
137
  convert_package
132
138
 
@@ -174,7 +180,7 @@ private
174
180
  end
175
181
 
176
182
  def add_docker_auth_config(package)
177
- return if (registry = get_registry).nil? || !registry.authentication_required?
183
+ return if (registry = get_registry).nil? || !should_auth?(registry)
178
184
  info "adding docker config file"
179
185
  registry.generate_config_file!
180
186
 
@@ -185,11 +191,18 @@ private
185
191
  package.attributes[:prefix] = nil
186
192
  end
187
193
 
194
+ def should_auth?(registry)
195
+ registry.is_a?(Dockly::Docker::Registry) &&
196
+ registry.authentication_required?
197
+ end
198
+
188
199
  def add_docker(package)
189
200
  return if docker.nil? || docker.s3_bucket
190
201
  info "adding docker image"
191
202
  docker.generate!
192
- return unless docker.registry.nil?
203
+
204
+ return if get_registry
205
+
193
206
  package.attributes[:prefix] = docker.package_dir
194
207
  Dir.chdir(File.dirname(docker.tar_path)) do
195
208
  package.input(File.basename(docker.tar_path))
@@ -198,7 +211,7 @@ private
198
211
  end
199
212
 
200
213
  def get_registry
201
- if docker && registry = docker.registry
214
+ if docker && (registry = docker.registry)
202
215
  registry
203
216
  end
204
217
  end
@@ -207,38 +220,53 @@ private
207
220
  scripts = ["#!/bin/bash"]
208
221
  bb = Dockly::BashBuilder.new
209
222
  scripts << bb.normalize_for_dockly
210
- if get_registry
211
- scripts << bb.registry_import(docker.repo, docker.tag)
212
- elsif docker
213
- if docker.s3_bucket.nil?
214
- docker_output = File.join(docker.package_dir, docker.export_filename)
215
- if docker.tar_diff
216
- scripts << bb.file_diff_docker_import(docker.import, docker_output, docker.name, docker.tag)
217
- else
218
- scripts << bb.file_docker_import(docker_output, docker.name, docker.tag)
223
+
224
+ if docker
225
+ if (registry = docker.registry)
226
+ if registry.is_a?(Dockly::Docker::ECR)
227
+ scripts << bb.auth_ecr(registry.server_address)
219
228
  end
229
+
230
+ scripts << bb.registry_import(docker.repo, docker.tag)
231
+ scripts << bb.docker_tag_latest(docker.repo, docker.tag, docker.name)
220
232
  else
221
- if docker.tar_diff
222
- scripts << bb.s3_diff_docker_import(docker.import, docker.s3_url, docker.name, docker.tag)
223
- else
224
- scripts << bb.s3_docker_import(docker.s3_url, docker.name, docker.tag)
225
- end
233
+ scripts += collect_non_registry_scripts(bb)
226
234
  end
227
- scripts << bb.docker_tag_latest(docker.repo, docker.tag)
228
235
  end
229
236
  scripts.join("\n")
230
237
  end
231
238
 
232
- def add_startup_script(package)
239
+ def collect_non_registry_scripts(bb)
240
+ scripts = []
241
+
242
+ if docker.s3_bucket.nil?
243
+ docker_output = File.join(docker.package_dir, docker.export_filename)
244
+ if docker.tar_diff
245
+ scripts << bb.file_diff_docker_import(docker.import, docker_output, docker.name, docker.tag)
246
+ else
247
+ scripts << bb.file_docker_import(docker_output, docker.name, docker.tag)
248
+ end
249
+ else
250
+ if docker.tar_diff
251
+ scripts << bb.s3_diff_docker_import(docker.import, docker.s3_url, docker.name, docker.tag)
252
+ else
253
+ scripts << bb.s3_docker_import(docker.s3_url, docker.name, docker.tag)
254
+ end
255
+ end
256
+
257
+ scripts << bb.docker_tag_latest(docker.repo, docker.tag, docker.repo)
258
+ end
259
+
260
+ def add_startup_script(package, startup_script = "dockly-startup.sh")
233
261
  ensure_present! :build_dir
234
- startup_script_path = File.join(build_dir, "dockly-startup.sh")
262
+ startup_script_path = File.join(build_dir, startup_script)
235
263
  File.open(startup_script_path, 'w+') do |f|
236
264
  f.write(post_startup_script)
237
265
  f.chmod(0755)
238
266
  end
239
267
  package.attributes[:prefix] = "/opt/dockly"
240
268
  Dir.chdir(build_dir) do
241
- package.input("dockly-startup.sh")
269
+ package.input(startup_script)
242
270
  end
243
271
  package.attributes[:prefix] = nil
244
272
  end
data/lib/dockly/docker.rb CHANGED
@@ -10,11 +10,13 @@ class Dockly::Docker
10
10
  include Dockly::Util::Logger::Mixin
11
11
 
12
12
  autoload :Registry, 'dockly/docker/registry'
13
+ autoload :ECR, 'dockly/docker/ecr'
13
14
 
14
15
  logger_prefix '[dockly docker]'
15
16
 
16
17
  dsl_class_attribute :build_cache, Dockly::BuildCache.model, type: Array
17
- dsl_class_attribute :registry, Dockly::Docker::Registry
18
+ dsl_class_attribute :docker_registry, Dockly::Docker::Registry
19
+ dsl_class_attribute :ecr, Dockly::Docker::ECR
18
20
 
19
21
  dsl_attribute :name, :import, :git_archive, :build, :tag, :build_dir, :package_dir,
20
22
  :timeout, :cleanup_images, :tar_diff, :s3_bucket, :s3_object_prefix
@@ -32,6 +34,10 @@ class Dockly::Docker
32
34
  (@build_env ||= {}).tap { |env| env.merge!(hash) if hash.is_a?(Hash) }
33
35
  end
34
36
 
37
+ def registry
38
+ ecr || docker_registry
39
+ end
40
+
35
41
  def copy_from_s3(sha)
36
42
  return if s3_bucket.nil?
37
43
  object = s3_object_for(sha)
@@ -177,7 +183,9 @@ class Dockly::Docker
177
183
  repo = "#{name}-base"
178
184
  tag = "dockly-#{Dockly::VERSION}-#{File.basename(import).split('.').first}"
179
185
  info "looking for imported base image with tag: #{tag}"
180
- image = Docker::Image.all.find { |img| img.info['RepoTags'].include?("#{repo}:#{tag}") }
186
+ image = Docker::Image.all.find do |img|
187
+ img.info['RepoTags'] && img.info['RepoTags'].include?("#{repo}:#{tag}")
188
+ end
181
189
  if image
182
190
  info "found imported base image: #{image.id}"
183
191
  image
@@ -316,14 +324,26 @@ class Dockly::Docker
316
324
  end
317
325
 
318
326
  def push_to_registry(image)
319
- ensure_present! :registry
327
+ raise "No registry to push to" if registry.nil?
328
+
320
329
  info "Exporting #{image.id} to Docker registry at #{registry.server_address}"
330
+
321
331
  registry.authenticate!
322
- image = Docker::Image.all(:all => true).find { |img|
323
- img.id.start_with?(image.id) || image.id.start_with?(img.id)
324
- }
332
+
333
+ image =
334
+ Docker::Image
335
+ .all(:all => true)
336
+ .find do |img|
337
+ img.id.include?(image.id) || image.id.include?(img.id)
338
+ end
339
+
325
340
  raise "Could not find image after authentication" if image.nil?
326
- image.push(registry.to_h, :registry => registry.server_address)
341
+
342
+ image.push(registry.to_h, :registry => registry.server_address) do |resp|
343
+ if resp.include?('errorDetail')
344
+ raise "Error pushing to registry: #{resp}"
345
+ end
346
+ end
327
347
  end
328
348
 
329
349
  def fetch_import
@@ -0,0 +1,60 @@
1
+ class Dockly::Docker::ECR
2
+ include Dockly::Util::DSL
3
+ include Dockly::Util::Logger::Mixin
4
+
5
+ logger_prefix '[dockly docker ecr]'
6
+
7
+ dsl_attribute :name, :server_address, :password, :username
8
+
9
+ def authenticate!
10
+ @username ||= login_from_aws[0]
11
+ @password ||= login_from_aws[1]
12
+
13
+ ensure_present! :password, :server_address, :username
14
+
15
+ debug "Attempting to authenticate at #{server_address}"
16
+
17
+ ::Docker.authenticate!(self.to_h)
18
+
19
+ info "Successfully authenticated at #{server_address}"
20
+ rescue ::Docker::Error::AuthenticationError
21
+ raise "Could not authenticate at #{server_address}"
22
+ end
23
+
24
+ def authentication_required?
25
+ true
26
+ end
27
+
28
+ def default_server_address?
29
+ false
30
+ end
31
+
32
+ def login_from_aws
33
+ @login_from_aws ||=
34
+ Base64
35
+ .decode64(auth_data.authorization_token)
36
+ .split(':')
37
+ end
38
+
39
+ def auth_data
40
+ @auth_data ||=
41
+ client
42
+ .get_authorization_token
43
+ .authorization_data
44
+ .first
45
+ end
46
+
47
+ def client
48
+ @client ||= Aws::ECR::Client.new(region: 'us-east-1')
49
+ end
50
+
51
+ def to_h
52
+ ensure_present! :username, :password, :server_address
53
+
54
+ {
55
+ 'serveraddress' => "https://#{server_address}",
56
+ 'username' => username,
57
+ 'password' => password
58
+ }
59
+ end
60
+ end
@@ -1,6 +1,6 @@
1
1
  module Dockly
2
- MAJOR = 3
3
- MINOR = 3
2
+ MAJOR = 4
3
+ MINOR = 2
4
4
  PATCH = 0
5
5
  RELEASE = nil
6
6
 
@@ -0,0 +1,11 @@
1
+ auth_ecr() {
2
+ $(aws ecr get-login --region us-east-1 --no-include-email)
3
+ }
4
+
5
+ worked=1
6
+ for attempt in {1..10}; do
7
+ [[ $worked != 0 ]] || break
8
+ auth_ecr && worked=0 || (log "ecr auth: attempt $attempt failed, sleeping 30"; sleep 30)
9
+ done
10
+ [[ $worked != 0 ]] && fatal "failed to auth to ecr"
11
+ log "ecr auth: successfully authenticated"
@@ -1,3 +1,3 @@
1
1
  <% if data[:tag] %>
2
- docker tag <%= data[:repo] %>:<%= data[:tag] %> <%= data[:repo] %>:latest
2
+ docker tag <%= data[:repo] %>:<%= data[:tag] %> <%= data[:new_name] %>:latest
3
3
  <% end %>
@@ -32,8 +32,8 @@ describe Dockly::BashBuilder do
32
32
 
33
33
  context "when there is a tag" do
34
34
  it "tags the repo:tag as repo:latest" do
35
- output = subject.docker_tag_latest("test_repo", "a_tag")
36
- expect(output).to include("docker tag test_repo:a_tag test_repo:latest")
35
+ output = subject.docker_tag_latest("registry/test_repo", "a_tag", "test_repo")
36
+ expect(output).to include("docker tag registry/test_repo:a_tag test_repo:latest")
37
37
  end
38
38
  end
39
39
  end
@@ -14,8 +14,11 @@ describe Dockly::BuildCache::Base do
14
14
  describe '#up_to_date?' do
15
15
  context 'when the object exists in s3' do
16
16
  before do
17
- allow(subject.connection)
18
- .to receive(:head_object)
17
+ allow(Dockly)
18
+ .to receive(:s3)
19
+ .and_return(
20
+ Aws::S3::Client.new(stub_responses: true)
21
+ )
19
22
  end
20
23
 
21
24
  its(:up_to_date?) { should be_true }
@@ -23,9 +26,13 @@ describe Dockly::BuildCache::Base do
23
26
 
24
27
  context 'when the object does not exist in s3' do
25
28
  before do
26
- allow(subject.connection)
27
- .to receive(:head_object)
28
- .and_raise(Aws::S3::Errors::NoSuchKey.new('Some Error', 500))
29
+ allow(Dockly)
30
+ .to receive(:s3)
31
+ .and_return(
32
+ Aws::S3::Client.new(
33
+ stub_responses: { :head_object => 'NoSuchKey' }
34
+ )
35
+ )
29
36
  end
30
37
 
31
38
  its(:up_to_date?) { should be_false }
@@ -37,9 +44,12 @@ describe Dockly::BuildCache::Base do
37
44
  let(:object) { double(:object) }
38
45
 
39
46
  before do
40
- allow(subject.connection)
41
- .to receive(:get_object)
42
- .and_return(object)
47
+ allow(Dockly)
48
+ .to receive(:s3)
49
+ .and_return(Aws::S3::Client.new(
50
+ stub_responses: { :get_object => object }
51
+ ))
52
+
43
53
  allow(object)
44
54
  .to receive(:body)
45
55
  .and_return(StringIO.new('hey dad').tap(&:rewind))