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 +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
|