#!/bin/bash
# KernelCare (https://kernelcare.com/) installation script v1.30
# Copyright (c) Cloud Linux Software, Inc

set -euo pipefail
cd /root/

# plesk integration notes:
# 1. plesk plugin ignores stdout, that's why errors are redirected to stderr
# 2. plesk plugin uses exit codes to distinguish error types
# 3. install script shouldn't be interactive, it shouldn't wait for input in any case

#Custom package name
PACKAGE_NAME=${KCARE_PACKAGE_NAME:-"kernelcare"}

# Default repo could be redefined during installation
repo=${KCARE_REPO:-"https://repo.cloudlinux.com"}

SIGSUFFIX=sig202505  # changed when we rotate repo signature keys
DEBIAN_SUBREPO_DEBIAN=kernelcare/debian-$SIGSUFFIX
DEBIAN_SUBREPO_UBUNTU=kernelcare/ubuntu-$SIGSUFFIX
# we have only old layout for debian8 and ubuntu14
DEBIAN_SUBREPO_DEBIAN_8=kernelcare/kernelcare-debian
RPM_SUBREPO=kernelcare/el-$SIGSUFFIX
RPM_KEYRING=RPM-GPG-KEY-KernelCare-rsa4096

version_pattern='[=-]?([0-9]+)\.([0-9]+)-?'
if [[ "${KCARE_PACKAGE_VERSION:-}" =~ $version_pattern ]]; then
    ver_major="${BASH_REMATCH[1]}"
    ver_minor="${BASH_REMATCH[2]}"
    # old versions are available in old repos only
    if [[ "$ver_major" -le 2 && "$ver_minor" -lt 97 ]]; then
        DEBIAN_SUBREPO_DEBIAN=kernelcare/kernelcare-debian
        DEBIAN_SUBREPO_UBUNTU=kernelcare-ubuntu
        RPM_SUBREPO=kernelcare
        RPM_KEYRING=RPM-GPG-KEY-KernelCare
    fi
elif [ -n "${KCARE_PATCH_SERVER:-}" ] && [ -z "${KCARE_REPO_SIGSUFFIX:-}" ]; then
    # if the script was executed by the eportal installation wrapper
    # and it is an old eportal version <= 2.17
    # we should use the old format of repo urs
    # otherwize set-kernelcare-repo will fail
    DEBIAN_SUBREPO_DEBIAN=kernelcare/kernelcare-debian
    DEBIAN_SUBREPO_UBUNTU=kernelcare-ubuntu
fi

DRY_RUN=
while getopts n option
do
case "${option}" in
n) DRY_RUN=1;;
*) continue;
esac
done

# shellcheck disable=SC2016
RPM_RELVER='$releasever'

if [ -e /etc/os-release ]; then
    rel=$(grep -w 'VERSION_ID' /etc/os-release | cut -d'.' -f1 | grep -oE "[0-9]*" || :)
    codename=$(grep -w 'VERSION_CODENAME' /etc/os-release | cut -d'.' -f1 || :)
    distr=$(grep -w 'ID' /etc/os-release | cut -d'=' -f2|tr -d '"' | xargs || :)
    distr_like=$(grep -w 'ID_LIKE' /etc/os-release | cut -d'=' -f2|tr -d '"' || :)

    case $distr in
        "debian" | "raspbian")
                min_debian_ver=8
                max_debian_ver=12

                DISTRO_FAMILY='deb'
                DEBIAN_CODENAME=kcare
                DEBIAN_SUBREPO=$DEBIAN_SUBREPO_DEBIAN
                if [ "$rel" -ge $max_debian_ver ]; then
                    DEBIAN_VERSION=$max_debian_ver
                elif [ "$rel" -le $min_debian_ver ]; then
                    DEBIAN_VERSION=$min_debian_ver
                    DEBIAN_SUBREPO=$DEBIAN_SUBREPO_DEBIAN_8
                else
                    DEBIAN_VERSION="$rel"
                fi
        ;;
        "ubuntu")
                DISTRO_FAMILY='deb'
                if grep -q 'VERSION_ID="14.04"' /etc/os-release; then
                    # we should use debian8 packages for ubuntu-14.04
                    DEBIAN_VERSION=8
                    DEBIAN_CODENAME=kcare
                    DEBIAN_SUBREPO=$DEBIAN_SUBREPO_DEBIAN_8
                else
                    DEBIAN_SUBREPO=$DEBIAN_SUBREPO_UBUNTU
                    # shellcheck disable=SC1091 disable=SC2046
                    eval $(source /etc/os-release; echo DEBIAN_VERSION="$VERSION_ID"; echo DEBIAN_CODENAME="$VERSION_CODENAME")
                fi
        ;;
        "amzn")
                DISTRO_FAMILY='rpm'
                # TODO: Remove this hack after amzn1 support dropped
                [[ "${rel}" -eq "2018" ]] && yum install -y python-argparse

                # Use el8 repo for AL2023
                if [[ "$rel" -eq 2023 ]]; then
                    RPM_RELVER=8
                fi
        ;;
        "almalinux" | "rocky" | "centos" | "rhel" | "ol" | "cloudlinux" | "virtuozzo")
                DISTRO_FAMILY='rpm'
        ;;
        * )
            echo "WARNING: Sorry, this distro isn't supported yet. If you'd like it to be, let us know at feedback@cloudlinux.com."
            case "$distr_like" in
                *"ubuntu"*)
                    DISTRO_FAMILY='deb'
                    DEBIAN_VERSION="$rel"
                    DEBIAN_CODENAME="$codename"
                    DEBIAN_SUBREPO=$DEBIAN_SUBREPO_UBUNTU
                ;;
                * )
                    DISTRO_FAMILY='rpm'
                    rel='7'
                ;;
            esac
        ;;
    esac
