beaker-docker 0.5.4 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/release.yml +24 -0
- data/.github/workflows/test.yml +105 -0
- data/Gemfile.local +5 -0
- data/README.md +94 -13
- data/Rakefile +8 -4
- data/acceptance/config/nodes/hosts.yaml +21 -14
- data/acceptance/tests/00_default_spec.rb +10 -0
- data/beaker-docker.gemspec +3 -13
- data/lib/beaker-docker/version.rb +1 -1
- data/lib/beaker/hypervisor/docker.rb +149 -48
- data/spec/beaker/hypervisor/docker_spec.rb +505 -479
- metadata +16 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d1f70940dc7c4b43db06838e143fc4e4a498247be0ed67ae0926ae84527f5786
|
|
4
|
+
data.tar.gz: b12830fb23b10ccf1718be061c3e6ffe3e81c0b47b3aff58e3882e2e0a843c7d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d182e05ba8dea02f896571bb5cf100f3a313349e1178f3eb9daf5e62f7ec93572114e4e1cf6e10a34aa18e8280d7be0ff7ed8a1482984cbd07ae3a530a7a0be9
|
|
7
|
+
data.tar.gz: 478ac68e7088d66a8f5a4732f59a1337b355293b5a5f8d38551e5d54b81e6e7634528139b4c5717462b3d0b4a8558de05afc83b2f2c51705f0e8d16b7fb885a8
|
|
@@ -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
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
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
4
|
-
platform:
|
|
3
|
+
centos8:
|
|
4
|
+
platform: el-8-x86_64
|
|
5
5
|
hypervisor: docker
|
|
6
|
-
image:
|
|
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
|
-
|
|
16
|
-
|
|
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:
|
|
18
|
+
image: centos:7
|
|
23
19
|
roles:
|
|
24
20
|
- agent
|
|
25
|
-
docker_cmd: '
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
data/beaker-docker.gemspec
CHANGED
|
@@ -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
|
-
|
|
24
|
-
|
|
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
|
|
|
@@ -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
|
-
|
|
23
|
-
#
|
|
22
|
+
|
|
23
|
+
# Ensure that we can correctly communicate with the docker API
|
|
24
24
|
begin
|
|
25
|
-
::Docker.
|
|
25
|
+
@docker_version = ::Docker.version
|
|
26
26
|
rescue Excon::Errors::SocketError => e
|
|
27
|
-
raise
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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
|
-
|
|
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
|
|
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 +=
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
472
|
+
EOF
|
|
383
473
|
when /fedora-(2[2-9])/
|
|
384
|
-
dockerfile +=
|
|
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
|
-
|
|
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 +=
|
|
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
|
-
|
|
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 +=
|
|
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
|
-
|
|
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 +=
|
|
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
|
-
|
|
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 +=
|
|
520
|
+
dockerfile += <<~EOF
|
|
420
521
|
RUN mkdir -p /var/run/sshd
|
|
421
522
|
RUN echo root:#{root_password} | chpasswd
|
|
422
|
-
|
|
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 +=
|
|
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
|
-
|
|
532
|
+
EOF
|
|
432
533
|
|
|
433
534
|
|
|
434
535
|
# Any extra commands specified for the host
|