docker-api 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.md +21 -48
  2. data/lib/docker/connection.rb +8 -1
  3. data/lib/docker/container.rb +11 -12
  4. data/lib/docker/error.rb +0 -4
  5. data/lib/docker/image.rb +44 -30
  6. data/lib/docker/model.rb +30 -40
  7. data/lib/docker/version.rb +1 -1
  8. data/spec/docker/connection_spec.rb +3 -2
  9. data/spec/docker/container_spec.rb +206 -377
  10. data/spec/docker/image_spec.rb +123 -237
  11. data/spec/vcr/Docker_Container/_all/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +2503 -263
  12. data/spec/vcr/Docker_Container/_attach/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/yields_each_chunk.yml +30 -22
  13. data/spec/vcr/Docker_Container/_changes/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/returns_the_changes_as_an_array.yml +41 -33
  14. data/spec/vcr/Docker_Container/_commit/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/creates_a_new_Image_from_the_Container_s_changes.yml +34 -28
  15. data/spec/vcr/Docker_Container/{_create_ → _create}/when_the_Container_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml +11 -9
  16. data/spec/vcr/Docker_Container/_export/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/yields_each_chunk.yml +43 -29
  17. data/spec/vcr/Docker_Container/_json/when_the_HTTP_response_status_is_200/returns_the_description_as_a_Hash.yml +63 -0
  18. data/spec/vcr/Docker_Container/_kill/when_the_HTTP_response_status_is_204/kills_the_container.yml +1358 -0
  19. data/spec/vcr/Docker_Container/_restart/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_204 → when_the_HTTP_response_status_is_204}/restarts_the_container.yml +73 -59
  20. data/spec/vcr/Docker_Container/_start/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/starts_the_container.yml +33 -28
  21. data/spec/vcr/Docker_Container/_stop/when_the_HTTP_response_status_is_204/stops_the_container.yml +1387 -0
  22. data/spec/vcr/Docker_Container/_wait/{when_the_Container_has_been_created/when_the_HTTP_response_status_is_200 → when_the_HTTP_response_status_is_200}/waits_for_the_command_to_finish.yml +31 -25
  23. data/spec/vcr/Docker_Image/_all/when_the_HTTP_response_is_a_200/materializes_each_Image_into_a_Docker_Image.yml +6 -6
  24. data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/builds_an_image.yml +4 -4
  25. data/spec/vcr/Docker_Image/_build/with_an_invalid_Dockerfile/throws_a_UnexpectedResponseError.yml +4 -4
  26. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/builds_the_image.yml +14 -14
  27. data/spec/vcr/Docker_Image/_create/when_the_Image_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml +33 -0
  28. data/spec/vcr/Docker_Image/_history/when_the_HTTP_response_status_is_200/returns_the_history_of_the_Image.yml +63 -0
  29. data/spec/vcr/Docker_Image/_import/when_the_file_does_exist/creates_the_Image.yml +11 -9
  30. data/spec/vcr/Docker_Image/_insert/when_the_HTTP_response_status_is_200/inserts_the_url_s_file_into_a_new_Image.yml +220 -0
  31. data/spec/vcr/Docker_Image/_json/when_the_HTTP_response_status_is_200/returns_additional_information_about_image_image.yml +63 -0
  32. data/spec/vcr/Docker_Image/_remove/when_the_HTTP_response_status_is_204/removes_the_Image.yml +93 -0
  33. data/spec/vcr/Docker_Image/_remove/when_the_Image_has_been_created/when_the_HTTP_response_status_is_204/removes_the_Image.yml +63 -0
  34. data/spec/vcr/Docker_Image/_run/when_the_Image_has_been_created/when_the_argument_is_a_String/splits_the_String_by_spaces_and_creates_a_new_Container.yml +119 -0
  35. data/spec/vcr/Docker_Image/_run/when_the_Image_has_been_created/when_the_argument_is_an_Array/creates_a_new_Container.yml +119 -0
  36. data/spec/vcr/Docker_Image/_run/when_the_argument_is_a_String/splits_the_String_by_spaces_and_creates_a_new_Container.yml +119 -0
  37. data/spec/vcr/Docker_Image/_run/when_the_argument_is_an_Array/creates_a_new_Container.yml +119 -0
  38. data/spec/vcr/Docker_Image/_tag/when_the_HTTP_response_status_is_200/tags_the_image_with_the_repo_name.yml +63 -0
  39. metadata +46 -29
  40. data/spec/vcr/Docker_Container/_json/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/returns_the_description_as_a_Hash.yml +0 -61
  41. data/spec/vcr/Docker_Container/_kill/when_the_Container_has_been_created/when_the_HTTP_response_status_is_204/kills_the_container.yml +0 -232
  42. data/spec/vcr/Docker_Container/_stop/when_the_Container_has_been_created/when_the_HTTP_response_status_is_204/stops_the_container.yml +0 -259
