#!/bin/bash

#Preupgrade Assistant performs system upgradability assessment
#and gathers information required for successful operating system upgrade.
#Copyright (C) 2013 Red Hat Inc.
#Ondrej Vasik <ovasik@redhat.com>, Petr Stodulka <pstodulk@redhat.com>
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.
. /usr/share/preupgrade/common.sh
#END GENERATED SECTION

# is created/copied by ReplacedPackages
_DST_NOAUTO_POSTSCRIPT="$NOAUTO_POSTUPGRADE_D/install_rpmlist.sh"
FILENAME_BASIS="RHRHEL7rpmlist_obsoleted"

get_repo_id() {
  grep -E "^[^-]*-$1;" "$COMMON_DIR/default_nreponames" | cut -d ";" -f3
}

[ ! -f "$VALUE_RPM_RHSIGNED" ] || [ ! -r "$COMMON_DIR" ] && {
  log_error "Signed RPM list or common file directory is missing. Contact the support."
  exit $RESULT_ERROR
}

ObsoletedPkgs=$(mktemp /tmp/.obsoletedpkgsXXX)
MoveObsoletedPkgs=$(mktemp /tmp/.mvreplacedpkgsXXX)
NotBasePkgs=$(mktemp /tmp/.notbasepkgsXXX)
cat $COMMON_DIR/default*_*obsoleted* | cut -f1,3 -d' ' | tr ' ' '|' | sort | uniq >"$ObsoletedPkgs"
grep -Hr "..*" $COMMON_DIR/default*_moved-obsoleted_?* | sed -r "s|^$COMMON_DIR/([^:]+):([^[:space:]]*).*$|\2 \1|" | sort | uniq >"$MoveObsoletedPkgs"
grep -Hr "..*" $COMMON_DIR/default-*_obsoleted | sed -r "s|^$COMMON_DIR/([^:]+):([^[:space:]]*).*$|\2 \1|" | sort | uniq >"$NotBasePkgs"



[ ! -r "$ObsoletedPkgs" ] \
      || [ ! -r "$MoveObsoletedPkgs" ] \
      || [ ! -r "$NotBasePkgs" ] && {
  log_error "Package content lists are missing. Contact the support."
  rm -f "$ObsoletedPkgs" "$MoveObsoletedPkgs" "$NotBasePkgs"
  exit $RESULT_ERROR
}

found=0
other_repositories=""
rm -f solution.txt "$KICKSTART_DIR/${FILENAME_BASIS}"*
echo \
"Some packages were obsoleted between Red Hat Enterprise Linux 5 and Red Hat Enterprise Linux 7. Red Hat provides
alternatives for them, but these alternatives may not be fully compatible.
Because of this, we do not replace them automatically.

For some of the obsoleted packages you will get the incompatibilities list
from separate preupgrade modules and you can adjust your migration as required.

Sometimes the functionality of a package requires more than one new package
to achieve the same functionality.

Note: All packages from the debug repositories are skipped and Red Hat
recommends that you remove them before upgrade.

The following packages are obsoleted and replaced by new ones:" >solution.txt

#Check for package obsolete type replacements in packages
# - packages from *debug repositories aren't important - ignore them (at least for now)
line=
while IFS= read line || [ -n "$line" ];
do
  orig_pkg=$(echo "$line" | cut -d'|' -f1)
  new_pkgs=$(echo "$line" | cut -d'|' -f2)
  #skip non-rh and unavailable packages
  is_pkg_installed "$orig_pkg" && is_dist_native $orig_pkg || continue

  is_moved=0
  is_not_base=0
  filename_suffix=""
  msg_channel=""
  req_pkgs=""
  msg_req=""
  func_log_risk=log_medium_risk

  for k in $(rpm -q --whatrequires $orig_pkg | grep -v "^no package requires" \
    | rev | cut -d'-' -f3- | rev | sort | uniq)
  do
    is_pkg_installed "$k" || continue
    is_dist_native "$k" || req_pkgs="$req_pkgs$k "
  done
  [ -n "$req_pkgs" ] && {
    req_pkgs="${req_pkgs% }"
    msg_req=" (required by Non Red Hat signed package(s):$req_pkgs)"
    func_log_risk=log_high_risk
  }
  channel="$(grep "^$orig_pkg[[:space:]]" "$MoveObsoletedPkgs" | rev | cut -d "_" -f 1 | rev)"

  if [ -n "$channel" ]; then
    [[ "$channel" =~ debug$ ]] && continue
    is_moved=1
  else
    channel=$(grep "^$orig_pkg[[:space:]]" "$NotBasePkgs" | sed -r "s/^.*default-(.*)_obsoleted$/\1/" )
    [[ "$channel" =~ debug$ ]] && continue
    [ -n "$channel" ] && is_not_base=1
  fi


  if [ $is_moved -eq 1 ] || [ $is_not_base -eq 1 ]; then
    # [ "$channel" == "optional" ] && optional=1 # unused variable
    other_repositories="${other_repositories}$channel "
    msg_channel=" ($channel channel in RHEL 7)"
  fi

  # logs / prints
  [ -n "$msg_req" ] && $func_log_risk "The $orig_pkg$msg_req package was removed (obsoleted) between Red Hat Enterprise Linux 5 and Red Hat Enterprise Linux 7."
  [ $is_moved -eq 1 ] && $func_log_risk "The partial replacement for the $orig_pkg package moved to the $channel channel between Red Hat Enterprise Linux 5 and Red Hat Enterprise Linux 7."
  [ $is_not_base -eq 1 ] && $func_log_risk "The partial replacement for the $orig_pkg package is available in the $channel channel in Red Hat Enterprise Linux 7."
  echo "${orig_pkg}$msg_req was obsoleted by ${new_pkgs}$msg_channel" >>solution.txt
  {
    # store data to kickstart files
    [ -n "$msg_req" ] && filename_suffix="${filename_suffix}-required"
    [ -n "$channel" ] && filename_suffix="${filename_suffix}-notbase"
    echo "${orig_pkg}|$req_pkgs|$(echo $new_pkgs | tr ',' ' ')|$(get_repo_id $channel)" >> "$KICKSTART_DIR/${FILENAME_BASIS}${filename_suffix}"
  }
  found=1
