dockistrano 0.0.5 → 0.0.6

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: 158d3061ea38673eaf98d564749fc35d959d304b
4
- data.tar.gz: 6c106bbf2921d25169e3c1b0c2ed8e783755fdbd
3
+ metadata.gz: 91762ce1db149fa71eab678c80fbc5c7e60c5cbd
4
+ data.tar.gz: 28d8236dcd51b0d5235fb3ef62252514064d07c2
5
5
  SHA512:
6
- metadata.gz: 9d77e9bfa8f228b922b55d0e874cbd13fecd18a6a9c8ca7c80f25653981615984cd0d3c212afa4fe0ddb93b0181ecba6b2314986103dc990f23186957dbb8063
7
- data.tar.gz: 6664a8a469961282bcccf1dacf140cc7e68de7b699011e324cad4d89e1fc2d825c0319ee81f66dace7f1bc1783f915c9a7f918f631006e9a28e16b51c859bcae
6
+ metadata.gz: eec347010dcdec6e2db6ba72799be478aa41dff197cb2360849d20ad66a1ca205af2f817ade16b7369d5fbb3f193f89005a3ff1900455e23a18c879845f66196
7
+ data.tar.gz: a52f46d46ef9510b6a6a8dd7c23db0a67531958dc9f9e0731c14a73d7b795a53e4a358cf016892692c28de1d642430e7847fad54ff6bf252f2cc0c1e0ec3dbd6
data/Guardfile CHANGED
@@ -7,3 +7,8 @@ guard :rspec do
7
7
  watch('spec/spec_helper.rb') { "spec" }
8
8
  end
9
9
 
10
+ guard :shell do
11
+ watch %r{^lib\/(.+)\.rb$} do |m|
12
+ `rake install`
13
+ end
14
+ end
data/dockistrano.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rake"
28
28
  spec.add_development_dependency "guard"
29
29
  spec.add_development_dependency "guard-rspec"
30
+ spec.add_development_dependency "guard-shell"
30
31
  spec.add_development_dependency "terminal-notifier-guard"
31
32
  spec.add_development_dependency "webmock"
32
33
  end
@@ -3,14 +3,7 @@ require "dotenv"
3
3
  Dotenv.load(".dockistrano")
4
4
  ENV["DOCKISTRANO_ENVIRONMENT"] ||= "default"
5
5
  ENV["DOCKER_HOST_IP"] ||= "127.0.0.1"
6
- ENV["DOCKER_BINARY"] ||= begin
7
- if RUBY_PLATFORM =~ /darwin|mac os/
8
- bin_dir = File.expand_path(File.dirname(__FILE__) + "/../../bin")
9
- "#{bin_dir}/docker"
10
- else
11
- "docker"
12
- end
13
- end
6
+ ENV["DOCKER_BINARY"] ||= "docker"
14
7
 
15
8
  module Dockistrano
16
9
 
@@ -145,6 +138,7 @@ module Dockistrano
145
138
  def stop(id=nil)
146
139
  if id
147
140
  Docker.stop(id)
141
+ Docker.remove_container(id)
148
142
  say_status("Stopped", id, :green)
149
143
  else
150
144
  current_service.stop
@@ -186,16 +180,28 @@ module Dockistrano
186
180
 
187
181
  desc "logs [NAME]", "Prints the logs for the service"
188
182
  def logs(name=nil)
189
- service = name ? current_service.backing_services[name] : current_service
183
+ if name and current_service.backing_services[name]
184
+ service = current_service.backing_services[name]
185
+ command_name = nil
186
+ else
187
+ service = current_service
188
+ command_name = name
189
+ end
190
+
190
191
  if service.running?
191
192
  say "Container #{service.image_name} running, attaching to output", :blue
192
- service.attach
193
+ service.attach(command_name)
193
194
  else
194
195
  say "Container #{service.image_name} stopped, printing logs of last run", :blue
195
- service.logs
196
+ service.logs(command_name)
196
197
  end
197
198
  end
198
199
 
200
+ desc "version", "Prints version information"
201
+ def version
202
+ say "Dockistrano version: #{Dockistrano::VERSION}"
203
+ end
204
+
199
205
  def method_missing(*args)
200
206
  command = args[0]
201
207
  if command and current_service.config["aliases"] and current_service.config["aliases"][command.to_s]
@@ -95,6 +95,10 @@ module Dockistrano
95
95
  execute(["attach", id], :stream)
96
96
  end
97
97
 
98
+ def self.remove_container(name)
99
+ execute(["rm", name])
100
+ end
101
+
98
102
  def self.clean
