-
Notifications
You must be signed in to change notification settings - Fork 189
/
Copy pathdocker.rb
236 lines (196 loc) · 7.06 KB
/
docker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# frozen_string_literal: true
require 'yaml'
class JT
class Docker
include Utilities
DOCKER = ENV['DOCKER'] || 'docker'
def docker(*args)
command = args.shift
case command
when 'build'
docker_build(*args)
when nil, 'test'
docker_test(*args)
when 'print'
puts dockerfile(*args, '--print')
else
abort "Unkown jt docker command #{command}"
end
end
private def docker_config
@config ||= begin
contents = File.read(File.join(TRUFFLERUBY_DIR, 'tool', 'docker-configs.yaml'))
YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(contents) : YAML.load(contents)
end
end
private def docker_distros
docker_config.each_pair.select { |_name, details| details.key?('base') }.map(&:first).map { |distro| "--#{distro}" }
end
private def default_docker_dir
@default_docker_dir ||= "#{TRUFFLERUBY_DIR}/tool/docker-pid#{Process.pid}"
end
private def docker_build(*args, docker_dir: default_docker_dir)
if args.first.nil? || args.first.start_with?('--')
image_name = 'truffleruby-test'
else
image_name = args.shift
end
File.write(File.join(docker_dir, 'Dockerfile'), dockerfile(*args, docker_dir: docker_dir))
begin
sh DOCKER, 'build', '-t', image_name, '.', chdir: docker_dir
ensure
FileUtils.rm_rf docker_dir
end
end
private def docker_test(*args)
distros = docker_distros
if args.first == '--filter'
args.shift
filter = args.shift
distros = distros.select { |distro| distro.include?(filter) }
end
distros.each do |distro|
puts '**********************************'
puts '**********************************'
puts '**********************************'
distros.each do |d|
print d
print ' <---' if d == distro
puts
end
puts '**********************************'
puts '**********************************'
puts '**********************************'
docker 'build', distro, *args
end
end
private def dockerfile(*args, docker_dir: default_docker_dir)
config = docker_config
distro_name = 'ol7'
install_method = nil
rebuild_openssl = true
basic_test = false
full_test = false
root = false
print_only = false
until args.empty?
arg = args.shift
case arg
when *docker_distros
distro_name = arg[2..-1]
when '--standalone'
install_method = :standalone
standalone_tarball = args.shift
when '--no-rebuild-openssl'
rebuild_openssl = false
when '--basic-test'
basic_test = true
when '--test'
full_test = true
test_branch = args.shift
when '--root'
root = true
when '--print'
print_only = true
docker_dir = nil # Make sure it is not used
else
abort "unknown option #{arg}"
end
end
distro = config.fetch(distro_name)
run_post_install_hook = rebuild_openssl
packages = []
packages << distro.fetch('locale')
packages << distro.fetch('tar')
packages << distro.fetch('specs') if full_test
packages << distro.fetch('zlib')
packages << distro.fetch('openssl')
packages << distro.fetch('yaml')
packages << distro.fetch('cext')
packages << distro.fetch('c++') if full_test
proxy_vars = []
# There is an issue with dnf + proxy in Fedora 34, install packages outside proxy to workaround
unless distro_name == 'fedora34'
%w[http_proxy https_proxy no_proxy].each do |var|
value = ENV[var]
proxy_vars << "ENV #{var}=#{value}" if value
end
end
lines = [
"FROM #{distro.fetch('base')}",
*proxy_vars,
[distro.fetch('install'), *packages.compact].join(' '),
*distro.fetch('set-locale'),
]
# Check the locale is properly generated
lines << 'RUN locale -a | grep en_US.utf8'
lines << 'WORKDIR /test'
lines << 'RUN useradd -ms /bin/bash test'
lines << 'RUN chown test /test'
lines << 'USER test' unless root
unless print_only
FileUtils.rm_rf docker_dir
Dir.mkdir docker_dir
end
case install_method
when :standalone
FileUtils.copy standalone_tarball, docker_dir unless print_only
standalone_tarball = File.basename(standalone_tarball)
lines << "COPY #{standalone_tarball} /test/"
ruby_base = '/test/truffleruby-standalone'
lines << "RUN mkdir #{ruby_base}"
lines << "RUN tar -zxf #{standalone_tarball} -C #{ruby_base} --strip-components=1"
ruby_bin = "#{ruby_base}/bin"
lines << "RUN #{ruby_base}/lib/truffle/post_install_hook.sh" if run_post_install_hook
else
raise "Unknown install method: #{install_method}"
end
if full_test
test_files = %w[
spec
test/truffle/compiler/pe
versions.json
]
unless print_only
chdir(docker_dir) do
branch_args = test_branch == 'current' ? [] : ['--branch', test_branch]
sh 'git', 'clone', *branch_args, TRUFFLERUBY_DIR, 'truffleruby-tests'
test_files.each do |file|
FileUtils.cp_r "truffleruby-tests/#{file}", '.'
end
FileUtils.rm_rf 'truffleruby-tests'
end
end
end
lines << "ENV PATH=#{ruby_bin}:$PATH"
lines << 'RUN ruby --version'
if basic_test || full_test
lines << "RUN cp -R #{ruby_base}/lib/gems /test/clean-gems"
gem_install = 'ruby -S gem install --no-document'
lines << "RUN #{gem_install} color"
lines << "RUN ruby -rcolor -e 'raise unless defined?(Color)'"
lines << "RUN #{gem_install} oily_png"
lines << "RUN ruby -roily_png -e 'raise unless defined?(OilyPNG::Color)'"
lines << "RUN #{gem_install} unf"
lines << "RUN ruby -runf -e 'raise unless defined?(UNF)'"
lines << "RUN rm -rf #{ruby_base}/lib/gems"
lines << "RUN mv /test/clean-gems #{ruby_base}/lib/gems"
end
if full_test
# lines << 'ENV TRUFFLERUBY_ALL_INTEROP_LIBRARY_METHODS_SPEC=false'
test_files.each do |path|
file = File.basename(path)
lines << "COPY --chown=test #{file} #{file}"
end
excludes = %w[fails slow]
%w[:command_line :security :language :core :tracepoint :library :capi :library_cext :truffle :truffle_capi].each do |set|
t_excludes = excludes.map { |e| '--excl-tag ' + e }.join(' ')
lines << "RUN ruby spec/mspec/bin/mspec -t #{ruby_bin}/ruby #{t_excludes} #{set}"
end
lines << 'RUN ruby --experimental-options --engine.CompilationFailureAction=ExitVM --compiler.TreatPerformanceWarningsAsErrors=all --compiler.IterativePartialEscape --engine.MultiTier=false pe/pe.rb || true'
end
lines << 'CMD bash'
lines.join("\n") + "\n"
end
end
end