#
# Cookbook Name:: cdh
# Recipe:: yum_repo
#
# Copyright 2013, whitestar
#
# 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.
#

def get_repo_urls(cdh_version, node_platform, node_platform_version, kernel_machine)
  platform = nil
  case node_platform
    when 'centos', 'rhel' then platform = 'redhat'
  end
  platform_major_version = node_platform_version.split('.')[0]
  
  platform_ctx = nil
  normalized_kernel_machine = nil
  case cdh_version.split(/[.u]/)[0]
  when '5'
    normalized_kernel_machine = 'x86_64'  # CDH 5 provides only 64-bit packages.
    platform_ctx = "#{platform}/#{platform_major_version}/#{normalized_kernel_machine}"
  when '4'
    normalized_kernel_machine = (platform_major_version == '5') \
      ? 'x86_64' \
      : kernel_machine
    normalized_kernel_machine = (normalized_kernel_machine == 'i686') \
      ? 'i386' \
      : normalized_kernel_machine
    platform_ctx = "#{platform}/#{platform_major_version}/#{normalized_kernel_machine}"
  when '3'
    platform_ctx = (platform_major_version == '5') \
      ? "#{platform}" \
      : "#{platform}/#{platform_major_version}/x86_64"
  end

  cdh_repo_pkg = nil
  cdh_repo_ctx = nil
  cdh_repo_file_ctx = nil
  cdh_repo_key_ctx = nil
  gplextras_repo_file_ctx = nil
  case cdh_version
  when '5.0.0'
    # YARN: 2.2.0+353
    # MRv1: 2.0.0+1475
    cdh_repo_pkg = "cloudera-cdh"
    cdh_repo_ctx = "cdh5/one-click-install/#{platform_ctx}/#{cdh_repo_pkg}-5-0.#{normalized_kernel_machine}.rpm"
    cdh_repo_file_ctx = "cdh5/#{platform_ctx}/cdh/#{cdh_repo_pkg}5.repo"
    cdh_repo_key_ctx = "cdh5/#{platform}/#{platform_major_version}/x86_64/cdh/RPM-GPG-KEY-cloudera"
    gplextras_repo_file_ctx = nil
  when '4.4.0', '4.3.1', '4.3.0', '4.2.1', '4.2.0'
    # YARN: 2.0.0+1475, 2.0.0+1367, 2.0.0+1357, 2.0.0+959, 2.0.0+922
    # MRv1: 2.0.0+1475, 2.0.0+1367, 2.0.0+1357, 0.20.2+1358, 0.20.2+1341
    cdh_repo_pkg = "cloudera-cdh"
    cdh_repo_ctx = "cdh4/one-click-install/#{platform_ctx}/#{cdh_repo_pkg}-4-0.#{normalized_kernel_machine}.rpm"
    cdh_repo_file_ctx = "cdh4/#{platform_ctx}/cdh/#{cdh_repo_pkg}4.repo"
    cdh_repo_key_ctx = "cdh4/#{platform}/#{platform_major_version}/x86_64/cdh/RPM-GPG-KEY-cloudera"
    gplextras_repo_file_ctx = "gplextras/#{platform_ctx}/gplextras/cloudera-gplextras4.repo"
  when '3u6', '3u5'  # End of Maintenance (EOM): June 20th, 2013.
    # 0.20.2+923.475, 0.20.2+923.421
    cdh_repo_pkg = 'cdh3-repository'
    cdh_repo_ctx = "#{platform_ctx}/cdh/#{cdh_repo_pkg}-1.0-1.noarch.rpm"
    cdh_repo_file_ctx = "#{platform_ctx}/cdh/cloudera-cdh3.repo"
    cdh_repo_key_ctx = "#{platform_ctx}/cdh/RPM-GPG-KEY-cloudera"
    gplextras_repo_file_ctx = nil
  else
    Chef::Application.fatal!("Non supported version: #{cdh_version}")
  end

  download_site_url = node['cdh']['archive_url']

  return [
    cdh_repo_pkg,
    "#{download_site_url}/#{cdh_repo_ctx}",
    "#{download_site_url}/#{cdh_repo_file_ctx}",
    "#{download_site_url}/#{cdh_repo_key_ctx}",
    (gplextras_repo_file_ctx.nil?) ? nil : "#{download_site_url}/#{gplextras_repo_file_ctx}"
  ]
end


platform = nil
platform_version = nil
kernel_machine = nil

if node['cdh']['yum_repo']['only_for_mirroring'] then
  yum_repo4mirroring = node['cdh']['yum_repo']['mirroring']
  platform = yum_repo4mirroring['platform']
  platform_version = yum_repo4mirroring['platform_version']
  kernel_machine = yum_repo4mirroring['arch']