99
103
  Dockistrano::CommandLine.command_with_stream("#{docker_command} rmi $(#{docker_command} images -a | grep \"^<none>\" | awk '{print $3}')")
100
104
  Dockistrano::CommandLine.command_with_stream("#{docker_command} rm $(#{docker_command} ps -a -q)")
@@ -115,18 +115,13 @@ module Dockistrano
115
115
 
116
116
  # Stops the container of the current service
117
117
  def stop
118
- if !host.nil?
119
- hipache = Hipache.new(ENV['DOCKER_HOST_IP'])
120
- if host.kind_of?(String)
121
- hipache.unregister(image_name, host, ip_address, port)
122
- else
123
- host.each do |hostname, port|
124
- hipache.unregister(image_name, hostname, ip_address, port)
125
- end
126
- end
118
+ update_hipache(false)
119
+ Docker.stop(image_name)
120
+ Docker.remove_container(image_name)
121
+ additional_commands.each do |name, _|
122
+ Docker.stop("#{image_name}_#{name}")
123
+ Docker.remove_container("#{image_name}_#{name}")
127
124
  end
128
-
129
- Docker.stop_all_containers_from_image(full_image_name)
130
125
  end
131
126
 
132
127
  # Returns if this service is running
@@ -151,6 +146,19 @@ module Dockistrano
151
146
  Dockistrano::Docker.push("#{registry}/#{image_name}", tag)
152
147
  end
153
148
 
149
+ def update_hipache(server_up=true)
150
+ if !host.nil?
151
+ hipache = Hipache.new(ENV['DOCKER_HOST_IP'])
152
+ host.each do |hostname, port|
153
+ if server_up
154
+ hipache.register(image_name, hostname, ip_address_for_port(port), port)
155
+ else
156
+ hipache.unregister(image_name, hostname, ip_address_for_port(port), port)
157
+ end
158
+ end
159
+ end
160
+ end
161
+
154
162
  # Starts this service
155
163
  def start(options={})
156
164
  ensure_backing_services
@@ -159,39 +167,29 @@ module Dockistrano
159
167
 
160
168
  if additional_commands.any?
161
169
  additional_commands.each do |name, command|
162
- Docker.run(full_image_name, e: environment, v: volumes, p: ports, d: true, command: command)
170
+ Docker.run(full_image_name, name: "#{image_name}_#{name}", link: link_backing_services, e: environment, v: volumes, d: true, command: command)
163
171
  end
164
172
  end
165
173
 
166
- Docker.run(full_image_name, e: environment, v: volumes, p: ports, d: true)
167
-
168
- if !host.nil?
169
- hipache = Hipache.new(ENV['DOCKER_HOST_IP'])
170
- if host.kind_of?(String)
171
- hipache.register(image_name, host, ip_address, port)
172
- else
173
- host.each do |hostname, port|
174
- hipache.register(image_name, hostname, ip_address, port)
175
- end
176
- end
177
- end
174
+ Docker.run(full_image_name, name: image_name, link: link_backing_services, e: environment, v: volumes, p: ports, d: true)
175
+ update_hipache(true)
178
176
  end
179
177
 
180
178
  # Runs a command in this container
181
179
  def run(command, options={})
182
- Docker.run(full_image_name_with_fallback, command: command, e: environment_variables, v: volumes, p: ports)
180
+ Docker.run(full_image_name_with_fallback, link: link_backing_services, command: command, e: environment_variables, v: volumes)
183
181
  end
184
182
 
185
183
  # Executes a command in this container
186
184
  def exec(command, options={})
187
185
  create_data_directories
188
- Docker.exec(full_image_name_with_fallback, command: command, e: environment_variables, v: volumes, p: ports)
186
+ Docker.exec(full_image_name_with_fallback, link: link_backing_services, command: command, e: environment_variables, v: volumes)
189
187
  end
190
188
 
191
189
  # Starts a console in the docker container
192
190
  def console(command, options={})
193
191
  create_data_directories
194
- Docker.console(full_image_name_with_fallback, command: command, e: environment_variables, v: volumes, p: ports)
192
+ Docker.console(full_image_name_with_fallback, link: link_backing_services, command: command, e: environment_variables, v: volumes)
195
193
  end
196
194
 
197
195
  # Lists all backing services for this service
@@ -205,6 +203,13 @@ module Dockistrano
205
203
  end
206
204
  end
207
205
 
206
+ # Returns an array of backing services to link
207
+ def link_backing_services
208
+ backing_services.collect { |name, service|
209
+ "#{service.image_name}:#{service.image_name}"
210
+ }
211
+ end
212
+
208
213
  # Returns an array of environment variables
