beaker-docker 0.5.2 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 64566eeaece32a9571e797f4c09a5e56babbcd1d
4
- data.tar.gz: b7746e663d8fb916ebb7820fea64ab9f55babe8b
2
+ SHA256:
3
+ metadata.gz: 1656bc0ada39719991d068356033f018e0e8a2d3ad36b9fb8abc7285f2bf4e0f
4
+ data.tar.gz: b2207cae132edc1bf03e4b6dd0f5bf34139e30868f20e6e6f585291a72cf310e
5
5
  SHA512:
6
- metadata.gz: ffcf6fd38005a3f28868b00de297205dbc5df5407764758115017fdd391f42797bc1d5866ee42136af7749fa8ba4555130e406f415af4216c662f19795c587e9
7
- data.tar.gz: ac43c591842f18a1cf1841cff074a1cca1393fab223a43e1e26b87fc9812138609c526ca51f46afa5ee87d6979a46c5318b50f11e0ac304054562802f7247d77
6
+ metadata.gz: 9054afd2e705cd0cdf2910bb243aa4e103aa58e9575c11b23b3192fa0215d7fe90465544b679e805f89f311c337cbd5af2acf92c3d0123e93e00e23a99d8647b
7
+ data.tar.gz: d5f352ca1ccc5a37ac60c76344fdcc2265fde3120f2c9c68ec963149c081b9477a490a84eaf926139274c30d27d59f3f37cefd593f17465edcc2038045ada7a2
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "13:00"
8
+ open-pull-requests-limit: 10
data/README.md CHANGED
@@ -42,3 +42,14 @@ bundle exec rake test:acceptance
42
42
  # Contributing
43
43
 
44
44
  Please refer to puppetlabs/beaker's [contributing](https://github.com/puppetlabs/beaker/blob/master/CONTRIBUTING.md) guide.
