beaker-docker 0.5.4 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/release.yml +24 -0
- data/.github/workflows/test.yml +105 -0
- data/Gemfile.local +5 -0
- data/README.md +94 -13
- data/Rakefile +8 -4
- data/acceptance/config/nodes/hosts.yaml +21 -14
- data/acceptance/tests/00_default_spec.rb +10 -0
- data/beaker-docker.gemspec +3 -13
- data/lib/beaker-docker/version.rb +1 -1
- data/lib/beaker/hypervisor/docker.rb +149 -48
- data/spec/beaker/hypervisor/docker_spec.rb +505 -479
- metadata +16 -54
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'fakefs/spec_helpers'
|
|
3
3
|
|
|
4
|
-
# fake the docker-api
|
|
5
|
-
module Docker
|
|
6
|
-
class Image
|
|
7
|
-
end
|
|
8
|
-
class Container
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
4
|
module Beaker
|
|
13
5
|
platforms = [
|
|
14
6
|
"ubuntu-14.04-x86_64",
|
|
@@ -20,6 +12,8 @@ module Beaker
|
|
|
20
12
|
]
|
|
21
13
|
|
|
22
14
|
describe Docker do
|
|
15
|
+
require 'docker'
|
|
16
|
+
|
|
23
17
|
let(:hosts) {
|
|
24
18
|
the_hosts = make_hosts
|
|
25
19
|
the_hosts[2]['dockeropts'] = {
|
|
@@ -60,14 +54,15 @@ module Beaker
|
|
|
60
54
|
image
|
|
61
55
|
end
|
|
62
56
|
|
|
63
|
-
let(:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
let(:container_mode) do
|
|
58
|
+
'rootless'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
let(:container_config) do
|
|
62
|
+
conf = {
|
|
63
|
+
'HostConfig' => {
|
|
64
|
+
'NetworkMode' => 'slirp4netns'
|
|
65
|
+
},
|
|
71
66
|
'NetworkSettings' => {
|
|
72
67
|
'IPAddress' => '192.0.2.1',
|
|
73
68
|
'Ports' => {
|
|
@@ -80,7 +75,24 @@ module Beaker
|
|
|
80
75
|
},
|
|
81
76
|
'Gateway' => '192.0.2.254'
|
|
82
77
|
}
|
|
83
|
-
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
unless container_mode == 'rootless'
|
|
81
|
+
conf['HostConfig']['NetworkMode'] = 'bridge'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
conf
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
let(:container) do
|
|
88
|
+
container = double('Docker::Container')
|
|
89
|
+
allow( container ).to receive(:id).and_return('abcdef')
|
|
90
|
+
allow( container ).to receive(:start)
|
|
91
|
+
allow( container ).to receive(:stats)
|
|
92
|
+
allow( container ).to receive(:info).and_return(
|
|
93
|
+
*(0..2).map { |index| { 'Names' => ["/spec-container-#{index}"] } }
|
|
94
|
+
)
|
|
95
|
+
allow( container ).to receive(:json).and_return(container_config)
|
|
84
96
|
allow( container ).to receive(:kill)
|
|
85
97
|
allow( container ).to receive(:delete)
|
|
86
98
|
allow( container ).to receive(:exec)
|
|
@@ -88,603 +100,617 @@ module Beaker
|
|
|
88
100
|
end
|
|
89
101
|
|
|
90
102
|
let (:docker) { ::Beaker::Docker.new( hosts, options ) }
|
|
103
|
+
|
|
91
104
|
let(:docker_options) { nil }
|
|
105
|
+
|
|
92
106
|
let (:version) { {"ApiVersion"=>"1.18", "Arch"=>"amd64", "GitCommit"=>"4749651", "GoVersion"=>"go1.4.2", "KernelVersion"=>"3.16.0-37-generic", "Os"=>"linux", "Version"=>"1.6.0"} }
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
#
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
allow( ::Docker ).to receive(:logger=)
|
|
101
|
-
allow( ::Docker ).to receive(:version).and_return(version)
|
|
102
|
-
allow( ::Docker::Image ).to receive(:build).and_return(image)
|
|
103
|
-
allow( ::Docker::Image ).to receive(:create).and_return(image)
|
|
104
|
-
allow( ::Docker::Container ).to receive(:create).and_return(container)
|
|
105
|
-
allow_any_instance_of( ::Docker::Container ).to receive(:start)
|
|
106
|
-
end
|
|
108
|
+
context 'with connection failure' do
|
|
109
|
+
describe '#initialize' do
|
|
110
|
+
before :each do
|
|
111
|
+
require 'excon'
|
|
112
|
+
expect( ::Docker ).to receive(:version).and_raise(Excon::Errors::SocketError.new( StandardError.new('oops') )).exactly(4).times
|
|
113
|
+
end
|
|
107
114
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
expect { docker }.to raise_error(RuntimeError, /Docker instance not connectable./)
|
|
115
|
-
expect { docker }.to raise_error(RuntimeError, /Check your DOCKER_HOST variable has been set/)
|
|
116
|
-
expect { docker }.to raise_error(RuntimeError, /If you are on OSX or Windows, you might not have Docker Machine setup correctly/)
|
|
117
|
-
expect { docker }.to raise_error(RuntimeError, /Error was: oops/)
|
|
115
|
+
it 'should fail when docker not present' do
|
|
116
|
+
expect { docker }.to raise_error(RuntimeError, /Docker instance not connectable/)
|
|
117
|
+
expect { docker }.to raise_error(RuntimeError, /Check your DOCKER_HOST variable has been set/)
|
|
118
|
+
expect { docker }.to raise_error(RuntimeError, /If you are on OSX or Windows, you might not have Docker Machine setup correctly/)
|
|
119
|
+
expect { docker }.to raise_error(RuntimeError, /Error was: oops/)
|
|
120
|
+
end
|
|
118
121
|
end
|
|
119
122
|
end
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
|
|
125
|
+
context 'with a working connection' do
|
|
122
126
|
before :each do
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
# Stub out all of the docker-api gem. we should never really call it
|
|
128
|
+
# from these tests
|
|
129
|
+
allow_any_instance_of( ::Beaker::Docker ).to receive(:require).with('docker')
|
|
130
|
+
allow( ::Docker ).to receive(:options).and_return(docker_options)
|
|
131
|
+
allow( ::Docker ).to receive(:options=)
|
|
132
|
+
allow( ::Docker ).to receive(:logger=)
|
|
133
|
+
allow( ::Docker ).to receive(:version).and_return(version)
|
|
134
|
+
allow( ::Docker::Image ).to receive(:build).and_return(image)
|
|
135
|
+
allow( ::Docker::Image ).to receive(:create).and_return(image)
|
|
136
|
+
allow( ::Docker::Container ).to receive(:create).and_return(container)
|
|
137
|
+
allow_any_instance_of( ::Docker::Container ).to receive(:start)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
describe '#initialize' do
|
|
141
|
+
it 'should require the docker gem' do
|
|
142
|
+
expect_any_instance_of( ::Beaker::Docker ).to receive(:require).with('docker').once
|
|
125
143
|
|
|
126
|
-
|
|
127
|
-
|
|
144
|
+
docker
|
|
145
|
+
end
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
it 'should fail when the gem is absent' do
|
|
148
|
+
allow_any_instance_of( ::Beaker::Docker ).to receive(:require).with('docker').and_raise(LoadError)
|
|
149
|
+
expect { docker }.to raise_error(LoadError)
|
|
150
|
+
end
|
|
131
151
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
expect { docker }.to raise_error(LoadError)
|
|
135
|
-
end
|
|
152
|
+
it 'should set Docker options' do
|
|
153
|
+
expect( ::Docker ).to receive(:options=).with({:write_timeout => 300, :read_timeout => 300}).once
|
|
136
154
|
|
|
137
|
-
|
|
138
|
-
|
|
155
|
+
docker
|
|
156
|
+
end
|
|
139
157
|
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
context 'when Docker options are already set' do
|
|
159
|
+
let(:docker_options) {{:write_timeout => 600, :foo => :bar}}
|
|
142
160
|
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
it 'should not override Docker options' do
|
|
162
|
+
expect( ::Docker ).to receive(:options=).with({:write_timeout => 600, :read_timeout => 300, :foo => :bar}).once
|
|
145
163
|
|
|
146
|
-
|
|
147
|
-
|
|
164
|
+
docker
|
|
165
|
+
end
|
|
166
|
+
end
|
|
148
167
|
|
|
168
|
+
it 'should check the Docker gem can work with the api' do
|
|
149
169
|
docker
|
|
150
170
|
end
|
|
151
|
-
end
|
|
152
171
|
|
|
153
|
-
|
|
154
|
-
|
|
172
|
+
it 'should hook the Beaker logger into the Docker one' do
|
|
173
|
+
expect( ::Docker ).to receive(:logger=).with(logger)
|
|
155
174
|
|
|
156
|
-
|
|
175
|
+
docker
|
|
176
|
+
end
|
|
157
177
|
end
|
|
158
178
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
179
|
+
describe '#install_ssh_components' do
|
|
180
|
+
let(:test_container) { double('container') }
|
|
181
|
+
let(:host) {hosts[0]}
|
|
182
|
+
before :each do
|
|
183
|
+
allow( docker ).to receive(:dockerfile_for)
|
|
184
|
+
end
|
|
165
185
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
platforms.each do |platform|
|
|
187
|
+
it 'should call exec at least twice' do
|
|
188
|
+
host['platform'] = platform
|
|
189
|
+
expect(test_container).to receive(:exec).at_least(:twice)
|
|
190
|
+
docker.install_ssh_components(test_container, host)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
173
193
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
host['platform'] = platform
|
|
194
|
+
it 'should accept alpine as valid platform' do
|
|
195
|
+
host['platform'] = 'alpine-3.8-x86_64'
|
|
177
196
|
expect(test_container).to receive(:exec).at_least(:twice)
|
|
178
197
|
docker.install_ssh_components(test_container, host)
|
|
179
198
|
end
|
|
180
|
-
end
|
|
181
199
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
200
|
+
it 'should raise an error with an unsupported platform' do
|
|
201
|
+
host['platform'] = 'boogeyman-2000-x86_64'
|
|
202
|
+
expect{docker.install_ssh_components(test_container, host)}.to raise_error(RuntimeError, /boogeyman/)
|
|
203
|
+
end
|
|
186
204
|
end
|
|
187
205
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
end
|
|
206
|
+
describe '#provision' do
|
|
207
|
+
before :each do
|
|
208
|
+
allow( docker ).to receive(:dockerfile_for)
|
|
209
|
+
end
|
|
193
210
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
211
|
+
context 'when the host has "tag" defined' do
|
|
212
|
+
before :each do
|
|
213
|
+
hosts.each do |host|
|
|
214
|
+
host['tag'] = 'my_tag'
|
|
215
|
+
end
|
|
216
|
+
end
|
|
199
217
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
host['tag'] = 'my_tag'
|
|
218
|
+
it 'will tag the image with the value of the tag' do
|
|
219
|
+
expect( image ).to receive(:tag).with({:repo => 'my_tag'}).exactly(3).times
|
|
220
|
+
docker.provision
|
|
204
221
|
end
|
|
205
222
|
end
|
|
206
223
|
|
|
207
|
-
|
|
208
|
-
expect( image ).to receive(:tag).with({:repo => 'my_tag'}).exactly(3).times
|
|
209
|
-
docker.provision
|
|
210
|
-
end
|
|
211
|
-
end
|
|
224
|
+
context 'when the host has "use_image_entry_point" set to true on the host' do
|
|
212
225
|
|
|
213
|
-
|
|
226
|
+
before :each do
|
|
227
|
+
hosts.each do |host|
|
|
228
|
+
host['use_image_entry_point'] = true
|
|
229
|
+
end
|
|
230
|
+
end
|
|
214
231
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
232
|
+
it 'should not call #dockerfile_for but run methods necessary for ssh installation' do
|
|
233
|
+
expect( docker ).not_to receive(:dockerfile_for)
|
|
234
|
+
expect( docker ).to receive(:install_ssh_components).exactly(3).times #once per host
|
|
235
|
+
expect( docker ).to receive(:fix_ssh).exactly(3).times #once per host
|
|
236
|
+
docker.provision
|
|
218
237
|
end
|
|
219
238
|
end
|
|
220
239
|
|
|
221
|
-
|
|
222
|
-
expect( docker ).not_to receive(:dockerfile_for)
|
|
223
|
-
expect( docker ).to receive(:install_ssh_components).exactly(3).times #once per host
|
|
224
|
-
expect( docker ).to receive(:fix_ssh).exactly(3).times #once per host
|
|
225
|
-
docker.provision
|
|
226
|
-
end
|
|
227
|
-
end
|
|
240
|
+
context 'when the host has a "dockerfile" for the host' do
|
|
228
241
|
|
|
229
|
-
|
|
242
|
+
before :each do
|
|
243
|
+
allow( docker ).to receive(:buildargs_for).and_return('buildargs')
|
|
244
|
+
hosts.each do |host|
|
|
245
|
+
host['dockerfile'] = 'mydockerfile'
|
|
246
|
+
end
|
|
247
|
+
end
|
|
230
248
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
249
|
+
it 'should not call #dockerfile_for but run methods necessary for ssh installation' do
|
|
250
|
+
allow( File ).to receive(:exist?).with('mydockerfile').and_return(true)
|
|
251
|
+
allow( ::Docker::Image ).to receive(:build_from_dir).with("/", hash_including(:rm => true, :buildargs => 'buildargs')).and_return(image)
|
|
252
|
+
expect( docker ).not_to receive(:dockerfile_for)
|
|
253
|
+
expect( docker ).to receive(:install_ssh_components).exactly(3).times #once per host
|
|
254
|
+
expect( docker ).to receive(:fix_ssh).exactly(3).times #once per host
|
|
255
|
+
docker.provision
|
|
235
256
|
end
|
|
236
257
|
end
|
|
237
258
|
|
|
238
|
-
it 'should
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
259
|
+
it 'should call image create for hosts when use_image_as_is is defined' do
|
|
260
|
+
hosts.each do |host|
|
|
261
|
+
host['use_image_as_is'] = true
|
|
262
|
+
expect( docker ).not_to receive(:install_ssh_components)
|
|
263
|
+
expect( docker ).not_to receive(:fix_ssh)
|
|
264
|
+
expect( ::Docker::Image ).to receive(:create).with('fromImage' => host['image']) #once per host
|
|
265
|
+
expect( ::Docker::Image ).not_to receive(:build)
|
|
266
|
+
expect( ::Docker::Image ).not_to receive(:build_from_dir)
|
|
267
|
+
end
|
|
247
268
|
|
|
248
|
-
|
|
249
|
-
hosts.each do |host|
|
|
250
|
-
host['use_image_as_is'] = true
|
|
251
|
-
expect( docker ).not_to receive(:install_ssh_components)
|
|
252
|
-
expect( docker ).not_to receive(:fix_ssh)
|
|
253
|
-
expect( ::Docker::Image ).to receive(:create).with('fromImage' => host['image']) #once per host
|
|
254
|
-
expect( ::Docker::Image ).not_to receive(:build)
|
|
255
|
-
expect( ::Docker::Image ).not_to receive(:build_from_dir)
|
|
269
|
+
docker.provision
|
|
256
270
|
end
|
|
257
271
|
|
|
258
|
-
|
|
259
|
-
|
|
272
|
+
it 'should call dockerfile_for with all the hosts' do
|
|
273
|
+
hosts.each do |host|
|
|
274
|
+
expect( docker ).not_to receive(:install_ssh_components)
|
|
275
|
+
expect( docker ).not_to receive(:fix_ssh)
|
|
276
|
+
expect( docker ).to receive(:dockerfile_for).with(host).and_return('')
|
|
277
|
+
end
|
|
260
278
|
|
|
261
|
-
|
|
262
|
-
hosts.each do |host|
|
|
263
|
-
expect( docker ).not_to receive(:install_ssh_components)
|
|
264
|
-
expect( docker ).not_to receive(:fix_ssh)
|
|
265
|
-
expect( docker ).to receive(:dockerfile_for).with(host).and_return('')
|
|
279
|
+
docker.provision
|
|
266
280
|
end
|
|
267
281
|
|
|
268
|
-
|
|
269
|
-
|
|
282
|
+
it 'should pass the Dockerfile on to Docker::Image.create' do
|
|
283
|
+
allow( docker ).to receive(:dockerfile_for).and_return('special testing value')
|
|
284
|
+
expect( ::Docker::Image ).to receive(:build).with('special testing value', { :rm => true, :buildargs => '{}' })
|
|
270
285
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
expect( ::Docker::Image ).to receive(:build).with('special testing value', { :rm => true, :buildargs => '{}' })
|
|
274
|
-
|
|
275
|
-
docker.provision
|
|
276
|
-
end
|
|
286
|
+
docker.provision
|
|
287
|
+
end
|
|
277
288
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
289
|
+
it 'should pass the buildargs from ENV DOCKER_BUILDARGS on to Docker::Image.create' do
|
|
290
|
+
allow( docker ).to receive(:dockerfile_for).and_return('special testing value')
|
|
291
|
+
ENV['DOCKER_BUILDARGS'] = 'HTTP_PROXY=http://1.1.1.1:3128'
|
|
292
|
+
expect( ::Docker::Image ).to receive(:build).with('special testing value', { :rm => true, :buildargs => "{\"HTTP_PROXY\":\"http://1.1.1.1:3128\"}" })
|
|
282
293
|
|
|
283
|
-
|
|
284
|
-
|
|
294
|
+
docker.provision
|
|
295
|
+
end
|
|
285
296
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
297
|
+
it 'should create a container based on the Image (identified by image.id)' do
|
|
298
|
+
hosts.each_with_index do |host,index|
|
|
299
|
+
expect( ::Docker::Container ).to receive(:create).with({
|
|
300
|
+
'Image' => image.id,
|
|
301
|
+
'Hostname' => host.name,
|
|
302
|
+
'HostConfig' => {
|
|
303
|
+
'PortBindings' => {
|
|
304
|
+
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
305
|
+
},
|
|
306
|
+
'PublishAllPorts' => true,
|
|
307
|
+
'RestartPolicy' => {
|
|
308
|
+
'Name' => 'always'
|
|
309
|
+
}
|
|
294
310
|
},
|
|
295
|
-
'
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
'one' => 1,
|
|
303
|
-
'two' => 2,
|
|
304
|
-
},
|
|
305
|
-
}).with(hash_excluding('name'))
|
|
306
|
-
end
|
|
311
|
+
'Labels' => {
|
|
312
|
+
'one' => (index == 2 ? 3 : 1),
|
|
313
|
+
'two' => (index == 2 ? 4 : 2),
|
|
314
|
+
},
|
|
315
|
+
'name' => /\Abeaker-/
|
|
316
|
+
})
|
|
317
|
+
end
|
|
307
318
|
|
|
308
|
-
|
|
309
|
-
|
|
319
|
+
docker.provision
|
|
320
|
+
end
|
|
310
321
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
322
|
+
it 'should pass the multiple buildargs from ENV DOCKER_BUILDARGS on to Docker::Image.create' do
|
|
323
|
+
allow( docker ).to receive(:dockerfile_for).and_return('special testing value')
|
|
324
|
+
ENV['DOCKER_BUILDARGS'] = 'HTTP_PROXY=http://1.1.1.1:3128 HTTPS_PROXY=https://1.1.1.1:3129'
|
|
325
|
+
expect( ::Docker::Image ).to receive(:build).with('special testing value', { :rm => true, :buildargs => "{\"HTTP_PROXY\":\"http://1.1.1.1:3128\",\"HTTPS_PROXY\":\"https://1.1.1.1:3129\"}" })
|
|
315
326
|
|
|
316
|
-
|
|
317
|
-
|
|
327
|
+
docker.provision
|
|
328
|
+
end
|
|
318
329
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
330
|
+
it 'should create a container based on the Image (identified by image.id)' do
|
|
331
|
+
hosts.each_with_index do |host,index|
|
|
332
|
+
expect( ::Docker::Container ).to receive(:create).with({
|
|
333
|
+
'Image' => image.id,
|
|
334
|
+
'Hostname' => host.name,
|
|
335
|
+
'HostConfig' => {
|
|
336
|
+
'PortBindings' => {
|
|
337
|
+
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
338
|
+
},
|
|
339
|
+
'PublishAllPorts' => true,
|
|
340
|
+
'RestartPolicy' => {
|
|
341
|
+
'Name' => 'always'
|
|
342
|
+
}
|
|
327
343
|
},
|
|
328
|
-
'
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
},
|
|
338
|
-
}).with(hash_excluding('name'))
|
|
344
|
+
'Labels' => {
|
|
345
|
+
'one' => (index == 2 ? 3 : 1),
|
|
346
|
+
'two' => (index == 2 ? 4 : 2),
|
|
347
|
+
},
|
|
348
|
+
'name' => /\Abeaker-/
|
|
349
|
+
})
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
docker.provision
|
|
339
353
|
end
|
|
340
354
|
|
|
341
|
-
|
|
342
|
-
|
|
355
|
+
it 'should create a named container based on the Image (identified by image.id)' do
|
|
356
|
+
hosts.each_with_index do |host, index|
|
|
357
|
+
container_name = "spec-container-#{index}"
|
|
358
|
+
host['docker_container_name'] = container_name
|
|
343
359
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
360
|
+
allow(::Docker::Container).to receive(:all).and_return([])
|
|
361
|
+
expect( ::Docker::Container ).to receive(:create).with({
|
|
362
|
+
'Image' => image.id,
|
|
363
|
+
'Hostname' => host.name,
|
|
364
|
+
'name' => container_name,
|
|
365
|
+
'HostConfig' => {
|
|
366
|
+
'PortBindings' => {
|
|
367
|
+
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
368
|
+
},
|
|
369
|
+
'PublishAllPorts' => true,
|
|
370
|
+
'RestartPolicy' => {
|
|
371
|
+
'Name' => 'always'
|
|
372
|
+
}
|
|
357
373
|
},
|
|
358
|
-
'
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
'Labels' => {
|
|
365
|
-
'one' => (index == 2 ? 3 : 1),
|
|
366
|
-
'two' => (index == 2 ? 4 : 2),
|
|
367
|
-
},
|
|
368
|
-
})
|
|
369
|
-
end
|
|
374
|
+
'Labels' => {
|
|
375
|
+
'one' => (index == 2 ? 3 : 1),
|
|
376
|
+
'two' => (index == 2 ? 4 : 2),
|
|
377
|
+
},
|
|
378
|
+
})
|
|
379
|
+
end
|
|
370
380
|
|
|
371
|
-
|
|
372
|
-
|
|
381
|
+
docker.provision
|
|
382
|
+
end
|
|
373
383
|
|
|
374
384
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
},
|
|
387
|
-
'mount3' => {
|
|
388
|
-
'host_path' => '/different_folder',
|
|
389
|
-
'container_path' => '/different_mount',
|
|
390
|
-
'opts' => 'rw',
|
|
391
|
-
},
|
|
392
|
-
'mount4' => {
|
|
393
|
-
'host_path' => './',
|
|
394
|
-
'container_path' => '/relative_mount',
|
|
395
|
-
},
|
|
396
|
-
'mount5' => {
|
|
397
|
-
'host_path' => 'local_folder',
|
|
398
|
-
'container_path' => '/another_relative_mount',
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
expect( ::Docker::Container ).to receive(:create).with({
|
|
403
|
-
'Image' => image.id,
|
|
404
|
-
'Hostname' => host.name,
|
|
405
|
-
'HostConfig' => {
|
|
406
|
-
'Binds' => [
|
|
407
|
-
'/source_folder:/mount_point',
|
|
408
|
-
'/another_folder:/another_mount:ro',
|
|
409
|
-
'/different_folder:/different_mount:rw',
|
|
410
|
-
"#{File.expand_path('./')}:/relative_mount",
|
|
411
|
-
"#{File.expand_path('local_folder')}:/another_relative_mount",
|
|
412
|
-
],
|
|
413
|
-
'PortBindings' => {
|
|
414
|
-
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
385
|
+
it 'should create a container with volumes bound' do
|
|
386
|
+
hosts.each_with_index do |host, index|
|
|
387
|
+
host['mount_folders'] = {
|
|
388
|
+
'mount1' => {
|
|
389
|
+
'host_path' => '/source_folder',
|
|
390
|
+
'container_path' => '/mount_point',
|
|
391
|
+
},
|
|
392
|
+
'mount2' => {
|
|
393
|
+
'host_path' => '/another_folder',
|
|
394
|
+
'container_path' => '/another_mount',
|
|
395
|
+
'opts' => 'ro',
|
|
415
396
|
},
|
|
416
|
-
'
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
'
|
|
397
|
+
'mount3' => {
|
|
398
|
+
'host_path' => '/different_folder',
|
|
399
|
+
'container_path' => '/different_mount',
|
|
400
|
+
'opts' => 'rw',
|
|
401
|
+
},
|
|
402
|
+
'mount4' => {
|
|
403
|
+
'host_path' => './',
|
|
404
|
+
'container_path' => '/relative_mount',
|
|
405
|
+
},
|
|
406
|
+
'mount5' => {
|
|
407
|
+
'host_path' => 'local_folder',
|
|
408
|
+
'container_path' => '/another_relative_mount',
|
|
420
409
|
}
|
|
421
|
-
}
|
|
422
|
-
'Labels' => {
|
|
423
|
-
'one' => (index == 2 ? 3 : 1),
|
|
424
|
-
'two' => (index == 2 ? 4 : 2),
|
|
425
|
-
},
|
|
426
|
-
})
|
|
427
|
-
end
|
|
410
|
+
}
|
|
428
411
|
|
|
429
|
-
|
|
430
|
-
|
|
412
|
+
expect( ::Docker::Container ).to receive(:create).with({
|
|
413
|
+
'Image' => image.id,
|
|
414
|
+
'Hostname' => host.name,
|
|
415
|
+
'HostConfig' => {
|
|
416
|
+
'Binds' => [
|
|
417
|
+
'/source_folder:/mount_point:z',
|
|
418
|
+
'/another_folder:/another_mount:ro',
|
|
419
|
+
'/different_folder:/different_mount:rw',
|
|
420
|
+
"#{File.expand_path('./')}:/relative_mount:z",
|
|
421
|
+
"#{File.expand_path('local_folder')}:/another_relative_mount:z",
|
|
422
|
+
],
|
|
423
|
+
'PortBindings' => {
|
|
424
|
+
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
425
|
+
},
|
|
426
|
+
'PublishAllPorts' => true,
|
|
427
|
+
'RestartPolicy' => {
|
|
428
|
+
'Name' => 'always'
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
'Labels' => {
|
|
432
|
+
'one' => (index == 2 ? 3 : 1),
|
|
433
|
+
'two' => (index == 2 ? 4 : 2),
|
|
434
|
+
},
|
|
435
|
+
'name' => /\Abeaker-/
|
|
436
|
+
})
|
|
437
|
+
end
|
|
431
438
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
host['docker_cap_add'] = ['NET_ADMIN', 'SYS_ADMIN']
|
|
439
|
+
docker.provision
|
|
440
|
+
end
|
|
435
441
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
'
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
+
it 'should create a container with capabilities added' do
|
|
443
|
+
hosts.each_with_index do |host, index|
|
|
444
|
+
host['docker_cap_add'] = ['NET_ADMIN', 'SYS_ADMIN']
|
|
445
|
+
|
|
446
|
+
expect( ::Docker::Container ).to receive(:create).with({
|
|
447
|
+
'Image' => image.id,
|
|
448
|
+
'Hostname' => host.name,
|
|
449
|
+
'HostConfig' => {
|
|
450
|
+
'PortBindings' => {
|
|
451
|
+
'22/tcp' => [{ 'HostPort' => /\b\d{4}\b/, 'HostIp' => '0.0.0.0'}]
|
|
452
|
+
},
|
|
453
|
+
'PublishAllPorts' => true,
|
|
454
|
+
'RestartPolicy' => {
|
|
455
|
+
'Name' => 'always'
|
|
456
|
+
},
|
|
457
|
+
'CapAdd' => ['NET_ADMIN', 'SYS_ADMIN']
|
|
442
458
|
},
|
|
443
|
-
'
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
'Name' => 'always'
|
|
459
|
+
'Labels' => {
|
|
460
|
+
'one' => (index == 2 ? 3 : 1),
|
|
461
|
+
'two' => (index == 2 ? 4 : 2),
|
|
447
462
|
},
|
|
448
|
-
'
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
},
|
|
454
|
-
})
|
|
463
|
+
'name' => /\Abeaker-/
|
|
464
|
+
})
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
docker.provision
|
|
455
468
|
end
|
|
456
469
|
|
|
457
|
-
|
|
458
|
-
|
|
470
|
+
it 'should start the container' do
|
|
471
|
+
expect( container ).to receive(:start)
|
|
459
472
|
|
|
460
|
-
|
|
461
|
-
|
|
473
|
+
docker.provision
|
|
474
|
+
end
|
|
462
475
|
|
|
463
|
-
|
|
464
|
-
|
|
476
|
+
context "connecting to ssh" do
|
|
477
|
+
context "rootless" do
|
|
478
|
+
before { @docker_host = ENV['DOCKER_HOST'] }
|
|
479
|
+
after { ENV['DOCKER_HOST'] = @docker_host }
|
|
480
|
+
|
|
481
|
+
it 'should expose port 22 to beaker' do
|
|
482
|
+
ENV['DOCKER_HOST'] = nil
|
|
483
|
+
docker.provision
|
|
484
|
+
|
|
485
|
+
expect( hosts[0]['ip'] ).to be === '127.0.1.1'
|
|
486
|
+
expect( hosts[0]['port'] ).to be === 8022
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it 'should expose port 22 to beaker when using DOCKER_HOST' do
|
|
490
|
+
ENV['DOCKER_HOST'] = "tcp://192.0.2.2:2375"
|
|
491
|
+
docker.provision
|
|
492
|
+
|
|
493
|
+
expect( hosts[0]['ip'] ).to be === '192.0.2.2'
|
|
494
|
+
expect( hosts[0]['port'] ).to be === 8022
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
it 'should have ssh agent forwarding enabled' do
|
|
498
|
+
ENV['DOCKER_HOST'] = nil
|
|
499
|
+
docker.provision
|
|
500
|
+
|
|
501
|
+
expect( hosts[0]['ip'] ).to be === '127.0.1.1'
|
|
502
|
+
expect( hosts[0]['port'] ).to be === 8022
|
|
503
|
+
expect( hosts[0]['ssh'][:password] ).to be === 'root'
|
|
504
|
+
expect( hosts[0]['ssh'][:port] ).to be === 8022
|
|
505
|
+
expect( hosts[0]['ssh'][:forward_agent] ).to be === true
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
it 'should connect to gateway ip' do
|
|
509
|
+
FakeFS do
|
|
510
|
+
File.open('/.dockerenv', 'w') { }
|
|
511
|
+
docker.provision
|
|
512
|
+
|
|
513
|
+
expect( hosts[0]['ip'] ).to be === '192.0.2.254'
|
|
514
|
+
expect( hosts[0]['port'] ).to be === 8022
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
end
|
|
465
518
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
519
|
+
context 'rootful' do
|
|
520
|
+
before { @docker_host = ENV['DOCKER_HOST'] }
|
|
521
|
+
after { ENV['DOCKER_HOST'] = @docker_host }
|
|
469
522
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
523
|
+
let(:container_mode) do
|
|
524
|
+
'rootful'
|
|
525
|
+
end
|
|
473
526
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
527
|
+
it 'should expose port 22 to beaker' do
|
|
528
|
+
ENV['DOCKER_HOST'] = nil
|
|
529
|
+
docker.provision
|
|
477
530
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
531
|
+
expect( hosts[0]['ip'] ).to be === '192.0.2.1'
|
|
532
|
+
expect( hosts[0]['port'] ).to be === '22'
|
|
533
|
+
end
|
|
534
|
+
end
|
|
481
535
|
|
|
482
|
-
expect( hosts[0]['ip'] ).to be === '192.0.2.2'
|
|
483
|
-
expect( hosts[0]['port'] ).to be === 8022
|
|
484
536
|
end
|
|
485
537
|
|
|
486
|
-
it
|
|
538
|
+
it "should generate a new /etc/hosts file referencing each host" do
|
|
487
539
|
ENV['DOCKER_HOST'] = nil
|
|
488
540
|
docker.provision
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
expect( hosts[0]['ssh'][:password] ).to be === 'root'
|
|
493
|
-
expect( hosts[0]['ssh'][:port] ).to be === 8022
|
|
494
|
-
expect( hosts[0]['ssh'][:forward_agent] ).to be === true
|
|
495
|
-
end
|
|
496
|
-
|
|
497
|
-
it 'should connect to gateway ip' do
|
|
498
|
-
FakeFS do
|
|
499
|
-
File.open('/.dockerenv', 'w') { }
|
|
500
|
-
docker.provision
|
|
501
|
-
|
|
502
|
-
expect( hosts[0]['ip'] ).to be === '192.0.2.254'
|
|
503
|
-
expect( hosts[0]['port'] ).to be === 8022
|
|
541
|
+
hosts.each do |host|
|
|
542
|
+
expect( docker ).to receive( :get_domain_name ).with( host ).and_return( 'labs.lan' )
|
|
543
|
+
expect( docker ).to receive( :set_etc_hosts ).with( host, "127.0.0.1\tlocalhost localhost.localdomain\n192.0.2.1\tvm1.labs.lan vm1\n192.0.2.1\tvm2.labs.lan vm2\n192.0.2.1\tvm3.labs.lan vm3\n" ).once
|
|
504
544
|
end
|
|
545
|
+
docker.hack_etc_hosts( hosts, options )
|
|
505
546
|
end
|
|
506
547
|
|
|
507
|
-
|
|
548
|
+
it 'should record the image and container for later' do
|
|
549
|
+
docker.provision
|
|
508
550
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
docker.provision
|
|
512
|
-
hosts.each do |host|
|
|
513
|
-
expect( docker ).to receive( :get_domain_name ).with( host ).and_return( 'labs.lan' )
|
|
514
|
-
expect( docker ).to receive( :set_etc_hosts ).with( host, "127.0.0.1\tlocalhost localhost.localdomain\n192.0.2.1\tvm1.labs.lan vm1\n192.0.2.1\tvm2.labs.lan vm2\n192.0.2.1\tvm3.labs.lan vm3\n" ).once
|
|
551
|
+
expect( hosts[0]['docker_image_id'] ).to be === image.id
|
|
552
|
+
expect( hosts[0]['docker_container_id'] ).to be === container.id
|
|
515
553
|
end
|
|
516
|
-
docker.hack_etc_hosts( hosts, options )
|
|
517
|
-
end
|
|
518
|
-
|
|
519
|
-
it 'should record the image and container for later' do
|
|
520
|
-
docker.provision
|
|
521
554
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
555
|
+
context 'provision=false' do
|
|
556
|
+
let(:options) {{
|
|
557
|
+
:logger => logger,
|
|
558
|
+
:forward_ssh_agent => true,
|
|
559
|
+
:provision => false
|
|
560
|
+
}}
|
|
525
561
|
|
|
526
|
-
context 'provision=false' do
|
|
527
|
-
let(:options) {{
|
|
528
|
-
:logger => logger,
|
|
529
|
-
:forward_ssh_agent => true,
|
|
530
|
-
:provision => false
|
|
531
|
-
}}
|
|
532
562
|
|
|
563
|
+
it 'should fix ssh' do
|
|
564
|
+
hosts.each_with_index do |host, index|
|
|
565
|
+
container_name = "spec-container-#{index}"
|
|
566
|
+
host['docker_container_name'] = container_name
|
|
533
567
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
expect( ::Docker::Container ).to receive(:all).and_return([container])
|
|
540
|
-
expect(docker).to receive(:fix_ssh).exactly(1).times
|
|
568
|
+
expect( ::Docker::Container ).to receive(:all).and_return([container])
|
|
569
|
+
expect(docker).to receive(:fix_ssh).exactly(1).times
|
|
570
|
+
end
|
|
571
|
+
docker.provision
|
|
541
572
|
end
|
|
542
|
-
docker.provision
|
|
543
|
-
end
|
|
544
573
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
574
|
+
it 'should not create a container if a named one already exists' do
|
|
575
|
+
hosts.each_with_index do |host, index|
|
|
576
|
+
container_name = "spec-container-#{index}"
|
|
577
|
+
host['docker_container_name'] = container_name
|
|
549
578
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
579
|
+
expect( ::Docker::Container ).to receive(:all).and_return([container])
|
|
580
|
+
expect( ::Docker::Container ).not_to receive(:create)
|
|
581
|
+
end
|
|
553
582
|
|
|
554
|
-
|
|
583
|
+
docker.provision
|
|
584
|
+
end
|
|
555
585
|
end
|
|
556
586
|
end
|
|
557
|
-
end
|
|
558
587
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
it 'should stop the containers' do
|
|
570
|
-
allow( docker ).to receive( :sleep ).and_return(true)
|
|
571
|
-
expect( container ).to receive(:kill)
|
|
572
|
-
docker.cleanup
|
|
573
|
-
end
|
|
588
|
+
describe '#cleanup' do
|
|
589
|
+
before :each do
|
|
590
|
+
# get into a state where there's something to clean
|
|
591
|
+
allow( ::Docker::Container ).to receive(:all).and_return([container])
|
|
592
|
+
allow( ::Docker::Image ).to receive(:remove).with(image.id)
|
|
593
|
+
allow( docker ).to receive(:dockerfile_for)
|
|
594
|
+
docker.provision
|
|
595
|
+
end
|
|
574
596
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
597
|
+
it 'should stop the containers' do
|
|
598
|
+
allow( docker ).to receive( :sleep ).and_return(true)
|
|
599
|
+
expect( container ).to receive(:kill)
|
|
600
|
+
docker.cleanup
|
|
601
|
+
end
|
|
580
602
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
603
|
+
it 'should delete the containers' do
|
|
604
|
+
allow( docker ).to receive( :sleep ).and_return(true)
|
|
605
|
+
expect( container ).to receive(:delete)
|
|
606
|
+
docker.cleanup
|
|
607
|
+
end
|
|
586
608
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
609
|
+
it 'should delete the images' do
|
|
610
|
+
allow( docker ).to receive( :sleep ).and_return(true)
|
|
611
|
+
expect( ::Docker::Image ).to receive(:remove).with(image.id)
|
|
612
|
+
docker.cleanup
|
|
591
613
|
end
|
|
592
|
-
expect( ::Docker::Image ).to_not receive(:remove)
|
|
593
|
-
docker.cleanup
|
|
594
|
-
end
|
|
595
614
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
615
|
+
it 'should not delete the image if docker_preserve_image is set to true' do
|
|
616
|
+
allow( docker ).to receive( :sleep ).and_return(true)
|
|
617
|
+
hosts.each do |host|
|
|
618
|
+
host['docker_preserve_image']=true
|
|
619
|
+
end
|
|
620
|
+
expect( ::Docker::Image ).to_not receive(:remove)
|
|
621
|
+
docker.cleanup
|
|
600
622
|
end
|
|
601
|
-
expect( ::Docker::Image ).to receive(:remove).with(image.id)
|
|
602
|
-
docker.cleanup
|
|
603
|
-
end
|
|
604
623
|
|
|
605
|
-
|
|
624
|
+
it 'should delete the image if docker_preserve_image is set to false' do
|
|
625
|
+
allow( docker ).to receive( :sleep ).and_return(true)
|
|
626
|
+
hosts.each do |host|
|
|
627
|
+
host['docker_preserve_image']=false
|
|
628
|
+
end
|
|
629
|
+
expect( ::Docker::Image ).to receive(:remove).with(image.id)
|
|
630
|
+
docker.cleanup
|
|
631
|
+
end
|
|
606
632
|
|
|
607
|
-
describe '#dockerfile_for' do
|
|
608
|
-
FakeFS.deactivate!
|
|
609
|
-
before :each do
|
|
610
|
-
allow( ::Docker ).to receive(:validate_version!)
|
|
611
|
-
end
|
|
612
|
-
it 'should raise on an unsupported platform' do
|
|
613
|
-
expect { docker.send(:dockerfile_for, {'platform' => 'a_sidewalk', 'image' => 'foobar' }) }.to raise_error(/platform a_sidewalk not yet supported/)
|
|
614
633
|
end
|
|
615
634
|
|
|
616
|
-
|
|
635
|
+
describe '#dockerfile_for' do
|
|
617
636
|
FakeFS.deactivate!
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
'platform' => platform,
|
|
621
|
-
'image' => 'foobar',
|
|
622
|
-
})
|
|
623
|
-
expect( dockerfile ).to be =~ /ENV container docker/
|
|
637
|
+
it 'should raise on an unsupported platform' do
|
|
638
|
+
expect { docker.send(:dockerfile_for, {'platform' => 'a_sidewalk', 'image' => 'foobar' }) }.to raise_error(/platform a_sidewalk not yet supported/)
|
|
624
639
|
end
|
|
625
|
-
end
|
|
626
640
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
]
|
|
638
|
-
})
|
|
641
|
+
it 'should set "ENV container docker"' do
|
|
642
|
+
FakeFS.deactivate!
|
|
643
|
+
platforms.each do |platform|
|
|
644
|
+
dockerfile = docker.send(:dockerfile_for, {
|
|
645
|
+
'platform' => platform,
|
|
646
|
+
'image' => 'foobar',
|
|
647
|
+
})
|
|
648
|
+
expect( dockerfile ).to be =~ /ENV container docker/
|
|
649
|
+
end
|
|
650
|
+
end
|
|
639
651
|
|
|
640
|
-
|
|
652
|
+
it 'should add docker_image_commands as RUN statements' do
|
|
653
|
+
FakeFS.deactivate!
|
|
654
|
+
platforms.each do |platform|
|
|
655
|
+
dockerfile = docker.send(:dockerfile_for, {
|
|
656
|
+
'platform' => platform,
|
|
657
|
+
'image' => 'foobar',
|
|
658
|
+
'docker_image_commands' => [
|
|
659
|
+
'special one',
|
|
660
|
+
'special two',
|
|
661
|
+
'special three',
|
|
662
|
+
]
|
|
663
|
+
})
|
|
664
|
+
|
|
665
|
+
expect( dockerfile ).to be =~ /RUN special one\nRUN special two\nRUN special three/
|
|
666
|
+
end
|
|
641
667
|
end
|
|
642
|
-
end
|
|
643
668
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
669
|
+
it 'should add docker_image_entrypoint' do
|
|
670
|
+
FakeFS.deactivate!
|
|
671
|
+
platforms.each do |platform|
|
|
672
|
+
dockerfile = docker.send(:dockerfile_for, {
|
|
673
|
+
'platform' => platform,
|
|
674
|
+
'image' => 'foobar',
|
|
675
|
+
'docker_image_entrypoint' => '/bin/bash'
|
|
676
|
+
})
|
|
677
|
+
|
|
678
|
+
expect( dockerfile ).to be =~ %r{ENTRYPOINT /bin/bash}
|
|
679
|
+
end
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
it 'should use zypper on sles' do
|
|
683
|
+
FakeFS.deactivate!
|
|
647
684
|
dockerfile = docker.send(:dockerfile_for, {
|
|
648
|
-
'platform' =>
|
|
685
|
+
'platform' => 'sles-12-x86_64',
|
|
649
686
|
'image' => 'foobar',
|
|
650
|
-
'docker_image_entrypoint' => '/bin/bash'
|
|
651
687
|
})
|
|
652
688
|
|
|
653
|
-
expect( dockerfile ).to be =~
|
|
689
|
+
expect( dockerfile ).to be =~ /RUN zypper -n in openssh/
|
|
654
690
|
end
|
|
655
|
-
end
|
|
656
691
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
692
|
+
(22..29).to_a.each do | fedora_release |
|
|
693
|
+
it "should use dnf on fedora #{fedora_release}" do
|
|
694
|
+
FakeFS.deactivate!
|
|
695
|
+
dockerfile = docker.send(:dockerfile_for, {
|
|
696
|
+
'platform' => "fedora-#{fedora_release}-x86_64",
|
|
697
|
+
'image' => 'foobar',
|
|
698
|
+
})
|
|
663
699
|
|
|
664
|
-
|
|
665
|
-
|
|
700
|
+
expect( dockerfile ).to be =~ /RUN dnf install -y sudo/
|
|
701
|
+
end
|
|
702
|
+
end
|
|
666
703
|
|
|
667
|
-
|
|
668
|
-
it "should use dnf on fedora #{fedora_release}" do
|
|
704
|
+
it 'should use pacman on archlinux' do
|
|
669
705
|
FakeFS.deactivate!
|
|
670
706
|
dockerfile = docker.send(:dockerfile_for, {
|
|
671
|
-
'platform' =>
|
|
707
|
+
'platform' => 'archlinux-current-x86_64',
|
|
672
708
|
'image' => 'foobar',
|
|
673
709
|
})
|
|
674
710
|
|
|
675
|
-
expect( dockerfile ).to be =~ /RUN
|
|
711
|
+
expect( dockerfile ).to be =~ /RUN pacman -S --noconfirm openssh/
|
|
676
712
|
end
|
|
677
713
|
end
|
|
678
|
-
|
|
679
|
-
it 'should use pacman on archlinux' do
|
|
680
|
-
FakeFS.deactivate!
|
|
681
|
-
dockerfile = docker.send(:dockerfile_for, {
|
|
682
|
-
'platform' => 'archlinux-current-x86_64',
|
|
683
|
-
'image' => 'foobar',
|
|
684
|
-
})
|
|
685
|
-
|
|
686
|
-
expect( dockerfile ).to be =~ /RUN pacman -S --noconfirm openssh/
|
|
687
|
-
end
|
|
688
714
|
end
|
|
689
715
|
end
|
|
690
716
|
end
|