done < "$ObsoletedPkgs"
rm -f "$ObsoletedPkgs" "$MoveObsoletedPkgs" "$NotBasePkgs"

# transform my-repo-names to known names
[ -n "$other_repositories" ] && [ $MIGRATE -eq 1 ] && {
  regexp_part="$(echo "${other_repositories}" | tr ' ' '|' | sed -e "s/^|*//" -e "s/|*$//" | sort | uniq )"
  migrate_repos="$(grep -E "^[^-]*(-($regexp_part))?;" < "$COMMON_DIR/default_nreponames")"
  repos_texts="$(echo "$migrate_repos" | cut -d ";" -f4)"

  echo "
One or more replacement packages are available only in other repositories.
If you want to install them later, you will need to attach subscriptions that provide:
$repos_texts

Then, enable any equivalent repositories (if they are disabled), and install any needed packages.
For this purpose, you can run a prepared script:
$_DST_NOAUTO_POSTSCRIPT <path/to/pkglist-file>

The script will install the available packages listed in the file.
See the ${KICKSTART_README} file for the details about the pkglist files.
" >>solution.txt
}

# it looks better sorted
for file in $(ls $KICKSTART_DIR/${FILENAME_BASIS}*); do
  # add header line
  echo "# old-package|required-by-pkgs|obsoleted-by-pkgs|repo-id" > ${file}.bak
  cat "$file" | sort | uniq >> ${file}.bak
  mv ${file}.bak $file
done

  echo -n "
 * ${FILENAME_BASIS} - This file contains all Red Hat Enterprise Linux 5 packages that were replaced in Red Hat Enterprise Linux 7 by alternatives that are not compatible and that are a part of the base channel. A direct dependency from the packages not signed by Red Hat was not discovered.
 * ${FILENAME_BASIS}-required - This file is similar to the ${FILENAME_BASIS} file, but in addition the packages are required by packages not signed by Red Hat. As some of your packages depend on it, check the changes closely.
 * ${FILENAME_BASIS}-notbase - This file is similar to the ${FILENAME_BASIS} file, but these packages are not a part of the base channel in Red Hat Enterprise Linux 7. You need to register the new machine and attach subscriptions with the correct repositories if you want to install them.
 * ${FILENAME_BASIS}-required-notbase - This file is similar to the ${FILENAME_BASIS}-required and ${FILENAME_BASIS}-notbase files. The packages are required by the packages not signed by Red Hat and they are not a part of the base channel.
" >> "$KICKSTART_README"

echo \
"
If a package not signed by Red Hat requires these packages, check if an alternative solution provided by Red Hat works for you. You may need to get the missing package from a source other than the Red Hat Enterprise Linux repositories.

You will need to install these new packages yourself after the assessment, as Red Hat cannot assess the suitablility of the replacements for your workload." >>solution.txt

[ $found -eq 1 ] && log_medium_risk "\
Some packages installed on the system were removed between Red Hat Enterprise Linux 5 and Red Hat Enterprise Linux 7. This might break the functionality of the packages that depend on them." && exit $RESULT_FAIL

rm -f solution.txt && touch solution.txt

exit $RESULT_PASS