@@ -1,57 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Docker::Image do
4
- describe '#initialize' do
5
- subject { described_class }
6
-
7
- context 'with no argument' do
8
- let(:image) { subject.new }
9
-
10
- it 'sets the id to nil' do
11
- image.id.should be_nil
12
- end
13
-
14
- it 'keeps the default Connection' do
15
- image.connection.should == Docker.connection
16
- end
17
- end
18
-
19
- context 'with an argument' do
20
- let(:id) { 'a7c2ee4' }
21
- let(:image) { subject.new(:id => id) }
22
-
23
- it 'sets the id to the argument' do
24
- image.id.should == id
25
- end
26
-
27
- it 'keeps the default Connection' do
28
- image.connection.should == Docker.connection
29
- end
30
- end
31
-
32
- context 'with two arguments' do
33
- context 'when the second argument is not a Docker::Connection' do
34
- let(:id) { 'abc123f' }
35
- let(:connection) { :not_a_connection }
36
- let(:image) { subject.new(:id => id, :connection => connection) }
37
-
38
- it 'raises an error' do
39
- expect { image }.to raise_error(Docker::Error::ArgumentError)
40
- end
41
- end
42
-
43
- context 'when the second argument is a Docker::Connection' do
44
- let(:id) { 'cb3f14a' }
45
- let(:connection) { Docker::Connection.new }
46
- let(:image) { subject.new(:id => id, :connection => connection) }
47
-
48
- it 'initializes the Image' do
49
- image.id.should == id
50
- image.connection.should == connection
51
- end
52
- end
53
- end
54
- end
4
+ subject { described_class.send(:new, :id => rand(10000).to_s) }
55
5
 
56
6
  describe '#to_s' do
57
7
  let(:id) { 'bf119e2' }
@@ -59,258 +9,196 @@ describe Docker::Image do
59
9
  let(:expected_string) do
60
10
  "Docker::Image { :id => #{id}, :connection => #{connection} }"
61
11
  end
62
- subject { described_class.new(:id => id, :connection => connection) }
12
+ before do
13
+ {
14
+ :@id => id,
15
+ :@connection => connection
16
+ }.each { |k, v| subject.instance_variable_set(k, v) }
17
+ end
63
18
 
64
19
  its(:to_s) { should == expected_string }
65
20
  end
66
21
 
67
- describe '#created?' do
68
- context 'when the id is nil' do
69
- its(:created?) { should be_false }
70
- end
71
-
72
- context 'when the id is present' do
73
- subject { described_class.new(:id => 'a732ebf') }
22
+ describe '#remove' do
23
+ context 'when the HTTP response status is not 204' do
24
+ before { Excon.stub({ :method => :delete }, { :status => 500 }) }
25
+ after { Excon.stubs.shift }
74
26
 
75
- its(:created?) { should be_true }
27
+ it 'raises an error' do
28
+ expect { subject.remove }
29
+ .to raise_error(Docker::Error::ServerError)
30
+ end
76
31
  end
77
- end
78
32
 
79
- describe '#create!' do
80
- context 'when the Image has already been created' do
81
- subject { described_class.new(:id => '5e88b2a') }
33
+ context 'when the HTTP response status is 204' do
34
+ let(:id) { subject.id }
35
+ subject { described_class.create('fromImage' => 'base') }
82
36
 
83
- it 'raises an error' do
84
- expect { subject.create! }
85
- .to raise_error(Docker::Error::StateError)
37
+ it 'removes the Image', :vcr do
38
+ subject.remove
39
+ Docker::Image.all.map(&:id).should_not include(id)
86
40
  end
87
41
  end
42
+ end
43
+
44
+ describe '#insert' do
45
+ context 'when the HTTP response status is not 200' do
46
+ before { Excon.stub({ :method => :post }, { :status => 500 }) }
47
+ after { Excon.stubs.shift }
88
48
 
89
- context 'when the body is not a Hash' do
90
49
  it 'raises an error' do
91
- expect { subject.create!(:not_a_hash) }
92
- .to raise_error(Docker::Error::ArgumentError)
50
+ expect { subject.insert }
51
+ .to raise_error(Docker::Error::ServerError)
93
52
  end
94
53
  end
95
54
 
