centurion 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +64 -5
- data/bin/centurion +2 -2
- data/lib/centurion/deploy.rb +3 -3
- data/lib/centurion/deploy_dsl.rb +21 -5
- data/lib/centurion/docker_server.rb +6 -3
- data/lib/centurion/docker_server_group.rb +5 -3
- data/lib/centurion/docker_via_api.rb +33 -9
- data/lib/centurion/docker_via_cli.rb +45 -5
- data/lib/centurion/dogestry.rb +6 -19
- data/lib/centurion/version.rb +1 -1
- data/lib/tasks/deploy.rake +12 -17
- data/spec/capistrano_dsl_spec.rb +1 -1
- data/spec/deploy_dsl_spec.rb +1 -1
- data/spec/deploy_spec.rb +66 -35
- data/spec/docker_server_group_spec.rb +1 -1
- data/spec/docker_server_spec.rb +2 -2
- data/spec/docker_via_api_spec.rb +211 -76
- data/spec/docker_via_cli_spec.rb +74 -25
- data/spec/dogestry_spec.rb +14 -7
- data/spec/support/matchers/capistrano_dsl_matchers.rb +2 -2
- metadata +2 -2
data/lib/centurion/version.rb
CHANGED
data/lib/tasks/deploy.rake
CHANGED
@@ -49,25 +49,18 @@ namespace :deploy do
|
|
49
49
|
s3_region: fetch(:s3_region) || 'us-east-1',
|
50
50
|
)
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
info "** Downloading image(#{fetch(:image)}:#{fetch(:tag)}) from S3 to local directory"
|
56
|
-
registry.download_image_to_temp_dir("#{fetch(:image)}:#{fetch(:tag)}", local_dir)
|
57
|
-
|
58
|
-
# Upload image from local /tmp/directory to specified Docker hosts
|
59
|
-
target_servers = Centurion::DockerServerGroup.new(fetch(:hosts), fetch(:docker_path))
|
60
|
-
target_servers.each_in_parallel do |target_server|
|
61
|
-
|
62
|
-
docker_host = "tcp://#{target_server.hostname}:#{target_server.port}"
|
52
|
+
target_servers = Centurion::DockerServerGroup.new(fetch(:hosts), fetch(:docker_path))
|
53
|
+
pull_hosts = []
|
63
54
|
|
64
|
-
|
55
|
+
target_servers.each do |target_server|
|
56
|
+
docker_host = "tcp://#{target_server.hostname}:#{target_server.port}"
|
57
|
+
pull_hosts.push(docker_host)
|
58
|
+
end
|
65
59
|
|
66
|
-
|
60
|
+
image_and_tag = "#{fetch(:image)}:#{fetch(:tag)}"
|
61
|
+
info "** Pulling image(#{image_and_tag}) from S3 to Docker Hosts: #{pull_hosts}"
|
67
62
|
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
63
|
+
registry.pull(image_and_tag, pull_hosts)
|
71
64
|
end
|
72
65
|
end
|
73
66
|
|
@@ -187,7 +180,9 @@ namespace :deploy do
|
|
187
180
|
if fetch(:registry) == 'dogestry'
|
188
181
|
invoke 'deploy:dogestry:pull_image'
|
189
182
|
else
|
190
|
-
|
183
|
+
hosts, docker_path = fetch(:hosts, []), fetch(:docker_path)
|
184
|
+
target_servers = Centurion::DockerServerGroup.new(hosts, docker_path,
|
185
|
+
build_tls_params)
|
191
186
|
target_servers.each_in_parallel do |target_server|
|
192
187
|
target_server.pull(fetch(:image), fetch(:tag))
|
193
188
|
end
|
data/spec/capistrano_dsl_spec.rb
CHANGED
data/spec/deploy_dsl_spec.rb
CHANGED
@@ -115,7 +115,7 @@ describe Centurion::DeployDSL do
|
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'gets current tags for an image' do
|
118
|
-
Centurion::DockerServer.
|
118
|
+
allow_any_instance_of(Centurion::DockerServer).to receive(:current_tags_for).and_return([ 'foo' ])
|
119
119
|
DeployDSLTest.set(:hosts, [ 'host1' ])
|
120
120
|
|
121
121
|
expect(DeployDSLTest.get_current_tags_for('asdf')).to eq [ { server: 'host1', tags: [ 'foo'] } ]
|
data/spec/deploy_spec.rb
CHANGED
@@ -3,9 +3,11 @@ require 'centurion/deploy_dsl'
|
|
3
3
|
require 'centurion/logging'
|
4
4
|
|
5
5
|
describe Centurion::Deploy do
|
6
|
-
let(:mock_ok_status) { double('http_status_ok').tap { |s| s.
|
7
|
-
let(:mock_bad_status) { double('http_status_ok').tap { |s| s.
|
8
|
-
let(:server) { double('docker_server').tap { |s|
|
6
|
+
let(:mock_ok_status) { double('http_status_ok').tap { |s| allow(s).to receive(:status).and_return(200) } }
|
7
|
+
let(:mock_bad_status) { double('http_status_ok').tap { |s| allow(s).to receive(:status).and_return(500) } }
|
8
|
+
let(:server) { double('docker_server').tap { |s|
|
9
|
+
allow(s).to receive(:hostname).and_return(hostname)
|
10
|
+
allow(s).to receive(:attach) } }
|
9
11
|
let(:port) { 8484 }
|
10
12
|
let(:container) { { 'Ports' => [{ 'PublicPort' => port }, 'Created' => Time.now.to_i ], 'Id' => '21adfd2ef2ef2349494a', 'Names' => [ 'name1' ] } }
|
11
13
|
let(:endpoint) { '/status/check' }
|
@@ -16,6 +18,12 @@ describe Centurion::Deploy do
|
|
16
18
|
o.send(:extend, Centurion::Logging)
|
17
19
|
end
|
18
20
|
end
|
21
|
+
let(:hostname) { 'host1' }
|
22
|
+
|
23
|
+
before do
|
24
|
+
allow(test_deploy).to receive(:fetch).and_return nil
|
25
|
+
allow(test_deploy).to receive(:fetch).with(:container_hostname, hostname).and_return(hostname)
|
26
|
+
end
|
19
27
|
|
20
28
|
describe '#http_status_ok?' do
|
21
29
|
it 'validates HTTP status checks when the response is good' do
|
@@ -25,7 +33,7 @@ describe Centurion::Deploy do
|
|
25
33
|
|
26
34
|
it 'identifies bad HTTP responses' do
|
27
35
|
expect(Excon).to receive(:get).and_return(mock_bad_status)
|
28
|
-
test_deploy.
|
36
|
+
allow(test_deploy).to receive(:warn)
|
29
37
|
expect(test_deploy.http_status_ok?(server, port, endpoint)).to be_falsey
|
30
38
|
end
|
31
39
|
|
@@ -46,32 +54,32 @@ describe Centurion::Deploy do
|
|
46
54
|
it 'recognizes when no containers are running' do
|
47
55
|
expect(server).to receive(:find_containers_by_public_port).and_return([])
|
48
56
|
|
49
|
-
test_deploy.container_up?(server, port).
|
57
|
+
expect(test_deploy.container_up?(server, port)).to be_falsey
|
50
58
|
end
|
51
59
|
|
52
60
|
it 'complains when more than one container is bound to this port' do
|
53
61
|
expect(server).to receive(:find_containers_by_public_port).and_return([1,2])
|
54
62
|
expect(test_deploy).to receive(:error).with /More than one container/
|
55
63
|
|
56
|
-
test_deploy.container_up?(server, port).
|
64
|
+
expect(test_deploy.container_up?(server, port)).to be_falsey
|
57
65
|
end
|
58
66
|
|
59
67
|
it 'recognizes when the container is actually running' do
|
60
68
|
expect(server).to receive(:find_containers_by_public_port).and_return([container])
|
61
69
|
expect(test_deploy).to receive(:info).with /Found container/
|
62
70
|
|
63
|
-
test_deploy.container_up?(server, port).
|
71
|
+
expect(test_deploy.container_up?(server, port)).to be_truthy
|
64
72
|
end
|
65
73
|
end
|
66
74
|
|
67
75
|
describe '#wait_for_http_status_ok?' do
|
68
76
|
before do
|
69
|
-
test_deploy.
|
77
|
+
allow(test_deploy).to receive(:info)
|
70
78
|
end
|
71
79
|
|
72
80
|
it 'identifies that a container is up' do
|
73
|
-
test_deploy.
|
74
|
-
test_deploy.
|
81
|
+
allow(test_deploy).to receive(:container_up?).and_return(true)
|
82
|
+
allow(test_deploy).to receive(:http_status_ok?).and_return(true)
|
75
83
|
|
76
84
|
test_deploy.wait_for_http_status_ok(server, port, '/foo', 'image_id', 'chaucer')
|
77
85
|
expect(test_deploy).to have_received(:info).with(/Waiting for the port/)
|
@@ -79,9 +87,9 @@ describe Centurion::Deploy do
|
|
79
87
|
end
|
80
88
|
|
81
89
|
it 'waits when the container is not yet up' do
|
82
|
-
test_deploy.
|
83
|
-
test_deploy.
|
84
|
-
test_deploy.
|
90
|
+
allow(test_deploy).to receive(:container_up?).and_return(false)
|
91
|
+
allow(test_deploy).to receive(:error)
|
92
|
+
allow(test_deploy).to receive(:warn)
|
85
93
|
expect(test_deploy).to receive(:exit)
|
86
94
|
expect(test_deploy).to receive(:sleep).with(0)
|
87
95
|
|
@@ -90,10 +98,10 @@ describe Centurion::Deploy do
|
|
90
98
|
end
|
91
99
|
|
92
100
|
it 'waits when the HTTP status is not OK' do
|
93
|
-
test_deploy.
|
94
|
-
test_deploy.
|
95
|
-
test_deploy.
|
96
|
-
test_deploy.
|
101
|
+
allow(test_deploy).to receive(:container_up?).and_return(true)
|
102
|
+
allow(test_deploy).to receive(:http_status_ok?).and_return(false)
|
103
|
+
allow(test_deploy).to receive(:error)
|
104
|
+
allow(test_deploy).to receive(:warn)
|
97
105
|
expect(test_deploy).to receive(:exit)
|
98
106
|
|
99
107
|
test_deploy.wait_for_http_status_ok(server, port, '/foo', 'image_id', 'chaucer', 1, 0)
|
@@ -215,18 +223,19 @@ describe Centurion::Deploy do
|
|
215
223
|
let(:bindings) { {'80/tcp'=>[{'HostIp'=>'0.0.0.0', 'HostPort'=>'80'}]} }
|
216
224
|
|
217
225
|
it 'pass host_config to start_container' do
|
218
|
-
server.
|
226
|
+
allow(server).to receive(:container_config_for).and_return({
|
219
227
|
'Image' => 'image_id',
|
220
228
|
'Hostname' => server.hostname,
|
221
229
|
})
|
222
230
|
|
223
|
-
server.
|
231
|
+
allow(server).to receive(:create_container).and_return({
|
224
232
|
'Id' => 'abc123456'
|
225
233
|
})
|
226
234
|
|
227
|
-
server.
|
235
|
+
allow(server).to receive(:inspect_container)
|
228
236
|
|
229
237
|
allow(test_deploy).to receive(:fetch).with(:custom_dns).and_return('8.8.8.8')
|
238
|
+
allow(test_deploy).to receive(:fetch).with(:name).and_return(nil)
|
230
239
|
|
231
240
|
expect(server).to receive(:start_container).with(
|
232
241
|
'abc123456',
|
@@ -242,14 +251,14 @@ describe Centurion::Deploy do
|
|
242
251
|
|
243
252
|
describe '#start_new_container' do
|
244
253
|
let(:bindings) { {'80/tcp'=>[{'HostIp'=>'0.0.0.0', 'HostPort'=>'80'}]} }
|
245
|
-
let(:env)
|
246
|
-
let(:volumes)
|
247
|
-
let(:command)
|
254
|
+
let(:env) { { 'FOO' => 'BAR' } }
|
255
|
+
let(:volumes) { ['/foo:/bar'] }
|
256
|
+
let(:command) { ['/bin/echo', 'hi'] }
|
248
257
|
|
249
258
|
it 'configures the container' do
|
250
259
|
expect(test_deploy).to receive(:container_config_for).with(server, 'image_id', bindings, nil, {}, nil).once
|
251
260
|
|
252
|
-
test_deploy.
|
261
|
+
allow(test_deploy).to receive(:start_container_with_config)
|
253
262
|
|
254
263
|
test_deploy.start_new_container(server, 'image_id', bindings, {}, nil)
|
255
264
|
end
|
@@ -260,22 +269,44 @@ describe Centurion::Deploy do
|
|
260
269
|
test_deploy.start_new_container(server, 'image_id', bindings, {})
|
261
270
|
end
|
262
271
|
|
272
|
+
it 'sets the container hostname when asked' do
|
273
|
+
allow(test_deploy).to receive(:fetch).with(:container_hostname, anything()).and_return('chaucer')
|
274
|
+
|
275
|
+
expect(server).to receive(:create_container).with(
|
276
|
+
hash_including(
|
277
|
+
'Image' => 'image_id',
|
278
|
+
'Hostname' => 'chaucer',
|
279
|
+
'ExposedPorts' => {'80/tcp'=>{}},
|
280
|
+
'Cmd' => command,
|
281
|
+
'Env' => ['FOO=BAR'],
|
282
|
+
'Volumes' => {'/bar' => {}},
|
283
|
+
),
|
284
|
+
nil
|
285
|
+
).and_return(container)
|
286
|
+
|
287
|
+
expect(server).to receive(:start_container)
|
288
|
+
expect(server).to receive(:inspect_container)
|
289
|
+
test_deploy.start_new_container(server, 'image_id', bindings, volumes, env, command)
|
290
|
+
end
|
291
|
+
|
263
292
|
it 'ultimately asks the server object to do the work' do
|
264
293
|
allow(test_deploy).to receive(:fetch).with(:custom_dns).and_return(nil)
|
294
|
+
allow(test_deploy).to receive(:fetch).with(:name).and_return('app1')
|
265
295
|
|
266
|
-
server.
|
296
|
+
expect(server).to receive(:create_container).with(
|
267
297
|
hash_including(
|
268
|
-
'Image'=>'image_id',
|
269
|
-
'Hostname'=>
|
270
|
-
'ExposedPorts'=>{'80/tcp'=>{}},
|
271
|
-
'Cmd'
|
272
|
-
'Env'
|
273
|
-
'Volumes'
|
274
|
-
)
|
298
|
+
'Image' => 'image_id',
|
299
|
+
'Hostname' => hostname,
|
300
|
+
'ExposedPorts' => {'80/tcp'=>{}},
|
301
|
+
'Cmd' => command,
|
302
|
+
'Env' => ['FOO=BAR'],
|
303
|
+
'Volumes' => {'/bar' => {}},
|
304
|
+
),
|
305
|
+
'app1'
|
275
306
|
).and_return(container)
|
276
307
|
|
277
|
-
server.
|
278
|
-
server.
|
308
|
+
expect(server).to receive(:start_container)
|
309
|
+
expect(server).to receive(:inspect_container)
|
279
310
|
|
280
311
|
new_container = test_deploy.start_new_container(server, 'image_id', bindings, volumes, env, command)
|
281
312
|
expect(new_container).to eq(container)
|
@@ -290,7 +321,7 @@ describe Centurion::Deploy do
|
|
290
321
|
|
291
322
|
it 'configures the container' do
|
292
323
|
expect(test_deploy).to receive(:container_config_for).with(server, 'image_id', bindings, env, volumes, command).once
|
293
|
-
test_deploy.
|
324
|
+
allow(test_deploy).to receive(:start_container_with_config)
|
294
325
|
|
295
326
|
test_deploy.start_new_container(server, 'image_id', bindings, volumes, env, command)
|
296
327
|
end
|
@@ -23,7 +23,7 @@ describe Centurion::DockerServerGroup do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'can run parallel operations' do
|
26
|
-
item = double('item').tap { |i| i.
|
26
|
+
item = double('item').tap { |i| allow(i).to receive(:dummy_method) }
|
27
27
|
expect(item).to receive(:dummy_method).twice
|
28
28
|
|
29
29
|
expect { group.each_in_parallel { |host| item.dummy_method } }.not_to raise_error
|
data/spec/docker_server_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe Centurion::DockerServer do
|
|
28
28
|
it "delegates '#{method}' to #{delegate}" do
|
29
29
|
dummy_result = double
|
30
30
|
dummy_delegate = double(method => dummy_result)
|
31
|
-
server.
|
31
|
+
allow(server).to receive(delegate).and_return(dummy_delegate)
|
32
32
|
expect(dummy_delegate).to receive(method)
|
33
33
|
expect(server.send(method)).to be(dummy_result)
|
34
34
|
end
|
@@ -37,7 +37,7 @@ describe Centurion::DockerServer do
|
|
37
37
|
|
38
38
|
it 'returns tags associated with an image' do
|
39
39
|
image_names = %w[target:latest target:production other:latest]
|
40
|
-
server.
|
40
|
+
allow(server).to receive(:ps).and_return(image_names.map {|name| { 'Image' => name } })
|
41
41
|
expect(server.current_tags_for('target')).to eq(%w[latest production])
|
42
42
|
end
|
43
43
|
end
|
data/spec/docker_via_api_spec.rb
CHANGED
@@ -4,8 +4,6 @@ require 'centurion/docker_via_api'
|
|
4
4
|
describe Centurion::DockerViaApi do
|
5
5
|
let(:hostname) { 'example.com' }
|
6
6
|
let(:port) { '2375' }
|
7
|
-
let(:api) { Centurion::DockerViaApi.new(hostname, port) }
|
8
|
-
let(:excon_uri) { "http://#{hostname}:#{port}/" }
|
9
7
|
let(:json_string) { '[{ "Hello": "World" }]' }
|
10
8
|
let(:json_value) { JSON.load(json_string) }
|
11
9
|
let(:inspected_containers) do
|
@@ -16,90 +14,227 @@ describe Centurion::DockerViaApi do
|
|
16
14
|
]
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
and_return(double(body: json_string, status: 200))
|
23
|
-
expect(api.ps).to eq(json_value)
|
24
|
-
end
|
17
|
+
context 'without TLS certificates' do
|
18
|
+
let(:excon_uri) { "http://#{hostname}:#{port}/" }
|
19
|
+
let(:api) { Centurion::DockerViaApi.new(hostname, port) }
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
it 'lists processes' do
|
22
|
+
expect(Excon).to receive(:get).
|
23
|
+
with(excon_uri + 'v1.7/containers/json', {}).
|
24
|
+
and_return(double(body: json_string, status: 200))
|
25
|
+
expect(api.ps).to eq(json_value)
|
26
|
+
end
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
28
|
+
it 'lists all processes' do
|
29
|
+
expect(Excon).to receive(:get).
|
30
|
+
with(excon_uri + 'v1.7/containers/json?all=1', {}).
|
31
|
+
and_return(double(body: json_string, status: 200))
|
32
|
+
expect(api.ps(all: true)).to eq(json_value)
|
33
|
+
end
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
35
|
+
it 'creates a container' do
|
36
|
+
configuration_as_json = double
|
37
|
+
configuration = double(:to_json => configuration_as_json)
|
38
|
+
expect(Excon).to receive(:post).
|
39
|
+
with(excon_uri + "v1.10" + "/containers/create",
|
40
|
+
query: nil,
|
41
|
+
body: configuration_as_json,
|
42
|
+
headers: {'Content-Type' => 'application/json'}).
|
43
|
+
and_return(double(body: json_string, status: 201))
|
44
|
+
api.create_container(configuration)
|
45
|
+
end
|
51
46
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
47
|
+
it 'creates a container with a name' do
|
48
|
+
configuration_as_json = double
|
49
|
+
configuration = double(:to_json => configuration_as_json)
|
50
|
+
expect(Excon).to receive(:post).
|
51
|
+
with(excon_uri + "v1.10" + "/containers/create",
|
52
|
+
query: { :name => match(/^app1-[a-f0-9]+$/) },
|
53
|
+
body: configuration_as_json,
|
54
|
+
headers: {'Content-Type' => 'application/json'}).
|
55
|
+
and_return(double(body: json_string, status: 201))
|
56
|
+
api.create_container(configuration, 'app1')
|
57
|
+
end
|
62
58
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
it 'starts a container' do
|
60
|
+
configuration_as_json = double
|
61
|
+
configuration = double(:to_json => configuration_as_json)
|
62
|
+
expect(Excon).to receive(:post).
|
63
|
+
with(excon_uri + "v1.10" + "/containers/12345/start",
|
64
|
+
body: configuration_as_json,
|
65
|
+
headers: {'Content-Type' => 'application/json'}).
|
66
|
+
and_return(double(body: json_string, status: 204))
|
67
|
+
api.start_container('12345', configuration)
|
68
|
+
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
it 'stops a container' do
|
71
|
+
expect(Excon).to receive(:post).
|
72
|
+
with(excon_uri + 'v1.7/containers/12345/stop?t=300', {}).
|
73
|
+
and_return(double(status: 204))
|
74
|
+
api.stop_container('12345', 300)
|
75
|
+
end
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
it 'stops a container with a custom timeout' do
|
78
|
+
expect(Excon).to receive(:post).
|
79
|
+
with(excon_uri + 'v1.7/containers/12345/stop?t=30', {}).
|
80
|
+
and_return(double(status: 204))
|
81
|
+
api.stop_container('12345')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'inspects a container' do
|
85
|
+
expect(Excon).to receive(:get).
|
86
|
+
with(excon_uri + 'v1.7/containers/12345/json', {}).
|
87
|
+
and_return(double(body: json_string, status: 200))
|
88
|
+
expect(api.inspect_container('12345')).to eq(json_value)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'removes a container' do
|
92
|
+
expect(Excon).to receive(:delete).
|
93
|
+
with(excon_uri + 'v1.7/containers/12345', {}).
|
94
|
+
and_return(double(status: 204))
|
95
|
+
expect(api.remove_container('12345')).to eq(true)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'lists old containers for a port' do
|
99
|
+
expect(Excon).to receive(:get).
|
100
|
+
with(excon_uri + 'v1.7/containers/json?all=1', {}).
|
101
|
+
and_return(double(body: inspected_containers.to_json, status: 200))
|
102
|
+
expect(Excon).to receive(:get).
|
103
|
+
with(excon_uri + 'v1.7/containers/123/json', {}).
|
104
|
+
and_return(double(body: inspected_container_on_port("123", 8485).to_json, status: 200))
|
105
|
+
expect(Excon).to receive(:get).
|
106
|
+
with(excon_uri + 'v1.7/containers/789/json', {}).
|
107
|
+
and_return(double(body: inspected_container_on_port("789", 8486).to_json, status: 200))
|
108
|
+
|
109
|
+
expect(api.old_containers_for_port(8485)).to eq([{"Id" => "123", "Status" => "Exit 0"}])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'inspects an image' do
|
113
|
+
expect(Excon).to receive(:get).
|
114
|
+
with(excon_uri + "v1.7" + "/images/foo:bar/json",
|
115
|
+
headers: {'Accept' => 'application/json'}).
|
116
|
+
and_return(double(body: json_string, status: 200))
|
117
|
+
expect(api.inspect_image('foo', 'bar')).to eq(json_value)
|
118
|
+
end
|
83
119
|
|
84
|
-
it 'removes a container' do
|
85
|
-
expect(Excon).to receive(:delete).
|
86
|
-
with(excon_uri + "v1.7" + "/containers/12345").
|
87
|
-
and_return(double(status: 204))
|
88
|
-
expect(api.remove_container('12345')).to eq(true)
|
89
120
|
end
|
90
121
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
122
|
+
context 'with TLS certificates' do
|
123
|
+
let(:excon_uri) { "https://#{hostname}:#{port}/" }
|
124
|
+
let(:tls_args) { { tls: true, tlscacert: '/certs/ca.pem',
|
125
|
+
tlscert: '/certs/cert.pem', tlskey: '/certs/key.pem' } }
|
126
|
+
let(:api) { Centurion::DockerViaApi.new(hostname, port, tls_args) }
|
127
|
+
|
128
|
+
it 'lists processes' do
|
129
|
+
expect(Excon).to receive(:get).
|
130
|
+
with(excon_uri + 'v1.7/containers/json',
|
131
|
+
client_cert: '/certs/cert.pem',
|
132
|
+
client_key: '/certs/key.pem').
|
133
|
+
and_return(double(body: json_string, status: 200))
|
134
|
+
expect(api.ps).to eq(json_value)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'lists all processes' do
|
138
|
+
expect(Excon).to receive(:get).
|
139
|
+
with(excon_uri + 'v1.7/containers/json?all=1',
|
140
|
+
client_cert: '/certs/cert.pem',
|
141
|
+
client_key: '/certs/key.pem').
|
142
|
+
and_return(double(body: json_string, status: 200))
|
143
|
+
expect(api.ps(all: true)).to eq(json_value)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'inspects an image' do
|
147
|
+
expect(Excon).to receive(:get).
|
148
|
+
with(excon_uri + 'v1.7/images/foo:bar/json',
|
149
|
+
client_cert: '/certs/cert.pem',
|
150
|
+
client_key: '/certs/key.pem',
|
151
|
+
headers: {'Accept' => 'application/json'}).
|
152
|
+
and_return(double(body: json_string, status: 200))
|
153
|
+
expect(api.inspect_image('foo', 'bar')).to eq(json_value)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'creates a container' do
|
157
|
+
configuration_as_json = double
|
158
|
+
configuration = double(:to_json => configuration_as_json)
|
159
|
+
expect(Excon).to receive(:post).
|
160
|
+
with(excon_uri + 'v1.10/containers/create',
|
161
|
+
client_cert: '/certs/cert.pem',
|
162
|
+
client_key: '/certs/key.pem',
|
163
|
+
query: nil,
|
164
|
+
body: configuration_as_json,
|
165
|
+
headers: {'Content-Type' => 'application/json'}).
|
166
|
+
and_return(double(body: json_string, status: 201))
|
167
|
+
api.create_container(configuration)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'starts a container' do
|
171
|
+
configuration_as_json = double
|
172
|
+
configuration = double(:to_json => configuration_as_json)
|
173
|
+
expect(Excon).to receive(:post).
|
174
|
+
with(excon_uri + 'v1.10/containers/12345/start',
|
175
|
+
client_cert: '/certs/cert.pem',
|
176
|
+
client_key: '/certs/key.pem',
|
177
|
+
body: configuration_as_json,
|
178
|
+
headers: {'Content-Type' => 'application/json'}).
|
179
|
+
and_return(double(body: json_string, status: 204))
|
180
|
+
api.start_container('12345', configuration)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'stops a container' do
|
184
|
+
expect(Excon).to receive(:post).
|
185
|
+
with(excon_uri + 'v1.7/containers/12345/stop?t=300',
|
186
|
+
client_cert: '/certs/cert.pem',
|
187
|
+
client_key: '/certs/key.pem').
|
188
|
+
and_return(double(status: 204))
|
189
|
+
api.stop_container('12345', 300)
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'stops a container with a custom timeout' do
|
193
|
+
expect(Excon).to receive(:post).
|
194
|
+
with(excon_uri + 'v1.7/containers/12345/stop?t=30',
|
195
|
+
client_cert: '/certs/cert.pem',
|
196
|
+
client_key: '/certs/key.pem').
|
197
|
+
and_return(double(status: 204))
|
198
|
+
api.stop_container('12345')
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'inspects a container' do
|
202
|
+
expect(Excon).to receive(:get).
|
203
|
+
with(excon_uri + 'v1.7/containers/12345/json',
|
204
|
+
client_cert: '/certs/cert.pem',
|
205
|
+
client_key: '/certs/key.pem').
|
206
|
+
and_return(double(body: json_string, status: 200))
|
207
|
+
expect(api.inspect_container('12345')).to eq(json_value)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'removes a container' do
|
211
|
+
expect(Excon).to receive(:delete).
|
212
|
+
with(excon_uri + 'v1.7/containers/12345',
|
213
|
+
client_cert: '/certs/cert.pem',
|
214
|
+
client_key: '/certs/key.pem').
|
215
|
+
and_return(double(status: 204))
|
216
|
+
expect(api.remove_container('12345')).to eq(true)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'lists old containers for a port' do
|
220
|
+
expect(Excon).to receive(:get).
|
221
|
+
with(excon_uri + 'v1.7/containers/json?all=1',
|
222
|
+
client_cert: '/certs/cert.pem',
|
223
|
+
client_key: '/certs/key.pem').
|
224
|
+
and_return(double(body: inspected_containers.to_json, status: 200))
|
225
|
+
expect(Excon).to receive(:get).
|
226
|
+
with(excon_uri + 'v1.7/containers/123/json',
|
227
|
+
client_cert: '/certs/cert.pem',
|
228
|
+
client_key: '/certs/key.pem').
|
229
|
+
and_return(double(body: inspected_container_on_port("123", 8485).to_json, status: 200))
|
230
|
+
expect(Excon).to receive(:get).
|
231
|
+
with(excon_uri + 'v1.7/containers/789/json',
|
232
|
+
client_cert: '/certs/cert.pem',
|
233
|
+
client_key: '/certs/key.pem').
|
234
|
+
and_return(double(body: inspected_container_on_port("789", 8486).to_json, status: 200))
|
235
|
+
|
236
|
+
expect(api.old_containers_for_port(8485)).to eq([{"Id" => "123", "Status" => "Exit 0"}])
|
237
|
+
end
|
103
238
|
end
|
104
239
|
|
105
240
|
def inspected_container_on_port(id, port)
|