beaker-docker 0.5.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7b9f93de9358670645ea7e0c3bf982a7c822b8ca
4
- data.tar.gz: 19730ee76587c0e098504bf7bae15627c10f1603
2
+ SHA256:
3
+ metadata.gz: f21e88681130028d956057cc5d7e10242d3ab4b0dd3afdddc1e4a77b6a30376e
4
+ data.tar.gz: 27f935f63ebaf20d0eb18afcab7360dccdb6cc7e037cee4d6e9e3a45aed9ef33
5
5
  SHA512:
6
- metadata.gz: 78b6a3d9dda05f73f12861c8f3675647b3265428cfa634de30dbd89da20eac938353ecbf44c900079cdc1a7113a9f7304e13915c78c3f39426e1364be9fee0e8
7
- data.tar.gz: a88c7fe2fa9ec4655e629e1996310baa0154bfc8c69e7294f0111479c447f3ef878305df2cf14b8c4fcd36b272f761c06fa9181bfa330ed943e51a27f63eded5
6
+ metadata.gz: 419eee4542d7283b98c1c9e56fae980816123bd5b4f8f69920180815c0ac61d047f0a8523ac68dc091e6bff6c101d8782905ec18d8a8d571274e62588872f58d
7
+ data.tar.gz: 7aa8635232484d7b4ef171d1714ab59805cd82e1b8c0d44d70174b903805376cf08e8ce48030f33f0efeb8d4ce845b8f2ad6b0f3deeb30bef602ffa86b092387
@@ -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
@@ -0,0 +1,32 @@
1
+ name: Test
2
+
3
+ on:
4
+ - pull_request
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby:
13
+ - "2.4"
14
+ - "2.5"
15
+ - "2.6"
16
+ - "2.7"
17
+ env:
18
+ BUNDLE_WITHOUT: release
19
+ name: Ruby ${{ matrix.ruby }}
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Install Ruby ${{ matrix.ruby }}
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ bundler-cache: true
27
+ - name: Run spec tests
28
+ run: bundle exec rake test:spec
29
+ # It seems some additonal setup of Docker may be needed for
30
+ # the acceptance tests to work.
31
+ # - name: Run acceptance tests
32
+ # run: bundle exec rake test:acceptance
data/README.md CHANGED
@@ -6,25 +6,94 @@ Beaker library to use docker hypervisor
6
6
 