96
- context 'when the Image does not yet exist and the body is a Hash' do
97
- context 'when the HTTP request does not return a 200' do
98
- before { Excon.stub({ :method => :post }, { :status => 400 }) }
99
- after { Excon.stubs.shift }
100
-
101
- it 'raises an error' do
102
- expect { subject.create! }.to raise_error(Docker::Error::ClientError)
103
- end
104
- end
55
+ context 'when the HTTP response status is 200' do
56
+ subject { described_class.build('from base') }
57
+ let(:new_image) { subject.insert(:path => '/stallman',
58
+ :url => 'http://stallman.org') }
59
+ let(:ls_output) { new_image.run('ls /').attach.split("\n") }
105
60
 
106
- context 'when the HTTP request returns a 200' do
107
- it 'sets the id', :vcr do
108
- expect { subject.create!('fromImage' => 'base') }
109
- .to change { subject.id }
110
- .from(nil)
111
- end
61
+ it 'inserts the url\'s file into a new Image', :vcr do
62
+ ls_output.should include('stallman')
112
63
  end
113
64
  end
114
65
  end
115
66
 
116
- describe '#remove' do
117
- context 'when the Image has not been created' do
67
+ describe '#push' do
68
+ context 'when the HTTP response status is not 200' do
69
+ before { Excon.stub({ :method => :post }, { :status => 500 }) }
70
+ after { Excon.stubs.shift }
71
+
118
72
  it 'raises an error' do
119
- expect { subject.remove }.to raise_error Docker::Error::StateError
73
+ expect { subject.push }
74
+ .to raise_error(Docker::Error::ServerError)
120
75
  end
121
76
  end
122
77
 
123
- context 'when the Image has been created' do
124
- context 'when the HTTP response status is not 204' do
125
- before do
126
- subject.stub(:created?).and_return(true)
127
- Excon.stub({ :method => :delete }, { :status => 500 })
128
- end
129
- after { Excon.stubs.shift }
130
-
131
- it 'raises an error' do
132
- expect { subject.remove }
133
- .to raise_error(Docker::Error::ServerError)
134
- end
135
- end
136
-
137
- context 'when the HTTP response status is 204' do
138
- before { subject.create!('fromImage' => 'base') }
78
+ context 'when the HTTP response status is 200' do
79
+ subject { described_class.create('fromImage' => 'base') }
139
80
 
140
- it 'nils out the id', :vcr do
141
- expect { subject.remove }
142
- .to change { subject.id }
143
- .to nil
144
- end
81
+ it 'pushes the Image', :vcr do
82
+ pending 'I don\'t want to push the Image to the Docker Registry'
83
+ subject.push
145
84
  end
146
85
  end
147
86
  end
148
87
 
149
- describe "#insert" do
150
- context 'when the Image has not been created' do
88
+ describe '#tag' do
89
+ context 'when the HTTP response status is not 200' do
90
+ before { Excon.stub({ :method => :post }, { :status => 500 }) }
91
+ after { Excon.stubs.shift }
92
+
151
93
  it 'raises an error' do
152
- expect { subject.insert }.to raise_error Docker::Error::StateError
94
+ expect { subject.tag }
95
+ .to raise_error(Docker::Error::ServerError)
153
96
  end
154
97
  end
155
98
 
156
- context 'when the Image has been created' do
157
- context 'when the HTTP response status is not 200' do
158
- before do
159
- subject.stub(:created?).and_return(true)
160
- Excon.stub({ :method => :post }, { :status => 500 })
161
- end
162
- after { Excon.stubs.shift }
99
+ context 'when the HTTP response status is 200' do
100
+ subject { described_class.create('fromImage' => 'base') }
163
101
 
164
- it 'raises an error' do
165
- expect { subject.insert }
166
- .to raise_error(Docker::Error::ServerError)
167
- end
168
- end
169
-
170
- context 'when the HTTP response status is 200' do
171
- subject { described_class.build('from base') }
172
- let(:new_image) { subject.insert(:path => '/stallman',
173
- :url => 'http://stallman.org') }
174
- let(:container) { Docker::Container.new }
175
- let(:ls_output) do
176
- container.tap(&:start)
177
- .attach(:stream => true, :stdout => true)
178
- .split("\n")
179
- end
180
- before { container.create!('Image' => new_image.id, 'Cmd' => %w[ls /]) }
181
-
182
- it 'inserts the url\'s file into a new Image', :vcr do
183
- ls_output.should include('stallman')
184
- end
102
+ it 'tags the image with the repo name', :vcr do
103
+ expect { subject.tag(:repo => 'base2', :force => true) }
104
+ .to_not raise_error
185
105
  end
