beaker-docker 1.5.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,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Beaker
4
+ # Docker hypervisor for Beaker acceptance testing framework
2
5
  class Docker < Beaker::Hypervisor
3
-
4
6
  # Docker hypvervisor initializtion
5
7
  # Env variables supported:
6
8
  # DOCKER_REGISTRY: Docker registry URL
@@ -10,13 +12,14 @@ module Beaker
10
12
  # or a role (String or Symbol) that identifies one or more hosts.
11
13
  # @param [Hash{Symbol=>String}] options Options to pass on to the hypervisor
12
14
  def initialize(hosts, options)
15
+ super
13
16
  require 'docker'
14
17
  @options = options
15
18
  @logger = options[:logger] || Beaker::Logger.new
16
19
  @hosts = hosts
17
20
 
18
21
  # increase the http timeouts as provisioning images can be slow
19
- default_docker_options = { :write_timeout => 300, :read_timeout => 300 }.merge(::Docker.options || {})
22
+ default_docker_options = { write_timeout: 300, read_timeout: 300 }.merge(::Docker.options || {})
20
23
  # Merge docker options from the entry in hosts file
21
24
  ::Docker.options = default_docker_options.merge(@options[:docker_options] || {})
22
25
 
@@ -37,13 +40,12 @@ module Beaker
37
40
  ::Docker.logger = @logger
38
41
 
39
42
  # Find out what kind of remote instance we are talking against
40
- if /swarm/.match?(@docker_version['Version'])
43
+ if @docker_version['Version'].include?('swarm')
41
44
  @docker_type = 'swarm'
42
- unless ENV['DOCKER_REGISTRY']
43
- raise "Using Swarm with beaker requires a private registry. Please setup the private registry and set the 'DOCKER_REGISTRY' env var"
44
- else
45
- @registry = ENV['DOCKER_REGISTRY']
46
- end
45
+ raise "Using Swarm with beaker requires a private registry. Please setup the private registry and set the 'DOCKER_REGISTRY' env var" unless ENV['DOCKER_REGISTRY']
46
+
47
+ @registry = ENV.fetch('DOCKER_REGISTRY', nil)
48
+
47
49
  elsif ::Docker.respond_to?(:podman?) && ::Docker.podman?
48
50
  @docker_type = 'podman'
49
51
  else
@@ -52,15 +54,15 @@ module Beaker
52
54
  end
53
55
 
54
56
  def install_and_run_ssh(host)
55
- def host.enable_root_login(host,opts)
57
+ def host.enable_root_login(host, _opts)
56
58
  logger.debug("Root login already enabled for #{host}")
57
59
  end
58
60
 
59
61
  # If the container is running ssh as its init process then this method
60
62
  # will cause issues.
61
- if /sshd/.match?(Array(host[:docker_cmd]).first)
63
+ if Array(host[:docker_cmd]).first&.include?('sshd')
62
64
  def host.ssh_service_restart
63
- self[:docker_container].exec(%w(kill -1 1))
65
+ self[:docker_container].exec(%w[kill -1 1])
64
66
  end
65
67
  end
66
68
 
@@ -69,49 +71,45 @@ module Beaker
69
71
 
70
72
  def get_container_opts(host, image_name)
71
73
  container_opts = {}
72
- if host['dockerfile']
73
- container_opts['ExposedPorts'] = {'22/tcp' => {} }
74
- end
75
-
76
- container_opts.merge! ( {
77
- 'Image' => image_name,
78
- 'Hostname' => host.name,
79
- 'HostConfig' => {
80
- 'PortBindings' => {
81
- '22/tcp' => [{ 'HostPort' => rand(1025..9999).to_s, 'HostIp' => '0.0.0.0'}]
82
- },
83
- 'PublishAllPorts' => true,
84
- 'RestartPolicy' => {
85
- 'Name' => 'always'
86
- }
87
- }
88
- } )
74
+ container_opts['ExposedPorts'] = { '22/tcp' => {} } if host['dockerfile']
75
+
76
+ container_opts.merge!({
77
+ 'Image' => image_name,
78
+ 'Hostname' => host.name,
79
+ 'HostConfig' => {
80
+ 'PortBindings' => {
81
+ '22/tcp' => [{ 'HostPort' => rand(1025..9999).to_s, 'HostIp' => '0.0.0.0' }],
82
+ },
83
+ 'PublishAllPorts' => true,
84
+ 'RestartPolicy' => {
85
+ 'Name' => 'always',
86
+ },
87
+ },
88
+ })
89
89
  end