7
7
  This gem that allows you to use hosts with [docker](docker.md) hypervisor with [beaker](https://github.com/puppetlabs/beaker).
8
8
 
9
- Beaker will automatically load the appropriate hypervisors for any given hosts file, so as long as your project dependencies are satisfied there's nothing else to do. No need to `require` this library in your tests.
9
+ Beaker will automatically load the appropriate hypervisors for any given hosts
10
+ file, so as long as your project dependencies are satisfied there's nothing else
11
+ to do. No need to `require` this library in your tests.
10
12
 
11
- ## With Beaker 3.x
12
-
13
- This library is included as a dependency of Beaker 3.x versions, so there's nothing to do.
14
-
15
- ## With Beaker 4.x
16
-
17
- As of Beaker 4.0, all hypervisor and DSL extension libraries have been removed and are no longer dependencies. In order to use a specific hypervisor or DSL extension library in your project, you will need to include them alongside Beaker in your Gemfile or project.gemspec. E.g.
13
+ In order to use a specific hypervisor or DSL extension library in your project,
14
+ you will need to include them alongside Beaker in your Gemfile or
15
+ project.gemspec. E.g.
18
16
 
19
17
  ~~~ruby
20
18
  # Gemfile
21
- gem 'beaker', '~>4.0'
22
- gem 'beaker-aws'
19
+ gem 'beaker', '~> 4.0'
20
+ gem 'beaker-docker'
23
21
  # project.gemspec
24
- s.add_runtime_dependency 'beaker', '~>4.0'
25
- s.add_runtime_dependency 'beaker-aws'
22
+ s.add_runtime_dependency 'beaker', '~> 4.0'
23
+ s.add_runtime_dependency 'beaker-docker'
24
+ ~~~
25
+
26
+ ## Nodeset Options
27
+
28
+ The following is a sample nodeset:
29
+
30
+ ~~~yaml
31
+ HOSTS:
32
+ el8:
33
+ platform: el-8-x86_64
34
+ hypervisor: docker
35
+ image: centos:8
36
+ docker_cmd: '["/sbin/init"]'
37
+ # Run arbitrary things
38
+ docker_image_commands:
39
+ - 'touch /tmp/myfile'
40
+ dockeropts:
41
+ Labels:
42
+ thing: 'stuff'
43
+ HostConfig:
44
+ Privileged: true
45
+ el7:
46
+ platform: el-7-x86_64
47
+ hypervisor: docker
48
+ image: centos:7
49
+ # EL7 images do not support nested systemd
50
+ docker_cmd: '/usr/sbin/sshd -D -E /var/log/sshd.log'
51
+ CONFIG:
52
+ docker_cap_add:
53
+ - AUDIT_WRITE
54
+ ~~~
55
+
56
+ ## Privileged containers
57
+
58
+ Containers are **not** run in privileged mode by default for safety.
59
+
60
+ If you wish to enable privileged mode, simply set the following in your node:
61
+
62
+ ~~~yaml
63
+ dockeropts:
64
+ HostConfig:
65
+ Privileged: true
66
+ ~~~
67
+
68
+ ## Cleaning up after tests
69
+
70
+ Containers created by this plugin may not be destroyed unless the tests complete
71
+ successfully. Each container created is prefixed by `beaker-` to make filtering
72
+ for clean up easier.
73
+
74
+ A quick way to clean up all nodes is as follows:
75
+
76
+ ~~~sh
77
+ podman rm -f $( podman ps -q -f name="beaker-*" )
26
78
  ~~~
27
79
 
80
+ # Working with `podman`
81
+
82
+ If you're using a version of `podman` that has API socket support then you
83
+ should be able to simply set `DOCKER_HOST` to your socket and connect as usual.
84
+
85
+ You also need to ensure that you're using a version of the `docker-api` gem that
86
+ supports `podman`.
87
+
88
+ You may find that not all of your tests work as expected. This will be due to
89
+ the tighter system restrictions placed on containers by `podman`. You may need
90
+ to edit the `dockeropts` hash in your nodeset to include different flags in the
91
+ `HostConfig` section.
92
+
93
+ See the
94
+ [HostConfig](https://any-api.com/docker_com/engine/docs/Definitions/HostConfig)
95
+ portion of the docker API for more information.
96
+
28
97
  # Spec tests
29
98
 
30
99
  Spec test live under the `spec` folder. There are the default rake task and therefore can run with a simple command:
@@ -34,7 +103,8 @@ bundle exec rake test:spec
34
103
 
35
104
  # Acceptance tests
36
105
 
37
- There is a simple rake task to invoke acceptance test for the library:
106
+ There is a simple rake task to invoke acceptance test for the library:
107
+
38
108
  ```bash
39
109
  bundle exec rake test:acceptance
40
110
  ```
@@ -42,3 +112,14 @@ bundle exec rake test:acceptance
42
112
  # Contributing
43
113
 
44
114
  Please refer to puppetlabs/beaker's [contributing](https://github.com/puppetlabs/beaker/blob/master/CONTRIBUTING.md) guide.
115
+
116
+ # Releasing
117
+
118
+ 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
119
+ lives on Puppet-internal infrastructure, so you'll need to be a part of the Puppet org to do this.
120
+
121
+ To run the job, click on `Build with Parameters` in the menu on the left. Make
122
+ sure you check the box next to `PUBLIC` and enter the appropriate version. The
123
+ version should adhere to [semantic version standards](https://semver.org).
124
+ When in doubt, consult the [maintainers of Beaker](https://github.com/puppetlabs/beaker/blob/master/CODEOWNERS)
125
+ for guidance.
data/Rakefile CHANGED
@@ -6,14 +6,14 @@ namespace :test do
6
6
 
7
7
  desc "Run spec tests"
8
8
  RSpec::Core::RakeTask.new(:run) do |t|
9
- t.rspec_opts = ['--color']
9
+ t.rspec_opts = ['--color', '--format documentation']
10
10
  t.pattern = 'spec/'
11
11
  end
12
12
 
13
13
  desc "Run spec tests with coverage"
14
14
  RSpec::Core::RakeTask.new(:coverage) do |t|
15
15
  ENV['BEAKER_DOCKER_COVERAGE'] = 'y'
16
- t.rspec_opts = ['--color']
16
+ t.rspec_opts = ['--color', '--format documentation']
17
17
  t.pattern = 'spec/'
18
18
  end
19
19
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  HOSTS:
3
- ubuntu1604-64-1:
4
- platform: ubuntu-1604-x86_64
3
+ centos8:
4
+ platform: el-8-x86_64
5
5
  hypervisor: docker
6
- image: ubuntu:16.04
6
+ image: centos:8
7
7
  roles:
8
8
  - master
9
9
  - agent
@@ -12,22 +12,24 @@ HOSTS:
12
12
  - classifier
13
13
  - default
14
14
  docker_cmd: '["/sbin/init"]'
15
+ docker_cap_add:
16
+ - AUDIT_WRITE
15
17
  dockeropts:
16
18
  Labels:
17
19
  one: '1'
18
20
  two: '2'
19
- ubuntu1604-64-2:
20
- platform: ubuntu-1604-x86_64
21
+ centos7:
22
+ platform: el-7-x86_64
21
23
  hypervisor: docker
22
- image: ubuntu:16.04
24
+ image: centos:7
23
25
  roles:
24
26
  - agent
25
- docker_cmd: '["/sbin/init"]'
27
+ docker_cmd: '/usr/sbin/sshd -D -E /var/log/sshd.log'
28
+ use_image_entrypoint: true
29
+ dockeropts:
30
+ HostConfig:
31
+ Privileged: true
26
32
  CONFIG:
27
33
  nfs_server: none
28
34
  consoleport: 443
29
35
  log_level: verbose
30
- dockeropts:
31
- Labels:
32
- one: '3'
33
- two: '4'
@@ -20,24 +20,14 @@ Gem::Specification.new do |s|
20
20
  # Testing dependencies
21
21
  s.add_development_dependency 'rspec', '~> 3.0'
22
22
  s.add_development_dependency 'rspec-its'
23
- # pin fakefs for Ruby < 2.3
24
- if RUBY_VERSION < "2.3"
25
- s.add_development_dependency 'fakefs', '~> 0.6', '< 0.14'
26
- else
27
- s.add_development_dependency 'fakefs', '~> 0.6'
28
- end
29
- s.add_development_dependency 'rake', '~> 10.1'
23
+ s.add_development_dependency 'fakefs', '~> 1.3'
24
+ s.add_development_dependency 'rake', '~> 13.0'
30
25
  s.add_development_dependency 'simplecov'
31
26
  s.add_development_dependency 'pry', '~> 0.10'
32
27
 
33
- # Documentation dependencies
34
- s.add_development_dependency 'yard'
35
- s.add_development_dependency 'markdown'
36
- s.add_development_dependency 'thin'
37
-
38
28
  # Run time dependencies
39
29
  s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
40
- s.add_runtime_dependency 'docker-api'
30
+ s.add_runtime_dependency 'docker-api', '< 3.0.0'
41
31
 
42
32
  end
43
33
 
@@ -1,3 +1,3 @@
1
1
  module BeakerDocker
2
- VERSION = '0.5.3'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -19,19 +19,25 @@ module Beaker
19
19
  default_docker_options = { :write_timeout => 300, :read_timeout => 300 }.merge(::Docker.options || {})
20
20
  # Merge docker options from the entry in hosts file
21
21
  ::Docker.options = default_docker_options.merge(@options[:docker_options] || {})
22
- # assert that the docker-api gem can talk to your docker
23
- # enpoint. Will raise if there is a version mismatch
22
+
23
+ # Ensure that we can correctly communicate with the docker API
24
24
  begin
25
- ::Docker.validate_version!
25
+ @docker_version = ::Docker.version
26
26
  rescue Excon::Errors::SocketError => e
27
- raise "Docker instance not connectable.\nError was: #{e}\nCheck your DOCKER_HOST variable has been set\nIf you are on OSX or Windows, you might not have Docker Machine setup correctly: https://docs.docker.com/machine/\n"
27
+ raise <<~ERRMSG
28
+ Docker instance not connectable
29
+ Error was: #{e}
30
+ * Check your DOCKER_HOST variable has been set
31
+ * If you are on OSX or Windows, you might not have Docker Machine setup correctly: https://docs.docker.com/machine/
32
+ * If you are using rootless podman, you might need to set up your local socket and service
33
+ ERRMSG
28
34
  end
29
35
 
30
36
  # Pass on all the logging from docker-api to the beaker logger instance
31
37
  ::Docker.logger = @logger
32
38
 
33
39
  # Find out what kind of remote instance we are talking against
34
- if ::Docker.version['Version'] =~ /swarm/
40
+ if @docker_version['Version'] =~ /swarm/
35
41
  @docker_type = 'swarm'
36
42
  unless ENV['DOCKER_REGISTRY']
37
43
  raise "Using Swarm with beaker requires a private registry. Please setup the private registry and set the 'DOCKER_REGISTRY' env var"
@@ -41,10 +47,21 @@ module Beaker
41
47
  else
42
48
  @docker_type = 'docker'
43
49
  end
44
-
45
50
  end
46
51
 
47
52
  def install_and_run_ssh(host)
53
+ def host.enable_root_login(host,opts)
54
+ logger.debug("Root login already enabled for #{host}")
55
+ end
56
+
57
+ # If the container is running ssh as its init process then this method
58
+ # will cause issues.
59
+ if host[:docker_cmd] =~ /sshd/
60
+ def host.ssh_service_restart
61
+ self[:docker_container].exec(%w(kill -1 1))
62
+ end
63
+ end
64
+
48
65
  host['dockerfile'] || host['use_image_entry_point']
49
66
  end
50
67
 
@@ -62,7 +79,6 @@ module Beaker
62
79
  '22/tcp' => [{ 'HostPort' => rand.to_s[2..5], 'HostIp' => '0.0.0.0'}]
63
80
  },
64
81
  'PublishAllPorts' => true,
65
- 'Privileged' => true,
66
82
  'RestartPolicy' => {
67
83
  'Name' => 'always'
68
84
  }
@@ -109,6 +125,45 @@ module Beaker
109
125
  { rm: true, buildargs: buildargs_for(host) })
110
126
  end
111
127
 
128
+ # Find out where the ssh port is from the container
129
+ # When running on swarm DOCKER_HOST points to the swarm manager so we have to get the
130
+ # IP of the swarm slave via the container data
131
+ # When we are talking to a normal docker instance DOCKER_HOST can point to a remote docker instance.
132
+ def get_ssh_connection_info(container)
133
+ ssh_connection_info = {
134
+ ip: nil,
135
+ port: nil
136
+ }
137
+
138
+ # Talking against a remote docker host which is a normal docker host
139
+ if @docker_type == 'docker' && ENV['DOCKER_HOST'] && !ENV.fetch('DOCKER_HOST','').include?(':///')
140
+ ip = URI.parse(ENV['DOCKER_HOST']).host
141
+ else
142
+ # Swarm or local docker host
143
+ if in_container?
144
+ ip = container.json["NetworkSettings"]["Gateway"]
145
+ else
146
+ ip = container.json["NetworkSettings"]["Ports"]["22/tcp"][0]["HostIp"]
147
+ end
148
+ end
149
+
150
+ network_settings = container.json['NetworkSettings']
151
+ host_config = container.json['HostConfig']
152
+
153
+ port = '22'
154
+ if host_config['NetworkMode'] == 'bridge' && network_settings['IPAddress'] && !network_settings['IPAddress'].empty?
155
+ ssh_connection_info[:ip] = network_settings['IPAddress']
156
+ else
157
+ port = network_settings['Ports']['22/tcp'][0]['HostPort']
158
+
159
+ # Update host metadata
160
+ ssh_connection_info[:ip] = (ip == '0.0.0.0') ? '127.0.0.1' : ip
161
+ end
162
+
163
+ ssh_connection_info[:port] = port
164
+ ssh_connection_info
165
+ end
166
+
112
167
  def provision
113
168
  @logger.notify "Provisioning docker"
114
169
 
@@ -144,10 +199,9 @@ module Beaker
144
199
 
145
200
  container = find_container(host)
146
201
 
147
- # Provisioning - Only provision if:
148
- # - provisioning was explicitly requested via options, or
149
- # - the host's container can't be found via its name or ID
150
- if @options[:provision] || container.nil?
202
+ # Provisioning - Only provision if the host's container can't be found
203
+ # via its name or ID
204
+ if container.nil?
151
205
  unless host['mount_folders'].nil?
152
206
  container_opts['HostConfig'] ||= {}
153
207
  container_opts['HostConfig']['Binds'] = host['mount_folders'].values.map do |mount|
@@ -157,21 +211,50 @@ module Beaker
157
211
  host_path = "/" + host_path.gsub(/^.\:/, host_path[/^(.)/].downcase)
158
212
  end
159
213
  a = [ host_path, mount['container_path'] ]
160
- a << mount['opts'] if mount.has_key?('opts')
214
+ if mount.has_key?('opts')
215
+ a << mount['opts'] if mount.has_key?('opts')
216
+ else
217
+ a << mount['opts'] = 'z'
218
+ end
219
+
161
220
  a.join(':')
162
221
  end
163
222
  end
164
223
 
224
+ if host['docker_env']
225
+ container_opts['Env'] = host['docker_env']
226
+ end
227
+
165
228
  if host['docker_cap_add']
166
229
  container_opts['HostConfig']['CapAdd'] = host['docker_cap_add']
167
230
  end
168
231
 
169
232
  if host['docker_container_name']
170
233
  container_opts['name'] = host['docker_container_name']
234
+ else
235
+ container_opts['name'] = ['beaker', host.name, SecureRandom.uuid.split('-').last].join('-')
171
236
  end
172
237
 
173
238
  @logger.debug("Creating container from image #{image_name}")
174
- container = ::Docker::Container.create(container_opts)
239
+
240
+ ok=false
241
+ retries=0
242
+ while(!ok && (retries < 5))
243
+ container = ::Docker::Container.create(container_opts)
244
+
245
+ if (get_ssh_connection_info(container)[:port].to_i < 1024) && (Process.uid != 0)
246
+ @logger.debug("#{host} was given a port less than 1024 but you are not running as root, retrying")
247
+
248
+ container.delete
249
+
250
+ retries+=1
251
+ next
252
+ end
253
+
254
+ ok=true
255
+ end
256
+ else
257
+ host['use_existing_container'] = true
175
258
  end
176
259
 
177
260
  if container.nil?
@@ -184,41 +267,35 @@ module Beaker
184
267
  @logger.debug("Starting container #{container.id}")
185
268
  container.start
186
269
 
270
+ # Preserve the ability to talk directly to the underlying API
271
+ #
272
+ # You can use any method defined by the docker-api gem on this object
273
+ # https://github.com/swipely/docker-api
274
+ host[:docker_container] = container
275
+
276
+ ssh_connection_info = get_ssh_connection_info(container)
277
+
278
+ ip = ssh_connection_info[:ip]
279
+ port = ssh_connection_info[:port]
280
+
281
+ @logger.info("Using container connection at #{ip}:#{port}")
282
+
187
283
  if install_and_run_ssh(host)
188
284
  @logger.notify("Installing ssh components and starting ssh daemon in #{host} container")
189
285
  install_ssh_components(container, host)
190
286
  # run fixssh to configure and start the ssh service
191
287
  fix_ssh(container, host)
192
288
  end
193
- # Find out where the ssh port is from the container
194
- # When running on swarm DOCKER_HOST points to the swarm manager so we have to get the
195
- # IP of the swarm slave via the container data
196
- # When we are talking to a normal docker instance DOCKER_HOST can point to a remote docker instance.
197
-
198
- # Talking against a remote docker host which is a normal docker host
199
- if @docker_type == 'docker' && ENV['DOCKER_HOST']
200
- ip = URI.parse(ENV['DOCKER_HOST']).host
201
- else
202
- # Swarm or local docker host
203
- if in_container?
204
- ip = container.json["NetworkSettings"]["Gateway"]
205
- else
206
- ip = container.json["NetworkSettings"]["Ports"]["22/tcp"][0]["HostIp"]
207
- end
208
- end
209
-
210
- @logger.info("Using docker server at #{ip}")
211
- port = container.json["NetworkSettings"]["Ports"]["22/tcp"][0]["HostPort"]
212
289
 
213
290
  forward_ssh_agent = @options[:forward_ssh_agent] || false
214
291
 
215
- # Update host metadata
216
- host['ip'] = ip
292
+ host['ip'] = ip
217
293
  host['port'] = port
218
294
  host['ssh'] = {
219
295
  :password => root_password,
220
296
  :port => port,
221
297
  :forward_agent => forward_ssh_agent,
298
+ :auth_methods => ['password', 'publickey', 'hostbased', 'keyboard-interactive']
222
299
  }
223
300
 
224
301
  @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
@@ -226,10 +303,12 @@ module Beaker
226
303
  host['docker_image_id'] = image.id
227
304
  host['vm_ip'] = container.json["NetworkSettings"]["IPAddress"].to_s
228
305
 
306
+ def host.reboot
307
+ @logger.warn("Rebooting containers is ineffective...ignoring")
308
+ end
229
309
  end
230
310
 
231
311
  hack_etc_hosts @hosts, @options
232
-
233
312
  end
234
313
 
235
314
  # This sideloads sshd after a container starts
@@ -238,19 +317,23 @@ module Beaker
238
317
  when /ubuntu/, /debian/
239
318
  container.exec(%w(apt-get update))
240
319
  container.exec(%w(apt-get install -y openssh-server openssh-client))
320
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
241
321
  when /cumulus/
242
322
  container.exec(%w(apt-get update))
243
323
  container.exec(%w(apt-get install -y openssh-server openssh-client))
324
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
244
325
  when /fedora-(2[2-9])/
245
326
  container.exec(%w(dnf clean all))
246
327
  container.exec(%w(dnf install -y sudo openssh-server openssh-clients))
247
328
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
248
329
  container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
330
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
249
331
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
250
332
  container.exec(%w(yum clean all))
251
333
  container.exec(%w(yum install -y sudo openssh-server openssh-clients))
252
334
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
253
335
  container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
336
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
254
337
  when /opensuse/, /sles/
255
338
  container.exec(%w(zypper -n in openssh))
256
339
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
@@ -279,38 +362,44 @@ module Beaker
279
362
  def cleanup
280
363
  @logger.notify "Cleaning up docker"
281
364
  @hosts.each do |host|
282
- container = find_container(host)
283
- if container
284
- @logger.debug("stop container #{container.id}")
285
- begin
286
- container.kill
287
- sleep 2 # avoid a race condition where the root FS can't unmount
288
- rescue Excon::Errors::ClientError => e
289
- @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
290
- end
291
- @logger.debug("delete container #{container.id}")
292
- begin
293
- container.delete
294
- rescue Excon::Errors::ClientError => e
295
- @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
296
- end
297
- end
298
-
299
- # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
300
- unless host['docker_preserve_image']
301
- image_id = host['docker_image_id']
302
-
303
- if image_id
304
- @logger.debug("deleting image #{image_id}")
365
+ # leave the container running if docker_preserve_container is set
366
+ # setting docker_preserve_container also implies docker_preserve_image
367
+ # is set, since you can't delete an image that's the base of a running
368
+ # container
369
+ unless host['docker_preserve_container']
370
+ container = find_container(host)
371
+ if container
372
+ @logger.debug("stop container #{container.id}")
305
373
  begin
306
- ::Docker::Image.remove(image_id)
374
+ container.kill
375
+ sleep 2 # avoid a race condition where the root FS can't unmount
307
376
  rescue Excon::Errors::ClientError => e
308
- @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
309
- rescue ::Docker::Error::DockerError => e
310
- @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
377
+ @logger.warn("stop of container #{container.id} failed: #{e.response.body}")
378
+ end
379
+ @logger.debug("delete container #{container.id}")
380
+ begin
381
+ container.delete
382
+ rescue Excon::Errors::ClientError => e
383
+ @logger.warn("deletion of container #{container.id} failed: #{e.response.body}")
384
+ end
385
+ end
386
+
387
+ # Do not remove the image if docker_preserve_image is set to true, otherwise remove it
388
+ unless host['docker_preserve_image']
389
+ image_id = host['docker_image_id']
390
+
391
+ if image_id
392
+ @logger.debug("deleting image #{image_id}")
393
+ begin
394
+ ::Docker::Image.remove(image_id)
395
+ rescue Excon::Errors::ClientError => e
396
+ @logger.warn("deletion of image #{image_id} failed: #{e.response.body}")
397
+ rescue ::Docker::Error::DockerError => e
398
+ @logger.warn("deletion of image #{image_id} caused internal Docker error: #{e.message}")
399
+ end
400
+ else
401
+ @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
311
402
  end
312
- else
313
- @logger.warn("Intended to delete the host's docker image, but host['docker_image_id'] was not set")
314
403
  end
315
404
  end
316
405
  end
@@ -360,64 +449,76 @@ module Beaker
360
449
  case host['platform']
361
450
  when /ubuntu/, /debian/
362
451
  service_name = "ssh"
363
- dockerfile += <<-EOF
452
+ dockerfile += <<~EOF
364
453
  RUN apt-get update
365
454
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::DEBIAN_PACKAGES.join(' ')}
366
- EOF
367
- when /cumulus/
368
- dockerfile += <<-EOF
455
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
456
+ EOF
457
+ when /cumulus/
458
+ dockerfile += <<~EOF
369
459
  RUN apt-get update
370
460
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::CUMULUS_PACKAGES.join(' ')}
371
- EOF
461
+ EOF
372
462
  when /fedora-(2[2-9])/