209
214
  def environment_variables
210
215
  vars = {}
@@ -214,9 +219,6 @@ module Dockistrano
214
219
  end
215
220
 
216
221
  backing_services.each do |name, backing_service|
217
- vars["#{name.upcase}_IP"] = backing_service.ip_address
218
- vars["#{name.upcase}_PORT"] = backing_service.port
219
-
220
222
  backing_service.backing_service_env.each do |k,v|
221
223
  vars["#{name.upcase}_#{k.upcase}"] = v
222
224
  end
@@ -226,8 +228,10 @@ module Dockistrano
226
228
 
227
229
  vars.each do |key, value|
228
230
  vars.each do |replacement_key, replacement_value|
229
- unless vars[key].nil? or replacement_value.nil?
230
- vars[key] = vars[key].gsub('$'+replacement_key, replacement_value)
231
+ vars[key] = if vars[key].nil? or replacement_value.nil? or replacement_value.empty?
232
+ vars[key].gsub('$'+replacement_key, '$'+replacement_key)
233
+ else
234
+ vars[key].gsub('$'+replacement_key, replacement_value)
231
235
  end
232
236
  end
233
237
  end
@@ -244,7 +248,9 @@ module Dockistrano
244
248
  [].tap do |volumes|
245
249
  volumes << "/dockistrano/#{image_name.gsub("-", "_")}/data:/dockistrano/data"
246
250
  if mount_src and !mount_src.empty?
247
- volumes << "/dockistrano/#{image_name.gsub("-", "_")}/src:#{mount_src}"
251
+ mount_src.each do |host_src, container_src|
252
+ volumes << "#{host_src}:#{container_src}"
253
+ end
248
254
  end
249
255
  end
250
256
  end
@@ -281,24 +287,34 @@ module Dockistrano
281
287
  end
282
288
  end
283
289
 
284
- def ip_address
285
- container_settings["NetworkSettings"]["IPAddress"] if running?
286
- end
287
-
288
- def port
289
- container_settings["NetworkSettings"]["PortMapping"]["Tcp"].keys.first if running?
290
+ def ip_address_for_port(port)
291
+ container_settings["NetworkSettings"]["Ports"]["#{port}/tcp"].first["HostIp"] if running?
290
292
  end
291
293
 
292
294
  def ports
293
- (config["ports"] || {}).collect { |k,v| "#{k}:#{v}" }
295
+ (config["ports"] || {}).collect { |k,v|
296
+ if k.to_s.include?(":")
297
+ "#{k}:#{v}"
298
+ else
299
+ "172.17.42.1:#{k}:#{v}"
300
+ end
301
+ }
294
302
  end
295
303
 
296
- def attach
297
- Docker.attach(Docker.running_container_id(full_image_name))
304
+ def attach(name=nil)
305
+ if name
306
+ Docker.attach("#{image_name}_#{name}")
307
+ else
308
+ Docker.attach(image_name)
309
+ end
298
310
  end
299
311
 
300
- def logs
301
- Docker.logs(Docker.last_run_container_id(full_image_name))
312
+ def logs(name=nil)
313
+ if name
314
+ Docker.logs("#{image_name}_#{name}")
315
+ else
316
+ Docker.logs(image_name)
317
+ end
302
318
  end
303
319
 
304
320
  def create_data_directories
@@ -309,7 +325,7 @@ module Dockistrano
309
325
  command = "mkdir -p #{data_directories.collect { |dir| "/dockistrano/data/#{dir}"}.join(" ") }; "
310
326
  command += "chown #{image_user}:#{image_user} #{data_directories.collect { |dir| "/dockistrano/data/#{dir}"}.join(" ") }"
311
327
  bash_command = "/bin/bash -c '#{command}'"
312
- Docker.run(full_image_name_with_fallback, command: bash_command, v: volumes, e: environment_variables, u: "root")
328
+ Docker.run(full_image_name_with_fallback, command: bash_command, v: volumes, e: environment_variables, u: "root", rm: true)
313
329
  end
314
330
  end
315
331
 
@@ -76,7 +76,7 @@ module Dockistrano
76
76
  end
77
77
 
78
78
  def load_from_image
79
- raw_config = Docker.run(backing_service.full_image_name, command: "cat /dockistrano.yml")
79
+ raw_config = Docker.run(backing_service.full_image_name, command: "cat /dockistrano.yml", rm: true)
80
80
  if raw_config.empty? or raw_config.include?("No such file or directory")
81
81
  if raw_config.include?("failed to mount")
82
82
  raise HostDirectoriesMissing
@@ -1,3 +1,3 @@
1
1
  module Dockistrano
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Dockistrano::Cli do
4
4
 