90
90
 
91
91
  def get_container_image(host)
92
- @logger.debug("Creating image")
92
+ @logger.debug('Creating image')
93
93
 
94
- if host['use_image_as_is']
95
- return ::Docker::Image.create('fromImage' => host['image'])
96
- end
94
+ return ::Docker::Image.create('fromImage' => host['image']) if host['use_image_as_is']
97
95
 
98
96
  dockerfile = host['dockerfile']
99
97
  if dockerfile
100
98
  # assume that the dockerfile is in the repo and tests are running
101
99
  # from the root of the repo; maybe add support for external Dockerfiles
102
100
  # with external build dependencies later.
103
- if File.exist?(dockerfile)
104
- dir = File.expand_path(dockerfile).chomp(dockerfile)
105
- return ::Docker::Image.build_from_dir(
106
- dir,
107
- { 'dockerfile' => dockerfile,
108
- :rm => true,
109
- :buildargs => buildargs_for(host)
110
- }
111
- )
112
- else
113
- raise "Unable to find dockerfile at #{dockerfile}"
114
- end
101
+ raise "Unable to find dockerfile at #{dockerfile}" unless File.exist?(dockerfile)
102
+
103
+ dir = File.expand_path(dockerfile).chomp(dockerfile)
104
+ return ::Docker::Image.build_from_dir(
105
+ dir,
106
+ {
107
+ 'dockerfile' => dockerfile,
108
+ :rm => true,
109
+ :buildargs => buildargs_for(host),
110
+ },
111
+ )
112
+
115
113
  elsif host['use_image_entry_point']
116
114
  df = <<-DF
117
115
  FROM #{host['image']}
@@ -123,13 +121,12 @@ module Beaker
123
121
  return ::Docker::Image.build(df, { rm: true, buildargs: buildargs_for(host) })
124
122
  end
125
123
 
126
- return ::Docker::Image.build(dockerfile_for(host),
127
- { rm: true, buildargs: buildargs_for(host) })
124
+ ::Docker::Image.build(dockerfile_for(host), { rm: true, buildargs: buildargs_for(host) })
128
125
  end
129
126
 
130
127
  # Nested Docker scenarios
131
128
  def nested_docker?
132
- ENV['DOCKER_IN_DOCKER'] || ENV['WSLENV']
129
+ ENV['DOCKER_IN_DOCKER'] || ENV.fetch('WSLENV', nil)
133
130
  end
134
131
 
135
132
  # Find out where the ssh port is from the container
@@ -139,7 +136,7 @@ module Beaker
139
136
  def get_ssh_connection_info(container)
140
137
  ssh_connection_info = {
141
138
  ip: nil,
142
- port: nil
139
+ port: nil,
143
140
  }
144
141
 
145
142
  container_json = container.json
@@ -149,82 +146,76 @@ module Beaker
149
146
  ip = nil
150
147
  port = nil
151
148
  # Talking against a remote docker host which is a normal docker host
152
- if @docker_type == 'docker' && ENV['DOCKER_HOST'] && !ENV.fetch('DOCKER_HOST','').include?(':///') && !nested_docker?
153
- ip = URI.parse(ENV['DOCKER_HOST']).host
154
- else
149
+ if @docker_type == 'docker' && ENV.fetch('DOCKER_HOST', nil) && !ENV.fetch('DOCKER_HOST', '').include?(':///') && !nested_docker?
150
+ ip = URI.parse(ENV.fetch('DOCKER_HOST', nil)).host
151
+ elsif in_container? && !nested_docker?
155
152
  # Swarm or local docker host
