docker-rails 0.4.1 → 0.5.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: 201c27258faf2fd7c7e3da8be4ef103692af5d3d
4
- data.tar.gz: 2cddc4422dd2fbde906a8b3eebeae4fe5659b4f8
3
+ metadata.gz: 285dc77cef10695d9e17976de3d0d4ce48191422
4
+ data.tar.gz: f8e2eca7b132eb6b97dced3fe8a04b64512d5dd8
5
5
  SHA512:
6
- metadata.gz: 10b164b7176bc7bc04fbf1aafe8700c108bc5916be22ee49ff961d253cadc39be6b6ae5f755dde04f6bbd469c694a9cccb9f535ba71cbbcd7800d36a0b7b2660
7
- data.tar.gz: fcaf8df78943d829d525c630d71517c28bf47d681d85d65ea6401d9b470ae0d2568979c1a13eb1c9b6728109055b71af27c4583bd9b8f8a45bb5e9ac04c08096
6
+ metadata.gz: 8ab35a4c1b39129157b8962f383e02eb4004a37c798c2512aa49ad993e97f39e7fb5229a7b5901175a767b057d5d2ab38fbd20ba385534530cde0df53cb25a3a
7
+ data.tar.gz: a9f88b10b75cdf755de564ed85479d6eee098ec522d98415fdc4211e23b57c092d83fb299fdd2dd697c8cfd6af5c4a41a980d5c3ef1b0f1bd0f0e2059935aed5
data/.travis.yml CHANGED
@@ -10,4 +10,9 @@ matrix:
10
10
  - rvm: ruby-head
11
11
  - rvm: jruby-head
12
12
 