373
- dockerfile += <<-EOF
463
+ dockerfile += <<~EOF
374
464
  RUN dnf clean all
375
465
  RUN dnf install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::UNIX_PACKAGES.join(' ')}
376
466
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
377
467
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
378
- EOF
468
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
469
+ EOF
470
+ when /el-8/
471
+ dockerfile += <<~EOF
472
+ RUN dnf clean all
473
+ RUN dnf install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::RHEL8_PACKAGES.join(' ')}
474
+ RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
475
+ RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
476
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
477
+ EOF
379
478
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
380
- dockerfile += <<-EOF
479
+ dockerfile += <<~EOF
381
480
  RUN yum clean all
382
481
  RUN yum install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::UNIX_PACKAGES.join(' ')}
383
482
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
384
483
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
385
- EOF
484
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
485
+ EOF
386
486
  when /opensuse/, /sles/
387
- dockerfile += <<-EOF
487
+ dockerfile += <<~EOF
388
488
  RUN zypper -n in openssh #{Beaker::HostPrebuiltSteps::SLES_PACKAGES.join(' ')}
389
489
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
390
490
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
391
491
  RUN sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config
392
- EOF
492
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
493
+ EOF
393
494
  when /archlinux/
394
- dockerfile += <<-EOF
495
+ dockerfile += <<~EOF
395
496
  RUN pacman --noconfirm -Sy archlinux-keyring