156
- if in_container? && !nested_docker?
157
- gw = network_settings['Gateway']
158
- ip = gw unless (gw.nil? || gw.empty?)
159
- else
160
- # The many faces of container networking
161
-
162
- # Host to Container
163
- port22 = network_settings.dig('PortBindings','22/tcp')
164
- if port22.nil? && network_settings.key?('Ports') && !nested_docker?
165
- port22 = network_settings.dig('Ports','22/tcp')
166
- end
153
+ gw = network_settings['Gateway']
154
+ ip = gw unless gw.nil? || gw.empty?
155
+ else
156
+ # The many faces of container networking
167
157
 
168
- ip = port22[0]['HostIp'] if port22
169
- port = port22[0]['HostPort'] if port22
158
+ # Host to Container
159
+ port22 = network_settings.dig('PortBindings', '22/tcp')
160
+ port22 = network_settings.dig('Ports', '22/tcp') if port22.nil? && network_settings.key?('Ports') && !nested_docker?
170
161
 
171
- # Container to container
172
- unless ip && port
173
- ip = network_settings['IPAddress']
174
- port = ip && !ip.empty? ? 22 : nil
175
- end
162
+ ip = port22[0]['HostIp'] if port22
163
+ port = port22[0]['HostPort'] if port22
176
164
 
177
- # Container through gateway
178
- unless ip && port
179
- ip = network_settings['Gateway']
165
+ # Container to container
166
+ unless ip && port
167
+ ip = network_settings['IPAddress']
168
+ port = ip && !ip.empty? ? 22 : nil
169
+ end
180
170
 
181
- if ip && !ip.empty?
182
- port22 = network_settings.dig('PortBindings','22/tcp')
183
- port = port22[0]['HostPort'] if port22
184
- else
185
- port = nil
186
- end
187
- end
171
+ # Container through gateway
172
+ unless ip && port
173
+ ip = network_settings['Gateway']
188
174
 
189
- # Legacy fallback
190
- unless ip && port
191
- port22 = network_settings.dig('Ports','22/tcp')
192
- ip = port22[0]["HostIp"] if port22
175
+ if ip && !ip.empty?
176
+ port22 = network_settings.dig('PortBindings', '22/tcp')
193
177
  port = port22[0]['HostPort'] if port22
178
+ else
179
+ port = nil
194
180
  end
195
181
  end
182
+
183
+ # Legacy fallback
184
+ unless ip && port
185
+ port22 = network_settings.dig('Ports', '22/tcp')
186
+ ip = port22[0]['HostIp'] if port22
187
+ port = port22[0]['HostPort'] if port22
188
+ end
196
189
  end
197
190
 
198
191
  if host_config['NetworkMode'] != 'slirp4netns' && network_settings['IPAddress'] && !network_settings['IPAddress'].empty?
199
192
  ip = network_settings['IPAddress'] if ip.nil?
200
193
  else
201
- port22 = network_settings.dig('Ports','22/tcp')
194
+ port22 = network_settings.dig('Ports', '22/tcp')
202
195
  port = port22[0]['HostPort'] if port22
203
196
  end
204
197
 
205
- ssh_connection_info[:ip] = (ip == '0.0.0.0') ? '127.0.0.1' : ip
198
+ ssh_connection_info[:ip] = ip == '0.0.0.0' ? '127.0.0.1' : ip
206
199
  ssh_connection_info[:port] = port || '22'
207
200
  ssh_connection_info
208
201
  end
209
202
 
210
203
  def provision
211
- @logger.notify "Provisioning docker"
204
+ @logger.notify 'Provisioning docker'
212
205
 
213
206
  @hosts.each do |host|
214
207
  @logger.notify "provisioning #{host.name}"