5
5
  let(:service) { double(registry: "registry.provider.tld", image_name: "application", tag: "develop", volumes: [], backing_services: { "postgresql" => backing_service }, environment_variables: {}, newer_version_available?: false, stop: nil) }
6
- let(:backing_service) { double(full_image_name: "registry.provider.tld/postgresql:develop", image_name: "postgresql", running?: false, newer_version_available?: false, start: nil, stop: nil) }
6
+ let(:backing_service) { double(:backing_service, full_image_name: "registry.provider.tld/postgresql:develop", image_name: "postgresql", running?: false, newer_version_available?: false, start: nil, stop: nil) }
7
7
  let(:hipache) { double }
8
8
  let(:output) { capture(:stdout) { described_class.start(command) } }
9
9
 
@@ -187,6 +187,7 @@ describe Dockistrano::Cli do
187
187
 
188
188
  it "stops the container with the id" do
189
189
  expect(Dockistrano::Docker).to receive(:stop).with("123456789")
190
+ expect(Dockistrano::Docker).to receive(:remove_container).with("123456789")
190
191
  expect(output).to include("Stopped")
191
192
  end
192
193
  end
@@ -259,33 +260,49 @@ describe Dockistrano::Cli do
259
260
 
260
261
  it "attaches to the containers output when the container is running" do
261
262
  expect(service).to receive(:running?).and_return(true)
262
- expect(service).to receive(:attach)
263
+ expect(service).to receive(:attach).with(nil)
263
264
  expect(output).to include("Container application running, attaching to output")
264
265
  end
265
266
 
266
267
  it "prints the logs of the last run" do
267
268
  expect(service).to receive(:running?).and_return(false)
268
- expect(service).to receive(:logs)
269
+ expect(service).to receive(:logs).with(nil)
269
270
  expect(output).to include("Container application stopped, printing logs of last run")
270
271
  end
271
272
  end
272
273
 
273
- context "doc logs NAME" do
274
+ context "doc logs BACKING_SERVICE" do
274
275
  let(:command) { ["logs", "postgresql"] }
275
276
 
276
277
  it "attaches to the containers output when the container is running" do
277
278
  expect(backing_service).to receive(:running?).and_return(true)
278
- expect(backing_service).to receive(:attach)
279
+ expect(backing_service).to receive(:attach).with(nil)
279
280
  expect(output).to include("Container postgresql running, attaching to output")
280
281
  end
281
282
 
282
283
  it "prints the logs of the last run" do
283
284
  expect(backing_service).to receive(:running?).and_return(false)
284
- expect(backing_service).to receive(:logs)
285
+ expect(backing_service).to receive(:logs).with(nil)
285
286
  expect(output).to include("Container postgresql stopped, printing logs of last run")
286
287
  end
287
288
  end
288
289
 
290
+ context "doc logs ADDITIONAL_COMMAND" do
291
+ let(:command) { ["logs", "worker"] }
292
+
293
+ it "attaches to the containers output when the container is running" do
294
+ expect(service).to receive(:running?).and_return(true)
295
+ expect(service).to receive(:attach).with("worker")
296
+ expect(output).to include("Container application running, attaching to output")
297
+ end
298
+
299
+ it "prints the logs of the last run" do
300
+ expect(service).to receive(:running?).and_return(false)
301
+ expect(service).to receive(:logs).with("worker")
302
+ expect(output).to include("Container application stopped, printing logs of last run")
303
+ end
304
+ end
305
+
289
306
  context "doc ALIAS ARGUMENTS" do
290
307
  let(:command) { ["rspec", "spec/models/my_model_spec.rb"] }
291
308
 
@@ -187,6 +187,13 @@ describe Dockistrano::Docker do
187
187
  end
188
188
  end
189
189
 
190
+ context ".remove_container" do
191
+ it "removes the container" do
192
+ expect(subject).to receive(:execute).with(["rm", "application"])
193
+ subject.remove_container("application")
194
+ end
195
+ end
196
+
190
197
  context ".inspect_container" do
191
198
  it "returns information about the container" do