45
+
46
+ # Releasing
47
+
48
+ To release new versions of beaker-docker, please use this [jenkins job](https://cinext-jenkinsmaster-sre-prod-1.delivery.puppetlabs.net/view/all/job/qe_beaker-docker_init-multijob_master/). This job
49
+ lives on Puppet-internal infrastructure, so you'll need to be a part of the Puppet org to do this.
50
+
51
+ To run the job, click on `Build with Parameters` in the menu on the left. Make
52
+ sure you check the box next to `PUBLIC` and enter the appropriate version. The
53
+ version should adhere to [semantic version standards](https://semver.org).
54
+ When in doubt, consult the [maintainers of Beaker](https://github.com/puppetlabs/beaker/blob/master/CODEOWNERS)
55
+ for guidance.
@@ -30,14 +30,9 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency 'simplecov'
31
31
  s.add_development_dependency 'pry', '~> 0.10'
32
32
 
33
- # Documentation dependencies
34
- s.add_development_dependency 'yard'
35
- s.add_development_dependency 'markdown'
36
- s.add_development_dependency 'thin'
37
-
38
33
  # Run time dependencies
39
34
  s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
40
- s.add_runtime_dependency 'docker-api'
35
+ s.add_runtime_dependency 'docker-api', '< 2.0.0'
41
36
 
42
37
  end
43
38
 
@@ -1,3 +1,3 @@
1
1
  module BeakerDocker
2
- VERSION = '0.5.2'
2
+ VERSION = '0.7.1'
3
3
  end
@@ -44,56 +44,84 @@ module Beaker
44
44
 
45
45
  end
46
46
 
47
+ def install_and_run_ssh(host)
48
+ host['dockerfile'] || host['use_image_entry_point']
49
+ end
50
+
51
+ def get_container_opts(host, image_name)
52
+ container_opts = {}
53
+ if host['dockerfile']
54
+ container_opts['ExposedPorts'] = {'22/tcp' => {} }
55
+ end
56
+
57
+ container_opts.merge! ( {
58
+ 'Image' => image_name,
59
+ 'Hostname' => host.name,
60
+ 'HostConfig' => {
61
+ 'PortBindings' => {
62
+ '22/tcp' => [{ 'HostPort' => rand.to_s[2..5], 'HostIp' => '0.0.0.0'}]
63
+ },
64
+ 'PublishAllPorts' => true,
65
+ 'Privileged' => true,
66
+ 'RestartPolicy' => {
67
+ 'Name' => 'always'
68
+ }
69
+ }
70
+ } )
71
+ end
72
+
73
+ def get_container_image(host)
74
+ @logger.debug("Creating image")
75
+
76
+ if host['use_image_as_is']
77
+ return ::Docker::Image.create('fromImage' => host['image'])
78
+ end
79
+
80
+ dockerfile = host['dockerfile']
81
+ if dockerfile
82
+ # assume that the dockerfile is in the repo and tests are running
83
+ # from the root of the repo; maybe add support for external Dockerfiles
84
+ # with external build dependencies later.
85
+ if File.exist?(dockerfile)
86
+ dir = File.expand_path(dockerfile).chomp(dockerfile)
87
+ return ::Docker::Image.build_from_dir(
88
+ dir,
89
+ { 'dockerfile' => dockerfile,
90
+ :rm => true,
91
+ :buildargs => buildargs_for(host)
92
+ }
93
+ )
94
+ else
95
+ raise "Unable to find dockerfile at #{dockerfile}"
96
+ end
97
+ elsif host['use_image_entry_point']
98
+ df = <<-DF
99
+ FROM #{host['image']}
100
+ EXPOSE 22
101
+ DF
102
+
103
+ cmd = host['docker_cmd']
104
+ df += cmd if cmd
105
+ return ::Docker::Image.build(df, { rm: true, buildargs: buildargs_for(host) })
106
+ end
107
+
108
+ return ::Docker::Image.build(dockerfile_for(host),
109
+ { rm: true, buildargs: buildargs_for(host) })
110
+ end
111
+
47
112
  def provision
48
113
  @logger.notify "Provisioning docker"
49
114
 
50
115
  @hosts.each do |host|
51
116
  @logger.notify "provisioning #{host.name}"
52
117
 
53
- container_opts = {}
54
- @logger.debug("Creating image")
55
-
56
- dockerfile = host['dockerfile']
57
- if dockerfile
58
- install_and_run_ssh = true
59
- container_opts['ExposedPorts'] = {'22/tcp' => {} }
60
- # assume that the dockerfile is in the repo and tests are running
61
- # from the root of the repo; maybe add support for external Dockerfiles
62
- # with external build dependencies later.
63
- if File.exist?(dockerfile)
64
- dir = File.expand_path(dockerfile).chomp(dockerfile)
65
- image = ::Docker::Image.build_from_dir(
66
- dir,
67
- { 'dockerfile' => dockerfile,
68
- :rm => true,
69
- :buildargs => buildargs_for(host)
70
- }
71
- )
72
- else
73
- raise "Unable to find dockerfile at #{dockerfile}"
74
- end
75
- elsif host['use_image_entry_point']
76
- install_and_run_ssh = true
77
- df = <<-DF
78
- FROM #{host['image']}
79
- EXPOSE 22
80
- DF
81
-
82
- cmd = host['docker_cmd']
83
- df += cmd if cmd
84
-
85
- image = ::Docker::Image.build(df, { rm: true, buildargs: buildargs_for(host) })
86
118
 
87
- else
119
+ image = get_container_image(host)
88
120
 
89
- image = ::Docker::Image.build(dockerfile_for(host),
90
- { rm: true, buildargs: buildargs_for(host) })
121
+ if host['tag']
122
+ image.tag({:repo => host['tag']})
91
123
  end
92
124
 
93
- if host['tag']
94
- image.tag({:repo => host['tag']})
95
- end
96
-
97
125
  if @docker_type == 'swarm'
98
126
  image_name = "#{@registry}/beaker/#{image.id}"
99
127
  ret = ::Docker::Image.search(:term => image_name)
@@ -106,20 +134,7 @@ module Beaker
106
134
  image_name = image.id
107
135
  end
108
136
 
109
- container_opts.merge! ( {
110
- 'Image' => image_name,
111
- 'Hostname' => host.name,
112
- 'HostConfig' => {
113
- 'PortBindings' => {
114
- '22/tcp' => [{ 'HostPort' => rand.to_s[2..5], 'HostIp' => '0.0.0.0'}]
115
- },
116
- 'PublishAllPorts' => true,
117
- 'Privileged' => true,
118
- 'RestartPolicy' => {
119
- 'Name' => 'always'
120
- }
121
- }
122
- } )
137
+ container_opts = get_container_opts(host, image_name)
123
138
  if host['dockeropts'] || @options[:dockeropts]
124
139
  dockeropts = host['dockeropts'] ? host['dockeropts'] : @options[:dockeropts]
125
140
  dockeropts.each do |k,v|
@@ -129,10 +144,9 @@ module Beaker
129
144
 
130
145
  container = find_container(host)
131
146
 
132
- # Provisioning - Only provision if:
133
- # - provisioning was explicitly requested via options, or
134
- # - the host's container can't be found via its name or ID
135
- if @options[:provision] || container.nil?
147
+ # Provisioning - Only provision if the host's container can't be found
148
+ # via its name or ID
149
+ if container.nil?
136
150
  unless host['mount_folders'].nil?
137
151
  container_opts['HostConfig'] ||= {}
138
152
  container_opts['HostConfig']['Binds'] = host['mount_folders'].values.map do |mount|
@@ -147,6 +161,10 @@ module Beaker
147
161
  end
148
162
  end
149
163
 
164
+ if host['docker_env']
165
+ container_opts['Env'] = host['docker_env']
166
+ end
167
+
150
168
  if host['docker_cap_add']
151
169
  container_opts['HostConfig']['CapAdd'] = host['docker_cap_add']
152
170
  end
@@ -157,6 +175,8 @@ module Beaker
157
175
 
158
176
  @logger.debug("Creating container from image #{image_name}")
159
177
  container = ::Docker::Container.create(container_opts)
178
+ else
179
+ host['use_existing_container'] = true
160
180
  end
161
181
 
162
182
  if container.nil?
@@ -169,7 +189,7 @@ module Beaker
169
189
  @logger.debug("Starting container #{container.id}")
170
190
  container.start
171
191
 
172
- if install_and_run_ssh
192
+ if install_and_run_ssh(host)
173
193
  @logger.notify("Installing ssh components and starting ssh daemon in #{host} container")
174
194
  install_ssh_components(container, host)
175
195
  # run fixssh to configure and start the ssh service
@@ -204,6 +224,7 @@ module Beaker
204
224
  :password => root_password,
205
225
  :port => port,
206
226
  :forward_agent => forward_ssh_agent,
227
+ :auth_methods => ['password', 'publickey', 'hostbased', 'keyboard-interactive']
207
228
  }
208
229
 
209
230
  @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
@@ -264,38 +285,44 @@ module Beaker
264
285
  def cleanup
265
286
  @logger.notify "Cleaning up docker"
266
287
  @hosts.each do |host|
267
- container = find_container(host)
268
- if container
269
- @logger.debug("stop container #{container.id}")
270
- begin
271
- container.kill
272
- sleep 2 # avoid a race condition where the root FS can't unmount
273
- rescue Excon::Errors::ClientError => e
274
- @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
275
- end
276
- @logger.debug("delete container #{container.id}")
277
- begin
278
- container.delete
279
- rescue Excon::Errors::ClientError => e
280
- @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
281
- end
282
- end
283
-
284
- # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
285
- unless host['docker_preserve_image']
286
- image_id = host['docker_image_id']
287
-
288
- if image_id
289
- @logger.debug("deleting image #{image_id}")
288
+ # leave the container running if docker_preserve_container is set
289
+ # setting docker_preserve_container also implies docker_preserve_image
290
+ # is set, since you can't delete an image that's the base of a running
291
+ # container
292
+ unless host['docker_preserve_container']
293
+ container = find_container(host)
294
+ if container
295
+ @logger.debug("stop container #{container.id}")
290
296
  begin
291
- ::Docker::Image.remove(image_id)
297
+ container.kill
298
+ sleep 2 # avoid a race condition where the root FS can't unmount
292
299
  rescue Excon::Errors::ClientError => e
293
- @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
294
- rescue ::Docker::Error::DockerError => e
295
- @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
300
+ @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
301
+ end
302
+ @logger.debug("delete container #{container.id}")
303
+ begin
304
+ container.delete
305
+ rescue Excon::Errors::ClientError => e
306
+ @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
307
+ end
308
+ end
309
+
310
+ # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
311
+ unless host['docker_preserve_image']
312
+ image_id = host['docker_image_id']
313
+
314
+ if image_id
315
+ @logger.debug("deleting image #{image_id}")
316
+ begin
317
+ ::Docker::Image.remove(image_id)
318
+ rescue Excon::Errors::ClientError => e
319
+ @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
320
+ rescue ::Docker::Error::DockerError => e
321
+ @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
322
+ end
323
+ else
324
+ @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
296
325
  end
297
- else
298
- @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
299
326
  end
300
327
  end
301
328
  end
@@ -349,7 +376,7 @@ module Beaker
349
376
  RUN apt-get update
350
377
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::DEBIAN_PACKAGES.join(' ')}
351
378
  EOF
352
- when /cumulus/
379
+ when /cumulus/
353
380
  dockerfile += <<-EOF
354
381
  RUN apt-get update
355
382
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::CUMULUS_PACKAGES.join(' ')}
@@ -361,6 +388,13 @@ module Beaker
361
388
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
362
389
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
363
390
  EOF
