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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c08f5cd20c40f88ec243742f3471581e3bdedaac
4
- data.tar.gz: a51dd89bab315c5bc3061e4c290335ca305c8932
2
+ SHA256:
3
+ metadata.gz: d1f70940dc7c4b43db06838e143fc4e4a498247be0ed67ae0926ae84527f5786
4
+ data.tar.gz: b12830fb23b10ccf1718be061c3e6ffe3e81c0b47b3aff58e3882e2e0a843c7d
5
5
  SHA512:
6
- metadata.gz: b475e8f7ce22f303fbe772749f0176511581ec9b84f3d116ad690fe2c5d318bc4b33b9f68186938bf5715b81e1a5f8b05f2a7833b6a3e469f7970eebfe5068b8
7
- data.tar.gz: f7a3654d9252c82362d88be8dcbfa75aa3a546d01f156e65838d0eed1525a17e55c2fbd937c559fb5dba472fce1f02b27282daee917be49d183d52e03ed83c82
6
+ metadata.gz: d182e05ba8dea02f896571bb5cf100f3a313349e1178f3eb9daf5e62f7ec93572114e4e1cf6e10a34aa18e8280d7be0ff7ed8a1482984cbd07ae3a530a7a0be9
7
+ data.tar.gz: 478ac68e7088d66a8f5a4732f59a1337b355293b5a5f8d38551e5d54b81e6e7634528139b4c5717462b3d0b4a8558de05afc83b2f2c51705f0e8d16b7fb885a8
@@ -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,24 @@
1
+ name: Release
2
+
3
+ on:
4
+ create:
5
+ ref_type: tag
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ if: github.repository == 'voxpupuli/beaker-docker'
11
+ env:
12
+ BUNDLE_WITHOUT: release
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Install Ruby 2.7
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: '2.7'
19
+ - name: Build gem
20
+ run: gem build *.gemspec
21
+ - name: Publish gem
22
+ run: gem push *.gem
23
+ env:
24
+ GEM_HOST_API_KEY: '${{ secrets.RUBYGEMS_AUTH_TOKEN }}'
@@ -0,0 +1,105 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - test_me_github
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ - master
11
+
12
+ jobs:
13
+ rspec:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: true
17
+ matrix:
18
+ ruby:
19
+ - "2.4"
20
+ - "2.5"
21
+ - "2.6"
22
+ - "2.7"
23
+ env:
24
+ BUNDLE_WITHOUT: release
25
+ name: RSpec - Ruby ${{ matrix.ruby }}
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - name: Install Ruby ${{ matrix.ruby }}
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby }}
32
+ bundler-cache: true
33
+ - name: install bundler
34
+ run: |
35
+ gem install bundler -v '~> 1.17.3'
36
+ bundle update
37
+ - name: spec tests
38
+ run: bundle exec rake test:spec
39
+
40
+ docker:
41
+ runs-on: ubuntu-latest
42
+ strategy:
43
+ fail-fast: true
44
+ matrix:
45
+ ruby:
46
+ - "2.6"
47
+ env:
48
+ BUNDLE_WITHOUT: release
49
+ name: Docker - Ruby ${{ matrix.ruby }}
50
+ steps:
51
+ - uses: actions/checkout@v2
52
+ - name: Install Ruby ${{ matrix.ruby }}
53
+ uses: ruby/setup-ruby@v1
54
+ with:
55
+ ruby-version: ${{ matrix.ruby }}
56
+ bundler-cache: true
57
+ - name: install bundler
58
+ run: |
59
+ gem install bundler -v '~> 1.17.3'
60
+ bundle update
61
+ - name: install container runtime
62
+ run: |
63
+ sudo apt-get remove -y docker docker-engine docker.io containerd runc ||:
64
+ sudo apt-get update -y
65
+ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
66
+ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
67
+ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
68
+ sudo apt-get update -y
69
+ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
70
+ sudo systemctl start docker
71
+ - name: Run acceptance tests
72
+ run: bundle exec rake test:acceptance
73
+
74
+ podman:
75
+ runs-on: ubuntu-latest
76
+ strategy:
77
+ fail-fast: true
78
+ matrix:
79
+ ruby:
80
+ - "2.6"
81
+ env:
82
+ BUNDLE_WITHOUT: release
83
+ name: Podman - Ruby ${{ matrix.ruby }}
84
+ steps:
85
+ - uses: actions/checkout@v2
86
+ - name: Install Ruby ${{ matrix.ruby }}
87
+ uses: ruby/setup-ruby@v1
88
+ with:
89
+ ruby-version: ${{ matrix.ruby }}
90
+ bundler-cache: true
91
+ - name: install bundler
92
+ run: |
93
+ gem install bundler -v '~> 1.17.3'
94
+ bundle update
95
+ # We need the latest version of podman for this to work
96
+ - name: install container runtime
97
+ run: |
98
+ . /etc/os-release
99
+ curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -
100
+ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/podman.list > /dev/null
101
+ sudo apt-get update
102
+ sudo apt-get -y install podman
103
+ sudo systemctl start podman
104
+ - name: Run acceptance tests
105
+ run: bundle exec rake test:acceptance
data/Gemfile.local ADDED
@@ -0,0 +1,5 @@
1
+ group :acceptance_testing do
2
+ # Needed for podman testing
3
+ gem "docker-api", :git => 'https://github.com/trevor-vaughan/docker-api', :branch => 'podman-compat'
4
+ gem "beaker-rspec"
5
+ end
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
 