else
  platform = node[:platform]
  platform_version = node[:platform_version]
  kernel_machine = node[:kernel][:machine]
end

if node['cdh']['yum_repo']['only_for_mirroring'] \
  || node[:platform_family] == 'rhel' then
  cdh_version = node['cdh']['version']
  cdh_repo_pkg, cdh_repo_url, cdh_repo_file_url, cdh_repo_key_url, gplextras_repo_file_url \
    = get_repo_urls(cdh_version, platform, platform_version, kernel_machine)

  if node['cdh']['yum_repo']['only_for_mirroring'] then
    # for mirroring only.
    # flat file installation.
    cdh_repo_file = nil
    cdh_repo_file_basename = File::basename(cdh_repo_file_url)
    case node[:platform]
    when 'centos', 'rhel'
      cdh_repo_file = "/etc/yum.repos.d/#{cdh_repo_file_basename}"
    when 'suse'
      cdh_repo_file = "/etc/zypp/repos.d/#{cdh_repo_file_basename}"
    when 'debian'  # for mirroring only.
      pkg = 'yum'
      resources(:package => pkg) rescue package pkg do
        action :install
      end
      cdh_repo_file = "/etc/yum/repos.d/#{cdh_repo_file_basename}"
    end

    cdh_repo_add_command \
      = "wget -nv #{cdh_repo_file_url} -O #{cdh_repo_file}"

    pkg = 'wget'
    resources(:package => pkg) rescue package pkg do
      action :nothing
    end.run_action(:install)  # at compile-time

    if node['cdh']['yum_repo']['update'] then
      file cdh_repo_file do
        action :nothing
      end.run_action(:delete)  # at compile-time
    end

    bash "add_cdh_yum_repositories-#{cdh_version}" do
      code <<-EOC
        #{cdh_repo_add_command}
      EOC
      creates cdh_repo_file unless cdh_repo_file_url.nil?
      action :nothing
    end.run_action(:run)  # at compile-time
  else
    # rpm package installation.
    file_cache_path = Chef::Config[:file_cache_path]
    downloaded_repo_pkg = "#{file_cache_path}/#{File::basename(cdh_repo_url)}"
  
    remote_file downloaded_repo_pkg do
      source cdh_repo_url
      not_if "rpm -qi #{cdh_repo_pkg}" unless node['cdh']['yum_repo']['update']
      action :create_if_missing
    end
  
    #cdh_repo_add_command \
    #  = "sudo yum --nogpgcheck localinstall #{downloaded_repo_pkg}"
    package cdh_repo_pkg do
      source downloaded_repo_pkg
      options '--nogpgcheck'
      #flush_cache [:after]
      not_if "rpm -qi #{cdh_repo_pkg}" unless node['cdh']['yum_repo']['update']
      action :install
    end
  
    #cdh_repo_key_add_command \
    #  = "sudo rpm --import #{cdh_repo_key_url}"
    yum_key 'RPM-GPG-KEY-cloudera' do
      url cdh_repo_key_url
      action :add
    end
  end

  if node['cdh']['yum_repo']['with_gplextras'] && !gplextras_repo_file_url.nil? then
    gplextras_repo_file = nil
    case node[:platform]
    when 'centos', 'rhel'
      gplextras_repo_file = '/etc/yum.repos.d/cloudera-gplextras4.repo'
    when 'suse'
      gplextras_repo_file = '/etc/zypp/repos.d/cloudera-gplextras4.repo'
    when 'debian'  # for mirroring only.
      pkg = 'yum'
      resources(:package => pkg) rescue package pkg do
        action :install
      end
      gplextras_repo_file = '/etc/yum/repos.d/cloudera-gplextras4.repo'
    end
  
    gplextras_repo_add_command \
      = "wget -nv #{gplextras_repo_file_url} -O #{gplextras_repo_file}"
  
    pkg = 'wget'
    resources(:package => pkg) rescue package pkg do
      action :nothing
    end.run_action(:install)  # at compile-time

    if node['cdh']['yum_repo']['update'] then
      file gplextras_repo_file do
        action :nothing
      end.run_action(:delete)  # at compile-time
    end
  
    bash "add_cloudera_gplextras_yum_repositories-#{cdh_version}" do
      code <<-EOC
        #{gplextras_repo_add_command}
      EOC
      creates gplextras_repo_file unless gplextras_repo_file_url.nil?
      action :nothing
    end.run_action(:run)  # at compile-time
  end
end