13
- script: rake
13
+ script: rake
14
+
15
+ notifications:
16
+ email:
17
+ on_success: change
18
+ on_failure: change
data/README.md CHANGED
@@ -18,6 +18,26 @@ A simplified pattern to execute rails applications within Docker (with a CI buil
18
18
  ### CI
19
19
 
20
20
  CI, the reason this is built. Do it all, do it consistently, do it concurrently, do it easily, and always cleanup after yourself.
21
+
22
+ `bundle exec ci test`
23
+
24
+ #### CI workflow
25
+
26
+ `ci` executes:
27
+
28
+ 1. `before_command` - run anything on the host prior to building the docker image e.g. `rm -Rf target`
29
+ 2. `compose` - create the resolved `docker-compose.yml`
30
+ 3. `gems_volume` - find or create the shared global gems volume for this ruby version
31
+ 4. `build` - `docker-compose build` the configuration
32
+ 5. `up` - `docker-compose up` the configuration
33
+ 6. `cleanup`
34
+ 1. `stop` - stop all containers for this configuration (including one-off sessions)
35
+ 2. `extract` - extract any defined files from any container
36
+ 3. `rm_volumes` - `docker-compose rm -v --force` to cleanup any container volumes (excluding the gems volume)
37
+ 4. `rm_compose` - cleanup the generated compose.yml file for the `build`
38
+ 5. `rm_dangling` - cleanup any dangling images
39
+
40
+ #### CI execution options
21
41
 
22
42
  ```bash
23
43
  bundle exec docker-rails ci --build=222 test
@@ -33,7 +53,7 @@ or for local testing (uses `1` for build)
33
53
 
34
54
  ```bash
35
55
  bundle exec docker-rails ci test
36
- ```
56
+ ```
37
57
 
38
58
  ### General CLI
39
59
 
@@ -41,7 +61,7 @@ Almost all of the commands below are in support of the `ci` command, so why not
41
61
 
42
62
  ```bash
43
63
  Commands:
44
- docker-rails bash_connect <target> <service_name> # Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db
64
+ docker-rails bash_connect <target> <service_name> # Open a bash shell to a running container (with automatic cleanup) e.g. bundle exec docker-rails bash --build=222 development db
45
65
  docker-rails build <target> # Build for the given build/target e.g. bundle exec docker-rails build --build=222 development
46
66
  docker-rails ci <target> # Execute the works, everything with cleanup included e.g. bundle exec docker-rails ci --build=222 test
47
67
  docker-rails cleanup <target> # Runs container cleanup functions stop, rm_volumes, rm_compose, rm_dangling, ps_all e.g. bundle exec docker-rails cleanup --build=222 development
@@ -107,6 +127,12 @@ RUN apt-get update -qq && \
107
127
 
108
128
  # https://github.com/docker/docker/issues/4032
109
129
  ENV DEBIAN_FRONTEND newt
130
+
131
+ # Bypass the union file system for better performance https://docs.docker.com/userguide/dockervolumes/
132
+ VOLUME /project
133
+
134
+ # Copy the project files into the container (again, better performance). Use `extract` in the docker-rails.yml to obtain files such as test results.
135
+ COPY . /project
110
136
  ```
111
137
 
112
138
  ### 2. Add a docker-rails.yml
data/lib/docker/rails.rb CHANGED
@@ -9,7 +9,8 @@ require 'thor'
9
9
  require 'docker'
10
10
  require 'archive/tar/minitar'
11
11
 
12
- require 'docker/rails/core_ext/hash'
12
+ require 'docker/rails/ext/hash'
13
+ require 'docker/rails/ext/container'
13
14
 
14
15
  require 'docker/rails/config'
15
16
  require 'docker/rails/compose_config'
@@ -76,36 +76,15 @@ module Docker
76
76
  end
77
77
 
78
78
  puts "\nExtracting #{service_name} #{from} to #{to}"
79
- extract_files(container, from, to)
79
+ begin
80
+ extract_files(container, from, to)
81
+ rescue => e
82
+ puts e.message
83
+ end
80
84
  end
81
85
  end
82
86
  end
83
87
 
84
-
85
- def extract_files(container, from, to)
86
- # or something like
87
- tar_stringio = StringIO.new
88
- container.copy(from) do |chunk|
89
- tar_stringio.write(chunk)
90
- end
91
-
92
- tar_stringio.rewind
93
-
94
- input = Archive::Tar::Minitar::Input.new(tar_stringio)
95
- input.each { |entry|
96
-
97
- # Need to check the file name length to prevent some very bad things from happening.
98
- if entry.full_name.length > 255
99
- puts "ERROR - file name length is > 255 characters: #{entry.full_name}"
100
- elsif entry.full_name.length <= 0
101
- puts "ERROR - file name length is too small: #{entry.full_name}"
102
- else
103
- puts "Extracting #{entry.full_name}"
104
- input.extract_entry(to, entry)
105
- end
106
- }
107
- end
108
-
109
88
  def compose
110
89
  # Write a docker-compose.yml with interpolated variables
111
90
  @compose_filename = compose_filename_from @build, @target
@@ -143,11 +122,21 @@ module Docker
143
122
  exec_compose 'ps'
144
123
  end
145
124
 
125
+ def exec_ps_all
126
+ puts "\n\nAll remaining containers..."
127
+ puts '-----------------------------'
128
+ exec 'docker ps -a'
129
+ end
130
+
146
131
  def exec_stop
147
132
  puts "\n\n\n\nStopping containers..."
148
133
  puts '-----------------------------'
149
- @compose_config.each_key do |service_name|
150
- stop(service_name)
134
+ containers = Docker::Container.all(all: true)
135
+ containers.each do |container|
136
+ if is_build_container?(container)
137
+ puts container.compose
138
+ container.stop
139
+ end
151
140
  end
152
141
  puts 'Done.'
153
142
  end
@@ -155,8 +144,14 @@ module Docker
155
144
  def exec_remove_volumes
156
145
  puts "\n\nRemoving container volumes..."
157
146
  puts '-----------------------------'
158
- @compose_config.each_key do |service_name|
159
- rm_v(service_name)
147
+
148
+ # http://docs.docker.com/v1.7/reference/api/docker_remote_api_v1.19/#remove-a-container
149
+ containers = Docker::Container.all(all: true)
150
+ containers.each do |container|
151
+ if is_build_container?(container)
152
+ puts container.compose
153
+ container.remove(v: true, force: true)
154
+ end
160
155
  end
161
156
  puts 'Done.'
162
157
  end
@@ -171,21 +166,21 @@ module Docker
171
166
  puts 'Done.'
172
167
  end
173
168
 
174
- def show_all_containers
175
- puts "\n\nAll remaining containers..."
176
- puts '-----------------------------'
177
- system 'docker ps -a'
178
- end
179
-
180
169
  def exec_run(service_name, command)
181
170
  # Run the compose configuration
182
171
  exec_compose "run #{service_name} #{command}"
183
172
  end
184
173
 
185
174
  def exec_bash_connect(service_name)
186
- # docker exec -it 222_db_1 bash
187
- container_name = get_container_name(service_name)
188
- exec "docker exec -it #{container_name} bash"
175
+ # docker exec -it 2ed97d0bb938 bash
176
+ container = get_container(service_name)
177
+ if container.nil?
178
+ puts "#{service_name} does not appear to be running for build #{@build}"
179
+ return
180
+ end
181
+
182
+ exec "docker exec -it #{container.id} bash"
183
+ container
189
184
  end
190
185
 
191
186
  # Create global gems data volume to cache gems for this version of ruby
@@ -220,46 +215,25 @@ module Docker
220
215
  exec("docker-compose -f #{@compose_filename} -p #{@build} #{cmd} #{options}", capture)
221
216
  end
222
217
 
223
- # service_name i.e. 'db' or 'web'
224
- def get_container_name(service_name)
225
- output = exec_compose "ps #{service_name}", true
226
- # puts "get_container(#{service_name}): \n#{output}"
227
- output =~ /^(\w+)/ # grab the name, only thing that is at the start of the line
228
- $1
229
- end
230
-
231
218
  def get_container(service_name)
232
- Docker::Container.get(get_container_name(service_name))
233
- end
234
-
235
- # def up_service(service_name, options = '')
236
- # exec_compose "up #{options} #{service_name}"
237
- # container_name = get_container_name(service_name)
238
- # puts "#{service_name}: container_name #{container_name}"
239
- #
240
- # container = Docker::Container.get(container_name)
241
- # # container.streaming_logs(stdout: true) { |stream, chunk| puts "#{service_name}: #{chunk}" }
242
- # # puts container
243
- #
244
- # {service_name => {'container' => container, 'container_name' => container_name}}
245
- # end
246
-
247
- def rm_v(service_name)
248
- exec_compose "rm -v --force #{service_name}"
249
- end
219
+ containers = Docker::Container.all(all: true)
220
+ containers.each do |container|
221
+ if is_build_container?(container) && container.compose.service.eql?(service_name)
222
+ return container
223
+ end
224
+ end
250
225
 
251
- def stop(service_name)
252
- exec_compose "stop #{service_name}"
226
+ nil
253
227
  end
254
228
 
255
- # def skip?(command)
256
- # skips = @config[:skip]
257
- # return false if skips.nil?
258
- # skip = skips.include? command.to_s
259
- # puts "Skipping #{command}" if skip && verbose?
260
- # skip
261
- # end
229
+ def is_build_container?(container)
230
+ # labels = container.info['Labels']
231
+ # build = labels['com.docker.compose.project']
262
232
 
233
+ return false if container.compose.nil?
234
+ return true if @build.eql? container.compose.project
235
+ false
236
+ end
263
237
 
264
238
  def verbose?
265
239
  @verbose ||= (@config['verbose'] unless @config.nil?) || false
@@ -281,6 +255,30 @@ module Docker
281
255
  def compose_filename_from(build, target)
282
256
  "docker-compose-#{target}-#{build}.yml"
283
257
  end
258
+
259
+ def extract_files(container, from, to)
260
+ # or something like
261
+ tar_stringio = StringIO.new
262
+ container.copy(from) do |chunk|
263
+ tar_stringio.write(chunk)
264
+ end
265
+
266
+ tar_stringio.rewind
267
+
268
+ input = Archive::Tar::Minitar::Input.new(tar_stringio)
269
+ input.each { |entry|
270
+
271
+ # Need to check the file name length to prevent some very bad things from happening.
272
+ if entry.full_name.length > 255
273
+ puts "ERROR - file name length is > 255 characters: #{entry.full_name}"
274
+ elsif entry.full_name.length <= 0
275
+ puts "ERROR - file name length is too small: #{entry.full_name}"
276
+ else
277
+ puts "Extracting #{entry.full_name}"
278
+ input.extract_entry(to, entry)
279
+ end
280
+ }
281
+ end
284
282
  end
285
283
  end
286
284
  end
@@ -131,10 +131,10 @@ module Docker
131
131
  desc 'ps_all', 'List all remaining containers regardless of state e.g. bundle exec docker-rails ps_all'
132
132
 
133
133
  def ps_all(build = nil, target = nil)
134
- App.instance.show_all_containers
134
+ App.instance.exec_ps_all
135
135
  end
136
136
 
137
- desc 'bash_connect <target> <service_name>', 'Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db'
137
+ desc 'bash_connect <target> <service_name>', 'Open a bash shell to a running container (with automatic cleanup) e.g. bundle exec docker-rails bash --build=222 development db'
138
138
 
139
139
  def bash_connect(target, service_name)
140
140
  # init singleton with full options
@@ -142,7 +142,12 @@ module Docker
142
142
 
143
143
  invoke :compose, [target], []
144
144
 
145
- app.exec_bash_connect(service_name)
145
+ container = app.exec_bash_connect(service_name)
146
+
147
+ # Automatically cleanup any remnants of a simple bash session.
148
+ return if container.nil?
149
+ container.stop
150
+ container.remove(v: true, force: true)
146
151
  end
147
152
 
148
153
 
@@ -0,0 +1,33 @@
1
+ class Docker::Container
2
+
3
+ def compose
4
+ return nil unless Compose.is_compose_container?(self)
5
+ @_compose ||= Compose.new(self)
6
+ end
7
+
8
+ class Compose
9
+ attr_reader :number, :oneoff, :project, :service, :version, :name
10
+
11
+ def initialize(container)
12
+ labels = container.info['Labels']
13
+ @service = labels['com.docker.compose.service']
14
+ @project = labels['com.docker.compose.project']
15
+ @oneoff = !!labels['com.docker.compose.oneoff']
16
+ @number = labels['com.docker.compose.container-number'].to_i
17
+ @version = labels['com.docker.compose.version']
18
+ @name = container.info['Names'][0].gsub(/^\//, '')
19
+ end
20
+
21
+ def to_s
22
+ @name
23
+ end
24
+
25
+ class << self
26
+ def is_compose_container?(container)
27
+ labels = container.info['Labels']
28
+ (!labels.nil? && !labels['com.docker.compose.version'].nil?)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
File without changes
@@ -1,5 +1,5 @@
1
1
  module Docker
2
2
  module Rails
3
- VERSION = '0.4.1'
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Ross
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-28 00:00:00.000000000 Z
11
+ date: 2015-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -162,7 +162,8 @@ files:
162
162
  - lib/docker/rails/cli/main.rb
163
163
  - lib/docker/rails/compose_config.rb
164
164
  - lib/docker/rails/config.rb
165
- - lib/docker/rails/core_ext/hash.rb
165
+ - lib/docker/rails/ext/container.rb
166
+ - lib/docker/rails/ext/hash.rb
166
167
  - lib/docker/rails/version.rb
167
168
  - spec/docker/rails/config_spec.rb
168
169
  - spec/docker/rails/docker-rails.yml