@@ -32,11 +32,15 @@ A quick acceptance test, named because it has no pre-suites to run
32
32
  beaker_test_base_dir = File.join(beaker_gem_dir, 'acceptance/tests/base')
33
33
  load_path_option = File.join(beaker_gem_dir, 'acceptance/lib')
34
34
 
35
+ ENV['BEAKER_setfile'] = 'acceptance/config/nodes/hosts.yaml'
35
36
  sh("beaker",
36
37
  "--hosts", "acceptance/config/nodes/hosts.yaml",
37
- "--tests", beaker_test_base_dir,
38
+ # We can't run these tests until the rsync support in the main
39
+ # beaker/host.rb is updated to work with passwords.
40
+ # "--tests", beaker_test_base_dir,
41
+ # "--load-path", load_path_option,
42
+ "--tests", 'acceptance/tests/',
38
43
  "--log-level", "debug",
39
- "--load-path", load_path_option,
40
44
  "--debug")
41
45
  end
42
46
 
@@ -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,29 @@ HOSTS:
12
12
  - classifier
13
13
  - default
14
14
  docker_cmd: '["/sbin/init"]'
15
- dockeropts:
16
- Labels:
17
- one: '1'
18
- two: '2'
19
- ubuntu1604-64-2:
20
- platform: ubuntu-1604-x86_64
15
+ centos7:
16
+ platform: el-7-x86_64
21
17
  hypervisor: docker
22
- image: ubuntu:16.04
18
+ image: centos:7
23
19
  roles:
24
20
  - agent
25
- docker_cmd: '["/sbin/init"]'
21
+ docker_cmd: '/usr/sbin/sshd -D -E /var/log/sshd.log'
22
+ use_image_entrypoint: true
26
23
  CONFIG:
27
24
  nfs_server: none
28
25
  consoleport: 443
29
26
  log_level: verbose
27
+ # Ubuntu runners need to run with full privileges
28
+ # RHEL derivitives just need the docker cap AUDIT_WRITE
30
29
  dockeropts:
31
- Labels:
32
- one: '3'
33
- two: '4'
30
+ HostConfig:
31
+ Privileged: true
32
+ # docker_cap_add:
33
+ # - AUDIT_WRITE
34
+ type: aio
35
+ ssh:
36
+ verify_host_key: false
37
+ user_known_hosts_file: '/dev/null'
38
+ password: root
39
+ auth_methods:
40
+ - password
@@ -0,0 +1,10 @@
1
+ require 'beaker'
2
+ require 'beaker-rspec'
3
+
4
+ RSpec.describe 'it can connect' do
5
+ hosts.each do |host|
6
+ context "on #{host}" do
7
+ on(host, 'ls /tmp')
8
+ end
9
+ end
10
+ end
@@ -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.4'
2
+ VERSION = '0.8.1'
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,48 @@ 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
+ container_json = container.json
139
+ network_settings = container_json['NetworkSettings']
140
+ host_config = container_json['HostConfig']
141
+
142
+ ip = nil
143
+ port = nil
144
+ # Talking against a remote docker host which is a normal docker host
145
+ if @docker_type == 'docker' && ENV['DOCKER_HOST'] && !ENV.fetch('DOCKER_HOST','').include?(':///')
146
+ ip = URI.parse(ENV['DOCKER_HOST']).host
147
+ else
148
+ # Swarm or local docker host
149
+ if in_container?
150
+ gw = network_settings['Gateway']
151
+ ip = gw unless (gw.nil? || gw.empty?)
152
+ else
153
+ port22 = network_settings.dig('Ports','22/tcp')
154
+ ip = port22[0]["HostIp"] if port22
155
+ end
156
+ end
157
+
158
+ if host_config['NetworkMode'] != 'slirp4netns' && network_settings['IPAddress'] && !network_settings['IPAddress'].empty?
159
+ ip = network_settings['IPAddress']
160
+ else
161
+ port22 = network_settings.dig('Ports','22/tcp')
162
+ port = port22[0]['HostPort'] if port22
163
+ end
164
+
165
+ ssh_connection_info[:ip] = (ip == '0.0.0.0') ? '127.0.0.1' : ip
166
+ ssh_connection_info[:port] = port || '22'
167
+ ssh_connection_info
168
+ end
169
+
112
170
  def provision
113
171
  @logger.notify "Provisioning docker"
114
172
 
@@ -156,7 +214,12 @@ module Beaker
156
214
  host_path = "/" + host_path.gsub(/^.\:/, host_path[/^(.)/].downcase)
157
215
  end
158
216
  a = [ host_path, mount['container_path'] ]
159
- a << mount['opts'] if mount.has_key?('opts')
217
+ if mount.has_key?('opts')
218
+ a << mount['opts'] if mount.has_key?('opts')
219
+ else
220
+ a << mount['opts'] = 'z'
221
+ end
222
+
160
223
  a.join(':')
161
224
  end
162
225
  end
@@ -171,10 +234,29 @@ module Beaker
171
234
 
172
235
  if host['docker_container_name']
173
236
  container_opts['name'] = host['docker_container_name']
237
+ else
238
+ container_opts['name'] = ['beaker', host.name, SecureRandom.uuid.split('-').last].join('-')
174
239
  end
175
240
 
176
241
  @logger.debug("Creating container from image #{image_name}")
177
- container = ::Docker::Container.create(container_opts)
242
+
243
+ ok=false
244
+ retries=0
245
+ while(!ok && (retries < 5))
246
+ container = ::Docker::Container.create(container_opts)
247
+
248
+ ssh_info = get_ssh_connection_info(container)
249
+ if ssh_info[:ip] == '127.0.0.1' && (ssh_info[:port].to_i < 1024) && (Process.uid != 0)
250
+ @logger.debug("#{host} was given a port less than 1024 but you are not running as root, retrying")
251
+
252
+ container.delete
253
+
254
+ retries+=1
255
+ next
256
+ end
257
+
258
+ ok=true
259
+ end
178
260
  else
179
261
  host['use_existing_container'] = true
180
262
  end
@@ -189,52 +271,55 @@ module Beaker
189
271
  @logger.debug("Starting container #{container.id}")
190
272
  container.start