215
208
 
216
209
  image = get_container_image(host)
217
210
 
218
- if host['tag']
219
- image.tag({:repo => host['tag']})
220
- end
211
+ image.tag({ repo: host['tag'] }) if host['tag']
221
212
 
222
213
  if @docker_type == 'swarm'
223
214
  image_name = "#{@registry}/beaker/#{image.id}"
224
- ret = ::Docker::Image.search(:term => image_name)
215
+ ret = ::Docker::Image.search(term: image_name)
225
216
  if ret.first.nil?
226
- @logger.debug("Image does not exist on registry. Pushing.")
227
- image.tag({:repo => image_name, :force => true})
217
+ @logger.debug('Image does not exist on registry. Pushing.')
218
+ image.tag({ repo: image_name, force: true })
228
219
  image.push
229
220
  end
230
221
  else
@@ -235,8 +226,8 @@ module Beaker
235
226
 
236
227
  container_opts = get_container_opts(host, image_name)
237
228
  if host['dockeropts'] || @options[:dockeropts]
238
- dockeropts = host['dockeropts'] ? host['dockeropts'] : @options[:dockeropts]
239
- dockeropts.each do |k,v|
229
+ dockeropts = host['dockeropts'] || @options[:dockeropts]
230
+ dockeropts.each do |k, v|
240
231
  container_opts[k] = v
241
232
  end
242
233
  end
@@ -251,12 +242,12 @@ module Beaker
251
242
  container_opts['HostConfig']['Binds'] = host['mount_folders'].values.map do |mount|
252
243
  host_path = File.expand_path(mount['host_path'])
253
244
  # When using docker_toolbox and getting a "(Driveletter):/" path, convert windows path to VM mount
254
- if ENV['DOCKER_TOOLBOX_INSTALL_PATH'] && host_path =~ /^.\:\//
255
- host_path = "/" + host_path.gsub(/^.\:/, host_path[/^(.)/].downcase)
256
- end
257
- a = [ host_path, mount['container_path'] ]
258
- if mount.has_key?('opts')
259
- a << mount['opts'] if mount.has_key?('opts')
245
+ host_path = "/#{host_path.gsub(/^.:/, host_path[/^(.)/].downcase)}" if ENV['DOCKER_TOOLBOX_INSTALL_PATH'] && host_path =~ %r{^.:/}
246
+ a = [host_path, mount['container_path']]
247
+
248
+ # TODO: rewrite this part
249
+ if mount.key?('opts')
250
+ a << mount['opts'] if mount.key?('opts')
260
251
  else
261
252
  a << mount['opts'] = 'z'
262
253
  end
@@ -265,9 +256,7 @@ module Beaker
265
256
  end
266
257
  end
267
258
 
268
- if host['docker_env']
269
- container_opts['Env'] = host['docker_env']
270
- end
259
+ container_opts['Env'] = host['docker_env'] if host['docker_env']
271
260
 
272
261
  # Fixup privileges
273
262
  #
@@ -282,11 +271,7 @@ module Beaker
282
271
  container_opts['HostConfig']['Privileged'] = container_opts['HostConfig']['Privileged'].nil? ? true : container_opts['HostConfig']['Privileged']
283
272
  end
284
273
 
285
- if host['docker_container_name']
286
- container_opts['name'] = host['docker_container_name']
287
- else
288
- container_opts['name'] = ['beaker', host.name, SecureRandom.uuid.split('-').last].join('-')
289
- end
274
+ container_opts['name'] = (host['docker_container_name'] || ['beaker', host.name, SecureRandom.uuid.split('-').last].join('-'))
290
275
 
291
276
  if host['docker_port_bindings']
292
277
  container_opts['ExposedPorts'] = {} if container_opts['ExposedPorts'].nil?
@@ -300,9 +285,9 @@ module Beaker
300
285
 
301
286
  @logger.debug("Creating container from image #{image_name}")
302
287
 