elif [ -e /etc/system-release ]; then
    rel=$(cut -d'.' -f1 /etc/system-release | grep -oE "[0-9]")
    DISTRO_FAMILY='rpm'
else
    rel=$(cut -d'.' -f1 /etc/redhat-release | grep -oE "[0-9]")
    DISTRO_FAMILY='rpm'
fi

download() {
    url="$1"
    fname="$2"
    if hash curl 2>/dev/null; then
        curl --fail -o "$fname" "$url"
    elif hash wget 2>/dev/null; then
        wget -O "$fname" "$url"
    else
        echo "Unable to install kernelcare: install curl or wget to continue." > /dev/stderr
        exit 2
    fi
}

# force default umask
umask 0022

case "${DISTRO_FAMILY}" in
    "deb")
        mkdir -p /usr/share/keyrings
        download "${repo}/kernelcare/kernelcare.gpg" /usr/share/keyrings/kcare.gpg
        chmod 644 /usr/share/keyrings/kcare.gpg
        if [[ ${DEBIAN_VERSION%%.*} -le 8 ]]; then
            apt-key add /usr/share/keyrings/kcare.gpg
            line_start="deb"
        else
            line_start="deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/kcare.gpg]"
        fi

        echo "$line_start $repo/$DEBIAN_SUBREPO/$DEBIAN_VERSION $DEBIAN_CODENAME main" > /etc/apt/sources.list.d/kcare.list
        if [ -n "${DRY_RUN}" ]; then
            exit 0
        fi

        export DEBIAN_FRONTEND=noninteractive
        apt-get update && apt-get install --no-install-recommends --yes "$PACKAGE_NAME${KCARE_PACKAGE_VERSION:-}"
    ;;
    "rpm")
        rpm --import "${repo}/kernelcare/${RPM_KEYRING}"
        cat >/etc/yum.repos.d/kernelcare.repo <<EOL
[kernelcare]
name=kernelcare
baseurl=$repo/${RPM_SUBREPO}/${FORCE_RELEASEVER:-$RPM_RELVER}/\$basearch
enabled=1
gpgcheck=1
gpgkey=$repo/kernelcare/${RPM_KEYRING}

EOL
        if [ -n "${DRY_RUN}" ]; then
            exit 0
        fi

        if [ "$rel" == "5" ]; then
            params=--nogpgcheck
        fi
        yum --disablerepo='*' --enablerepo=kernelcare clean all
        # shellcheck disable=SC2086
        yum -y install "${PACKAGE_NAME}${KCARE_PACKAGE_VERSION:-}" ${params:-}
    ;;
    *)
        echo "Unable to install kernelcare: this linux distribution is not rpm/deb capable." > /dev/stderr
        exit 1
    ;;
esac