191
273
 
274
+ begin
275
+ container.stats
276
+ rescue StandardError => e
277
+ container.delete
278
+ raise "Container '#{container.id}' in a bad state: #{e}"
279
+ end
280
+
281
+ # Preserve the ability to talk directly to the underlying API
282
+ #
283
+ # You can use any method defined by the docker-api gem on this object
284
+ # https://github.com/swipely/docker-api
285
+ host[:docker_container] = container
286
+
192
287
  if install_and_run_ssh(host)
193
288
  @logger.notify("Installing ssh components and starting ssh daemon in #{host} container")
194
289
  install_ssh_components(container, host)
195
290
  # run fixssh to configure and start the ssh service
196
291
  fix_ssh(container, host)
197
292
  end
198
- # Find out where the ssh port is from the container
199
- # When running on swarm DOCKER_HOST points to the swarm manager so we have to get the
200
- # IP of the swarm slave via the container data
201
- # When we are talking to a normal docker instance DOCKER_HOST can point to a remote docker instance.
202
-
203
- # Talking against a remote docker host which is a normal docker host
204
- if @docker_type == 'docker' && ENV['DOCKER_HOST']
205
- ip = URI.parse(ENV['DOCKER_HOST']).host
206
- else
207
- # Swarm or local docker host
208
- if in_container?
209
- ip = container.json["NetworkSettings"]["Gateway"]
210
- else
211
- ip = container.json["NetworkSettings"]["Ports"]["22/tcp"][0]["HostIp"]
212
- end
213
- end
214
293
 
215
- @logger.info("Using docker server at #{ip}")
216
- port = container.json["NetworkSettings"]["Ports"]["22/tcp"][0]["HostPort"]
294
+ ssh_connection_info = get_ssh_connection_info(container)
295
+
296
+ ip = ssh_connection_info[:ip]
297
+ port = ssh_connection_info[:port]
298
+
299
+ @logger.info("Using container connection at #{ip}:#{port}")
217
300
 
218
301
  forward_ssh_agent = @options[:forward_ssh_agent] || false
219
302
 
220
- # Update host metadata
221
- host['ip'] = ip
303
+ host['ip'] = ip
222
304
  host['port'] = port
223
305
  host['ssh'] = {
224
306
  :password => root_password,
225
307
  :port => port,
226
308
  :forward_agent => forward_ssh_agent,
309
+ :auth_methods => ['password', 'publickey', 'hostbased', 'keyboard-interactive']
227
310
  }
228
311
 
229
- @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
312
+ @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
230
313
  host['docker_container_id'] = container.id
231
314
  host['docker_image_id'] = image.id
232
315
  host['vm_ip'] = container.json["NetworkSettings"]["IPAddress"].to_s
233
316
 
317
+ def host.reboot
318
+ @logger.warn("Rebooting containers is ineffective...ignoring")
319
+ end
234
320
  end
235
321
 
236
322
  hack_etc_hosts @hosts, @options
237
-
238
323
  end
239
324
 
240
325
  # This sideloads sshd after a container starts
@@ -243,19 +328,23 @@ module Beaker
243
328
  when /ubuntu/, /debian/
244
329
  container.exec(%w(apt-get update))
245
330
  container.exec(%w(apt-get install -y openssh-server openssh-client))
331
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
246
332
  when /cumulus/
247
333
  container.exec(%w(apt-get update))
248
334
  container.exec(%w(apt-get install -y openssh-server openssh-client))
335
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
249
336
  when /fedora-(2[2-9])/
250
337
  container.exec(%w(dnf clean all))
251
338
  container.exec(%w(dnf install -y sudo openssh-server openssh-clients))
252
339
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
253
340
  container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
341
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
254
342
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
255
343
  container.exec(%w(yum clean all))
256
344
  container.exec(%w(yum install -y sudo openssh-server openssh-clients))
257
345
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
258
346
  container.exec(%w(ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key))