391
+ when /el-8/
392
+ dockerfile += <<-EOF
393
+ RUN yum clean all
394
+ RUN yum install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::RHEL8_PACKAGES.join(' ')}
395
+ RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
396
+ RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
397
+ EOF
364
398
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
365
399
  dockerfile += <<-EOF
366
400
  RUN yum clean all
@@ -483,6 +517,7 @@ module Beaker
483
517
 
484
518
  return container unless container.nil?
485
519
  @logger.debug("Existing container not found")
520
+ return nil
486
521
  end
487
522
 
488
523
  # return true if we are inside a docker container
@@ -100,6 +100,7 @@ module Beaker
100
100
  allow( ::Docker ).to receive(:logger=)
101
101
  allow( ::Docker ).to receive(:version).and_return(version)
102
102
  allow( ::Docker::Image ).to receive(:build).and_return(image)
103
+ allow( ::Docker::Image ).to receive(:create).and_return(image)
103
104
  allow( ::Docker::Container ).to receive(:create).and_return(container)
104
105
  allow_any_instance_of( ::Docker::Container ).to receive(:start)
105
106
  end
@@ -244,6 +245,19 @@ module Beaker
244
245
  end
245
246
  end
246
247
 
248
+ it 'should call image create for hosts when use_image_as_is is defined' do
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)
256
+ end
257
+
258
+ docker.provision
259
+ end
260
+
247
261
  it 'should call dockerfile_for with all the hosts' do
