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.
@@ -1,3 +1,3 @@
1
1
  module Centurion
2
- VERSION = '1.3.1'
2
+ VERSION = '1.4.0'
3
3
  end
@@ -49,25 +49,18 @@ namespace :deploy do
49
49
  s3_region: fetch(:s3_region) || 'us-east-1',
50
50
  )
51
51
 
52
- # Download image from S3 to local /tmp/directory
53
- Dir.mktmpdir("dogestry") do |local_dir|
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
- image_and_tag = "#{fetch(:image)}:#{fetch(:tag)}"
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
- info "** Pushing image(#{image_and_tag}) from #{local_dir} to Docker: #{docker_host}"
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
- registry.upload_temp_dir_image_to_docker(image_and_tag, local_dir, docker_host)
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
- target_servers = Centurion::DockerServerGroup.new(fetch(:hosts), fetch(:docker_path))
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
@@ -61,7 +61,7 @@ describe Capistrano::DSL do
61
61
  end
62
62
 
63
63
  DSLTest.set(:foo, NoAny.new)
64
- DSLTest.any?(:foo).should eq('oh no')
64
+ expect(DSLTest.any?(:foo)).to eq('oh no')
65
65
  end
66
66
  end
67
67
  end
@@ -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.any_instance.stub(current_tags_for: [ 'foo' ])
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'] } ]
@@ -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.stub(status: 200) } }
7
- let(:mock_bad_status) { double('http_status_ok').tap { |s| s.stub(status: 500) } }
8
- let(:server) { double('docker_server').tap { |s| s.stub(hostname: 'host1'); s.stub(:attach) } }
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.stub(:warn)
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).should be_falsey
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).should be_falsey
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).should be_truthy
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.stub(:info)
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.stub(:container_up? => true)
74
- test_deploy.stub(:http_status_ok? => true)
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.stub(:container_up? => false)
83
- test_deploy.stub(:error)
84
- test_deploy.stub(:warn)
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.stub(:container_up? => true)
94
- test_deploy.stub(:http_status_ok? => false)
95
- test_deploy.stub(:error)
96
- test_deploy.stub(:warn)
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.stub(:container_config_for).and_return({
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.stub(:create_container).and_return({
231
+ allow(server).to receive(:create_container).and_return({
224
232
  'Id' => 'abc123456'
225
233
  })
226
234
 
227
- server.stub(:inspect_container)
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) { { 'FOO' => 'BAR' } }
246
- let(:volumes) { ['/foo:/bar'] }
247
- let(:command) { ['/bin/echo', 'hi'] }
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.stub(:start_container_with_config)
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.should_receive(:create_container).with(
296
+ expect(server).to receive(:create_container).with(
267
297
  hash_including(
268
- 'Image'=>'image_id',
269
- 'Hostname'=>'host1',
270
- 'ExposedPorts'=>{'80/tcp'=>{}},
271
- 'Cmd' => command,
272
- 'Env' => ['FOO=BAR'],
273
- 'Volumes' => {'/bar' => {}},
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.should_receive(:start_container)
278
- server.should_receive(:inspect_container)
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.stub(:start_container_with_config)
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.stub(:dummy_method) }
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
@@ -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.stub(delegate => dummy_delegate)
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.stub(ps: image_names.map {|name| { 'Image' => name } })
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
@@ -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
- it 'lists processes' do
20
- expect(Excon).to receive(:get).
21
- with(excon_uri + "v1.7" + "/containers/json").
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
- it 'lists all processes' do
27
- expect(Excon).to receive(:get).
28
- with(excon_uri + "v1.7" + "/containers/json?all=1").
29
- and_return(double(body: json_string, status: 200))
30
- expect(api.ps(all: true)).to eq(json_value)
31
- end
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
- it 'inspects an image' do
34
- expect(Excon).to receive(:get).
35
- with(excon_uri + "v1.7" + "/images/foo:bar/json",
36
- headers: {'Accept' => 'application/json'}).
37
- and_return(double(body: json_string, status: 200))
38
- expect(api.inspect_image('foo', 'bar')).to eq(json_value)
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
- it 'creates a container' do
42
- configuration_as_json = double
43
- configuration = double(:to_json => configuration_as_json)
44
- expect(Excon).to receive(:post).
45
- with(excon_uri + "v1.10" + "/containers/create",
46
- body: configuration_as_json,
47
- headers: {'Content-Type' => 'application/json'}).
48
- and_return(double(body: json_string, status: 201))
49
- api.create_container(configuration)
50
- end
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
- it 'starts a container' do
53
- configuration_as_json = double
54
- configuration = double(:to_json => configuration_as_json)
55
- expect(Excon).to receive(:post).
56
- with(excon_uri + "v1.10" + "/containers/12345/start",
57
- body: configuration_as_json,
58
- headers: {'Content-Type' => 'application/json'}).
59
- and_return(double(body: json_string, status: 204))
60
- api.start_container('12345', configuration)
61
- end
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
- it 'stops a container' do
64
- expect(Excon).to receive(:post).
65
- with(excon_uri + "v1.7" + "/containers/12345/stop?t=300").
66
- and_return(double(status: 204))
67
- api.stop_container('12345', 300)
68
- end
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
- it 'stops a container with a custom timeout' do
71
- expect(Excon).to receive(:post).
72
- with(excon_uri + "v1.7" + "/containers/12345/stop?t=30").
73
- and_return(double(status: 204))
74
- api.stop_container('12345')
75
- end
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
- it 'inspects a container' do
78
- expect(Excon).to receive(:get).
79
- with(excon_uri + "v1.7" + "/containers/12345/json").
80
- and_return(double(body: json_string, status: 200))
81
- expect(api.inspect_container('12345')).to eq(json_value)
82
- end
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
- it 'lists old containers for a port' do
92
- expect(Excon).to receive(:get).
93
- with(excon_uri + "v1.7" + "/containers/json?all=1").
94
- and_return(double(body: inspected_containers.to_json, status: 200))
95
- expect(Excon).to receive(:get).
96
- with(excon_uri + "v1.7" + "/containers/123/json").
97
- and_return(double(body: inspected_container_on_port("123", 8485).to_json, status: 200))
98
- expect(Excon).to receive(:get).
99
- with(excon_uri + "v1.7" + "/containers/789/json").
100
- and_return(double(body: inspected_container_on_port("789", 8486).to_json, status: 200))
101
-
102
- expect(api.old_containers_for_port(8485)).to eq([{"Id" => "123", "Status" => "Exit 0"}])
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)