347
+ container.exec(%w(sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*))
259
348
  when /opensuse/, /sles/
260
349
  container.exec(%w(zypper -n in openssh))
261
350
  container.exec(%w(ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key))
@@ -371,64 +460,76 @@ module Beaker
371
460
  case host['platform']
372
461
  when /ubuntu/, /debian/
373
462
  service_name = "ssh"
374
- dockerfile += <<-EOF
463
+ dockerfile += <<~EOF
375
464
  RUN apt-get update
376
465
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::DEBIAN_PACKAGES.join(' ')}
377
- EOF
378
- when /cumulus/
379
- dockerfile += <<-EOF
466
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
467
+ EOF
468
+ when /cumulus/
469
+ dockerfile += <<~EOF
380
470
  RUN apt-get update
381
471
  RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::CUMULUS_PACKAGES.join(' ')}
382
- EOF
472
+ EOF
383
473
  when /fedora-(2[2-9])/
384
- dockerfile += <<-EOF
474
+ dockerfile += <<~EOF
385
475
  RUN dnf clean all
386
476
  RUN dnf install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::UNIX_PACKAGES.join(' ')}
387
477
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
388
478
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
389
- EOF
479
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
480
+ EOF
481
+ when /el-8/
482
+ dockerfile += <<~EOF
483
+ RUN dnf clean all
484
+ RUN dnf install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::RHEL8_PACKAGES.join(' ')}
485
+ RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
486
+ RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
487
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
488
+ EOF
390
489
  when /^el-/, /centos/, /fedora/, /redhat/, /eos/
391
- dockerfile += <<-EOF
490
+ dockerfile += <<~EOF
392
491
  RUN yum clean all
393
492
  RUN yum install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::UNIX_PACKAGES.join(' ')}
394
493
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
395
494
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
396
- EOF
495
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
496
+ EOF
397
497
  when /opensuse/, /sles/
398
- dockerfile += <<-EOF
498
+ dockerfile += <<~EOF
399
499
  RUN zypper -n in openssh #{Beaker::HostPrebuiltSteps::SLES_PACKAGES.join(' ')}
400
500
  RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
401
501
  RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
402
502
  RUN sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config
403
- EOF
503
+ RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
504
+ EOF
404
505
  when /archlinux/
405
- dockerfile += <<-EOF
506
+ dockerfile += <<~EOF
406
507
  RUN pacman --noconfirm -Sy archlinux-keyring
407
508
  RUN pacman --noconfirm -Syu
408
509
  RUN pacman -S --noconfirm openssh #{Beaker::HostPrebuiltSteps::ARCHLINUX_PACKAGES.join(' ')}
409
510
  RUN ssh-keygen -A
410
511
  RUN sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config
411
512
  RUN systemctl enable sshd
412
- EOF
513
+ EOF
413
514
  else
414
515
  # TODO add more platform steps here
415
516
  raise "platform #{host['platform']} not yet supported on docker"
416
517
  end
417
518
 
418
519
  # Make sshd directory, set root password
419
- dockerfile += <<-EOF
520
+ dockerfile += <<~EOF
420
521
  RUN mkdir -p /var/run/sshd
421
522
  RUN echo root:#{root_password} | chpasswd
422
- EOF
523
+ EOF
423
524
 
424
525
  # Configure sshd service to allowroot login using password
425
526
  # Also, disable reverse DNS lookups to prevent every. single. ssh
426
527
  # operation taking 30 seconds while the lookup times out.
427
- dockerfile += <<-EOF
528
+ dockerfile += <<~EOF
428
529
  RUN sed -ri 's/^#?PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config
429
530
  RUN sed -ri 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' /etc/ssh/sshd_config
430
531
  RUN sed -ri 's/^#?UseDNS .*/UseDNS no/' /etc/ssh/sshd_config
431
- EOF
532
+ EOF
432
533
 
433
534
 
434
535
  # Any extra commands specified for the host