303
- ok=false
304
- retries=0
305
- while(!ok && (retries < 5))
288
+ ok = false
289
+ retries = 0
290
+ while !ok && (retries < 5)
306
291
  container = ::Docker::Container.create(container_opts)
307
292
 
308
293
  ssh_info = get_ssh_connection_info(container)
@@ -312,19 +297,19 @@ module Beaker
312
297
  container.delete(force: true)
313
298
  container = nil
314
299
 
315
- retries+=1
300
+ retries += 1
316
301
  next
317
302
  end
318
303
 
319
- ok=true
304
+ ok = true
320
305
  end
321
306
  else
322
307
  host['use_existing_container'] = true
323
308
  end
324
309
 
325
310
  if container.nil?
326
- raise RuntimeError, 'Cannot continue because no existing container ' +
327
- 'could be found and provisioning is disabled.'
311
+ raise 'Cannot continue because no existing container ' \
312
+ 'could be found and provisioning is disabled.'
328
313
  end
329
314
 
330
315
  fix_ssh(container) if @options[:provision] == false
@@ -364,19 +349,19 @@ module Beaker
364
349
  host['ip'] = ip
365
350
  host['port'] = port
366
351
  host['ssh'] = {
367
- :password => root_password,
368
- :port => port,
369
- :forward_agent => forward_ssh_agent,
370
- :auth_methods => ['password', 'publickey', 'hostbased', 'keyboard-interactive']
352
+ password: root_password,
353
+ port: port,
354
+ forward_agent: forward_ssh_agent,
355
+ auth_methods: %w[password publickey hostbased keyboard-interactive],
371
356
  }
372
357
 
373
358
  @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
374
359
  host['docker_container_id'] = container.id
375
360
  host['docker_image_id'] = image.id
376
- host['vm_ip'] = container.json["NetworkSettings"]["IPAddress"].to_s
361
+ host['vm_ip'] = container.json['NetworkSettings']['IPAddress'].to_s
377
362
 
378
363
  def host.reboot
379
- @logger.warn("Rebooting containers is ineffective...ignoring")
364
+ @logger.warn('Rebooting containers is ineffective...ignoring')
380
365
  end
381
366
  end
382
367
 
@@ -386,92 +371,88 @@ module Beaker
386
371
  # This sideloads sshd after a container starts
387
372
  def install_ssh_components(container, host)
388
373
  case host['platform']
389
- when /ubuntu/, /debian/
390
- container.exec(%w(apt-get update))
391
- container.exec(%w(apt-get install -y openssh-server openssh-client))
392
- container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
393
- when /cumulus/
394
- container.exec(%w(apt-get update))
395
- container.exec(%w(apt-get install -y openssh-server openssh-client))
396
- container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
374
+ when /ubuntu/, /debian/, /cumulus/
375
+ container.exec(%w[apt-get update])
376
+ container.exec(%w[apt-get install -y openssh-server openssh-client])
377
+ container.exec(%w[sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*])
397
378
  when /el-[89]/, /fedora-(2[2-9]|3[0-9])/
398
- container.exec(%w(dnf clean all))
399
- container.exec(%w(dnf install -y sudo openssh-server openssh-clients))
400
- container.exec(%w(ssh-keygen -A))
401
- container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
379
+ container.exec(%w[dnf clean all])
380
+ container.exec(%w[dnf install -y sudo openssh-server openssh-clients])
381
+ container.exec(%w[ssh-keygen -A])
382
+ container.exec(%w[sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*])
402
383
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
403
- container.exec(%w(yum clean all))
404
- container.exec(%w(yum install -y sudo openssh-server openssh-clients))
405
- container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
406
- container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
407
- container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
384
+ container.exec(%w[yum clean all])
385
+ container.exec(%w[yum install -y sudo openssh-server openssh-clients])
386
+ container.exec(%w[ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key])
387
+ container.exec(%w[ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key])
388
+ container.exec(%w[sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*])
408
389
  when /opensuse/, /sles/