396
497
  RUN pacman --noconfirm -Syu
397
498
  RUN pacman -S --noconfirm openssh #{Beaker::HostPrebuiltSteps::ARCHLINUX_PACKAGES.join(' ')}
398
499
  RUN ssh-keygen -A
399
500
  RUN sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config
400
501
  RUN systemctl enable sshd
401
- EOF
502
+ EOF
402
503
  else
403
504
  # TODO add more platform steps here
404
505
  raise "platform #{host['platform']} not yet supported on docker"
405
506
  end
406
507
 
407
508
  # Make sshd directory, set root password
408
- dockerfile += <<-EOF
509
+ dockerfile += <<~EOF
409
510
  RUN mkdir -p /var/run/sshd
410
511
  RUN echo root:#{root_password} | chpasswd
411
- EOF
512
+ EOF
412
513
 
413
514
  # Configure sshd service to allowroot login using password
414
515
  # Also, disable reverse DNS lookups to prevent every. single. ssh
415
516
  # operation taking 30 seconds while the lookup times out.
416
- dockerfile += <<-EOF
517
+ dockerfile += <<~EOF
417
518
  RUN sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config
418
519
  RUN sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config
419
520
  RUN sed -ri 's/^#?UseDNS .*/UseDNS no/' /etc/ssh/sshd_config
420
- EOF
521
+ EOF
421
522
 
422
523
 
423
524
  # Any extra commands specified for the host
@@ -498,6 +599,7 @@ module Beaker
498
599
 
499
600
  return container unless container.nil?
500
601
  @logger.debug("Existing container not found")
602
+ return nil
501
603
  end
502
604
 
503
605
  # return true if we are inside a docker container