dockistrano 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Guardfile +5 -0
- data/dockistrano.gemspec +1 -0
- data/lib/dockistrano/cli.rb +17 -11
- data/lib/dockistrano/docker.rb +4 -0
- data/lib/dockistrano/service.rb +61 -45
- data/lib/dockistrano/service_dependency.rb +1 -1
- data/lib/dockistrano/version.rb +1 -1
- data/spec/dockistrano/cli_spec.rb +23 -6
- data/spec/dockistrano/docker_spec.rb +7 -0
- data/spec/dockistrano/service_dependency_spec.rb +4 -4
- data/spec/dockistrano/service_spec.rb +98 -71
- metadata +16 -4
- data/bin/docker +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91762ce1db149fa71eab678c80fbc5c7e60c5cbd
|
4
|
+
data.tar.gz: 28d8236dcd51b0d5235fb3ef62252514064d07c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eec347010dcdec6e2db6ba72799be478aa41dff197cb2360849d20ad66a1ca205af2f817ade16b7369d5fbb3f193f89005a3ff1900455e23a18c879845f66196
|
7
|
+
data.tar.gz: a52f46d46ef9510b6a6a8dd7c23db0a67531958dc9f9e0731c14a73d7b795a53e4a358cf016892692c28de1d642430e7847fad54ff6bf252f2cc0c1e0ec3dbd6
|
data/Guardfile
CHANGED
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
|
data/lib/dockistrano/cli.rb
CHANGED
@@ -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"] ||=
|
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
|
-
|
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]
|
data/lib/dockistrano/docker.rb
CHANGED
@@ -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)")
|
data/lib/dockistrano/service.rb
CHANGED
@@ -115,18 +115,13 @@ module Dockistrano
|
|
115
115
|
|
116
116
|
# Stops the container of the current service
|
117
117
|
def stop
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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,
|
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
|
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
|
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
|
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
|
-
|
230
|
-
vars[key]
|
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
|
-
|
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
|
285
|
-
container_settings["NetworkSettings"]["
|
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|
|
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
|
-
|
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
|
-
|
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
|
data/lib/dockistrano/version.rb
CHANGED
@@ -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
|
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(:
|
165
|
-
allow(Dockistrano::
|
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(:
|
169
|
+
expect(Dockistrano::Docker).to receive(:stop).with(subject.image_name)
|
170
170
|
subject.stop
|
171
171
|
end
|
172
172
|
|
173
|
-
it "
|
174
|
-
|
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 "
|
182
|
-
|
183
|
-
expect(
|
184
|
-
|
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(:
|
269
|
+
let(:links) { double }
|
247
270
|
|
248
271
|
before do
|
249
|
-
allow(
|
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,
|
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 "
|
288
|
-
|
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(:
|
301
|
-
expect(Dockistrano::Docker).to receive(:run).with(subject.full_image_name_with_fallback, e: environment, v: volumes,
|
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(:
|
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,
|
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(:
|
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,
|
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
|
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("/
|
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 "#
|
457
|
-
it "returns the ip address
|
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" => { "
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
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(
|
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(
|
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.
|
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-
|
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
|