dry-dock 0.1.6 → 0.2.0

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: 2627cbab1b9589543ec9a8997d95eb6071ecd17a
4
- data.tar.gz: 6fe87f56623532901d4fb285a8cc07a584007cb0
3
+ metadata.gz: 724b93603dd12d8266b970fcfd095031882aa55e
4
+ data.tar.gz: e98e3ac6436a74e1d550742856b9b6cd5ff524f5
5
5
  SHA512:
6
- metadata.gz: f4360c64a1b7d07b36ef1e6e79fc6fb65d73b14ecea226be78bc75819f0fe77b7fbe4f24b0572bfcb4d84900167f442f1709d332d6d5f71cee5b6d66660e5495
7
- data.tar.gz: b28fa39b7acbe2e4044b7f75748d314b198f9f90b9da2098bb96552c5495da6548a9daf53080cc672984368464ac343d1124892443587cb5c879bcf975a7b16d
6
+ metadata.gz: 445f04f2533c11dc3bce10be0f137919a898eca7bf67be0c70a754bd5c1a48d7ff5aab63d6b7032613a77ef183364d2e615d00538535786f431ef57d012d8914
7
+ data.tar.gz: c7d058056ed5273ba4dc1aca588b2783ae5c5476cb6ed7443957579aa87e6d67a58b8203d500993de2a423d95e3e838d4c0fe7c9ee4b24cfb38a6a4d40f5992c
@@ -0,0 +1 @@
1
+ 2.2.3
@@ -3,13 +3,12 @@ services:
3
3
  - docker
4
4
  language: ruby
5
5
  rvm:
6
- - 2.1.5
6
+ - 2.2.3
7
7
  before_install:
8
- - sudo service docker stop
9
- - sudo apt-get purge lxc-docker-1.7.0
10
- - curl -sSL https://get.docker.com/ | sudo sh
11
8
  - docker version
12
9
  - docker info
10
+ - docker pull alpine:latest
11
+ - docker pull alpine:3.2
13
12
  script: bundle exec rspec
14
13
  addons:
15
14
  code_climate:
data/Gemfile CHANGED
@@ -19,6 +19,6 @@ group :test do
19
19
  end
20
20
 
21
21
  gem 'attr_extras', '~> 4.4'
22
- gem 'docker-api', '~> 1.22', require: 'docker'
22
+ gem 'docker-api', '~> 1.24', require: 'docker'
23
23
  gem 'excon', '~> 0.45'
24
24
  gem 'memoist', '~> 0.12'
@@ -14,7 +14,7 @@ GEM
14
14
  thread_safe (~> 0.3, >= 0.3.1)
15
15
  diff-lcs (1.2.5)
16
16
  docile (1.1.5)
17
- docker-api (1.22.4)
17
+ docker-api (1.24.1)
18
18
  excon (>= 0.38.0)
19
19
  json
20
20
  excon (0.45.4)
@@ -107,7 +107,7 @@ PLATFORMS
107
107
  DEPENDENCIES
108
108
  attr_extras (~> 4.4)
109
109
  codeclimate-test-reporter
110
- docker-api (~> 1.22)
110
+ docker-api (~> 1.24)
111
111
  excon (~> 0.45)
112
112
  fakefs
113
113
  jeweler (~> 2.0)
@@ -121,4 +121,4 @@ DEPENDENCIES
121
121
  simplecov-rcov (~> 0.2)
122
122
 
123
123
  BUNDLED WITH
124
- 1.10.5
124
+ 1.10.6
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # drydock
2
2
 