192
199
  stub_request(:get, 'http://127.0.0.1:4243/containers/123456789/json').to_return({
@@ -98,7 +98,7 @@ describe Dockistrano::ServiceDependency do
98
98
  end
99
99
 
100
100
  it "reads the configuration from the image and caches the configuration" do
101
- expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml").and_return(raw_config = "---\ndefault:\n\tconfiguration: value")
101
+ expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml", rm: true).and_return(raw_config = "---\ndefault:\n\tconfiguration: value")
102
102
 
103
103
  expect(FileUtils).to receive(:mkdir_p).with("tmp/configuration_cache")
104
104
  expect(File).to receive(:open).with("tmp/configuration_cache/#{backing_service.image_id}", "w+").and_return(file = double)
@@ -111,17 +111,17 @@ describe Dockistrano::ServiceDependency do
111
111
  end
112
112
 
113
113
  it "raises an error when host directories are missing" do
114
- expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml").and_return("No such file or directory: failed to mount")
114
+ expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml", rm: true).and_return("No such file or directory: failed to mount")
115
115
  expect { subject.load_from_image }.to raise_error(Dockistrano::ServiceDependency::HostDirectoriesMissing)
116
116
  end
117
117
 
118
118
  it "raises an error when the configuration is not found" do
119
- expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml").and_return("No such file or directory: dockistrano.yml")
119
+ expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml", rm: true).and_return("No such file or directory: dockistrano.yml")
120
120
  expect { subject.load_from_image }.to raise_error(Dockistrano::ServiceDependency::ContainerConfigurationMissing)
121
121
  end
122
122
 
123
123
  it "raises an error when the configuration is empty" do
124
- expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml").and_return("")
124
+ expect(Dockistrano::Docker).to receive(:run).with(backing_service.full_image_name, command: "cat /dockistrano.yml", rm: true).and_return("")
125
125
  expect { subject.load_from_image }.to raise_error(Dockistrano::ServiceDependency::ContainerConfigurationMissing)
126
126
  end
127
127
  end
@@ -158,30 +158,31 @@ describe Dockistrano::Service do
158
158
  end
159
159
 
160
160
  context "#stop" do
161
- let(:hipache) { double }
162
-
163
161
  before do
164
- allow(Dockistrano::Docker).to receive(:stop_all_containers_from_image)
165
- allow(Dockistrano::Hipache).to receive(:new).and_return(hipache)
162
+ allow(Dockistrano::Docker).to receive(:stop)
163
+ allow(Dockistrano::Docker).to receive(:remove_container)
164
+ allow(subject).to receive(:additional_commands).and_return({ "worker" => "sidekiq" })
165
+ allow(subject).to receive(:update_hipache)
166
166
  end
167
167
 
168
168
  it "stops the container" do
169
- expect(Dockistrano::Docker).to receive(:stop_all_containers_from_image).with(subject.full_image_name)
169
+ expect(Dockistrano::Docker).to receive(:stop).with(subject.image_name)
170
170
  subject.stop
171
171
  end
172
172
 
173
- it "unregisters a host from Hipache" do
174
- allow(subject).to receive(:host).and_return("hostname.dev")
175
- expect(subject).to receive(:ip_address).and_return("33.33.33.33")
176
- expect(subject).to receive(:port).and_return("3000")
177
- expect(hipache).to receive(:unregister).with(subject.image_name, "hostname.dev", "33.33.33.33", "3000")
173
+ it "removes the container from Docker" do
174
+ expect(Dockistrano::Docker).to receive(:remove_container).with(subject.image_name)
178
175
  subject.stop
179
176
  end
180
177
 
181
- it "unregisters multiple hosts from Hipache" do
182
- allow(subject).to receive(:host).and_return({ "hostname.dev" => "8000" })
183
- expect(subject).to receive(:ip_address).and_return("33.33.33.33")
184
- expect(hipache).to receive(:unregister).with(subject.image_name, "hostname.dev", "33.33.33.33", "8000")
178
+ it "stops containers running additional commands" do
179
+ expect(Dockistrano::Docker).to receive(:stop).with("#{subject.image_name}_worker")
180
+ expect(Dockistrano::Docker).to receive(:remove_container).with("#{subject.image_name}_worker")
181
+ subject.stop
182
+ end
183
+
184
+ it "updates Hipache" do
185
+ expect(subject).to receive(:update_hipache).with(false)
185
186
  subject.stop
186
187
  end
187
188
  end
@@ -239,19 +240,42 @@ describe Dockistrano::Service do
239
240
  end
240
241
  end
241
242
 
243
+ context "#update_hipache" do
244
+ let(:hipache) { double }
245
+
246
+ before do
247
+ allow(Dockistrano::Hipache).to receive(:new).and_return(hipache)
248
+ end
249
+
250
+ it "registers the host in Hipache when the server is up" do
251
+ allow(subject).to receive(:host).and_return({ "hostname.dev" => "8000" })
252
+ expect(subject).to receive(:ip_address_for_port).with("8000").and_return("33.33.33.33")
253
+ expect(hipache).to receive(:register).with(subject.image_name, "hostname.dev", "33.33.33.33", "8000")
254
+ subject.update_hipache(true)
255
+ end
256
+
257
+ it "unregisters the host in Hipache when the server is down" do
258
+ allow(subject).to receive(:host).and_return({ "hostname.dev" => "8000" })
259
+ expect(subject).to receive(:ip_address_for_port).with("8000").and_return("33.33.33.33")
260
+ expect(hipache).to receive(:unregister).with(subject.image_name, "hostname.dev", "33.33.33.33", "8000")
261
+ subject.update_hipache(false)
262
+ end
263
+ end
264
+
242
265
  context "#start" do
243
266
  let(:environment) { double }
244
267
  let(:volumes) { double }
245
268
  let(:ports) { double }
246
- let(:hipache) { double }
269
+ let(:links) { double }
247
270
 
248
271
  before do
249
- allow(Dockistrano::Hipache).to receive(:new).and_return(hipache)
272
+ allow(subject).to receive(:update_hipache)
250
273
  allow(subject).to receive(:ensure_backing_services)
251
274
  allow(subject).to receive(:create_data_directories)
252
275
  allow(subject).to receive(:checked_environment_variables).and_return(environment)
253
276
  allow(subject).to receive(:volumes).and_return(volumes)
254
277
  allow(subject).to receive(:ports).and_return(ports)
278
+ allow(subject).to receive(:link_backing_services).and_return(links)
255
279
  allow(Dockistrano::Docker).to receive(:run)
256
280
  end
257
281
 
@@ -267,27 +291,17 @@ describe Dockistrano::Service do
267
291
 
268
292
  it "starts additional container when additional commands are configured" do
269
293
  allow(subject).to receive(:additional_commands).and_return({ "worker" => "sidekiq start" })
270
- expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name, e: environment, v: volumes, p: ports, d: true, command: "sidekiq start")
294
+ expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name, name: "#{subject.image_name}_worker", link: links, e: environment, v: volumes, d: true, command: "sidekiq start")
271
295
  subject.start
