forked from sous-chefs/java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoracle_install.rb
More file actions
272 lines (250 loc) · 9.81 KB
/
Copy pathoracle_install.rb
File metadata and controls
272 lines (250 loc) · 9.81 KB
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
# Cookbook:: java
# Resource:: oracle_install
#
# Copyright:: 2011, Bryan w. Berry
# Copyright:: 2017-2018, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# backwards compatibility with the old name
provides :java_oracle_install
provides :java_ark
property :url, String
property :mirrorlist, Array, default: []
property :checksum, String, regex: /^[0-9a-f]{32}$|^[a-zA-Z0-9]{40,64}$/
property :md5, String, regex: /^[0-9a-f]{32}$|^[a-zA-Z0-9]{40,64}$/
property :app_home, String
property :app_home_mode, Integer, default: 0755
property :bin_cmds, Array, default: []
property :owner, String, default: 'root'
property :group, String, default: lazy { node['root_group'] }
property :default, [true, false], default: true
property :alternatives_priority, Integer, default: 1
property :connect_timeout, Integer, default: 30 # => 30 seconds
property :reset_alternatives, [true, false], default: true
property :use_alt_suffix, [true, false], default: true
property :download_timeout, Integer, default: 600 # => 600 seconds
property :proxy, String
property :accept_oracle_download_terms, [true, false], default: lazy { node['java']['oracle']['accept_oracle_download_terms'] }
action :install do
app_dir_name, tarball_name = parse_app_dir_name(new_resource.url)
app_root = new_resource.app_home.split('/')[0..-2].join('/')
app_dir = app_root + '/' + app_dir_name
app_group = new_resource.group
if !new_resource.default && new_resource.use_alt_suffix
Chef::Log.debug('processing alternate jdk')
app_dir += '_alt'
app_home = new_resource.app_home + '_alt'
else
app_home = new_resource.app_home
end
directory app_root do
owner new_resource.owner
group app_group
mode new_resource.app_home_mode
recursive true
action :nothing
end.run_action(:create)
unless ::File.exist?(app_dir)
if new_resource.url =~ /oracle\.com.*$/
download_path = "#{Chef::Config[:file_cache_path]}/#{tarball_name}"
if oracle_downloaded?(download_path, new_resource)
Chef::Log.debug('oracle tarball already downloaded, not downloading again')
else
Chef::Log.warn('Downloading directly from Oracle is unreliable as artifacts have been removed in the past. Change download url.')
download_direct_from_oracle tarball_name, new_resource
end
else
Chef::Log.debug('downloading tarball from an unofficial repository')
remote_file "#{Chef::Config[:file_cache_path]}/#{tarball_name}" do
source new_resource.url
checksum new_resource.checksum
retries new_resource.retries
retry_delay new_resource.retry_delay
mode '0755'
action :nothing
end.run_action(:create_if_missing)
end
converge_by("extract compressed data into Chef file cache path and move extracted data to #{app_dir}") do
case tarball_name
when /^.*\.bin/
cmd = shell_out(
%(cd "#{Chef::Config[:file_cache_path]}";
bash ./#{tarball_name} -noregister
)
)
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
when /^.*\.zip/
cmd = shell_out(
%(unzip "#{Chef::Config[:file_cache_path]}/#{tarball_name}" -d "#{Chef::Config[:file_cache_path]}" )
)
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
when /^.*\.(tar.gz|tgz)/
package 'tar' do
not_if { platform_family?('mac_os_x', 'windows') }
action :nothing
end.run_action(:install)
cmd = shell_out(
%(tar xvzf "#{Chef::Config[:file_cache_path]}/#{tarball_name}" -C "#{Chef::Config[:file_cache_path]}" --no-same-owner)
)
unless cmd.exitstatus == 0
Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
end
end
cmd = shell_out(
%(mv "#{Chef::Config[:file_cache_path]}/#{app_dir_name}" "#{app_dir}" )
)
unless cmd.exitstatus == 0
Chef::Application.fatal!(%( Command \' mv "#{Chef::Config[:file_cache_path]}/#{app_dir_name}" "#{app_dir}" \' failed ))
end
# change ownership of extracted files
FileUtils.chown_R new_resource.owner, app_group, app_dir
end
end
# set up .jinfo file for update-java-alternatives
java_name = app_home.split('/')[-1]
jinfo_file = "#{app_root}/.#{java_name}.jinfo"
if platform_family?('debian') && !::File.exist?(jinfo_file)
converge_by("Add #{jinfo_file} for debian") do
template jinfo_file do
cookbook 'java'
source 'oracle.jinfo.erb'
owner new_resource.owner
group app_group
variables(
priority: new_resource.alternatives_priority,
bin_cmds: new_resource.bin_cmds,
name: java_name,
app_dir: app_home
)
action :nothing
end.run_action(:create)
end
end
# link app_home to app_dir
Chef::Log.debug "app_home is #{app_home} and app_dir is #{app_dir}"
current_link = ::File.symlink?(app_home) ? ::File.readlink(app_home) : nil
if current_link != app_dir
converge_by("symlink #{app_dir} to #{app_home}") do
FileUtils.rm_f app_home
FileUtils.ln_sf app_dir, app_home
FileUtils.chown new_resource.owner, app_group, app_home
end
end
# update-alternatives
java_alternatives 'set-java-alternatives' do
java_location app_home
bin_cmds new_resource.bin_cmds
priority new_resource.alternatives_priority
default new_resource.default
reset_alternatives new_resource.reset_alternatives
action :set
end
end
action :remove do
app_dir_name, _tarball_name = parse_app_dir_name(new_resource.url)
app_root = new_resource.app_home.split('/')[0..-2].join('/')
app_dir = app_root + '/' + app_dir_name
if new_resource.default
app_home = new_resource.app_home
else
Chef::Log.debug('processing alternate jdk')
app_dir += '_alt'
app_home = new_resource.app_home + '_alt'
end
if ::File.exist?(app_dir)
java_alternatives 'unset-java-alternatives' do
java_location app_home
bin_cmds new_resource.bin_cmds
action :unset
end
converge_by("remove #{new_resource.name} at #{app_dir}") do
Chef::Log.info "Removing #{new_resource.name} at #{app_dir}"
FileUtils.rm_rf app_dir
end
end
end
action_class do
require 'uri'
def parse_app_dir_name(url)
uri = URI.parse(url)
file_name = uri.path.split('/').last
# funky logic to parse oracle's non-standard naming convention
# for jdk1.6
if file_name =~ /^(jre|jdk|server-jre).*$/
major_num = file_name.scan(/\d{1,}/)[0]
package_name = file_name =~ /^server-jre.*$/ ? 'jdk' : file_name.scan(/[a-z]+/)[0]
if major_num.to_i >= 10
# Versions 10 and above incorporate semantic versioning
version_result = file_name.scan(/.*-(\d+)\.(\d+)\.(\d+)_.*/)[0]
major_num = version_result[0]
minor_num = version_result[1]
patch_num = version_result[2]
app_dir_name = "#{package_name}-#{major_num}.#{minor_num}.#{patch_num}"
else
update_token = file_name.scan(/u(\d+)/)[0]
update_num = update_token ? update_token[0] : '0'
# pad a single digit number with a zero
update_num = '0' + update_num if update_num.length < 2
app_dir_name = if update_num == '00'
"#{package_name}1.#{major_num}.0"
else
"#{package_name}1.#{major_num}.0_#{update_num}"
end
end
else
app_dir_name = file_name.split(/(.tgz|.tar.gz|.zip)/)[0]
app_dir_name = app_dir_name.split('-bin')[0]
end
[app_dir_name, file_name]
end
def oracle_downloaded?(download_path, new_resource)
if ::File.exist? download_path
require 'openssl'
if new_resource.checksum =~ /^[0-9a-f]{32}$/
downloaded_md5 = OpenSSL::Digest::MD5.file(download_path).hexdigest
downloaded_md5 == new_resource.checksum
else
downloaded_sha = OpenSSL::Digest::SHA256.file(download_path).hexdigest
downloaded_sha == new_resource.checksum
end
else
false
end
end
def download_direct_from_oracle(tarball_name, new_resource)
download_path = "#{Chef::Config[:file_cache_path]}/#{tarball_name}"
cookie = 'oraclelicense=accept-securebackup-cookie'
proxy = "-x #{new_resource.proxy}" unless new_resource.proxy.nil?
if new_resource.accept_oracle_download_terms
# install the curl package
package 'curl' do
action :nothing
end.run_action(:install)
converge_by('download oracle tarball straight from the server') do
Chef::Log.debug 'downloading oracle tarball straight from the source'
shell_out!(
%(curl --create-dirs -L --retry #{new_resource.retries} --retry-delay #{new_resource.retry_delay} --cookie "#{cookie}" #{new_resource.url} -o #{download_path} --connect-timeout #{new_resource.connect_timeout} #{proxy} ),
timeout: new_resource.download_timeout
)
end
else
Chef::Application.fatal!("You must set the resource property 'accept_oracle_download_terms' or set the node attribute node['java']['oracle']['accept_oracle_download_terms'] to true if you want to download directly from the oracle site!")
end
end
end