dry-dock 0.1.6 → 0.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,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