272
296
  end
273
297
 
274
298
  it "starts the container with the default command, providing env variables and volumes" do
275
- expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name, e: environment, v: volumes, p: ports, d: true)
276
- subject.start
277
- end
278
-
279
- it "registers a host with Hipache" do
280
- allow(subject).to receive(:host).and_return("hostname.dev")
281
- expect(subject).to receive(:ip_address).and_return("33.33.33.33")
282
- expect(subject).to receive(:port).and_return("3000")
283
- expect(hipache).to receive(:register).with(subject.image_name, "hostname.dev", "33.33.33.33", "3000")
299
+ expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name, name: subject.image_name, link: links, e: environment, v: volumes, p: ports, d: true)
284
300
  subject.start
285
301
  end
286
302
 
287
- it "registers multiple hosts with Hipache" do
288
- allow(subject).to receive(:host).and_return({ "hostname.dev" => "8000" })
289
- expect(subject).to receive(:ip_address).and_return("33.33.33.33")
290
- expect(hipache).to receive(:register).with(subject.image_name, "hostname.dev", "33.33.33.33", "8000")
303
+ it "updates Hipache" do
304
+ expect(subject).to receive(:update_hipache)
291
305
  subject.start
292
306
  end
293
307
  end
@@ -297,8 +311,8 @@ describe Dockistrano::Service do
297
311
  allow(subject).to receive(:full_image_name_with_fallback).and_return("image:develop")
298
312
  allow(subject).to receive(:environment_variables).and_return(environment = double)
299
313
  allow(subject).to receive(:volumes).and_return(volumes = double)
300
- allow(subject).to receive(:ports).and_return(ports = double)
301
- expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name_with_fallback, e: environment, v: volumes, p: ports, command: "foobar")
314
+ allow(subject).to receive(:link_backing_services).and_return(link = double)
315
+ expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name_with_fallback, link: link, e: environment, v: volumes, command: "foobar")
302
316
  subject.run("foobar")
303
317
  end
304
318
  end
@@ -308,9 +322,9 @@ describe Dockistrano::Service do
308
322
  allow(subject).to receive(:full_image_name_with_fallback).and_return("image:develop")
309
323
  allow(subject).to receive(:environment_variables).and_return(environment = double)
310
324
  allow(subject).to receive(:volumes).and_return(volumes = double)
311
- allow(subject).to receive(:ports).and_return(ports = double)
325
+ allow(subject).to receive(:link_backing_services).and_return(link = double)
312
326
  expect(subject).to receive(:create_data_directories)