409
- container.exec(%w(zypper -n in openssh))
410
- container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
411
- container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
412
- container.exec(%w(sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config))
390
+ container.exec(%w[zypper -n in openssh])
391
+ container.exec(%w[ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key])
392
+ container.exec(%w[ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key])
393
+ container.exec(%w[sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config])
413
394
  when /archlinux/
414
- container.exec(%w(pacman --noconfirm -Sy archlinux-keyring))
415
- container.exec(%w(pacman --noconfirm -Syu))
416
- container.exec(%w(pacman -S --noconfirm openssh))
417
- container.exec(%w(ssh-keygen -A))
418
- container.exec(%w(sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config))
419
- container.exec(%w(systemctl enable sshd))
395
+ container.exec(%w[pacman --noconfirm -Sy archlinux-keyring])
396
+ container.exec(%w[pacman --noconfirm -Syu])
397
+ container.exec(%w[pacman -S --noconfirm openssh])
398
+ container.exec(%w[ssh-keygen -A])
399
+ container.exec(%w[sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config])
400
+ container.exec(%w[systemctl enable sshd])
420
401
  when /alpine/
421
- container.exec(%w(apk add --update openssh))
422
- container.exec(%w(ssh-keygen -A))
402
+ container.exec(%w[apk add --update openssh])
403
+ container.exec(%w[ssh-keygen -A])
423
404
  else
424
- # TODO add more platform steps here
405
+ # TODO: add more platform steps here
425
406
  raise "platform #{host['platform']} not yet supported on docker"
426
407
  end
427
408
 
428
409
  # Make sshd directory, set root password
429
- container.exec(%w(mkdir -p /var/run/sshd))
410
+ container.exec(%w[mkdir -p /var/run/sshd])
430
411
  container.exec(['/bin/sh', '-c', "echo root:#{root_password} | chpasswd"])
431
412
  end
432
413
 
433
414
  def cleanup
434
- @logger.notify "Cleaning up docker"
415
+ @logger.notify 'Cleaning up docker'
435
416
  @hosts.each do |host|
436
417
  # leave the container running if docker_preserve_container is set
437
418
  # setting docker_preserve_container also implies docker_preserve_image
438
419
  # is set, since you can't delete an image that's the base of a running
439
420
  # container
440
- unless host['docker_preserve_container']
441
- container = find_container(host)
442
- if container
443
- @logger.debug("stop container #{container.id}")
444
- begin
445
- container.kill
446
- sleep 2 # avoid a race condition where the root FS can't unmount
447
- rescue Excon::Errors::ClientError => e
448
- @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
449
- end
450
- @logger.debug("delete container #{container.id}")
451
- begin
452
- container.delete(force: true)
453
- rescue Excon::Errors::ClientError => e
454
- @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
455
- end
421
+ next if host['docker_preserve_container']
422
+
423
+ container = find_container(host)
424
+ if container
425
+ @logger.debug("stop container #{container.id}")
426
+ begin
427
+ container.kill
428
+ sleep 2 # avoid a race condition where the root FS can't unmount
429
+ rescue Excon::Errors::ClientError => e
430
+ @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
431
+ end
432
+ @logger.debug("delete container #{container.id}")
433
+ begin
434
+ container.delete(force: true)
435
+ rescue Excon::Errors::ClientError => e
436
+ @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
456
437
  end
438
+ end
457
439
 
458
- # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
459
- unless host['docker_preserve_image']
460
- image_id = host['docker_image_id']
461
-
462
- if image_id
463
- @logger.debug("deleting image #{image_id}")
464
- begin
465
- ::Docker::Image.remove(image_id)
466
- rescue Excon::Errors::ClientError => e
467
- @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
468
- rescue ::Docker::Error::DockerError => e
469
- @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
470
- end
471
- else
472
- @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
473
- end
440
+ # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
441
+ next if host['docker_preserve_image']
442
+
443
+ image_id = host['docker_image_id']
444
+
445
+ if image_id
446
+ @logger.debug("deleting image #{image_id}")
447
+ begin
448
+ ::Docker::Image.remove(image_id)
449
+ rescue Excon::Errors::ClientError => e
450
+ @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
451
+ rescue ::Docker::Error::DockerError => e
452
+ @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
474
453
  end