186
106
  end
187
107
  end
188
108
 
189
- describe "#push" do
190
- context 'when the Image has not been created' do
109
+ describe '#json' do
110
+ context 'when the HTTP response status is not 200' do
111
+ before do
112
+ subject.stub(:created?).and_return(true)
113
+ Excon.stub({ :method => :get }, { :status => 500 })
114
+ end
115
+ after { Excon.stubs.shift }
116
+
191
117
  it 'raises an error' do
192
- expect { subject.push }.to raise_error Docker::Error::StateError
118
+ expect { subject.json }
119
+ .to raise_error(Docker::Error::ServerError)
193
120
  end
194
121
  end
195
122
 
196
- context 'when the Image has been created' do
197
- context 'when the HTTP response status is not 200' do
198
- before do
199
- subject.stub(:created?).and_return(true)
200
- Excon.stub({ :method => :post }, { :status => 500 })
201
- end
202
- after { Excon.stubs.shift }
123
+ context 'when the HTTP response status is 200' do
124
+ subject { described_class.create('fromImage' => 'base') }
125
+ let(:json) { subject.json }
203
126
 
204
- it 'raises an error' do
205
- expect { subject.push }
206
- .to raise_error(Docker::Error::ServerError)
207
- end
208
- end
209
-
210
- context 'when the HTTP response status is 200' do
211
- it 'pushes the Image', :vcr do
212
- pending 'I don\'t want to push the Image to the Docker Registry'
213
- subject.create!('fromImage' => 'base')
214
- subject.push
215
- end
127
+ it 'returns additional information about image image', :vcr do
128
+ json.should be_a Hash
129
+ json.length.should_not be_zero
216
130
  end
217
131
  end
218
132
  end
219
133
 
220
- describe "#tag" do
221
- context 'when the Image has not been created' do
134
+ describe '#history' do
135
+ context 'when the HTTP response status is not 200' do
136
+ before { Excon.stub({ :method => :get }, { :status => 500 }) }
137
+ after { Excon.stubs.shift }
138
+
222
139
  it 'raises an error' do
223
- expect { subject.tag }.to raise_error Docker::Error::StateError
140
+ expect { subject.history }
141
+ .to raise_error(Docker::Error::ServerError)
224
142
  end
225
143
  end
226
144
 
227
- context 'when the Image has been created' do
228
- context 'when the HTTP response status is not 200' do
229
- before do
230
- subject.stub(:created?).and_return(true)
231
- Excon.stub({ :method => :post }, { :status => 500 })
232
- end
233
- after { Excon.stubs.shift }
234
-
235
- it 'raises an error' do
236
- expect { subject.tag }
237
- .to raise_error(Docker::Error::ServerError)
238
- end
239
- end
145
+ context 'when the HTTP response status is 200' do
146
+ subject { described_class.create('fromImage' => 'base') }
147
+ let(:history) { subject.history }
240
148
 
241
- context 'when the HTTP response status is 200' do
242
- before { subject.create!('fromImage' => 'base') }
243
-
244
- it 'tags the image with the repo name', :vcr do
245
- expect { subject.tag(:repo => 'base2', :force => true) }
246
- .to_not raise_error
247
- end
149
+ it 'returns the history of the Image', :vcr do
150
+ history.should be_a Array
151
+ history.length.should_not be_zero
152
+ history.should be_all { |elem| elem.is_a? Hash }
248
153
  end
249
154
  end
250
155
  end
251
156
 
252
- describe "#json" do
253
- context 'when the Image has not been created' do
254
- it 'raises an error' do
255
- expect { subject.json }.to raise_error Docker::Error::StateError
256
- end
257
- end
157
+ describe '#run' do
158
+ subject { described_class.create('fromImage' => 'base') }
159
+ let(:output) { subject.run(cmd).attach }
258
160
 
259
- context 'when the Image has been created' do
260
- context 'when the HTTP response status is not 200' do
261
- before do
262
- subject.stub(:created?).and_return(true)
263
- Excon.stub({ :method => :get }, { :status => 500 })
264
- end
265
- after { Excon.stubs.shift }
266
-
267
- it 'raises an error' do
268
- expect { subject.json }
269
- .to raise_error(Docker::Error::ServerError)
270
- end
161
+ context 'when the argument is a String', :vcr do
162
+ let(:cmd) { 'ls /lib64/' }
163
+ it 'splits the String by spaces and creates a new Container' do
164
+ output.should == "ld-linux-x86-64.so.2\n"
271
165
  end