313
- expect(Dockistrano::Docker).to receive(:exec).with(subject.full_image_name_with_fallback, e: environment, v: volumes, p: ports, command: "foobar")
327
+ expect(Dockistrano::Docker).to receive(:exec).with(subject.full_image_name_with_fallback, link: link, e: environment, v: volumes, command: "foobar")
314
328
  subject.exec("foobar")
315
329
  end
316
330
  end
@@ -320,9 +334,9 @@ describe Dockistrano::Service do
320
334
  allow(subject).to receive(:full_image_name_with_fallback).and_return("image:develop")
321
335
  allow(subject).to receive(:environment_variables).and_return(environment = double)
322
336
  allow(subject).to receive(:volumes).and_return(volumes = double)
323
- allow(subject).to receive(:ports).and_return(ports = double)
337
+ allow(subject).to receive(:link_backing_services).and_return(link = double)
324
338
  expect(subject).to receive(:create_data_directories)
325
- expect(Dockistrano::Docker).to receive(:console).with(subject.full_image_name_with_fallback, e: environment, v: volumes, p: ports, command: "foobar")
339
+ expect(Dockistrano::Docker).to receive(:console).with(subject.full_image_name_with_fallback, link: link, e: environment, v: volumes, command: "foobar")
326
340
  subject.console("foobar")
327
341
  end
328
342
  end
@@ -345,13 +359,23 @@ describe Dockistrano::Service do
345
359
  end
346
360
  end
347
361
 
362
+ context "#link_backing_services" do
363
+ it "returns an array with image names of backing services" do
364
+ allow(subject).to receive(:backing_services).and_return({
365
+ "postgresql" => double(image_name: "postgresql"),
366
+ "redis" => double(image_name: "redis")
367
+ })
368
+ expect(subject.link_backing_services).to eq(["postgresql:postgresql", "redis:redis"])
369
+ end
370
+ end
371
+
348
372
  context "#environment_variables" do
349
373
  let(:backing_service){
350
374
  double(
351
375
  ip_address: "172.0.0.1",
352
376
  port: "1245",
353
377
  backing_service_env: { database: "dockistrano_development" },
354
- provided_environment_variables: { "DATABASE_URL" => "postgres://postgres@$POSTGRESQL_IP/$POSTGRESQL_DATABASE"}
378
+ provided_environment_variables: { "DATABASE_URL" => "postgres://postgres@172.0.0.1/$POSTGRESQL_DATABASE"}
355
379
  )
356
380
  }
357
381
 
@@ -365,11 +389,6 @@ describe Dockistrano::Service do
365
389
  expect(subject.environment_variables["RAILS_ENV"]).to eq("test")
366
390
  end
367
391
 
368
- it "includes environment variables with the ip and port of each backing service" do
369
- expect(subject.environment_variables).to include("POSTGRESQL_IP")
370
- expect(subject.environment_variables).to include("POSTGRESQL_PORT")
371
- end
372
-
373
392
  it "includes variables for the backing service provided in the local configuration" do
374
393
  expect(subject.environment_variables).to include("POSTGRESQL_DATABASE")
375
394
  expect(subject.environment_variables["POSTGRESQL_DATABASE"]).to eq("dockistrano_development")
@@ -383,6 +402,11 @@ describe Dockistrano::Service do
383
402
  it "interpolates environment variables with present values" do
384
403
  expect(subject.environment_variables["DATABASE_URL"]).to eq("postgres://postgres@172.0.0.1/dockistrano_development")
385
404
  end
405
+
406
+ it "leaves variables in tact that could not be replaced" do
407
+ subject.config = { "environment" => { "rails_env" => "test$FOOBAR" } }
408
+ expect(subject.environment_variables["RAILS_ENV"]).to eq("test$FOOBAR")
409
+ end
386
410
  end
387
411
 
388
412
  context "#provided_environment_variables" do
@@ -400,8 +424,8 @@ describe Dockistrano::Service do
400
424
  end
401
425
 
402
426
  it "includes a source mount when configured" do
403
- allow(subject).to receive(:mount_src).and_return("/home/app")
404
- expect(subject.volumes).to include("/dockistrano/image/src:/home/app")
427
+ allow(subject).to receive(:mount_src).and_return({ "/home/vagrant/src/app2" => "/home/app" })
428
+ expect(subject.volumes).to include("/home/vagrant/src/app2:/home/app")
405
429
  end
406
430
  end
407
431
 
@@ -453,53 +477,55 @@ describe Dockistrano::Service do
453
477
  end
454
478
  end
455
479
 
