Knife-Zero doesn't include Berkshelf support, so vendoring everything in the repo is convenient again
		
			
				
	
	
		
			203 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
#
 | 
						|
# Cookbook:: java
 | 
						|
# Resource:: adoptopenjdk_install
 | 
						|
#
 | 
						|
# Based on oracle_install.rb by Bryan W. Berry (<bryan.berry@gmail.com>)
 | 
						|
#
 | 
						|
 | 
						|
resource_name :adoptopenjdk_install
 | 
						|
 | 
						|
default_action :install
 | 
						|
 | 
						|
property :url, String
 | 
						|
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 :reset_alternatives, [true, false], default: true
 | 
						|
property :variant, ['hotspot', 'openj9', 'openj9-large-heap'], default: 'openj9'
 | 
						|
 | 
						|
action :install do
 | 
						|
  raise 'No URL provided to download AdoptOpenJDK\'s tar file!' if new_resource.url.nil? || new_resource.url.empty?
 | 
						|
  app_dir_name, tarball_name, app_root, app_dir =
 | 
						|
    parse_dir_names(new_resource.url,
 | 
						|
                    new_resource.app_home,
 | 
						|
                    new_resource.variant)
 | 
						|
  app_group = new_resource.group
 | 
						|
  app_home = new_resource.app_home
 | 
						|
  Chef::Log.debug("processing #{new_resource.variant} variant")
 | 
						|
 | 
						|
  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)
 | 
						|
    download_path = "#{node['java']['download_path']}/#{tarball_name}"
 | 
						|
    if adoptopendjk_downloaded?(download_path, new_resource)
 | 
						|
      Chef::Log.debug('AdoptOpenJDK tarball already downloaded, not downloading again')
 | 
						|
    else
 | 
						|
      Chef::Log.debug("downloading tarball from #{URI.parse(new_resource.url).host}")
 | 
						|
      remote_file "#{node['java']['download_path']}/#{tarball_name}" do
 | 
						|
        source new_resource.url
 | 
						|
        checksum new_resource.checksum
 | 
						|
        retries new_resource.retries
 | 
						|
        retry_delay new_resource.retry_delay
 | 
						|
        mode 0o644
 | 
						|
        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
 | 
						|
      package 'tar' do
 | 
						|
        not_if { platform_family?('mac_os_x', 'windows') }
 | 
						|
        action :nothing
 | 
						|
      end.run_action(:install)
 | 
						|
 | 
						|
      cmd = shell_out(%(tar xvzf "#{node['java']['download_path']}/#{tarball_name}" -C "#{node['java']['download_path']}" --no-same-owner)
 | 
						|
                     )
 | 
						|
      unless cmd.exitstatus == 0
 | 
						|
        Chef::Application.fatal!("Failed to extract file #{tarball_name}!")
 | 
						|
      end
 | 
						|
 | 
						|
      cmd = shell_out(
 | 
						|
        %(mv "#{node['java']['download_path']}/#{app_dir_name}" "#{app_dir}" )
 | 
						|
      )
 | 
						|
      unless cmd.exitstatus == 0
 | 
						|
        Chef::Application.fatal!(%( Command \' mv "#{node['java']['download_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, jinfo_file = alternatives_config_file(app_root, app_home)
 | 
						|
  if platform_family?('debian') && !::File.exist?(jinfo_file)
 | 
						|
    converge_by("Add #{jinfo_file} for debian") do
 | 
						|
      template jinfo_file do
 | 
						|
        cookbook 'java'
 | 
						|
        source 'adoptopenjdk.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
 | 
						|
  raise 'No URL provided for AdoptOpenJDK\'s tar file!' if new_resource.url.nil? || new_resource.url.empty?
 | 
						|
  _app_dir_name, _tarball_name, _app_root, app_dir =
 | 
						|
    parse_dir_names(new_resource.url,
 | 
						|
                    new_resource.app_home,
 | 
						|
                    new_resource.variant)
 | 
						|
  app_home = new_resource.app_home
 | 
						|
  Chef::Log.debug("processing #{new_resource.variant} variant")
 | 
						|
 | 
						|
  if ::File.exist?(app_dir)
 | 
						|
    java_alternatives 'unset-java-alternatives' do
 | 
						|
      java_location app_home
 | 
						|
      bin_cmds new_resource.bin_cmds
 | 
						|
      action :unset
 | 
						|
    end
 | 
						|
 | 
						|
    directory "AdoptOpenJDK removal of #{app_home}" do
 | 
						|
      path app_home
 | 
						|
      recursive true
 | 
						|
      action :delete
 | 
						|
    end
 | 
						|
    directory "AdoptOpenJDK removal of #{app_dir}" do
 | 
						|
      path app_dir
 | 
						|
      recursive true
 | 
						|
      action :delete
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
action_class do
 | 
						|
  require 'uri'
 | 
						|
 | 
						|
  def parse_app_dir_name(url)
 | 
						|
    uri = URI.parse(url)
 | 
						|
    file_name = uri.path.split('/').last
 | 
						|
    if file_name =~ /jdk\d+u\d+-b\d+/ # OpenJDK8
 | 
						|
      dir_name_results = file_name.scan(/_(jdk\d+u\d+-b\d+)(?:_openj[-.\d]+)?\.tar\.gz$/)
 | 
						|
      app_dir_name = dir_name_results[0][0] unless dir_name_results.empty?
 | 
						|
    elsif file_name =~ /_\d+u\d+b\d+\.tar\.gz$/ # OpenJDK8U
 | 
						|
      dir_name_results = file_name.scan(/_(\d+u\d+)(b\d+)\.tar\.gz$/)
 | 
						|
      app_dir_name = "jdk#{dir_name_results[0][0]}-#{dir_name_results[0][1]}" unless dir_name_results.empty?
 | 
						|
    else
 | 
						|
      dir_name_results = file_name.scan(/[-_]([.\d]+)[._]([\d]+)(?:_openj[-.\d]+)?\.tar\.gz$/)
 | 
						|
      app_dir_name = "jdk-#{dir_name_results[0][0]}+#{dir_name_results[0][1]}" unless dir_name_results.empty?
 | 
						|
    end
 | 
						|
    Chef::Application.fatal!("Failed to parse #{file_name} for application directory name!") if dir_name_results.empty?
 | 
						|
 | 
						|
    [app_dir_name, file_name]
 | 
						|
  end
 | 
						|
 | 
						|
  def parse_dir_names(url, app_home, variant)
 | 
						|
    app_dir_name, tarball_name = parse_app_dir_name(url)
 | 
						|
    app_root = app_home.split('/')[0..-2].join('/')
 | 
						|
    app_dir = "#{app_root}/#{app_dir_name}-#{variant}"
 | 
						|
    [app_dir_name, tarball_name, app_root, app_dir]
 | 
						|
  end
 | 
						|
 | 
						|
  def alternatives_config_file(app_root, app_home)
 | 
						|
    java_name = app_home.split('/')[-1]
 | 
						|
    config_file = "#{app_root}/.#{java_name}.jinfo"
 | 
						|
    [java_name, config_file]
 | 
						|
  end
 | 
						|
 | 
						|
  def adoptopendjk_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
 | 
						|
end
 |