docker-api 1.27.0 → 2.0.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,61 +0,0 @@
1
- description "Docker daemon"
2
-
3
- start on (local-filesystems and net-device-up IFACE!=lo)
4
- stop on runlevel [!2345]
5
- limit nofile 524288 1048576
6
- limit nproc 524288 1048576
7
-
8
- respawn
9
-
10
- kill timeout 20
11
-
12
- pre-start script
13
- # see also https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
14
- if grep -v '^#' /etc/fstab | grep -q cgroup \
15
- || [ ! -e /proc/cgroups ] \
16
- || [ ! -d /sys/fs/cgroup ]; then
17
- exit 0
18
- fi
19
- if ! mountpoint -q /sys/fs/cgroup; then
20
- mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
21
- fi
22
- (
23
- cd /sys/fs/cgroup
24
- for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
25
- mkdir -p $sys
26
- if ! mountpoint -q $sys; then
27
- if ! mount -n -t cgroup -o $sys cgroup $sys; then
28
- rmdir $sys || true
29
- fi
30
- fi
31
- done
32
- )
33
- end script
34
-
35
- script
36
- # modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
37
- DOCKER=/usr/bin/$UPSTART_JOB
38
- DOCKER_OPTS=
39
- if [ -f /etc/default/$UPSTART_JOB ]; then
40
- . /etc/default/$UPSTART_JOB
41
- fi
42
- exec "$DOCKER" -d $DOCKER_OPTS
43
- end script
44
-
45
- # Don't emit "started" event until docker.sock is ready.
46
- # See https://github.com/docker/docker/issues/6647
47
- post-start script
48
- DOCKER_OPTS=
49
- if [ -f /etc/default/$UPSTART_JOB ]; then
50
- . /etc/default/$UPSTART_JOB
51
- fi
52
- if ! printf "%s" "$DOCKER_OPTS" | grep -qE -e '-H|--host'; then
53
- while ! [ -e /var/run/docker.sock ]; do
54
- initctl status $UPSTART_JOB | grep -qE "(stop|respawn)/" && exit 1
55
- echo "Waiting for /var/run/docker.sock"
56
- sleep 0.1
57
- done
58
- echo "/var/run/docker.sock is up"
59
- fi
60
- end script
61
-
@@ -1,35 +0,0 @@
1
- #!/bin/bash
2
- set -x
3
- set -e
4
-
5
- # argv[0]
6
- DOCKER_VERSION=$1
7
-
8
- # disable travis default installation
9
- service docker stop
10
- apt-get -y --purge remove docker-engine
11
-
12
- # install gpg key for docker rpo
13
- apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv 58118E89F3A912897C070ADBF76221572C52609D
14
-
15
- # enable docker repo
16
- echo 'deb "https://apt.dockerproject.org/repo" ubuntu-trusty main' >> /etc/apt/sources.list.d/docker-main.list
17
- apt-get update -o Dir::Etc::sourcelist='sources.list.d/docker-main.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0'
18
- apt-cache gencaches
19
-
20
- # install package
21
- apt-get -y --force-yes install docker-engine=${DOCKER_VERSION}-0~trusty
22
- echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid"' > /etc/default/docker
23
- cat /etc/default/docker
24
-
25
- # docker 1.6 packages did not come with init files
26
- if [[ $DOCKER_VERSION == 1.6.* ]]
27
- then
28
- cp script/docker.conf /etc/init/docker.conf
29
- cp script/docker /etc/init.d/docker
30
- chmod +x /etc/init.d/docker
31
- else
32
- service docker stop
33
- fi
34
-
35
- service docker start
@@ -1,123 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Docker::Connection do
4
- subject { described_class.new('http://localhost:4243', {}) }
5
-
6
- describe '#initialize' do
7
- let(:url) { 'http://localhost:4243' }
8
- let(:options) { {} }
9
- subject { described_class.new(url, options) }
10
-
11
- context 'when the first argument is not a String' do
12
- let(:url) { :lol_not_a_string }
13
-
14
- it 'raises an error' do
15
- expect { subject }.to raise_error(Docker::Error::ArgumentError)
16
- end
17
- end
18
-
19
- context 'when the first argument is a String' do
20
- context 'and the url is a unix socket' do
21
- let(:url) { 'unix:///var/run/docker.sock' }
22
-
23
- it 'sets the socket path in the options' do
24
- expect(subject.url).to eq('unix:///')
25
- expect(subject.options).to include(:socket => '/var/run/docker.sock')
26
- end
27
- end
28
-
29
- context 'but the second argument is not a Hash' do
30
- let(:options) { :lol_not_a_hash }
31
-
32
- it 'raises an error' do
33
- expect { subject }.to raise_error(Docker::Error::ArgumentError)
34
- end
35
- end
36
-
37
- context 'and the second argument is a Hash' do
38
- it 'sets the url and options' do
39
- expect(subject.url).to eq url
40
- expect(subject.options).to eq options
41
- end
42
- end
43
- end
44
-
45
- context 'url conversion to uri' do
46
- context 'when the url does not contain a scheme' do
47
- let(:url) { 'localhost:4243' }
48
-
49
- it 'adds the scheme to the url' do
50
- expect(subject.url).to eq "http://#{url}"
51
- end
52
- end
53
-
54
- context 'when the url is a complete uri' do
55
- let(:url) { 'http://localhost:4243' }
56
-
57
- it 'leaves the url intact' do
58
- expect(subject.url).to eq url
59
- end
60
- end
61
- end
62
- end
63
-
64
- describe '#resource' do
65
- its(:resource) { should be_a Excon::Connection }
66
- end
67
-
68
- describe '#request' do
69
- let(:method) { :get }
70
- let(:path) { '/test' }
71
- let(:query) { { :all => true } }
72
- let(:options) { { :expects => 201, :lol => true } }
73
- let(:body) { rand(10000000) }
74
- let(:resource) { double(:resource) }
75
- let(:response) { double(:response, :body => body) }
76
- let(:expected_hash) {
77
- {
78
- :method => method,
79
- :path => "/v#{Docker::API_VERSION}#{path}",
80
- :query => query,
81
- :headers => { 'Content-Type' => 'text/plain',
82
- 'User-Agent' => "Swipely/Docker-API #{Docker::VERSION}",
83
- },
84
- :expects => 201,
85
- :idempotent => true,
86
- :lol => true
87
- }
88
- }
89
-
90
- before do
91
- allow(subject).to receive(:resource).and_return(resource)
92
- expect(resource).to receive(:request).
93
- with(expected_hash).
94
- and_return(response)
95
- end
96
-
97
- it 'sends #request to #resource with the compiled params' do
98
- expect(subject.request(method, path, query, options)).to eq body
99
- end
100
- end
101
-
102
- [:get, :put, :post, :delete].each do |method|
103
- describe "##{method}" do
104
- it 'is delegated to #request' do
105
- expect(subject).to receive(:request).with(method)
106
- subject.public_send(method)
107
- end
108
- end
109
- end
110
-
111
- describe '#to_s' do
112
- let(:url) { 'http://google.com:4000' }
113
- let(:options) { {} }
114
- let(:expected_string) {
115
- "Docker::Connection { :url => #{url}, :options => #{options} }"
116
- }
117
- subject { described_class.new(url, options) }
118
-
119
- it 'returns a pretty version with the url and port' do
120
- expect(subject.to_s).to eq expected_string
121
- end
122
- end
123
- end
@@ -1,801 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Docker::Container do
4
- describe '#to_s' do
5
- subject {
6
- described_class.send(:new, Docker.connection, 'id' => rand(10000).to_s)
7
- }
8
-
9
- let(:id) { 'bf119e2' }
10
- let(:connection) { Docker.connection }
11
- let(:expected_string) {
12
- "Docker::Container { :id => #{id}, :connection => #{connection} }"
13
- }
14
- before do
15
- {
16
- :@id => id,
17
- :@connection => connection
18
- }.each { |k, v| subject.instance_variable_set(k, v) }
19
- end
20
-
21
- its(:to_s) { should == expected_string }
22
- end
23
-
24
- describe '#json' do
25
- subject {
26
- described_class.create('Cmd' => %w[true], 'Image' => 'debian:wheezy')
27
- }
28
- let(:description) { subject.json }
29
- after(:each) { subject.remove }
30
-
31
- it 'returns the description as a Hash' do
32
- expect(description).to be_a Hash
33
- expect(description['Id']).to start_with(subject.id)
34
- end
35
- end
36
-
37
- describe '#streaming_logs' do
38
- let(:options) { {} }
39
- subject do
40
- described_class.create(
41
- {'Cmd' => ['/bin/bash', '-lc', 'echo hello'], 'Image' => 'debian:wheezy'}.merge(options)
42
- )
43
- end
44
-
45
- before(:each) { subject.tap(&:start).wait }
46
- after(:each) { subject.remove }
47
-
48
- context 'when not selecting any stream' do
49
- let(:non_destination) { subject.streaming_logs }
50
- it 'raises a client error' do
51
- expect { non_destination }.to raise_error(Docker::Error::ClientError)
52
- end
53
- end
54
-
55
- context 'when selecting stdout' do
56
- let(:stdout) { subject.streaming_logs(stdout: 1) }
57
- it 'returns blank logs' do
58
- expect(stdout).to be_a String
59
- expect(stdout).to match("hello")
60
- end
61
- end
62
-
63
- context 'when using a tty' do
64
- let(:options) { { 'Tty' => true } }
65
-
66
- let(:output) { subject.streaming_logs(stdout: 1, tty: 1) }
67
- it 'returns `hello`' do
68
- expect(output).to be_a(String)
69
- expect(output).to match("hello")
70
- end
71
- end
72
-
73
- context 'when passing a block' do
74
- let(:lines) { [] }
75
- let(:output) { subject.streaming_logs(stdout: 1, follow: 1) { |s,c| lines << c } }
76
- it 'returns `hello`' do
77
- expect(output).to be_a(String)
78
- expect(output).to match("hello")
79
- expect(lines.join).to match("hello")
80
- end
81
- end
82
- end
83
-
84
- describe '#logs' do
85
- subject {
86
- described_class.create('Cmd' => "echo hello", 'Image' => 'debian:wheezy')
87
- }
88
- after(:each) { subject.remove }
89
-
90
- context "when not selecting any stream" do
91
- let(:non_destination) { subject.logs }
92
- it 'raises a client error' do
93
- expect { non_destination }.to raise_error(Docker::Error::ClientError)
94
- end
95
- end
96
-
97
- context "when selecting stdout" do
98
- let(:stdout) { subject.logs(stdout: 1) }
99
- it 'returns blank logs' do
100
- expect(stdout).to be_a String
101
- expect(stdout).to eq ""
102
- end
103
- end
104
- end
105
-
106
- describe '#create' do
107
- subject {
108
- described_class.create({
109
- 'Cmd' => %w[true],
110
- 'Image' => 'debian:wheezy'
111
- }.merge(opts))
112
- }
113
-
114
- context 'when creating a container named bob' do
115
- let(:opts) { {"name" => "bob"} }
116
- after(:each) { subject.remove }
117
-
118
- it 'should have name set to bob' do
119
- expect(subject.json["Name"]).to eq("/bob")
120
- end
121
- end
122
- end
123
-
124
- describe '#rename' do
125
- subject {
126
- described_class.create({
127
- 'name' => 'foo',
128
- 'Cmd' => %w[true],
129
- 'Image' => 'debian:wheezy'
130
- })
131
- }
132
-
133
- before { subject.start }
134
- after(:each) { subject.tap(&:wait).remove }
135
-
136
- it 'renames the container' do
137
- subject.rename('bar')
138
- expect(subject.json["Name"]).to match(%r{bar})
139
- end
140
- end
141
-
142
- describe '#changes' do
143
- subject {
144
- described_class.create(
145
- 'Cmd' => %w[rm -rf /root],
146
- 'Image' => 'debian:wheezy'
147
- )
148
- }
149
- let(:changes) { subject.changes }
150
-
151
- before { subject.tap(&:start).tap(&:wait) }
152
- after(:each) { subject.tap(&:wait).remove }
153
-
154
- it 'returns the changes as an array' do
155
- expect(changes).to eq [
156
- {
157
- "Path" => "/root",
158
- "Kind" => 2
159
- },
160
- ]
161
- end
162
- end
163
-
164
- describe '#top' do
165
- let(:dir) {
166
- File.join(File.dirname(__FILE__), '..', 'fixtures', 'top')
167
- }
168
- let(:image) { Docker::Image.build_from_dir(dir) }
169
- let(:top) { sleep 1; container.top }
170
- let!(:container) { image.run('/while') }
171
- after do
172
- container.kill!.remove
173
- image.remove
174
- end
175
-
176
- it 'returns the top commands as an Array' do
177
- expect(top).to be_a Array
178
- expect(top).to_not be_empty
179
- expect(top.first.keys).to include('PID')
180
- end
181
- end
182
-
183
- describe '#copy' do
184
- let(:image) { Docker::Image.create('fromImage' => 'debian:wheezy') }
185
- subject { image.run('touch /test').tap { |c| c.wait } }
186
-
187
- after(:each) { subject.remove }
188
-
189
- context 'when the file does not exist' do
190
- it 'raises an error' do
191
- expect { subject.copy('/lol/not/a/real/file') { |chunk| puts chunk } }
192
- .to raise_error
193
- end
194
- end
195
-
196
- context 'when the input is a file' do
197
- it 'yields each chunk of the tarred file' do
198
- chunks = []
199
- subject.copy('/test') { |chunk| chunks << chunk }
200
- chunks = chunks.join("\n")
201
- expect(chunks).to be_include('test')
202
- end
203
- end
204
-
205
- context 'when the input is a directory' do
206
- it 'yields each chunk of the tarred directory' do
207
- chunks = []
208
- subject.copy('/etc/logrotate.d') { |chunk| chunks << chunk }
209
- chunks = chunks.join("\n")
210
- expect(%w[apt dpkg]).to be_all { |file| chunks.include?(file) }
211
- end
212
- end
213
- end
214
-
215
- describe '#archive_in', :docker_1_8 do
216
- let(:license_path) { File.absolute_path(File.join(__FILE__, '..', '..', '..', 'LICENSE')) }
217
- subject { Docker::Container.create('Image' => 'debian:wheezy', 'Cmd' => ['/bin/sh']) }
218
- let(:committed_image) { subject.commit }
219
- let(:ls_container) { committed_image.run('ls /').tap(&:wait) }
220
- let(:output) { ls_container.streaming_logs(stdout: true, stderr: true) }
221
-
222
- after do
223
- subject.remove
224
- end
225
-
226
- context 'when the input is a tar' do
227
- after do
228
- ls_container.remove
229
- committed_image.remove
230
- end
231
-
232
- it 'file exists in the container' do
233
- subject.archive_in(license_path, '/', overwrite: false)
234
- expect(output).to include('LICENSE')
235
- end
236
- end
237
- end
238
-
239
- describe '#archive_in_stream', :docker_1_8 do
240
- let(:tar) { StringIO.new(Docker::Util.create_tar('/lol' => 'TEST')) }
241
- subject { Docker::Container.create('Image' => 'debian:wheezy', 'Cmd' => ['/bin/sh']) }
242
- let(:committed_image) { subject.commit }
243
- let(:ls_container) { committed_image.run('ls /').tap(&:wait) }
244
- let(:output) { ls_container.streaming_logs(stdout: true, stderr: true) }
245
-
246
- after do
247
- subject.remove
248
- end
249
-
250
- context 'when the input is a tar' do
251
- after do
252
- ls_container.remove
253
- committed_image.remove
254
- end
255
-
256
- it 'file exists in the container' do
257
- subject.archive_in_stream('/', overwrite: false) { tar.read }
258
- expect(output).to include('lol')
259
- end
260
- end
261
-
262
- context 'when the input would overwrite a directory with a file' do
263
- let(:tar) { StringIO.new(Docker::Util.create_tar('/etc' => 'TEST')) }
264
-
265
- it 'raises an error' do
266
- # Docs say this should return a client error: clearly wrong
267
- # https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/
268
- # #extract-an-archive-of-files-or-folders-to-a-directory-in-a-container
269
- expect {
270
- subject.archive_in_stream('/', overwrite: false) { tar.read }
271
- }.to raise_error(Docker::Error::ServerError)
272
- end
273
- end
274
- end
275
-
276
- describe '#archive_out', :docker_1_8 do
277
- subject { Docker::Container.create('Image' => 'debian:wheezy', 'Cmd' => ['touch','/test']) }
278
-
279
- after { subject.remove }
280
-
281
- context 'when the file does not exist' do
282
- it 'raises an error' do
283
- subject.start
284
- subject.wait
285
-
286
- expect { subject.archive_out('/lol') { |chunk| puts chunk } }
287
- .to raise_error(Docker::Error::NotFoundError)
288
- end
289
- end
290
-
291
- context 'when the input is a file' do
292
- it 'yields each chunk of the tarred file' do
293
- subject.start; subject.wait
294
-
295
- chunks = []
296
- subject.archive_out('/test') { |chunk| chunks << chunk }
297
- chunks = chunks.join("\n")
298
- expect(chunks).to be_include('test')
299
- end
300
- end
301
-
302
- context 'when the input is a directory' do
303
- it 'yields each chunk of the tarred directory' do
304
- subject.start; subject.wait
305
-
306
- chunks = []
307
- subject.archive_out('/etc/logrotate.d') { |chunk| chunks << chunk }
308
- chunks = chunks.join("\n")
309
- expect(%w[apt dpkg]).to be_all { |file| chunks.include?(file) }
310
- end
311
- end
312
- end
313
-
314
- describe '#export' do
315
- subject { described_class.create('Cmd' => %w[/true],
316
- 'Image' => 'tianon/true') }
317
- before { subject.start }
318
- after { subject.tap(&:wait).remove }
319
-
320
- it 'yields each chunk' do
321
- first = nil
322
- subject.export do |chunk|
323
- first ||= chunk
324
- end
325
- expect(first[257..261]).to eq "ustar" # Make sure the export is a tar.
326
- end
327
- end
328
-
329
- describe '#attach' do
330
- subject {
331
- described_class.create(
332
- 'Cmd' => ['bash','-c','sleep 2; echo hello'],
333
- 'Image' => 'debian:wheezy'
334
- )
335
- }
336
-
337
- before { subject.start }
338
- after(:each) { subject.stop.remove }
339
-
340
- context 'with normal sized chunks' do
341
- it 'yields each chunk' do
342
- chunk = nil
343
- subject.attach do |stream, c|
344
- chunk ||= c
345
- end
346
- expect(chunk).to eq("hello\n")
347
- end
348
- end
349
-
350
- context 'with very small chunks' do
351
- before do
352
- Docker.options = { :chunk_size => 1 }
353
- end
354
-
355
- after do
356
- Docker.options = {}
357
- end
358
-
359
- it 'yields each chunk' do
360
- chunk = nil
361
- subject.attach do |stream, c|
362
- chunk ||= c
363
- end
364
- expect(chunk).to eq("hello\n")
365
- end
366
- end
367
- end
368
-
369
- describe '#attach with stdin' do
370
- it 'yields the output' do
371
- container = described_class.create(
372
- 'Cmd' => %w[cat],
373
- 'Image' => 'debian:wheezy',
374
- 'OpenStdin' => true,
375
- 'StdinOnce' => true
376
- )
377
- chunk = nil
378
- container
379
- .tap(&:start)
380
- .attach(stdin: StringIO.new("foo\nbar\n")) do |stream, c|
381
- chunk ||= c
382
- end
383
- container.tap(&:wait).remove
384
-
385
- expect(chunk).to eq("foo\nbar\n")
386
- end
387
- end
388
-
389
- describe '#start' do
390
- subject {
391
- described_class.create(
392
- 'Cmd' => %w[test -d /foo],
393
- 'Image' => 'debian:wheezy',
394
- 'Volumes' => {'/foo' => {}}
395
- )
396
- }
397
- let(:all) { Docker::Container.all(all: true) }
398
-
399
- before { subject.start('Binds' => ["/tmp:/foo"]) }
400
- after(:each) { subject.remove }
401
-
402
- it 'starts the container' do
403
- expect(all.map(&:id)).to be_any { |id| id.start_with?(subject.id) }
404
- expect(subject.wait(10)['StatusCode']).to be_zero
405
- end
406
- end
407
-
408
- describe '#stop' do
409
- subject {
410
- described_class.create('Cmd' => %w[true], 'Image' => 'debian:wheezy')
411
- }
412
-
413
- before { subject.tap(&:start).stop('timeout' => '10') }
414
- after { subject.remove }
415
-
416
- it 'stops the container' do
417
- expect(described_class.all(:all => true).map(&:id)).to be_any { |id|
418
- id.start_with?(subject.id)
419
- }
420
- expect(described_class.all.map(&:id)).to be_none { |id|
421
- id.start_with?(subject.id)
422
- }
423
- end
424
- end
425
-
426
- describe '#exec' do
427
- subject {
428
- described_class.create(
429
- 'Cmd' => %w[sleep 20],
430
- 'Image' => 'debian:wheezy'
431
- ).start
432
- }
433
- after { subject.kill!.remove }
434
-
435
- context 'when passed only a command' do
436
- let(:output) { subject.exec(['bash','-c','sleep 2; echo hello']) }
437
-
438
- it 'returns the stdout/stderr messages and exit code' do
439
- expect(output).to eq([["hello\n"], [], 0])
440
- end
441
- end
442
-
443
- context 'when detach is true' do
444
- let(:output) { subject.exec(['date'], detach: true) }
445
-
446
- it 'returns the Docker::Exec object' do
447
- expect(output).to be_a Docker::Exec
448
- expect(output.id).to_not be_nil
449
- end
450
- end
451
-
452
- context 'when passed a block' do
453
- it 'streams the stdout/stderr messages' do
454
- chunk = nil
455
- subject.exec(['bash','-c','sleep 2; echo hello']) do |stream, c|
456
- chunk ||= c
457
- end
458
- expect(chunk).to eq("hello\n")
459
- end
460
- end
461
-
462
- context 'when stdin object is passed' do
463
- let(:output) { subject.exec(['cat'], stdin: StringIO.new("hello")) }
464
-
465
- it 'returns the stdout/stderr messages' do
466
- expect(output).to eq([["hello"],[],0])
467
- end
468
- end
469
-
470
- context 'when tty is true' do
471
- let(:command) { [
472
- "bash", "-c",
473
- "if [ -t 1 ]; then echo -n \"I'm a TTY!\"; fi"
474
- ] }
475
- let(:output) { subject.exec(command, tty: true) }
476
-
477
- it 'returns the raw stdout/stderr output' do
478
- expect(output).to eq([["I'm a TTY!"], [], 0])
479
- end
480
- end
481
- end
482
-
483
- describe '#kill' do
484
- let(:command) { ['/bin/bash', '-c', 'while [ 1 ]; do echo hello; done'] }
485
- subject {
486
- described_class.create('Cmd' => command, 'Image' => 'debian:wheezy')
487
- }
488
-
489
- before { subject.start }
490
- after(:each) {subject.remove }
491
-
492
- it 'kills the container' do
493
- subject.kill
494
- expect(described_class.all.map(&:id)).to be_none { |id|
495
- id.start_with?(subject.id)
496
- }
497
- expect(described_class.all(:all => true).map(&:id)).to be_any { |id|
498
- id.start_with?(subject.id)
499
- }
500
- end
501
-
502
- context 'with a kill signal' do
503
- let(:command) {
504
- [
505
- '/bin/bash',
506
- '-c',
507
- 'trap echo SIGTERM; while [ 1 ]; do echo hello; done'
508
- ]
509
- }
510
- it 'kills the container' do
511
- subject.kill(:signal => "SIGTERM")
512
- expect(described_class.all.map(&:id)).to be_any { |id|
513
- id.start_with?(subject.id)
514
- }
515
- expect(described_class.all(:all => true).map(&:id)).to be_any { |id|
516
- id.start_with?(subject.id)
517
- }
518
-
519
- subject.kill(:signal => "SIGKILL")
520
- expect(described_class.all.map(&:id)).to be_none { |id|
521
- id.start_with?(subject.id)
522
- }
523
- expect(described_class.all(:all => true).map(&:id)).to be_any { |id|
524
- id.start_with?(subject.id)
525
- }
526
- end
527
- end
528
- end
529
-
530
- describe '#delete' do
531
- subject {
532
- described_class.create('Cmd' => ['ls'], 'Image' => 'debian:wheezy')
533
- }
534
-
535
- it 'deletes the container' do
536
- subject.delete(:force => true)
537
- expect(described_class.all.map(&:id)).to be_none { |id|
538
- id.start_with?(subject.id)
539
- }
540
- end
541
- end
542
-
543
- describe '#restart' do
544
- subject {
545
- described_class.create('Cmd' => %w[sleep 10], 'Image' => 'debian:wheezy')
546
- }
547
-
548
- before { subject.start }
549
- after { subject.kill!.remove }
550
-
551
- it 'restarts the container' do
552
- expect(described_class.all.map(&:id)).to be_any { |id|
553
- id.start_with?(subject.id)
554
- }
555
- subject.stop
556
- expect(described_class.all.map(&:id)).to be_none { |id|
557
- id.start_with?(subject.id)
558
- }
559
- subject.restart('timeout' => '10')
560
- expect(described_class.all.map(&:id)).to be_any { |id|
561
- id.start_with?(subject.id)
562
- }
563
- end
564
- end
565
-
566
- describe '#pause' do
567
- subject {
568
- described_class.create(
569
- 'Cmd' => %w[sleep 50],
570
- 'Image' => 'debian:wheezy'
571
- ).start
572
- }
573
- after { subject.unpause.kill!.remove }
574
-
575
- it 'pauses the container' do
576
- subject.pause
577
- expect(described_class.get(subject.id).info['State']['Paused']).to be true
578
- end
579
- end
580
-
581
- describe '#unpause' do
582
- subject {
583
- described_class.create(
584
- 'Cmd' => %w[sleep 50],
585
- 'Image' => 'debian:wheezy'
586
- ).start
587
- }
588
- before { subject.pause }
589
- after { subject.kill!.remove }
590
-
591
- it 'unpauses the container' do
592
- subject.unpause
593
- expect(
594
- described_class.get(subject.id).info['State']['Paused']
595
- ).to be false
596
- end
597
- end
598
-
599
- describe '#wait' do
600
- subject {
601
- described_class.create(
602
- 'Cmd' => %w[tar nonsense],
603
- 'Image' => 'debian:wheezy'
604
- )
605
- }
606
-
607
- before { subject.start }
608
- after(:each) { subject.remove }
609
-
610
- it 'waits for the command to finish' do
611
- expect(subject.wait['StatusCode']).to_not be_zero
612
- end
613
-
614
- context 'when an argument is given' do
615
- subject { described_class.create('Cmd' => %w[sleep 5],
616
- 'Image' => 'debian:wheezy') }
617
-
618
- it 'sets the :read_timeout to that amount of time' do
619
- expect(subject.wait(6)['StatusCode']).to be_zero
620
- end
621
-
622
- context 'and a command runs for too long' do
623
- it 'raises a ServerError' do
624
- expect{subject.wait(4)}.to raise_error(Docker::Error::TimeoutError)
625
- subject.tap(&:wait)
626
- end
627
- end
628
- end
629
- end
630
-
631
- describe '#run' do
632
- let(:run_command) { subject.run('ls') }
633
-
634
- context 'when the Container\'s command does not return status code of 0' do
635
- subject { described_class.create('Cmd' => %w[false],
636
- 'Image' => 'debian:wheezy') }
637
-
638
- after do
639
- subject.remove
640
- end
641
-
642
- it 'raises an error' do
643
- expect { run_command }
644
- .to raise_error(Docker::Error::UnexpectedResponseError)
645
- end
646
- end
647
-
648
- context 'when the Container\'s command returns a status code of 0' do
649
- subject { described_class.create('Cmd' => %w[pwd],
650
- 'Image' => 'debian:wheezy') }
651
- after do
652
- subject.remove
653
- image = run_command.json['Image']
654
- run_command.remove
655
- Docker::Image.get(image).history.each do |layer|
656
- next unless layer['CreatedBy'] == 'pwd'
657
- Docker::Image.get(layer['Id']).remove(:noprune => true)
658
- end
659
- end
660
-
661
- it 'creates a new container to run the specified command' do
662
- expect(run_command.wait['StatusCode']).to be_zero
663
- end
664
- end
665
- end
666
-
667
- describe '#commit' do
668
- subject {
669
- described_class.create('Cmd' => %w[true], 'Image' => 'debian:wheezy')
670
- }
671
- let(:image) { subject.commit }
672
-
673
- after(:each) do
674
- subject.remove
675
- image.remove
676
- end
677
-
678
- it 'creates a new Image from the Container\'s changes' do
679
- subject.tap(&:start).wait
680
-
681
- expect(image).to be_a Docker::Image
682
- expect(image.id).to_not be_nil
683
- end
684
-
685
- context 'if run is passed, it saves the command in the image' do
686
- let(:image) { subject.commit }
687
- let(:container) { image.run('pwd') }
688
-
689
- it 'saves the command' do
690
- container.wait
691
- expect(container.attach(logs: true, stream: false)).to eql [["/\n"],[]]
692
- container.remove
693
- end
694
- end
695
- end
696
-
697
- describe '.create' do
698
- subject { described_class }
699
-
700
- context 'when the Container does not yet exist' do
701
- context 'when the HTTP request does not return a 200' do
702
- before do
703
- Docker.options = { :mock => true }
704
- Excon.stub({ :method => :post }, { :status => 400 })
705
- end
706
- after do
707
- Excon.stubs.shift
708
- Docker.options = {}
709
- end
710
-
711
- it 'raises an error' do
712
- expect { subject.create }.to raise_error(Docker::Error::ClientError)
713
- end
714
- end
715
-
716
- context 'when the HTTP request returns a 200' do
717
- let(:options) do
718
- {
719
- "Cmd" => ["date"],
720
- "Image" => "debian:wheezy",
721
- }
722
- end
723
- let(:container) { subject.create(options) }
724
- after { container.remove }
725
-
726
- it 'sets the id' do
727
- expect(container).to be_a Docker::Container
728
- expect(container.id).to_not be_nil
729
- expect(container.connection).to_not be_nil
730
- end
731
- end
732
- end
733
- end
734
-
735
- describe '.get' do
736
- subject { described_class }
737
-
738
- context 'when the HTTP response is not a 200' do
739
- before do
740
- Docker.options = { :mock => true }
741
- Excon.stub({ :method => :get }, { :status => 500 })
742
- end
743
- after do
744
- Excon.stubs.shift
745
- Docker.options = {}
746
- end
747
-
748
- it 'raises an error' do
749
- expect { subject.get('randomID') }
750
- .to raise_error(Docker::Error::ServerError)
751
- end
752
- end
753
-
754
- context 'when the HTTP response is a 200' do
755
- let(:container) {
756
- subject.create('Cmd' => ['ls'], 'Image' => 'debian:wheezy')
757
- }
758
- after { container.remove }
759
-
760
- it 'materializes the Container into a Docker::Container' do
761
- expect(subject.get(container.id)).to be_a Docker::Container
762
- end
763
- end
764
-
765
- end
766
-
767
- describe '.all' do
768
- subject { described_class }
769
-
770
- context 'when the HTTP response is not a 200' do
771
- before do
772
- Docker.options = { :mock => true }
773
- Excon.stub({ :method => :get }, { :status => 500 })
774
- end
775
- after do
776
- Excon.stubs.shift
777
- Docker.options = {}
778
- end
779
-
780
- it 'raises an error' do
781
- expect { subject.all }
782
- .to raise_error(Docker::Error::ServerError)
783
- end
784
- end
785
-
786
- context 'when the HTTP response is a 200' do
787
- let(:container) {
788
- subject.create('Cmd' => ['ls'], 'Image' => 'debian:wheezy')
789
- }
790
- before { container }
791
- after { container.remove }
792
-
793
- it 'materializes each Container into a Docker::Container' do
794
- expect(subject.all(:all => true)).to be_all { |container|
795
- container.is_a?(Docker::Container)
796
- }
797
- expect(subject.all(:all => true).length).to_not be_zero
798
- end
799
- end
800
- end
801
- end