456
- context "#ip_address" do
457
- it "returns the ip address of the running container" do
458
- allow(subject).to receive(:running?).and_return(true)
459
- allow(subject).to receive(:container_settings).and_return({ "NetworkSettings" => { "IPAddress" => "33.33.33.10" }})
460
- expect(subject.ip_address).to eq("33.33.33.10")
461
- end
462
-
463
- it "returns nil when the container is not running" do
464
- allow(subject).to receive(:running?).and_return(false)
465
- expect(subject.ip_address).to be_nil
466
- end
467
- end
468
-
469
- context "#port" do
470
- it "returns the ip address of the running container" do
480
+ context "#ip_address_for_port" do
481
+ it "returns the ip address at which the port is listening" do
471
482
  allow(subject).to receive(:running?).and_return(true)
472
- allow(subject).to receive(:container_settings).and_return({ "NetworkSettings" => { "PortMapping" => { "Tcp" => { "8000" => "80" } } } })
473
- expect(subject.port).to eq("8000")
474
- end
475
-
476
- it "returns nil when the container is not running" do
477
- allow(subject).to receive(:running?).and_return(false)
478
- expect(subject.port).to be_nil
483
+ allow(subject).to receive(:container_settings).and_return({ "NetworkSettings" => { "Ports" => {
484
+ "3000/tcp" => [
485
+ {
486
+ "HostIp" => "127.0.0.1",
487
+ "HostPort" => "3000"
488
+ }
489
+ ]
490
+ }}})
491
+ expect(subject.ip_address_for_port(3000)).to eq("127.0.0.1")
479
492
  end
480
493
  end
481
494
 
482
495
  context "#ports" do
483
496
  it "returns a string representation of the port mappings" do
484
497
  subject.config = { "ports" => { "1234" => "5678" } }
485
- expect(subject.ports).to eq(["1234:5678"])
498
+ expect(subject.ports).to eq(["172.17.42.1:1234:5678"])
499
+ end
500
+
501
+ it "returns the ip address included in the configuration" do
502
+ subject.config = { "ports" => { "33.33.33.10:1234" => "5678" } }
503
+ expect(subject.ports).to eq(["33.33.33.10:1234:5678"])
486
504
  end
487
505
  end
488
506
 
489
507
  context "#attach" do
490
508
  it "attaches to the output of the container" do
491
- expect(Dockistrano::Docker).to receive(:attach).with("123456")
492
- expect(Dockistrano::Docker).to receive(:running_container_id).with(subject.full_image_name).and_return("123456")
509
+ expect(Dockistrano::Docker).to receive(:attach).with(subject.image_name)
493
510
  subject.attach
494
511
  end
512
+
513
+ it "attaches to the output of the container when additional command given" do
514
+ expect(Dockistrano::Docker).to receive(:attach).with("#{subject.image_name}_worker")
515
+ subject.attach("worker")
516
+ end
495
517
  end
496
518
 
497
519
  context "#logs" do
498
520
  it "returns the logs of the last run of the container" do
499
- expect(Dockistrano::Docker).to receive(:logs).with("123456")
500
- expect(Dockistrano::Docker).to receive(:last_run_container_id).with(subject.full_image_name).and_return("123456")
521
+ expect(Dockistrano::Docker).to receive(:logs).with(subject.image_name)
501
522
  subject.logs
502
523
  end
524
+
525
+ it "returns the logs of the last run of the container when additional command given" do
526
+ expect(Dockistrano::Docker).to receive(:logs).with("#{subject.image_name}_worker")
527
+ subject.logs("worker")
528
+ end
503
529
  end
504
530
 
505
531
  context "#create_data_directories" do
@@ -514,6 +540,7 @@ describe Dockistrano::Service do
514
540
  v: volumes,
515
541
  e: environment_variables,
516
542
  u: "root",
543
+ rm: true,
517
544
  command: "/bin/bash -c 'mkdir -p /dockistrano/data/logs; chown app:app /dockistrano/data/logs'"
518
545
  )
519
546
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edwin Vlieg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-28 00:00:00.000000000 Z
11
+ date: 2013-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-shell
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: terminal-notifier-guard
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -169,7 +183,6 @@ email:
169
183
  - edwin@moneybird.com
170
184
  executables:
171
185
  - doc
172
- - docker
173
186
  extensions: []
174
187
  extra_rdoc_files: []
175
188
  files:
@@ -181,7 +194,6 @@ files:
181
194
  - README.md
182
195
  - Rakefile
183
196
  - bin/doc
184
- - bin/docker
185
197
  - dockistrano.gemspec
186
198
  - lib/dockistrano.rb
187
199
  - lib/dockistrano/cli.rb
data/bin/docker DELETED
Binary file