248
262
  hosts.each do |host|
249
263
  expect( docker ).not_to receive(:install_ssh_components)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker-docker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rishi Javia, Kevin Imber, Tony Vu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-11 00:00:00.000000000 Z
11
+ date: 2020-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -94,48 +94,6 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.10'
97
- - !ruby/object:Gem::Dependency
98
- name: yard
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: markdown
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: thin
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
97
  - !ruby/object:Gem::Dependency
140
98
  name: stringify-hash
141
99
  requirement: !ruby/object:Gem::Requirement
@@ -154,16 +112,16 @@ dependencies:
154
112
  name: docker-api
155
113
  requirement: !ruby/object:Gem::Requirement
156
114
  requirements:
157
- - - ">="
115
+ - - "<"
158
116
  - !ruby/object:Gem::Version
159
- version: '0'
117
+ version: 2.0.0
160
118
  type: :runtime
161
119
  prerelease: false
162
120
  version_requirements: !ruby/object:Gem::Requirement
163
121
  requirements:
164
- - - ">="
122
+ - - "<"
165
123
  - !ruby/object:Gem::Version
166
- version: '0'
124
+ version: 2.0.0
167
125
  description: For use for the Beaker acceptance testing tool
168
126
  email:
169
127
  - rishi.javia@puppet.com, kevin.imber@puppet.com, tony.vu@puppet.com
@@ -172,6 +130,7 @@ executables:
172
130
  extensions: []
173
131
  extra_rdoc_files: []
174
132
  files:
133
+ - ".github/dependabot.yml"
175
134
  - ".gitignore"
176
135
  - ".simplecov"
177
136
  - Gemfile
@@ -205,8 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
164
  - !ruby/object:Gem::Version
206
165
  version: '0'
207
166
  requirements: []
208
- rubyforge_project:
209
- rubygems_version: 2.5.1
167
+ rubygems_version: 3.0.8
210
168
  signing_key:
211
169
  specification_version: 4
212
170
  summary: Beaker DSL Extension Helpers!