beaker-docker 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.editorconfig +10 -0
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/test.yml +58 -49
- data/.gitignore +2 -0
- data/.rubocop.yml +48 -0
- data/.rubocop_todo.yml +572 -0
- data/.simplecov +2 -0
- data/CHANGELOG.md +47 -0
- data/Gemfile +7 -5
- data/Rakefile +40 -137
- data/acceptance/tests/00_default_spec.rb +5 -4
- data/beaker-docker.gemspec +24 -18
- data/bin/beaker-docker +8 -10
- data/lib/beaker/hypervisor/docker.rb +90 -111
- data/lib/beaker-docker/version.rb +3 -1
- data/lib/beaker-docker.rb +1 -0
- data/spec/beaker/hypervisor/docker_spec.rb +48 -9
- data/spec/spec_helper.rb +6 -5
- metadata +79 -25
- data/Gemfile.local +0 -3
data/Rakefile
CHANGED
@@ -1,176 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rspec/core/rake_task'
|
2
4
|
|
3
|
-
|
5
|
+
begin
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
rescue LoadError
|
8
|
+
# RuboCop is an optional group
|
9
|
+
else
|
10
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
11
|
+
# These make the rubocop experience maybe slightly less terrible
|
12
|
+
task.options = ['--display-cop-names', '--display-style-guide', '--extra-details']
|
13
|
+
# Use Rubocop's Github Actions formatter if possible
|
14
|
+
task.formatters << 'github' if ENV['GITHUB_ACTIONS'] == 'true'
|
15
|
+
end
|
16
|
+
end
|
4
17
|
|
18
|
+
namespace :test do
|
5
19
|
namespace :spec do
|
6
|
-
|
7
|
-
desc "Run spec tests"
|
20
|
+
desc 'Run spec tests'
|
8
21
|
RSpec::Core::RakeTask.new(:run) do |t|
|
9
22
|
t.rspec_opts = ['--color', '--format documentation']
|
10
23
|
t.pattern = 'spec/'
|
11
24
|
end
|
12
25
|
|
13
|
-
desc
|
26
|
+
desc 'Run spec tests with coverage'
|
14
27
|
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
28
|
ENV['BEAKER_DOCKER_COVERAGE'] = 'y'
|
16
29
|
t.rspec_opts = ['--color', '--format documentation']
|
17
30
|
t.pattern = 'spec/'
|
18
31
|
end
|
19
|
-
|
20
32
|
end
|
21
33
|
|
22
34
|
namespace :acceptance do
|
23
|
-
|
24
|
-
desc <<-EOS
|
25
|
-
A quick acceptance test, named because it has no pre-suites to run
|
26
|
-
EOS
|
35
|
+
desc 'A quick acceptance test, named because it has no pre-suites to run'
|
27
36
|
task :quick do
|
28
|
-
|
29
|
-
|
30
|
-
beaker_gem_spec = Gem::Specification.find_by_name('beaker')
|
31
|
-
beaker_gem_dir = beaker_gem_spec.gem_dir
|
32
|
-
beaker_test_base_dir = File.join(beaker_gem_dir, 'acceptance/tests/base')
|
33
|
-
load_path_option = File.join(beaker_gem_dir, 'acceptance/lib')
|
37
|
+
## setup & load_path of beaker's acceptance base and lib directory
|
38
|
+
## see below for the reason why it's commented out atm
|
39
|
+
# beaker_gem_spec = Gem::Specification.find_by_name('beaker')
|
40
|
+
# beaker_gem_dir = beaker_gem_spec.gem_dir
|
41
|
+
# beaker_test_base_dir = File.join(beaker_gem_dir, 'acceptance/tests/base')
|
42
|
+
# load_path_option = File.join(beaker_gem_dir, 'acceptance/lib')
|
34
43
|
|
35
44
|
ENV['BEAKER_setfile'] = 'acceptance/config/nodes/hosts.yaml'
|
36
|
-
sh(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
+
sh('beaker',
|
46
|
+
'--hosts', 'acceptance/config/nodes/hosts.yaml',
|
47
|
+
## We can't run these tests until the rsync support in the main
|
48
|
+
## beaker/host.rb is updated to work with passwords.
|
49
|
+
# '--tests', beaker_test_base_dir,
|
50
|
+
# '--load-path', load_path_option,
|
51
|
+
'--tests', 'acceptance/tests/',
|
52
|
+
'--log-level', 'debug',
|
53
|
+
'--debug')
|
45
54
|
end
|
46
|
-
|
47
55
|
end
|
48
|
-
|
49
56
|
end
|
50
57
|
|
51
58
|
# namespace-named default tasks.
|
52
59
|
# these are the default tasks invoked when only the namespace is referenced.
|
53
60
|
# they're needed because `task :default` in those blocks doesn't work as expected.
|
54
|
-
task 'test:spec'
|
55
|
-
task 'test:acceptance'
|
61
|
+
task 'test:spec': %i[test:spec:run]
|
62
|
+
task 'test:acceptance': %i[test:acceptance:quick]
|
56
63
|
|
57
64
|
# global defaults
|
58
|
-
task :
|
59
|
-
task :
|
60
|
-
|
61
|
-
###########################################################
|
62
|
-
#
|
63
|
-
# Documentation Tasks
|
64
|
-
#
|
65
|
-
###########################################################
|
66
|
-
DOCS_DAEMON = "yard server --reload --daemon --server thin"
|
67
|
-
FOREGROUND_SERVER = 'bundle exec yard server --reload --verbose --server thin lib/beaker'
|
68
|
-
|
69
|
-
def running?( cmdline )
|
70
|
-
ps = `ps -ef`
|
71
|
-
found = ps.lines.grep( /#{Regexp.quote( cmdline )}/ )
|
72
|
-
if found.length > 1
|
73
|
-
raise StandardError, "Found multiple YARD Servers. Don't know what to do."
|
74
|
-
end
|
75
|
-
|
76
|
-
yes = found.empty? ? false : true
|
77
|
-
return yes, found.first
|
78
|
-
end
|
79
|
-
|
80
|
-
def pid_from( output )
|
81
|
-
output.squeeze(' ').strip.split(' ')[1]
|
82
|
-
end
|
83
|
-
|
84
|
-
desc 'Start the documentation server in the foreground'
|
85
|
-
task :docs => 'docs:clear' do
|
86
|
-
original_dir = Dir.pwd
|
87
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
88
|
-
sh FOREGROUND_SERVER
|
89
|
-
Dir.chdir( original_dir )
|
90
|
-
end
|
91
|
-
|
92
|
-
namespace :docs do
|
93
|
-
|
94
|
-
desc 'Clear the generated documentation cache'
|
95
|
-
task :clear do
|
96
|
-
original_dir = Dir.pwd
|
97
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
98
|
-
sh 'rm -rf docs'
|
99
|
-
Dir.chdir( original_dir )
|
100
|
-
end
|
101
|
-
|
102
|
-
desc 'Generate static documentation'
|
103
|
-
task :gen => 'docs:clear' do
|
104
|
-
original_dir = Dir.pwd
|
105
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
106
|
-
output = `bundle exec yard doc`
|
107
|
-
puts output
|
108
|
-
if output =~ /\[warn\]|\[error\]/
|
109
|
-
fail "Errors/Warnings during yard documentation generation"
|
110
|
-
end
|
111
|
-
Dir.chdir( original_dir )
|
112
|
-
end
|
113
|
-
|
114
|
-
desc 'Run the documentation server in the background, alias `bg`'
|
115
|
-
task :background => 'docs:clear' do
|
116
|
-
yes, output = running?( DOCS_DAEMON )
|
117
|
-
if yes
|
118
|
-
puts "Not starting a new YARD Server..."
|
119
|
-
puts "Found one running with pid #{pid_from( output )}."
|
120
|
-
else
|
121
|
-
original_dir = Dir.pwd
|
122
|
-
Dir.chdir( File.expand_path(File.dirname(__FILE__)) )
|
123
|
-
sh "bundle exec #{DOCS_DAEMON}"
|
124
|
-
Dir.chdir( original_dir )
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
task(:bg) { Rake::Task['docs:background'].invoke }
|
129
|
-
|
130
|
-
desc 'Check the status of the documentation server'
|
131
|
-
task :status do
|
132
|
-
yes, output = running?( DOCS_DAEMON )
|
133
|
-
if yes
|
134
|
-
pid = pid_from( output )
|
135
|
-
puts "Found a YARD Server running with pid #{pid}"
|
136
|
-
else
|
137
|
-
puts "Could not find a running YARD Server."
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
desc "Stop a running YARD Server"
|
142
|
-
task :stop do
|
143
|
-
yes, output = running?( DOCS_DAEMON )
|
144
|
-
if yes
|
145
|
-
pid = pid_from( output )
|
146
|
-
puts "Found a YARD Server running with pid #{pid}"
|
147
|
-
`kill #{pid}`
|
148
|
-
puts "Stopping..."
|
149
|
-
yes, output = running?( DOCS_DAEMON )
|
150
|
-
if yes
|
151
|
-
`kill -9 #{pid}`
|
152
|
-
yes, output = running?( DOCS_DAEMON )
|
153
|
-
if yes
|
154
|
-
puts "Could not Stop Server!"
|
155
|
-
else
|
156
|
-
puts "Server stopped."
|
157
|
-
end
|
158
|
-
else
|
159
|
-
puts "Server stopped."
|
160
|
-
end
|
161
|
-
else
|
162
|
-
puts "Could not find a running YARD Server"
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
65
|
+
task lint: %i[lint:rubocop]
|
66
|
+
task test: %i[test:spec]
|
67
|
+
task default: %i[test]
|
166
68
|
|
167
69
|
begin
|
168
70
|
require 'rubygems'
|
169
71
|
require 'github_changelog_generator/task'
|
170
72
|
rescue LoadError
|
73
|
+
# Do nothing if no required gem installed
|
171
74
|
else
|
172
75
|
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
173
|
-
config.exclude_labels = %w
|
76
|
+
config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog]
|
174
77
|
config.user = 'voxpupuli'
|
175
78
|
config.project = 'beaker-docker'
|
176
79
|
gem_version = Gem::Specification.load("#{config.project}.gemspec").version
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'beaker'
|
2
|
-
require 'beaker-rspec'
|
3
4
|
|
4
|
-
|
5
|
+
test_name 'Ensure docker container is accessible' do
|
5
6
|
hosts.each do |host|
|
6
|
-
|
7
|
-
on(host, '
|
7
|
+
step "on #{host}" do
|
8
|
+
on(host, 'true')
|
8
9
|
end
|
9
10
|
end
|
10
11
|
end
|
data/beaker-docker.gemspec
CHANGED
@@ -1,35 +1,41 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
3
4
|
require 'beaker-docker/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
7
|
+
s.name = 'beaker-docker'
|
7
8
|
s.version = BeakerDocker::VERSION
|
8
9
|
s.authors = [
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
'Vox Pupuli',
|
11
|
+
'Rishi Javia',
|
12
|
+
'Kevin Imber',
|
13
|
+
'Tony Vu',
|
13
14
|
]
|
14
|
-
s.email = [
|
15
|
-
s.homepage =
|
16
|
-
s.summary =
|
17
|
-
s.description =
|
15
|
+
s.email = ['voxpupuli@groups.io']
|
16
|
+
s.homepage = 'https://github.com/voxpupuli/beaker-docker'
|
17
|
+
s.summary = 'Docker hypervisor for Beaker acceptance testing framework'
|
18
|
+
s.description = 'Allows running Beaker tests using Docker'
|
18
19
|
s.license = 'Apache-2.0'
|
19
20
|
|
20
21
|
s.files = `git ls-files`.split("\n")
|
21
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
-
s.require_paths = [
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
24
|
+
s.require_paths = ['lib']
|
25
|
+
|
26
|
+
s.required_ruby_version = '>= 2.4', '< 4'
|
24
27
|
|
25
28
|
# Testing dependencies
|
26
|
-
s.add_development_dependency '
|
27
|
-
s.add_development_dependency 'rspec-its', '~> 1.3'
|
28
|
-
s.add_development_dependency 'fakefs', '~> 1.3'
|
29
|
+
s.add_development_dependency 'fakefs', '>= 1.3', '< 3.0'
|
29
30
|
s.add_development_dependency 'rake', '~> 13.0'
|
31
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
s.add_development_dependency 'rubocop', '~> 1.12.0'
|
33
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.10'
|
34
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.2'
|
35
|
+
s.add_development_dependency 'rubocop-rspec', '>= 1.44'
|
30
36
|
|
31
37
|
# Run time dependencies
|
32
|
-
s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
|
33
|
-
s.add_runtime_dependency 'docker-api', '~> 2.1'
|
34
38
|
s.add_runtime_dependency 'beaker', '>= 4.34'
|
39
|
+
s.add_runtime_dependency 'docker-api', '~> 2.1'
|
40
|
+
s.add_runtime_dependency 'stringify-hash', '~> 0.0.0'
|
35
41
|
end
|
data/bin/beaker-docker
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'rubygems' unless defined?(Gem)
|
4
5
|
require 'beaker-docker'
|
5
6
|
|
6
|
-
VERSION_STRING =
|
7
|
-
"
|
7
|
+
VERSION_STRING = <<'VER'
|
8
8
|
_ .--.
|
9
9
|
( ` )
|
10
10
|
beaker-docker .-' `--,
|
@@ -14,19 +14,17 @@ VERSION_STRING =
|
|
14
14
|
;| _| _| _| '-'__,--'`--'
|
15
15
|
| _| _| _| _| |
|
16
16
|
_ || _| _| _| _| %s
|
17
|
-
_(
|
17
|
+
_( `--.\_| _| _| _|/
|
18
18
|
.-' )--,| _| _|.`
|
19
19
|
(__, (_ ) )_| _| /
|
20
|
-
`-.__
|
20
|
+
`-.__.\ _,--'\|__|__/
|
21
21
|
;____;
|
22
|
-
|
22
|
+
\YT/
|
23
23
|
||
|
24
|
-
|
24
|
+
|""|
|
25
25
|
'=='
|
26
|
-
|
26
|
+
VER
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
puts BeakerDocker::VERSION
|
28
|
+
puts VERSION_STRING % BeakerDocker::VERSION
|
31
29
|
|
32
30
|
exit 0
|
@@ -30,14 +30,14 @@ module Beaker
|
|
30
30
|
* Check your DOCKER_HOST variable has been set
|
31
31
|
* If you are on OSX or Windows, you might not have Docker Machine setup correctly: https://docs.docker.com/machine/
|
32
32
|
* If you are using rootless podman, you might need to set up your local socket and service
|
33
|
-
|
33
|
+
ERRMSG
|
34
34
|
end
|
35
35
|
|
36
36
|
# Pass on all the logging from docker-api to the beaker logger instance
|
37
37
|
::Docker.logger = @logger
|
38
38
|
|
39
39
|
# Find out what kind of remote instance we are talking against
|
40
|
-
if @docker_version['Version']
|
40
|
+
if /swarm/.match?(@docker_version['Version'])
|
41
41
|
@docker_type = 'swarm'
|
42
42
|
unless ENV['DOCKER_REGISTRY']
|
43
43
|
raise "Using Swarm with beaker requires a private registry. Please setup the private registry and set the 'DOCKER_REGISTRY' env var"
|
@@ -58,7 +58,7 @@ module Beaker
|
|
58
58
|
|
59
59
|
# If the container is running ssh as its init process then this method
|
60
60
|
# will cause issues.
|
61
|
-
if host[:docker_cmd]
|
61
|
+
if /sshd/.match?(Array(host[:docker_cmd]).first)
|
62
62
|
def host.ssh_service_restart
|
63
63
|
self[:docker_container].exec(%w(kill -1 1))
|
64
64
|
end
|
@@ -142,9 +142,9 @@ module Beaker
|
|
142
142
|
port: nil
|
143
143
|
}
|
144
144
|
|
145
|
-
container_json
|
145
|
+
container_json = container.json
|
146
146
|
network_settings = container_json['NetworkSettings']
|
147
|
-
host_config
|
147
|
+
host_config = container_json['HostConfig']
|
148
148
|
|
149
149
|
ip = nil
|
150
150
|
port = nil
|
@@ -161,31 +161,28 @@ module Beaker
|
|
161
161
|
|
162
162
|
# Host to Container
|
163
163
|
port22 = network_settings.dig('PortBindings','22/tcp')
|
164
|
-
if port22.nil? && network_settings.key?('Ports')
|
164
|
+
if port22.nil? && network_settings.key?('Ports') && !nested_docker?
|
165
165
|
port22 = network_settings.dig('Ports','22/tcp')
|
166
166
|
end
|
167
|
+
|
167
168
|
ip = port22[0]['HostIp'] if port22
|
168
169
|
port = port22[0]['HostPort'] if port22
|
169
170
|
|
170
171
|
# Container to container
|
171
172
|
unless ip && port
|
172
|
-
ip = nil
|
173
|
-
port = nil
|
174
|
-
|
175
173
|
ip = network_settings['IPAddress']
|
176
|
-
port =
|
174
|
+
port = ip && !ip.empty? ? 22 : nil
|
177
175
|
end
|
178
176
|
|
179
177
|
# Container through gateway
|
180
178
|
unless ip && port
|
181
|
-
ip = nil
|
182
|
-
port = nil
|
183
|
-
|
184
179
|
ip = network_settings['Gateway']
|
185
180
|
|
186
181
|
if ip && !ip.empty?
|
187
182
|
port22 = network_settings.dig('PortBindings','22/tcp')
|
188
183
|
port = port22[0]['HostPort'] if port22
|
184
|
+
else
|
185
|
+
port = nil
|
189
186
|
end
|
190
187
|
end
|
191
188
|
|
@@ -216,7 +213,6 @@ module Beaker
|
|
216
213
|
@hosts.each do |host|
|
217
214
|
@logger.notify "provisioning #{host.name}"
|
218
215
|
|
219
|
-
|
220
216
|
image = get_container_image(host)
|
221
217
|
|
222
218
|
if host['tag']
|
@@ -510,145 +506,129 @@ module Beaker
|
|
510
506
|
|
511
507
|
def dockerfile_for(host)
|
512
508
|
# specify base image
|
513
|
-
dockerfile =
|
509
|
+
dockerfile = <<~DF
|
514
510
|
FROM #{host['image']}
|
515
511
|
ENV container docker
|
516
|
-
|
512
|
+
DF
|
517
513
|
|
518
514
|
# Commands before any other commands. Can be used for eg. proxy configuration
|
519
|
-
dockerfile += (host['docker_image_first_commands'] || []).map { |
|
520
|
-
"RUN #{command}\n"
|
521
|
-
}.join('')
|
522
|
-
|
523
|
-
# additional options to specify to the sshd
|
524
|
-
# may vary by platform
|
525
|
-
sshd_options = ''
|
515
|
+
dockerfile += (host['docker_image_first_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join('')
|
526
516
|
|
527
517
|
# add platform-specific actions
|
528
|
-
service_name =
|
518
|
+
service_name = 'sshd'
|
529
519
|
additional_packages = host_packages(host)
|
530
520
|
case host['platform']
|
531
521
|
when /ubuntu/, /debian/
|
532
|
-
service_name =
|
533
|
-
dockerfile += <<~
|
534
|
-
RUN apt-get update
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
when
|
539
|
-
|
540
|
-
RUN apt-get update
|
541
|
-
|
542
|
-
|
522
|
+
service_name = 'ssh'
|
523
|
+
dockerfile += <<~DF
|
524
|
+
RUN apt-get update \
|
525
|
+
&& apt-get install -y openssh-server openssh-client #{additional_packages.join(' ')} \
|
526
|
+
&& sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
|
527
|
+
DF
|
528
|
+
when /cumulus/
|
529
|
+
dockerfile += <<~DF
|
530
|
+
RUN apt-get update \
|
531
|
+
&& apt-get install -y openssh-server openssh-client #{additional_packages.join(' ')}
|
532
|
+
DF
|
543
533
|
when /el-[89]/, /fedora-(2[2-9]|3)/
|
544
|
-
dockerfile += <<~
|
545
|
-
RUN dnf clean all
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
EOF
|
534
|
+
dockerfile += <<~DF
|
535
|
+
RUN dnf clean all \
|
536
|
+
&& dnf install -y sudo openssh-server openssh-clients #{additional_packages.join(' ')} \
|
537
|
+
&& ssh-keygen -A \
|
538
|
+
&& sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
|
539
|
+
DF
|
551
540
|
when /^el-/, /centos/, /fedora/, /redhat/, /eos/
|
552
|
-
dockerfile += <<~
|
553
|
-
RUN yum clean all
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
EOF
|
541
|
+
dockerfile += <<~DF
|
542
|
+
RUN yum clean all \
|
543
|
+
&& yum install -y sudo openssh-server openssh-clients #{additional_packages.join(' ')} \
|
544
|
+
&& ssh-keygen -A \
|
545
|
+
&& sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
|
546
|
+
DF
|
559
547
|
when /opensuse/, /sles/
|
560
|
-
dockerfile += <<~
|
561
|
-
RUN zypper -n in openssh #{additional_packages.join(' ')}
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
EOF
|
548
|
+
dockerfile += <<~DF
|
549
|
+
RUN zypper -n in openssh #{additional_packages.join(' ')} \
|
550
|
+
&& ssh-keygen -A \
|
551
|
+
&& sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config \
|
552
|
+
&& sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/*
|
553
|
+
DF
|
567
554
|
when /archlinux/
|
568
|
-
dockerfile += <<~
|
569
|
-
RUN pacman --sync --refresh --noconfirm archlinux-keyring
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
555
|
+
dockerfile += <<~DF
|
556
|
+
RUN pacman --sync --refresh --noconfirm archlinux-keyring \
|
557
|
+
&& pacman --sync --refresh --noconfirm --sysupgrade \
|
558
|
+
&& pacman --sync --noconfirm #{additional_packages.join(' ')} \
|
559
|
+
&& ssh-keygen -A \
|
560
|
+
&& sed -ri 's/^#?UsePAM .*/UsePAM no/' /etc/ssh/sshd_config \
|
561
|
+
&& systemctl enable sshd
|
562
|
+
DF
|
576
563
|
else
|
577
|
-
# TODO add more platform steps here
|
564
|
+
# TODO: add more platform steps here
|
578
565
|
raise "platform #{host['platform']} not yet supported on docker"
|
579
566
|
end
|
580
567
|
|
581
568
|
# Make sshd directory, set root password
|
582
|
-
dockerfile += <<~
|
583
|
-
RUN mkdir -p /var/run/sshd
|
584
|
-
|
585
|
-
|
569
|
+
dockerfile += <<~DF
|
570
|
+
RUN mkdir -p /var/run/sshd \
|
571
|
+
&& echo root:#{root_password} | chpasswd
|
572
|
+
DF
|
586
573
|
|
587
574
|
# Configure sshd service to allowroot login using password
|
588
575
|
# Also, disable reverse DNS lookups to prevent every. single. ssh
|
589
576
|
# operation taking 30 seconds while the lookup times out.
|
590
|
-
|
591
|
-
|
592
|
-
RUN sed -ri
|
593
|
-
|
594
|
-
|
595
|
-
|
577
|
+
# Also unbreak users with a bunch of SSH keys loaded in their keyring.
|
578
|
+
dockerfile += <<~DF
|
579
|
+
RUN sed -ri \
|
580
|
+
-e 's/^#?PermitRootLogin .*/PermitRootLogin yes/' \
|
581
|
+
-e 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/' \
|
582
|
+
-e 's/^#?UseDNS .*/UseDNS no/' \
|
583
|
+
-e 's/^#?MaxAuthTries.*/MaxAuthTries 1000/' \
|
584
|
+
/etc/ssh/sshd_config
|
585
|
+
DF
|
596
586
|
|
597
587
|
# Any extra commands specified for the host
|
598
|
-
dockerfile += (host['docker_image_commands'] || []).map { |
|
599
|
-
"RUN #{command}\n"
|
600
|
-
}.join('')
|
588
|
+
dockerfile += (host['docker_image_commands'] || []).map { |cmd| "RUN #{cmd}\n" }.join('')
|
601
589
|
|
602
590
|
# Override image entrypoint
|
603
|
-
if host['docker_image_entrypoint']
|
604
|
-
dockerfile += "ENTRYPOINT #{host['docker_image_entrypoint']}\n"
|
605
|
-
end
|
591
|
+
dockerfile += "ENTRYPOINT #{host['docker_image_entrypoint']}\n" if host['docker_image_entrypoint']
|
606
592
|
|
607
593
|
# How to start a sshd on port 22. May be an init for more supervision
|
608
594
|
# Ensure that the ssh server can be restarted (done from set_env) and container keeps running
|
609
|
-
cmd = host['docker_cmd'] || [
|
610
|
-
dockerfile +=
|
595
|
+
cmd = host['docker_cmd'] || ['sh', '-c', "service #{service_name} start; tail -f /dev/null"]
|
596
|
+
dockerfile += <<~DF
|
611
597
|
EXPOSE 22
|
612
598
|
CMD #{cmd}
|
613
|
-
|
614
|
-
|
615
|
-
# end
|
599
|
+
DF
|
616
600
|
|
617
601
|
@logger.debug("Dockerfile is #{dockerfile}")
|
618
|
-
|
602
|
+
|
603
|
+
dockerfile
|
619
604
|
end
|
620
605
|
|
621
606
|
# a puppet run may have changed the ssh config which would
|
622
607
|
# keep us out of the container. This is a best effort to fix it.
|
623
608
|
# Optionally pass in a host object to to determine which ssh
|
624
609
|
# restart command we should try.
|
625
|
-
def fix_ssh(container, host=nil)
|
610
|
+
def fix_ssh(container, host = nil)
|
626
611
|
@logger.debug("Fixing ssh on container #{container.id}")
|
627
|
-
container.exec(['sed','-ri',
|
628
|
-
's/^#?PermitRootLogin .*/PermitRootLogin yes/',
|
629
|
-
'/
|
630
|
-
|
631
|
-
|
632
|
-
'/
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
container.exec(%w(/usr/sbin/sshd))
|
645
|
-
else
|
646
|
-
container.exec(%w(service ssh restart))
|
647
|
-
end
|
612
|
+
container.exec(['sed', '-ri',
|
613
|
+
'-e', 's/^#?PermitRootLogin .*/PermitRootLogin yes/',
|
614
|
+
'-e', 's/^#?PasswordAuthentication .*/PasswordAuthentication yes/',
|
615
|
+
'-e', 's/^#?UseDNS .*/UseDNS no/',
|
616
|
+
# Unbreak users with a bunch of SSH keys loaded in their keyring.
|
617
|
+
'-e', 's/^#?MaxAuthTries.*/MaxAuthTries 1000/',
|
618
|
+
'/etc/ssh/sshd_config',])
|
619
|
+
|
620
|
+
return unless host
|
621
|
+
|
622
|
+
case host['platform']
|
623
|
+
when /alpine/
|
624
|
+
container.exec(%w[/usr/sbin/sshd])
|
625
|
+
when /ubuntu/, /debian/
|
626
|
+
container.exec(%w[service ssh restart])
|
627
|
+
else
|
628
|
+
container.exec(%w[service sshd restart])
|
648
629
|
end
|
649
630
|
end
|
650
631
|
|
651
|
-
|
652
632
|
# return the existing container if we're not provisioning
|
653
633
|
# and docker_container_name is set
|
654
634
|
def find_container(host)
|
@@ -679,6 +659,5 @@ module Beaker
|
|
679
659
|
def in_container?
|
680
660
|
return File.file?('/.dockerenv')
|
681
661
|
end
|
682
|
-
|
683
662
|
end
|
684
663
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|