#!/bin/bash

ARCH=`uname -i`

show_help() {
cat << EOF
Usage: $0 [-h] [-y] [-s] [-d] [-8s]
	-h - help
	-y - "yes" (do not ask)
	-s - skip update/clean of current OS
	-d - download only
	-c - post upgrade cleanup
	-8s - switch CentOS 8 to CentOS 8 Stream
	-2r - upgrade 2 releases of Fedora
	--centos8stream - upgrade centos 7 to centos 8 stream (default for C7)
	--centos8 - upgrade centos7 to centos 8
	--almalinux8 - upgrade to almalinux 8 using deploy script from github
EOF
}

fix_selinux() {
  if [ "`getenforcing 2>&1`" = "Enforcing" ]; then
    fixfiles onboot
  fi
}

upgrade_centos6_to_centos7() {
  CENTOS_RELEASE=`rpm -E %rhel`
  CENTOS_NEXT=$((CENTOS_RELEASE+1))
  if [ "$CENTOS_RELEASE" = "6" ]; then
    yum install --enablerepo=upg -y \
      redhat-upgrade-tool preupgrade-assistant-contents openscap-1.0.8
    # fix dependency problems
    for i in pcre grep openldap vim-minimal nss nspr nss-util; do
      rpm -e --nodeps --justdb -v $i
    done
    #  elfutils-libelf elfutils-libs nss nspr nss-util
    # downgrade some packages for compatibility
    #yum downgrade -y \
    #  http://vault.centos.org/6.7/os/x86_64/Packages/elfutils-libelf-0.161-3.el6.x86_64.rpm \
    #  http://vault.centos.org/6.7/os/x86_64/Packages/elfutils-libs-0.161-3.el6.x86_64.rpm
    # import keys
    rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
    rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Security-6
    rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
    # run preupgrade
    UPG=`preupg -l`
    if [ "$ARG_Y" = "-y" ]; then
      upgrade_force="--force"
      upgrade_tool_reboot="--reboot"
    fi
    preupg -s $UPG $upgrade_force
    if [ ! "$ARG_Y" = "-y" ]; then
      echo "Press ENTER to upgrade or CTRL+C to stop."
      read enter
    fi
    PUD=/root/preupgrade/postupgrade.d
    # upgrade other pkgs after base upgrade
    mkdir -p $PUD/salpack
    (
      echo "#!/bin/bash"
      echo ""
      echo "/usr/sbin/salpack-os-upgrade -y"
    ) > $PUD/salpack/salpack.sh
    # fix broken library problems
    mkdir -p $PUD/0salpack
    (
      echo "#!/bin/bash"
      echo ""
      echo "cp -avf $PUD/0salpack/*.so /usr/lib64/"
      echo "/sbin/ldconfig -v"
      #echo "rpm -Uhv $PUD/0salpack/*.rpm --force"
    ) > $PUD/0salpack/salpack.sh
    for lib in libelf-0.163.so; do
      curl http://work.salstar.sk/public/c/$lib > $PUD/0salpack/$lib
    done
    #for rpm in elfutils-libelf-0.163-3.el7.x86_64.rpm; do
    #  curl http://ftp.upjs.sk/pub/centos/7/os/x86_64/Packages/$rpm > $PUD/0salpack/$rpm
    #done
    chmod +x $PUD/*salpack/*.sh
    # run regular update
    if [ -z "$CENTOS_REPO" ]; then
      CENTOS_REPO=http://ftp.upjs.sk/pub/centos/$CENTOS_NEXT/os/$ARCH/
    elif [ "$CENTOS_REPO" = "7.2" ]; then
      CENTOS_VER=7.2.1511
      CENTOS_REPO=http://vault.centos.org/$CENTOS_VER/os/$ARCH/
    fi
    set -x
    centos-upgrade-tool-cli --network $CENTOS_NEXT \
      --instrepo=$CENTOS_REPO \
      --enablerepo="salstar.sk" \
      --cleanup-post $upgrade_tool_reboot $upgrade_force
      #--addrepo="epel$CENTOS_NEXT=http://ftp.upjs.sk/pub/mirrors/epel/$CENTOS_NEXT/$ARCH/" \
      #--enablerepo="epel$CENTOS_NEXT" \
  else
    echo "Unknown CentOS version [$CENTOS_RELEASE]!"
    exit 2
  fi
}

upgrade_centos7_to_v8() {
  if [ ! "$ARG_S" ]; then
    yum update $ARG_Y
    yum install $ARG_Y dnf
    # redhat-upgrade-tool conflicts with kernel workaround swap
    dnf remove redhat-upgrade-tool $ARG_Y
    # kernel is renamed in CentOS 8 and need to be removed, but it's protected
    #rpm -e kernel
    dnf swap grubby kernel-workaround $ARG_Y
    # sysvinit-tools is obsoleted by salpack
    # rpm -e sysvinit-tools --nodeps
    # Remove conflicts for yum files, they are replaced by dnf after upgrade
    rm -rf /etc/yum/vars /etc/yum/protected.d /etc/yum/pluginconf.d
  fi

  # Run the upgrade
  # redhat-rpm-config should be excluded due to:
  # (annobin if gcc) is required for redhat-rpm-config-116-1.el8.0.1.noarch
  # rpmpmlib(RichDependencies) <= 4.12.0-1 je vyžadovaný pre mariadb-connector-c-3.1.11-2.el8_3.x86_64
  dnf distro-sync $ARG_Y --allowerasing \
    --releasever 8 --setopt=module_platform_id=platform:el8 \
    --setopt=install_weak_deps=False \
    --disablerepo=\* "$@" \
    --exclude=redhat-rpm-config --exclude=mariadb-connector-c \
    $ARG_OTHER
}

upgrade_centos7_to_centos8() {
  echo "Upgrading to CentOS 8 (non-stream)!"
  upgrade_centos7_to_v8 --enablerepo=c8upg-\*
}

upgrade_centos7_to_centos8stream() {
  echo "Upgrading to CentOS 8 Stream!"
  upgrade_centos7_to_v8 --enablerepo=c8supg-\* \
    --enablerepo=c8upg-epel --enablerepo=c8upg-salstar.sk
}

upgrade_centos7_to_almalinux8() {
  # This doesn't really work due to centos-release package conflicts.
  echo "Upgrading to AlmaLinux 8!"
  # gpg subkeys are not supported on centos7
  upgrade_centos7_to_v8 --enablerepo=a8upg-\* \
    --enablerepo=c8upg-epel --enablerepo=c8upg-salstar.sk \
    --nogpgcheck
}

centos8_to_centos8stream() {
  echo "Switching CentOS 8 to CentOS 8-Stream"
  echo "    https://www.centos.org/centos-stream/"
  dnf swap centos-linux-repos centos-stream-repos $ARG_Y \
    --disablerepo=appstream --disablerepo=baseos
  dnf distro-sync $ARG_Y --setopt=install_weak_deps=False
}

centos8_to_almalinux8() {
  echo "Switching to AlmaLinux 8 using deploy script from github"
  cd
  curl -O https://raw.githubusercontent.com/AlmaLinux/almalinux-deploy/master/almalinux-deploy.sh
  # allow also downgrade from CentOS 8 Stream
  bash almalinux-deploy.sh --downgrade
}

almalinux8_to_almalinux9() {
  rpm --import https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9
  rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
  dnf distro-sync $ARG_Y --allowerasing \
    --releasever 9 --setopt=module_platform_id=platform:el9 \
    --setopt=install_weak_deps=False \
    --disablerepo=epel\* --enablerepo=c9upg-epel \
    $ARG_OTHER
  systemctl restart rpmdb-rebuild.service
  dnf module disable $ARG_Y virt perl perl-IO-Socket-SSL perl-libwww-perl
}

post_upgrade_cleanup() {
  # remove obsolete packages
  echo "Running package cleanup only ..."
  dnf update -y --setopt=install_weak_deps=False
  dnf remove "$@" `dnf repoquery --extras` $ARG_OTHER
  # remove el7 kernel boot entries
  #rm -i /boot/loader/entries/*.el7.*.conf
}

dnf_upgrade() {
  echo "Running upgrade ..."
  rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$FEDORA_NEXT-$ARCH
  if [ ! "$ARG_S" ]; then
    echo "Upgrading and cleaning current system ..."
    dnf upgrade $ARG_Y --setopt=install_weak_deps=False
    dnf clean all
  fi
  echo "Upgrading to version $FEDORA_NEXT ..."
  echo "dnf --releasever=$FEDORA_NEXT --setopt=deltarpm=false --setopt=install_weak_deps=False distro-sync $ARG_Y $ARG_D $ARG_OTHER"
  dnf --releasever=$FEDORA_NEXT --setopt=deltarpm=false \
    --setopt=install_weak_deps=False \
    distro-sync $ARG_Y $ARG_D $ARG_OTHER
  if [ $? = 0 ]; then
    echo "Extra packages after install:"
    dnf list extras
  fi
}

upgrade_fedora() {
  FEDORA_MIRROR=http://ftp.upjs.sk/pub/fedora/linux
  FEDORA_RELEASE=`rpm -E %fedora`
  FEDORA_NEXT=$((FEDORA_RELEASE+1))
  FEDORA_NEXT2=$((FEDORA_RELEASE+2))
  if [ "$ARG_RELEASE_PLUS2" ]; then
    FEDORA_NEXT=$FEDORA_NEXT2
  elif wget -O /dev/null -q $FEDORA_MIRROR/releases/$FEDORA_NEXT2/; then
    echo "Currently running Fedora $FEDORA_RELEASE."
    echo "Fedora $FEDORA_NEXT2 is already available, do you want to update"
    echo "to Fedora $FEDORA_NEXT2? Type \"y\" or \"yes\" to confirm."
    if [ "$ARG_Y" = "-y" ]; then
      yn="yes"
    else
      read yn
    fi
    echo "Answer: $yn"
    if [ "$yn" = "yes" -o "$yn" = "y" ]; then
      FEDORA_NEXT=$FEDORA_NEXT2
    fi
  fi
  if [ "$FEDORA_RELEASE" -ge "22" ]; then
    dnf_upgrade
  else
    echo "Unsupported Fedora release [$FEDORA_RELEASE]!"
    exit 2
  fi
}

ARG_Y=""
ARG_S=""
ARG_D=""
ARG_C=""
ARG_TARGET=""
ARG_RELEASE_PLUS2=""
for arg in "$@"; do
  case $arg in
    -h|--help)
	show_help
	exit
	;;
    -y|--yes)
	ARG_Y=-y
	;;
    -s|--skip|--short)
	ARG_S=yes
	;;
    -d|--downloadonly)
	ARG_D=--downloadonly
	;;
    -c|--cleanup)
	ARG_C=yes
	;;
    -2r)
        ARG_RELEASE_PLUS2=yes
        ;;
    -8s|--8-stream|--centos8stream|8s|8-stream)
	ARG_TARGET=centos8stream
	;;
    --almalinux8|--almalinux|--alma8|--alma)
        ARG_TARGET=almalinux8
        ;;
    --centos8)
        ARG_TARGET=centos8
        ;;
    *)
	ARG_OTHER="$ARG_OTHER $arg"
	;;
  esac
done

echo "This is an upgrade script for CentOS/Fedora."
echo "WARNING: Use with caution!"

if [ ! "$ARG_Y" = "-y" ]; then
  echo "Press ENTER to continue or CTRL+C to stop."
  read enter
fi

if [ "$ARG_C" = "yes" ]; then
  post_upgrade_cleanup
  exit
fi

if [ -f /etc/centos-release ]; then
  if grep '^CentOS release 6' /etc/centos-release; then
    upgrade_centos6_to_centos7
  elif grep '^CentOS Linux release 7' /etc/centos-release; then
    if [ "$ARG_TARGET" = "centos8" ]; then
      upgrade_centos7_to_centos8
    elif [ "$ARG_TARGET" = "almalinux8" ]; then
      upgrade_centos7_to_almalinux8
    else
      upgrade_centos7_to_centos8stream
    fi
  elif grep '^CentOS \(Linux\|Stream\) release 8' /etc/centos-release; then
    if [ "$ARG_TARGET" = "centos8stream" ]; then
      centos8_to_centos8stream "$@"
    elif [ "$ARG_TARGET" = "almalinux8" ]; then
      centos8_to_almalinux8
    else
      post_upgrade_cleanup "$@"
    fi
  elif grep '^AlmaLinux release 8' /etc/centos-release; then
    #post_upgrade_cleanup "$@"
    almalinux8_to_almalinux9
  else
    echo "ERROR: Unknown release of CentOS!"
    cat /etc/centos-release
  fi
elif [ -f /etc/fedora-release ]; then
  if [ -z "$STY" -a -z "$TMUX" ]; then
    echo "Please run this script under screen or tmux."
    #exit 1
  fi
  upgrade_fedora
fi
