dockistrano 0.0.1
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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +101 -0
- data/Rakefile +1 -0
- data/bin/doc +13 -0
- data/bin/docker +0 -0
- data/dockistrano.gemspec +32 -0
- data/lib/dockistrano/cli.rb +220 -0
- data/lib/dockistrano/command_line.rb +28 -0
- data/lib/dockistrano/docker.rb +188 -0
- data/lib/dockistrano/git.rb +27 -0
- data/lib/dockistrano/hipache.rb +62 -0
- data/lib/dockistrano/registry.rb +48 -0
- data/lib/dockistrano/service.rb +331 -0
- data/lib/dockistrano/service_dependency.rb +114 -0
- data/lib/dockistrano/version.rb +3 -0
- data/lib/dockistrano.rb +14 -0
- data/spec/dockistrano/cli_spec.rb +296 -0
- data/spec/dockistrano/command_line_spec.rb +27 -0
- data/spec/dockistrano/docker_spec.rb +242 -0
- data/spec/dockistrano/git_spec.rb +48 -0
- data/spec/dockistrano/hipache_spec.rb +81 -0
- data/spec/dockistrano/registry_spec.rb +56 -0
- data/spec/dockistrano/service_dependency_spec.rb +154 -0
- data/spec/dockistrano/service_spec.rb +536 -0
- data/spec/fixtures/project_1/Dockerfile +0 -0
- data/spec/fixtures/project_1/config/dockistrano.yml +8 -0
- data/spec/spec_helper.rb +21 -0
- metadata +242 -0
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dockistrano::Cli do
|
4
|
+
|
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) }
|
7
|
+
let(:hipache) { double }
|
8
|
+
let(:output) { capture(:stdout) { described_class.start(command) } }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(Dockistrano::Service).to receive(:factory).and_return(service)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "doc status" do
|
15
|
+
let(:command) { ["status"] }
|
16
|
+
|
17
|
+
it "prints the DOCKISTRANO_ENVIRONMENT" do
|
18
|
+
expect(output).to include("DOCKISTRANO_ENVIRONMENT: default")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "prints the DOCKER_HOST_IP" do
|
22
|
+
expect(output).to include("DOCKER_HOST_IP: 127.0.0.1")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "prints the DOCKER_BINARY" do
|
26
|
+
expect(output).to include("DOCKER_BINARY:")
|
27
|
+
expect(output).to include("bin/docker")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "prints the registry" do
|
31
|
+
expect(output).to include("registry: #{service.registry}")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "prints the name of the image" do
|
35
|
+
expect(output).to include("image name: #{service.image_name}")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "prints the tag" do
|
39
|
+
expect(output).to include("tag: #{service.tag}")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "lists all dependencies" do
|
43
|
+
expect(output).to include(backing_service.full_image_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "lists environment variables" do
|
47
|
+
allow(service).to receive(:environment_variables).and_return({ "VARIABLE" => "value"} )
|
48
|
+
expect(output).to include("VARIABLE=value")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "lists the Hipache configuration" do
|
52
|
+
allow(Dockistrano::Hipache).to receive(:new).with("127.0.0.1").and_return(hipache)
|
53
|
+
allow(hipache).to receive(:status).and_return({ "somehostname.dev" => ["127.0.0.1:1000", "23.45.56.75:1234"] })
|
54
|
+
expect(output).to include("somehostname.dev: 127.0.0.1:1000, 23.45.56.75:1234")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "doc build" do
|
59
|
+
let(:command) { ["build"] }
|
60
|
+
|
61
|
+
it "builds a container" do
|
62
|
+
expect(service).to receive(:build).and_return(true)
|
63
|
+
expect(service).to receive(:test).and_return(true)
|
64
|
+
expect(service).to receive(:push).and_return(true)
|
65
|
+
expect(output).to include("built")
|
66
|
+
expect(output).to include("tests")
|
67
|
+
expect(output).to include("pushed")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "doesn't run the tests and push when building failed" do
|
71
|
+
expect(service).to receive(:build).and_return(false)
|
72
|
+
expect(service).to_not receive(:test)
|
73
|
+
expect(service).to_not receive(:push)
|
74
|
+
expect { output }.to raise_error(SystemExit)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "doesn't push when tests failed" do
|
78
|
+
expect(service).to receive(:build).and_return(true)
|
79
|
+
expect(service).to receive(:test).and_return(false)
|
80
|
+
expect(service).to_not receive(:push)
|
81
|
+
expect { output }.to raise_error(SystemExit)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "doc pull" do
|
86
|
+
let(:command) { ["pull"] }
|
87
|
+
|
88
|
+
it "pulls a backing service when newer versions are available" do
|
89
|
+
expect(backing_service).to receive(:newer_version_available?).and_return(true)
|
90
|
+
expect(backing_service).to receive(:pull)
|
91
|
+
expect(output).to include("Pulled")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "doesn't pull a service when no new versions are available" do
|
95
|
+
expect(backing_service).to receive(:newer_version_available?).and_return(false)
|
96
|
+
expect(backing_service).to_not receive(:pull)
|
97
|
+
expect(output).to include("Uptodate")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "pulls the application container when newer versions are available" do
|
101
|
+
expect(service).to receive(:newer_version_available?).and_return(true)
|
102
|
+
expect(service).to receive(:pull)
|
103
|
+
expect(output).to include("Pulled")
|
104
|
+
end
|
105
|
+
|
106
|
+
it "doesn't pull the application container when no newer versions are available" do
|
107
|
+
expect(service).to receive(:newer_version_available?).and_return(false)
|
108
|
+
expect(service).to_not receive(:pull)
|
109
|
+
expect(output).to include("Uptodate")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "doc push" do
|
114
|
+
it "pushes the current container" do
|
115
|
+
expect(service).to receive(:push)
|
116
|
+
described_class.start(["push"])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "doc start-services" do
|
121
|
+
let(:command) { ["start-services"] }
|
122
|
+
|
123
|
+
it "starts a backing service when it is not running" do
|
124
|
+
expect(backing_service).to receive(:running?).and_return(false)
|
125
|
+
expect(backing_service).to receive(:start)
|
126
|
+
expect(output).to include("Started")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "does nothing when a backing services is already running" do
|
130
|
+
expect(backing_service).to receive(:running?).and_return(true)
|
131
|
+
expect(backing_service).to_not receive(:start)
|
132
|
+
expect(output).to include("Running")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "doc stop-all" do
|
137
|
+
let(:command) { ["stop-all"] }
|
138
|
+
|
139
|
+
it "stops the current container" do
|
140
|
+
expect(service).to receive(:stop)
|
141
|
+
expect(output).to include("Stopped")
|
142
|
+
end
|
143
|
+
|
144
|
+
it "stops all backing services" do
|
145
|
+
expect(backing_service).to receive(:running?).and_return(true)
|
146
|
+
expect(backing_service).to receive(:stop)
|
147
|
+
expect(output).to include("Stopped")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "doc start" do
|
152
|
+
let(:command) { ["start"] }
|
153
|
+
|
154
|
+
it "starts the services when not running" do
|
155
|
+
expect(service).to receive(:running?).and_return(false)
|
156
|
+
expect(service).to receive(:start)
|
157
|
+
expect(output).to include("Started")
|
158
|
+
end
|
159
|
+
|
160
|
+
it "doesn't start the services when already running" do
|
161
|
+
expect(service).to receive(:running?).and_return(true)
|
162
|
+
expect(service).to_not receive(:start)
|
163
|
+
expect(output).to include("Running")
|
164
|
+
end
|
165
|
+
|
166
|
+
it "prints an error when environment variables are missing" do
|
167
|
+
expect(service).to receive(:running?).and_return(false)
|
168
|
+
expect(service).to receive(:start).and_raise(Dockistrano::Service::EnvironmentVariablesMissing.new("error message"))
|
169
|
+
expect(output).to include("error message")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "doc stop" do
|
174
|
+
let(:command) { ["stop"] }
|
175
|
+
|
176
|
+
it "stops the current container" do
|
177
|
+
expect(service).to receive(:stop)
|
178
|
+
expect(output).to include("Stopped")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "doc stop ID" do
|
183
|
+
let(:command) { ["stop", "123456789"] }
|
184
|
+
|
185
|
+
it "stops the container with the id" do
|
186
|
+
expect(Dockistrano::Docker).to receive(:stop).with("123456789")
|
187
|
+
expect(output).to include("Stopped")
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "doc restart" do
|
192
|
+
let(:command) { ["restart"] }
|
193
|
+
|
194
|
+
it "restarts the current container" do
|
195
|
+
expect(service).to receive(:stop)
|
196
|
+
expect(service).to receive(:start)
|
197
|
+
expect(output).to include("Stopped")
|
198
|
+
expect(output).to include("Started")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "doc exec COMMAND" do
|
203
|
+
let(:command) { ["exec", "bin/rspec", "-t", "spec/models/my_model_spec.rb"] }
|
204
|
+
|
205
|
+
it "executes the command in the container" do
|
206
|
+
expect(service).to receive(:exec).with("bin/rspec -t spec/models/my_model_spec.rb", { "environment" => "default" })
|
207
|
+
output
|
208
|
+
end
|
209
|
+
|
210
|
+
it "prints an error when environment variables are missing" do
|
211
|
+
expect(service).to receive(:exec).and_raise(Dockistrano::Service::EnvironmentVariablesMissing.new("error message"))
|
212
|
+
expect(output).to include("error message")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "doc console" do
|
217
|
+
let(:command) { ["console"] }
|
218
|
+
|
219
|
+
it "starts a bash console in the container" do
|
220
|
+
expect(service).to receive(:console).with("/bin/bash", { "environment" => "default" })
|
221
|
+
output
|
222
|
+
end
|
223
|
+
|
224
|
+
it "prints an error when environment variables are missing" do
|
225
|
+
expect(service).to receive(:console).and_raise(Dockistrano::Service::EnvironmentVariablesMissing.new("error message"))
|
226
|
+
expect(output).to include("error message")
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "doc console COMMAND" do
|
231
|
+
let(:command) { ["console", "bin/rails console"] }
|
232
|
+
|
233
|
+
it "starts a console in the container" do
|
234
|
+
expect(service).to receive(:console).with("bin/rails console", { "environment" => "default" })
|
235
|
+
output
|
236
|
+
end
|
237
|
+
|
238
|
+
it "prints an error when environment variables are missing" do
|
239
|
+
expect(service).to receive(:console).and_raise(Dockistrano::Service::EnvironmentVariablesMissing.new("error message"))
|
240
|
+
expect(output).to include("error message")
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "doc clean" do
|
245
|
+
let(:command) { ["clean"] }
|
246
|
+
|
247
|
+
it "cleans the Docker instance and service dependency cache" do
|
248
|
+
expect(Dockistrano::Docker).to receive(:clean)
|
249
|
+
expect(Dockistrano::ServiceDependency).to receive(:clear_cache)
|
250
|
+
output
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context "doc logs" do
|
255
|
+
let(:command) { ["logs"] }
|
256
|
+
|
257
|
+
it "attaches to the containers output when the container is running" do
|
258
|
+
expect(service).to receive(:running?).and_return(true)
|
259
|
+
expect(service).to receive(:attach)
|
260
|
+
expect(output).to include("Container application running, attaching to output")
|
261
|
+
end
|
262
|
+
|
263
|
+
it "prints the logs of the last run" do
|
264
|
+
expect(service).to receive(:running?).and_return(false)
|
265
|
+
expect(service).to receive(:logs)
|
266
|
+
expect(output).to include("Container application stopped, printing logs of last run")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "doc logs NAME" do
|
271
|
+
let(:command) { ["logs", "postgresql"] }
|
272
|
+
|
273
|
+
it "attaches to the containers output when the container is running" do
|
274
|
+
expect(backing_service).to receive(:running?).and_return(true)
|
275
|
+
expect(backing_service).to receive(:attach)
|
276
|
+
expect(output).to include("Container postgresql running, attaching to output")
|
277
|
+
end
|
278
|
+
|
279
|
+
it "prints the logs of the last run" do
|
280
|
+
expect(backing_service).to receive(:running?).and_return(false)
|
281
|
+
expect(backing_service).to receive(:logs)
|
282
|
+
expect(output).to include("Container postgresql stopped, printing logs of last run")
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context "doc ALIAS ARGUMENTS" do
|
287
|
+
let(:command) { ["rspec", "spec/models/my_model_spec.rb"] }
|
288
|
+
|
289
|
+
it "executes aliases that are defined in the configuration" do
|
290
|
+
allow(service).to receive(:config).and_return({ "aliases" => { "rspec" => "exec -e test bin/rspec" } })
|
291
|
+
expect(Kernel).to receive(:exec).with("doc exec -e test bin/rspec spec/models/my_model_spec.rb")
|
292
|
+
output
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dockistrano::CommandLine do
|
4
|
+
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
context ".command_with_result" do
|
8
|
+
it "executes the command and returns a string with the result" do
|
9
|
+
expect(described_class.command_with_result("date")).to eq(`date`)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context ".command_with_stream" do
|
14
|
+
it "executes the command and returns a stream of output" do
|
15
|
+
expect(Kernel).to receive(:system).with("date").and_return(true)
|
16
|
+
expect(described_class.command_with_stream("date")).to be_true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context ".command_with_interaction" do
|
21
|
+
it "executes the command and returns a stream of output" do
|
22
|
+
expect(Kernel).to receive(:exec).with("date").and_return(true)
|
23
|
+
expect(described_class.command_with_interaction("date")).to be_true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dockistrano::Docker do
|
4
|
+
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
before do
|
8
|
+
ENV["DOCKER_BINARY"] = "docker"
|
9
|
+
ENV["DOCKER_HOST_IP"] = "127.0.0.1"
|
10
|
+
end
|
11
|
+
|
12
|
+
context ".docker_command" do
|
13
|
+
it "returns a string that allows us to call docker" do
|
14
|
+
ENV["DOCKER_BINARY"] = "/bin/docker"
|
15
|
+
ENV["DOCKER_HOST_IP"] = "127.0.0.1"
|
16
|
+
expect(subject.docker_command).to eq("/bin/docker -H 127.0.0.1")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises an error when DOCKER_BINARY is not set" do
|
20
|
+
ENV["DOCKER_BINARY"] = nil
|
21
|
+
ENV["DOCKER_HOST_IP"] = "127.0.0.1"
|
22
|
+
expect { subject.docker_command }.to raise_error(Dockistrano::Docker::EnvironmentVariableMissing, /DOCKER_BINARY/)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises an error when DOCKER_BINARY is not set" do
|
26
|
+
ENV["DOCKER_BINARY"] = "/bin/docker"
|
27
|
+
ENV["DOCKER_HOST_IP"] = nil
|
28
|
+
expect { subject.docker_command }.to raise_error(Dockistrano::Docker::EnvironmentVariableMissing, /DOCKER_HOST_IP/)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context ".ps" do
|
33
|
+
it "calls docker with the ps command" do
|
34
|
+
expect(subject).to receive(:execute).with(["ps", {}])
|
35
|
+
subject.ps
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context ".stop" do
|
40
|
+
it "stops the container" do
|
41
|
+
expect(subject).to receive(:execute).with(["stop", "123456789"])
|
42
|
+
subject.stop("123456789")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context ".run" do
|
47
|
+
it "runs the default command when no command is given" do
|
48
|
+
expect(subject).to receive(:execute).with(["run", {e: "VAR=value"}, "registry/image:tag"])
|
49
|
+
subject.run("registry/image:tag", e: "VAR=value")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "runs the default command when no command is given" do
|
53
|
+
expect(subject).to receive(:execute).with(["run", {e: "VAR=value"}, "registry/image:tag", "echo 'foobar'"])
|
54
|
+
subject.run("registry/image:tag", e: "VAR=value", command: "echo 'foobar'")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context ".exec" do
|
59
|
+
it "runs the default command when no command is given" do
|
60
|
+
expect(subject).to receive(:execute).with(["run", {e: "VAR=value"}, "registry/image:tag"], :stream)
|
61
|
+
subject.exec("registry/image:tag", e: "VAR=value")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "runs the default command when no command is given" do
|
65
|
+
expect(subject).to receive(:execute).with(["run", {e: "VAR=value"}, "registry/image:tag", "echo 'foobar'"], :stream)
|
66
|
+
subject.exec("registry/image:tag", e: "VAR=value", command: "echo 'foobar'")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context ".console" do
|
71
|
+
it "runs the default command when no command is given" do
|
72
|
+
expect(subject).to receive(:execute).with(["run", { "e" => "VAR=value", "t" => true, "i" => true }, "registry/image:tag"], :interaction)
|
73
|
+
subject.console("registry/image:tag", "e" => "VAR=value")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "runs the default command when no command is given" do
|
77
|
+
expect(subject).to receive(:execute).with(["run", { "e" => "VAR=value", "t" => true, "i" => true}, "registry/image:tag", "echo 'foobar'"], :interaction)
|
78
|
+
subject.console("registry/image:tag", "e" => "VAR=value", command: "echo 'foobar'")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context ".execute" do
|
83
|
+
it "calls docker and returns the result" do
|
84
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_result).with("docker -H 127.0.0.1 version")
|
85
|
+
subject.execute(["version"])
|
86
|
+
end
|
87
|
+
|
88
|
+
it "adds options to the command" do
|
89
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_result).with("docker -H 127.0.0.1 version -a")
|
90
|
+
subject.execute(["version", { a: true }])
|
91
|
+
end
|
92
|
+
|
93
|
+
it "adds array options to the command" do
|
94
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_result).with("docker -H 127.0.0.1 version -a b -a c")
|
95
|
+
subject.execute(["version", { a: ["b", "c"] }])
|
96
|
+
end
|
97
|
+
|
98
|
+
it "calls docker and stream to stdout" do
|
99
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_stream).with("docker -H 127.0.0.1 version")
|
100
|
+
subject.execute(["version"], :stream)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "calls docker and takes over the console" do
|
104
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_interaction).with("docker -H 127.0.0.1 version")
|
105
|
+
subject.execute(["version"], :interaction)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context ".running_container_id" do
|
110
|
+
it "returns the first id of a running container matching with the image name" do
|
111
|
+
stub_request(:get, "http://127.0.0.1:4243/containers/json").to_return(status: 200, body: '[{"Id":"8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"bin/provider webserver","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49225,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
112
|
+
{"Id":"107fc12c1c4b8e42091bd46e97c985d42c9e0d06506327e84f28fef585f9865a","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"bin/provider worker","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49224,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
113
|
+
{"Id":"066474c539231e445c636dd6ef2879e6a3e304cead10f78bd79e385b161cbdf5","Image":"registry.dev.provider.net/hipache:develop","Command":"supervisord -n","Created":1382447352,"Status":"Up 24 hours","Ports":[{"PrivatePort":80,"PublicPort":80,"Type":"tcp"},{"PrivatePort":6379,"PublicPort":16379,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0}]')
|
114
|
+
|
115
|
+
expect(subject.running_container_id("registry.dev.provider.net/provider-app-2.0:develop")).to eq("8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context ".last_run_container_id" do
|
120
|
+
it "returns the id of the previous run of the container" do
|
121
|
+
stub_request(:get, "http://127.0.0.1:4243/containers/json?all=1").to_return(status: 200, body: '[{"Id":"8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"cat /dockistrano.yml","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49225,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
122
|
+
{"Id":"107fc12c1c4b8e42091bd46e97c985d42c9e0d06506327e84f28fef585f9865a","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"bin/provider worker","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49224,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
123
|
+
{"Id":"066474c539231e445c636dd6ef2879e6a3e304cead10f78bd79e385b161cbdf5","Image":"registry.dev.provider.net/hipache:develop","Command":"supervisord -n","Created":1382447352,"Status":"Up 24 hours","Ports":[{"PrivatePort":80,"PublicPort":80,"Type":"tcp"},{"PrivatePort":6379,"PublicPort":16379,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0}]')
|
124
|
+
|
125
|
+
expect(subject.last_run_container_id("registry.dev.provider.net/provider-app-2.0:develop")).to eq("107fc12c1c4b8e42091bd46e97c985d42c9e0d06506327e84f28fef585f9865a")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context ".image_id" do
|
130
|
+
it "returns the id of the image with the given name" do
|
131
|
+
expect(subject).to receive(:inspect_image).and_return({ "id" => "123456789" })
|
132
|
+
expect(subject.image_id("registry.dev/application:tag")).to eq("123456789")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context ".inspect_image" do
|
137
|
+
it "returns information about the image" do
|
138
|
+
stub_request(:get, "http://127.0.0.1:4243/images/123456789/json").to_return({
|
139
|
+
status: 200,
|
140
|
+
body: '{"id":"49f387cc90f2d5b82ded91c239b6e583f8b955cb532912cc959b1d1289b3f8f1","parent":"7735e8f30a47f02aa46732e864879fad0fb0b74230f7695b6235d6faf766dcb2","created":"2013-10-21T16:03:17.191097983+02:00","container":"5c2c523d3561d205f5459925325890bbf8054010cd908f61feed3e76520dcf54","container_config":{},"docker_version":"0.6.3","config":{},"architecture":"x86_64","Size":12288}'
|
141
|
+
})
|
142
|
+
expect(subject.inspect_image("123456789")).to include('id')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "raises an error when the image is not found" do
|
146
|
+
stub_request(:get, "http://127.0.0.1:4243/images/123456789/json").to_return({
|
147
|
+
status: 404,
|
148
|
+
body: 'No such image: 123456789'
|
149
|
+
})
|
150
|
+
|
151
|
+
expect { subject.inspect_image("123456789") }.to raise_error(Dockistrano::Docker::ImageNotFound, /No such image: 123456789/)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context ".build" do
|
156
|
+
it "builds the container" do
|
157
|
+
expect(subject).to receive(:execute).with(["build", {t: "full_image_name"}, "."], :stream)
|
158
|
+
subject.build("full_image_name")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context ".pull" do
|
163
|
+
it "pulls the container with Docker" do
|
164
|
+
expect(subject).to receive(:execute).with(["pull", { t: "tag" }, "full_image_name"])
|
165
|
+
subject.pull("full_image_name", "tag")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context ".push" do
|
170
|
+
it "pushes the container with Docker" do
|
171
|
+
expect(subject).to receive(:execute).with(["push", "full_image_name", "tag"], :stream)
|
172
|
+
subject.push("full_image_name", "tag")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context ".logs" do
|
177
|
+
it "returns the logs for the container" do
|
178
|
+
expect(subject).to receive(:execute).with(["logs", "72819312"], :stream)
|
179
|
+
subject.logs("72819312")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context ".attach" do
|
184
|
+
it "attaches to the containers output" do
|
185
|
+
expect(subject).to receive(:execute).with(["attach", "72819312"], :stream)
|
186
|
+
subject.attach("72819312")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context ".inspect_container" do
|
191
|
+
it "returns information about the container" do
|
192
|
+
stub_request(:get, 'http://127.0.0.1:4243/containers/123456789/json').to_return({
|
193
|
+
status: 200,
|
194
|
+
body: '{"ID":"8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36","Created":"2013-10-22T15:43:00.213138644+02:00"}'
|
195
|
+
})
|
196
|
+
|
197
|
+
expect(subject.inspect_container("123456789")).to include("ID")
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context ".clean" do
|
202
|
+
before do
|
203
|
+
allow(Dockistrano::CommandLine).to receive(:command_with_stream)
|
204
|
+
allow(subject).to receive(:docker_command).and_return("docker")
|
205
|
+
end
|
206
|
+
|
207
|
+
it "cleans images from the docker instance" do
|
208
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_stream).with("docker rmi $(docker images -a | grep \"^<none>\" | awk '{print $3}')")
|
209
|
+
subject.clean
|
210
|
+
end
|
211
|
+
|
212
|
+
it "cleans containers from the docker instance" do
|
213
|
+
expect(Dockistrano::CommandLine).to receive(:command_with_stream).with("docker rm $(docker ps -a -q)")
|
214
|
+
subject.clean
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context ".stop_all_containers_from_image" do
|
219
|
+
it "stops all containers from an image" do
|
220
|
+
stub_request(:get, "http://127.0.0.1:4243/containers/json").to_return(status: 200, body: '[{"Id":"8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"bin/provider webserver","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49225,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
221
|
+
{"Id":"107fc12c1c4b8e42091bd46e97c985d42c9e0d06506327e84f28fef585f9865a","Image":"registry.dev.provider.net/provider-app-2.0:develop","Command":"bin/provider worker","Created":1382449380,"Status":"Up 24 hours","Ports":[{"PrivatePort":3000,"PublicPort":49224,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0},
|
222
|
+
{"Id":"066474c539231e445c636dd6ef2879e6a3e304cead10f78bd79e385b161cbdf5","Image":"registry.dev.provider.net/hipache:develop","Command":"supervisord -n","Created":1382447352,"Status":"Up 24 hours","Ports":[{"PrivatePort":80,"PublicPort":80,"Type":"tcp"},{"PrivatePort":6379,"PublicPort":16379,"Type":"tcp"}],"SizeRw":0,"SizeRootFs":0}]')
|
223
|
+
|
224
|
+
expect(subject).to receive(:execute).with(["stop", "8e319853f561ba2c22de2ec9ff2584f99d091dd20cc5b393ab874631c6993a36"])
|
225
|
+
expect(subject).to receive(:execute).with(["stop", "107fc12c1c4b8e42091bd46e97c985d42c9e0d06506327e84f28fef585f9865a"])
|
226
|
+
|
227
|
+
subject.stop_all_containers_from_image("registry.dev.provider.net/provider-app-2.0:develop")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context ".tags_for_image" do
|
232
|
+
it "returns a list of tags for an image" do
|
233
|
+
stub_request(:get, "http://127.0.0.1:4243/images/json").to_return({
|
234
|
+
status: 200,
|
235
|
+
body: '[{"Repository":"registry.provider.net/application","Tag":"develop"},{"Repository":"registry.provider.net/application","Tag":"latest"},{"Repository":"registry.provider.net/memcached","Tag":"develop"}]'
|
236
|
+
})
|
237
|
+
|
238
|
+
expect(subject.tags_for_image("registry.provider.net/application")).to eq(["develop", "latest"])
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dockistrano::Git do
|
4
|
+
|
5
|
+
context ".repository_name" do
|
6
|
+
let(:command) { double }
|
7
|
+
|
8
|
+
it "returns the name from a ssh remote" do
|
9
|
+
expect(Cocaine::CommandLine).to receive(:new).with("git config --get remote.origin.url").and_return(command)
|
10
|
+
expect(command).to receive(:run).and_return("git@github.com:username/reponame-with-2.0.git")
|
11
|
+
|
12
|
+
expect(described_class.repository_name).to eq("reponame-with-2.0")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns the name from a ssh remote ending without .git" do
|
16
|
+
expect(Cocaine::CommandLine).to receive(:new).with("git config --get remote.origin.url").and_return(command)
|
17
|
+
expect(command).to receive(:run).and_return("git@github.com:username/reponame-with-2.0")
|
18
|
+
|
19
|
+
expect(described_class.repository_name).to eq("reponame-with-2.0")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns the name from a https remote" do
|
23
|
+
expect(Cocaine::CommandLine).to receive(:new).with("git config --get remote.origin.url").and_return(command)
|
24
|
+
expect(command).to receive(:run).and_return("https://github.com/username/reponame-with-2.0")
|
25
|
+
|
26
|
+
expect(described_class.repository_name).to eq("reponame-with-2.0")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context ".branch" do
|
32
|
+
let(:command) { double }
|
33
|
+
it "returns the name of the branch" do
|
34
|
+
expect(Cocaine::CommandLine).to receive(:new).with("git rev-parse --abbrev-ref HEAD").and_return(command)
|
35
|
+
expect(command).to receive(:run).and_return("branch_name\n")
|
36
|
+
|
37
|
+
expect(described_class.branch).to eq("branch_name")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the JANKY_BRANCH env variable when available" do
|
41
|
+
ENV["JANKY_BRANCH"] = "feature/foobar"
|
42
|
+
expect(described_class.branch).to eq("feature-foobar")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|