166
+ end
272
167
 
273
- context 'when the HTTP response status is 200' do
274
- let(:json) { subject.json }
275
- before { subject.create!('fromImage' => 'base') }
168
+ context 'when the argument is an Array' do
169
+ let(:cmd) { %[which pwd] }
276
170
 
277
- it 'returns additional information about image image', :vcr do
278
- json.should be_a Hash
279
- json.length.should_not be_zero
280
- end
171
+ it 'creates a new Container', :vcr do
172
+ output.should == "/bin/pwd\n"
281
173
  end
282
174
  end
283
175
  end
284
176
 
285
- describe "#history" do
286
- context 'when the Image has not been created' do
177
+ describe '.create' do
178
+ subject { described_class }
179
+
180
+ context 'when the body is not a Hash' do
287
181
  it 'raises an error' do
288
- expect { subject.history }.to raise_error Docker::Error::StateError
182
+ expect { subject.create(:not_a_hash) }
183
+ .to raise_error(Docker::Error::ArgumentError)
289
184
  end
290
185
  end
291
186
 
292
- context 'when the Image has been created' do
293
- context 'when the HTTP response status is not 200' do
294
- before do
295
- subject.stub(:created?).and_return(true)
296
- Excon.stub({ :method => :get }, { :status => 500 })
297
- end
187
+ context 'when the Image does not yet exist and the body is a Hash' do
188
+ context 'when the HTTP request does not return a 200' do
189
+ before { Excon.stub({ :method => :post }, { :status => 400 }) }
298
190
  after { Excon.stubs.shift }
299
191
 
300
192
  it 'raises an error' do
301
- expect { subject.history }
302
- .to raise_error(Docker::Error::ServerError)
193
+ expect { subject.create }.to raise_error(Docker::Error::ClientError)
303
194
  end
304
195
  end
305
196
 
306
- context 'when the HTTP response status is 200' do
307
- let(:history) { subject.history }
308
- before { subject.create!('fromImage' => 'base') }
309
-
310
- it 'returns the history of the Image', :vcr do
311
- history.should be_a Array
312
- history.length.should_not be_zero
313
- history.should be_all { |elem| elem.is_a? Hash }
197
+ context 'when the HTTP request returns a 200' do
198
+ let(:image) { subject.create('fromImage' => 'base') }
199
+ it 'sets the id', :vcr do
200
+ image.should be_a Docker::Image
201
+ image.id.should_not be_nil
314
202
  end
315
203
  end
316
204
  end
@@ -359,7 +247,8 @@ describe Docker::Image do
359
247
 
360
248
  context 'when the HTTP response is a 200' do
361
249
  let(:images) { subject.all(:all => true) }
362
- before { subject.new.create!('fromImage' => 'base') }
250
+ before { subject.create('fromImage' => 'base') }
251
+
363
252
  it 'materializes each Image into a Docker::Image', :vcr do
364
253
  images.should be_all { |image|
365
254
  !image.id.nil? && image.is_a?(described_class)
@@ -384,7 +273,6 @@ describe Docker::Image do
384
273
 
385
274
  context 'when the HTTP response is a 200' do
386
275
  it 'materializes each Image into a Docker::Image', :vcr do
387
- subject.new.create!('fromImage' => 'base')
388
276
  subject.search('term' => 'sshd').should be_all { |image|
389
277
  !image.id.nil? && image.is_a?(described_class)
390
278
  }
@@ -412,7 +300,7 @@ describe Docker::Image do
412
300
  end
413
301
  end
414
302
 
415
- describe '.build_from_dir', :current do
303
+ describe '.build_from_dir' do
416
304
  subject { described_class }
417
305
 
418
306
  context 'with a valid Dockerfile' do
@@ -420,13 +308,11 @@ describe Docker::Image do
420
308
  let(:docker_file) { File.new("#{dir}/Dockerfile") }
421
309
  let(:image) { subject.build_from_dir(dir) }
422
310
  let(:container) do
423
- Docker::Container.new.create!('Image' => image.id,
424
- 'Cmd' => %w[cat /Dockerfile])
311
+ Docker::Container.create('Image' => image.id,
312
+ 'Cmd' => %w[cat /Dockerfile])
425
313
  end
426
314
  let(:output) { container.tap(&:start)
427
- .attach(:stream => true,
428
- :stdout => true,
429
- :stderr => true) }
315
+ .attach(:stderr => true) }
430
316
 
431
317
  it 'builds the image', :vcr do
432
318
  pending 'webmock / vcr issue'