3
- WORK IN PROGRESS ALPHA-RELEASE SOFTWARE
4
- SOME FEATURES REQUIRE DOCKER 1.8.0 OR NEWER
3
+ **WARNING:** Work in progress. Although this software has test coverage, it is
4
+ considered unstable. Refer to [LICENSE](LICENSE.md) for licensing information.
5
+
6
+ See section on [Compatibility](#compatibility) for a list of supported Docker
7
+ versions for every Drydock version.
5
8
 
6
9
  [![Automated Build Status](https://travis-ci.org/ripta/drydock.svg)](https://travis-ci.org/ripta/drydock)
7
10
  [![Code Climate](https://codeclimate.com/github/ripta/drydock/badges/gpa.svg)](https://codeclimate.com/github/ripta/drydock)
@@ -100,6 +103,16 @@ branch, make your changes, commit, and open a pull request.
100
103
  After cloning your repo, `bundle` should take care of it.
101
104
 
102
105
 
106
+ ## Release
107
+
108
+ ```
109
+ $ bundle
110
+ $ # increment VERSION file
111
+ $ bundle exec rake gemspec build
112
+ $ # upload .gem file to rubygems.org
113
+ ```
114
+
115
+
103
116
  ## Roadmap
104
117
 
105
118
  1. Customizable caching subsystem with pluggable caching strategies.
@@ -107,3 +120,13 @@ After cloning your repo, `bundle` should take care of it.
107
120
  3. Unarchiving a file directly into a container.
108
121
  4. Proper `ONBUILD` implementation and expanded support for hooks.
109
122
  5. Drydock instructions corresponding to `LABEL`, `VOLUME`, `USER`, and `WORKDIR` Docker instructions.
123
+
124
+
125
+ ## Compatibility
126
+
127
+ The following version combinations are officially tested and supported:
128
+
129
+ | Docker Versions | Drydock Versions |
130
+ | --------------- | ---------------- |
131
+ | v1.8.0 | v0.1.0 onwards |
132
+ | v1.9.0 | v0.2.0 onwards |
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.2.0
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: dry-dock 0.1.6 ruby lib
5
+ # stub: dry-dock 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "dry-dock"
9
- s.version = "0.1.6"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Ripta Pasay"]
14
- s.date = "2015-10-08"
14
+ s.date = "2016-01-08"
15
15
  s.description = "A Dockerfile-replacement DSL for building complex images"
16
16
  s.email = "github@r8y.org"
17
17
  s.executables = ["drydock", "json-test-consumer.rb", "json-test-producer.rb", "test-tar-writer-digest.rb"]
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  ".pryrc",
26
26
  ".rspec",
27
27
  ".rubocop.yml",
28
+ ".ruby-version",
28
29
  ".travis.yml",
29
30
  ".yardopts",
30
31
  "Dockerfile",
@@ -105,7 +106,7 @@ Gem::Specification.new do |s|
105
106
  ]
106
107
  s.homepage = "http://github.com/ripta/drydock"
107
108
  s.licenses = ["MIT"]
108
- s.rubygems_version = "2.2.2"
109
+ s.rubygems_version = "2.4.5.1"
109
110
  s.summary = "Docker Image Pipeline DSL"
110
111
 
111
112
  if s.respond_to? :specification_version then
@@ -113,7 +114,7 @@ Gem::Specification.new do |s|
113
114
 
114
115
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
115
116
  s.add_runtime_dependency(%q<attr_extras>, ["~> 4.4"])
116
- s.add_runtime_dependency(%q<docker-api>, ["~> 1.22"])
117
+ s.add_runtime_dependency(%q<docker-api>, ["~> 1.24"])
117
118
  s.add_runtime_dependency(%q<excon>, ["~> 0.45"])
118
119
  s.add_runtime_dependency(%q<memoist>, ["~> 0.12"])
119
120
  s.add_development_dependency(%q<rake>, ["~> 10.0"])
@@ -124,7 +125,7 @@ Gem::Specification.new do |s|
124
125
  s.add_development_dependency(%q<simplecov-rcov>, ["~> 0.2"])
125
126
  else
126
127
  s.add_dependency(%q<attr_extras>, ["~> 4.4"])
127
- s.add_dependency(%q<docker-api>, ["~> 1.22"])
128
+ s.add_dependency(%q<docker-api>, ["~> 1.24"])
128
129
  s.add_dependency(%q<excon>, ["~> 0.45"])
129
130
  s.add_dependency(%q<memoist>, ["~> 0.12"])
130
131
  s.add_dependency(%q<rake>, ["~> 10.0"])
@@ -136,7 +137,7 @@ Gem::Specification.new do |s|
136
137
  end
137
138
  else
138
139
  s.add_dependency(%q<attr_extras>, ["~> 4.4"])
139
- s.add_dependency(%q<docker-api>, ["~> 1.22"])
140
+ s.add_dependency(%q<docker-api>, ["~> 1.24"])
140
141
  s.add_dependency(%q<excon>, ["~> 0.45"])
141
142
  s.add_dependency(%q<memoist>, ["~> 0.12"])
142
143
  s.add_dependency(%q<rake>, ["~> 10.0"])
@@ -32,6 +32,7 @@ module Drydock
32
32
  end
33
33
 
34
34
  # Logic taken from https://github.com/docker/docker/blob/master/runconfig/compare.go
35
+ # Last updated to conform to docker v1.9.1
35
36
  def ==(other)
36
37
  return false if other.nil?
37
38
 
@@ -44,7 +45,7 @@ module Drydock
44
45
 
45
46
  return false if self['Cmd'] != other['Cmd']
46
47
  return false if Array(self['Env']).sort != Array(other['Env']).sort
47
- return false if self['Labels'] != other['Labels']
48
+ return false if (self['Labels'] || {}) != (other['Labels'] || {})
48
49
  return false if self['Entrypoint'] != other['Entrypoint']
49
50
 
50
51
  my_ports = self['ExposedPorts'] || {}
@@ -41,7 +41,7 @@ module Drydock
41
41
  end
42
42
 
43
43
  def self.select_by_config(config)
44
- # we want to look at 'ContainerConfig', because we're interesting in how
44
+ # Look at 'ContainerConfig' instead of 'Config', because we're interesting in how
45
45
  # the image was built, not how the image will run
46
46
  self.select { |image| config == ContainerConfig.from(image.info['ContainerConfig']) }
47
47
  end
@@ -20,6 +20,11 @@ module Drydock
20
20
  new(*h.values_at(*members))
21
21
  end
22
22
 
23
+ def initialize(*args)
24
+ super
25
+ @finalized = false
26
+ end
27
+
23
28
  def built?
24
29
  !cached?
25
30
  end
@@ -29,6 +34,10 @@ module Drydock
29
34
  end
30
35
 
31
36
  def destroy!(force: false)
37
+ return self if frozen?
38
+
39
+ finalize!(force: force)
40
+
32
41
  if result_image
33
42
  begin
34
43
  result_image.remove(force: force)
@@ -38,15 +47,21 @@ module Drydock
38
47
  end
39
48
  end
40
49
 
41
- build_container.remove(force: force) if built?
42
- self
50
+ freeze
43
51
  end
44
52
 
45
53
  def finalize!(force: false)
46
- return self unless built?
47
- build_container.remove(force: force)
54
+ unless finalized?
55
+ build_container.remove(force: force) if built?
56
+ @finalized = true
57
+ end
58
+
48
59
  self
49
60
  end
50
61
 
62
+ def finalized?
63
+ @finalized
64
+ end
65
+
51
66
  end
52
67
  end
@@ -53,9 +53,9 @@ module Drydock
53
53
 
54
54
  def self.build_pull_opts(repo, tag = nil)
55
55
  if tag
56
- {fromImage: repo, tag: tag}
56
+ {fromImage: "#{repo}:#{tag}"}
57
57
  else
58
- {fromImage: repo}
58
+ {fromImage: "#{repo}:latest"}
59
59
  end
60
60
  end
61
61
 
@@ -64,6 +64,7 @@ module Drydock
64
64
  meta_options = cfg[:MetaOptions] || {}
65
65
  timeout = meta_options.fetch(:read_timeout, Excon.defaults[:read_timeout]) || 60
66
66
 
67
+ Drydock.logger.debug(message: "Create container configuration: #{cfg.inspect}")
67
68
  Docker::Container.create(cfg).tap do |c|
68
69
  # The call to Container.create merely creates a container, to be
69
70
  # scheduled to run. Start a separate thread that attaches to the
@@ -153,6 +154,8 @@ module Drydock
153
154
  @parent = parent
154
155
  @children = []
155
156
 
157
+ @finalized = false
158
+
156
159
  @ephemeral_containers = []
157
160
 
158
161
  if parent
@@ -178,10 +181,11 @@ module Drydock
178
181
 
179
182
  def destroy!(force: false)
180
183
  return self if frozen?
184
+
185
+ finalize!
181
186
  children.reverse_each { |c| c.destroy!(force: force) } if children
182
- ephemeral_containers.map { |c| c.remove(force: force) }
187
+ reverse_each { |p| p.destroy!(force: force) }
183
188
 
184
- reverse_each { |c| c.destroy!(force: force) }
185
189
  freeze
186
190
  end
187
191
 
@@ -194,14 +198,20 @@ module Drydock
194
198
  end
195
199
 
196
200
  def finalize!(force: false)
197
- return self if frozen?
201
+ return self if finalized?
198
202
 
199
- children.map { |c| c.finalize!(force: force) } if children
200
- ephemeral_containers.map { |c| c.remove(force: force) }
203
+ children.reverse_each { |c| c.finalize!(force: force) } if children
204
+ ephemeral_containers.reverse_each { |c| c.remove(force: force) }
201
205
 
202
206
  Drydock.logger.info("##{serial}: Final image ID is #{last_image.id}") unless empty?
203
- map { |p| p.finalize!(force: force) }
204
- freeze
207
+ reverse_each { |p| p.finalize!(force: force) }
208
+
209
+ @finalized = true
210
+ self
211
+ end
212
+
213
+ def finalized?
214
+ @finalized
205
215
  end
206
216
 
207
217
  def images
@@ -223,6 +233,7 @@ module Drydock
223
233
  no_cache = opts.fetch(:no_cache, false)
224
234
  no_cache = true if no_commit
225
235
 
236
+ Drydock.logger.debug(message: "Source image: #{src_image.inspect}")
226
237
  build_config = self.class.build_container_opts(src_image.id, cmd, opts)
227
238
  cached_image = ImageRepository.find_by_config(build_config)
228
239
 
@@ -157,12 +157,15 @@ module Drydock
157
157
  end
158
158
 
159
159
  # Destroy the images and containers created, and attempt to return the docker
160
- # state as it was before the project.
160
+ # state as it was before the project. The project object itself cannot be reused
161
+ # after it is destroyed.
161
162
  #
162
163
  # @api private
163
164
  def destroy!(force: false)
164
- chain.destroy!(force: force) if chain
165
+ return self if frozen?
165
166
  finalize!(force: force)
167
+ chain.destroy!(force: force) if chain
168
+ freeze
166
169
  end
167
170
 
168
171
  # Meta instruction to signal to the builder that the build is done.
@@ -395,8 +398,12 @@ module Drydock
395
398
  # Finalize everything. This will be automatically invoked at the end of
396
399
  # the build, and should not be called manually.
397
400
  #
401
+ # No further changes to the object is possible after finalization.
402
+ #
398
403
  # @api private
399
404
  def finalize!(force: false)
405
+ return self if finalized?
406
+
400
407
  if chain
401
408
  chain.finalize!(force: force)
402
409
  end
@@ -406,6 +413,7 @@ module Drydock
406
413
  stream_monitor.join
407
414
  end
408
415
 
416
+ @finalized = true
409
417
  self
410
418
  end
411
419
 
@@ -474,6 +482,10 @@ module Drydock
474
482
  end
475
483
  end
476
484
 
485
+ def finalized?
486
+ @finalized
487
+ end
488
+
477
489
  # Access to the logger object.
478
490
  #
479
491
  # @return [Logger] A logger object on which one could call `#info`, `#error`,
@@ -1,6 +1,6 @@
1
1
 
2
2
  RSpec.describe Drydock::ImageRepository do
3
-
3
+
4
4
  describe '.all' do
5
5
  it 'completes without an error' do
6
6
  expect { described_class.all }.not_to raise_error
@@ -23,7 +23,7 @@ RSpec.describe Drydock::ImageRepository do
23
23
 
24
24
  describe '.find_by_config' do
25
25
  let(:cmd) { '/bin/ls -l' }
26
- let(:image) { Docker::Image.create(fromImage: 'alpine', tag: 'latest') }
26
+ let(:image) { Docker::Image.create(fromImage: 'alpine:latest') }
27
27
  let(:container) { image.run(cmd).tap(&:wait) }
28
28
  let(:run_image) { container.commit }
29
29
 
@@ -1,13 +1,6 @@
1
1
 
2
2
  RSpec.describe Drydock::PhaseChain do
3
3
 
4
- EXPECTED_IMAGE_TO_ID_MAPPINGS = {
5
- 'alpine' => {
6
- '3.2' => 'f4fddc471ec2',
7
- 'latest' => 'f4fddc471ec2'
8
- }
9
- }
10
-
11
4
  describe '.from_repo' do
12
5
 
13
6
  it 'takes a repo name forced without a tag' do
@@ -32,8 +25,13 @@ RSpec.describe Drydock::PhaseChain do
32
25
  expect(subject).to be_a(Docker::Image)
33
26
  end
34
27
 
35
- it 'matches the image ID' do
36
- expect(subject.id).to eq(EXPECTED_IMAGE_TO_ID_MAPPINGS['alpine']['3.2'])
28
+ it 'matches the image tag' do
29
+ expect(subject.info).not_to be_nil
30
+
31
+ # Docker Remote API v1.21 introduced RepoTags
32
+ if subject.info.key?('RepoTags')
33
+ expect(subject.info['RepoTags']).to include('alpine:3.2')
34
+ end
37
35
  end
38
36
 
39
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-dock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ripta Pasay
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-08 00:00:00.000000000 Z
11
+ date: 2016-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: attr_extras
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.22'
33
+ version: '1.24'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.22'
40
+ version: '1.24'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: excon
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -167,6 +167,7 @@ files:
167
167
  - ".pryrc"
168
168
  - ".rspec"
169
169
  - ".rubocop.yml"
170
+ - ".ruby-version"
170
171
  - ".travis.yml"
171
172
  - ".yardopts"
172
173
  - Dockerfile
@@ -264,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
265
  version: '0'
265
266
  requirements: []
266
267
  rubyforge_project:
267
- rubygems_version: 2.2.2
268
+ rubygems_version: 2.4.5.1
268
269
  signing_key:
269
270
  specification_version: 4
270
271
  summary: Docker Image Pipeline DSL