454
+ else
455
+ @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
475
456
  end
476
457
  end
477
458
  end
@@ -484,22 +465,20 @@ module Beaker
484
465
 
485
466
  def buildargs_for(host)
486
467
  docker_buildargs = {}
487
- docker_buildargs_env = ENV['DOCKER_BUILDARGS']
488
- if docker_buildargs_env != nil
489
- docker_buildargs_env.split(/ +|\t+/).each do |arg|
490
- key,value=arg.split(/=/)
491
- if key
492
- docker_buildargs[key]=value
493
- else
494
- @logger.warn("DOCKER_BUILDARGS environment variable appears invalid, no key found for value #{value}" )
495
- end
468
+ docker_buildargs_env = ENV.fetch('DOCKER_BUILDARGS', nil)
469
+ docker_buildargs_env&.split(/ +|\t+/)&.each do |arg|
470
+ key, value = arg.split('=')
471
+ if key
472
+ docker_buildargs[key] = value
473
+ else
474
+ @logger.warn("DOCKER_BUILDARGS environment variable appears invalid, no key found for value #{value}")
496
475
  end
497
476
  end
498
- if docker_buildargs.empty?
499
- buildargs = host['docker_buildargs'] || {}
500
- else
501
- buildargs = docker_buildargs
502
- end
477
+ buildargs = if docker_buildargs.empty?
478
+ host['docker_buildargs'] || {}
479
+ else
480
+ docker_buildargs
481
+ end
503
482
  @logger.debug("Docker build buildargs: #{buildargs}")
504
483
  JSON.generate(buildargs)
505
484
  end
@@ -512,7 +491,7 @@ module Beaker
512
491
  DF
513
492
 
514
493
  # Commands before any other commands. Can be used for eg. proxy configuration
515
- dockerfile += (host['docker_image_first_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join('')
494
+ dockerfile += (host['docker_image_first_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join
516
495
 
517
496
  # add platform-specific actions
518
497
  service_name = 'sshd'
@@ -585,7 +564,7 @@ module Beaker
585
564
  DF
586
565
 
587
566
  # Any extra commands specified for the host
588
- dockerfile += (host['docker_image_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join('')
567
+ dockerfile += (host['docker_image_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join
589
568
 
590
569
  # Override image entrypoint
591
570
  dockerfile += "ENTRYPOINT #{host['docker_image_entrypoint']}\n" if host['docker_image_entrypoint']
@@ -640,24 +619,25 @@ module Beaker
640
619
 
641
620
  if id
642
621
  @logger.debug("Looking for an existing container with ID #{id}")
643
- container = containers.select { |c| c.id == id }.first
622
+ container = containers.find { |c| c.id == id }
644
623
  end
645
624
 
646
625
  if name && container.nil?
647
626
  @logger.debug("Looking for an existing container with name #{name}")
648
- container = containers.select do |c|
627
+ container = containers.find do |c|
649
628
  c.info['Names'].include? "/#{name}"
650
- end.first
629
+ end
651
630
  end
652
631
 
653
632
  return container unless container.nil?
654
- @logger.debug("Existing container not found")
655
- return nil
633
+
634
+ @logger.debug('Existing container not found')
635
+ nil
656
636
  end
657
637
 
658
638
  # return true if we are inside a docker container
659
639
  def in_container?
660
- return File.file?('/.dockerenv')
640
+ File.file?('/.dockerenv')
661
641
  end
662
642
  end
663
643
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeakerDocker
4
- VERSION = '1.5.0'
4
+ VERSION = '2.0.0'
5
5
  end