Update install-ruby-rvm.sh
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Recompile Openssl 1.1.1w on RHEL9+ and install Old Rubies
|
||||
# Mateusz Gruszczyński @linuxiarz.pl
|
||||
# Recompile OpenSSL 1.1.1w on RHEL9+ and install old Rubies
|
||||
# Mateusz Gruszczyński @liuxiarz.pl
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
@@ -8,25 +8,111 @@ OPENSSL_VERSION="1.1.1w"
|
||||
OPENSSL_PREFIX="/opt/openssl111"
|
||||
SRC_DIR="/usr/local/src"
|
||||
|
||||
if [ "${EUID}" -ne 0 ]; then
|
||||
echo "ERROR: run this script as root"
|
||||
exit 1
|
||||
fi
|
||||
FORCE_OPENSSL=0
|
||||
WEB_PROXY=""
|
||||
TARGET_RUBY_VERSION=""
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 2.7.X"
|
||||
exit 1
|
||||
fi
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage:
|
||||
$0 --version 2.7.X [--force-openssl] [--webproxy http://proxy:port]
|
||||
|
||||
RUBY_VERSION="$1"
|
||||
Options:
|
||||
--version VER Ruby version to install, e.g. 2.7.8
|
||||
--force-openssl Force rebuild of OpenSSL ${OPENSSL_VERSION}
|
||||
--webproxy URL Proxy URL used for downloads and RVM, e.g. http://proxy.example:8080
|
||||
-h, --help Show this help
|
||||
|
||||
if [[ ! "${RUBY_VERSION}" =~ ^2\.7\.[0-9]+$ ]]; then
|
||||
echo "ERROR: only Ruby 2.7.X is allowed"
|
||||
echo "Example: $0 2.7.8"
|
||||
Examples:
|
||||
$0 --version 2.7.8
|
||||
$0 --version 2.7.8 --force-openssl
|
||||
$0 --version 2.7.8 --webproxy http://proxy.local:8080
|
||||
|
||||
Backward compatibility:
|
||||
$0 2.7.8
|
||||
EOF
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "ERROR: $*" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
log() {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
package_installed() {
|
||||
local pkg="$1"
|
||||
|
||||
rpm -q "${pkg}" >/dev/null 2>&1 && return 0
|
||||
rpm -q --whatprovides "${pkg}" >/dev/null 2>&1 && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
shift
|
||||
[ $# -gt 0 ] || die "--version requires a value"
|
||||
[ -z "${TARGET_RUBY_VERSION}" ] || die "Ruby version already provided: ${TARGET_RUBY_VERSION}"
|
||||
TARGET_RUBY_VERSION="$1"
|
||||
;;
|
||||
--force-openssl)
|
||||
FORCE_OPENSSL=1
|
||||
;;
|
||||
--webproxy)
|
||||
shift
|
||||
[ $# -gt 0 ] || die "--webproxy requires a value"
|
||||
WEB_PROXY="$1"
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
die "unknown option: $1"
|
||||
;;
|
||||
*)
|
||||
[ -z "${TARGET_RUBY_VERSION}" ] || die "Ruby version already provided: ${TARGET_RUBY_VERSION}"
|
||||
TARGET_RUBY_VERSION="$1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ -n "${TARGET_RUBY_VERSION}" ] || die "missing Ruby version, use --version 2.7.X"
|
||||
|
||||
if [[ ! "${TARGET_RUBY_VERSION}" =~ ^2\.7\.[0-9]+$ ]]; then
|
||||
die "only Ruby 2.7.X is allowed, e.g. 2.7.9"
|
||||
fi
|
||||
}
|
||||
|
||||
apply_proxy_env() {
|
||||
if [ -n "${WEB_PROXY}" ]; then
|
||||
export http_proxy="${WEB_PROXY}"
|
||||
export https_proxy="${WEB_PROXY}"
|
||||
export ftp_proxy="${WEB_PROXY}"
|
||||
export all_proxy="${WEB_PROXY}"
|
||||
|
||||
export HTTP_PROXY="${WEB_PROXY}"
|
||||
export HTTPS_PROXY="${WEB_PROXY}"
|
||||
export FTP_PROXY="${WEB_PROXY}"
|
||||
export ALL_PROXY="${WEB_PROXY}"
|
||||
|
||||
log "Using web proxy: ${WEB_PROXY}"
|
||||
fi
|
||||
}
|
||||
|
||||
load_rvm() {
|
||||
export rvm_silence_path_mismatch_check_flag=1
|
||||
|
||||
if [ -s /etc/profile.d/rvm.sh ]; then
|
||||
. /etc/profile.d/rvm.sh
|
||||
elif [ -s /usr/local/rvm/scripts/rvm ]; then
|
||||
@@ -34,27 +120,97 @@ load_rvm() {
|
||||
elif [ -s /root/.rvm/scripts/rvm ]; then
|
||||
. /root/.rvm/scripts/rvm
|
||||
else
|
||||
echo "ERROR: RVM was not found"
|
||||
exit 1
|
||||
die "RVM was not found"
|
||||
fi
|
||||
|
||||
if ! command -v rvm >/dev/null 2>&1; then
|
||||
echo "ERROR: RVM is not available in this shell"
|
||||
exit 1
|
||||
die "RVM is not available in this shell"
|
||||
fi
|
||||
}
|
||||
|
||||
ruby_already_installed() {
|
||||
if command -v ruby >/dev/null 2>&1; then
|
||||
current_ruby_version="$(ruby -e 'print RUBY_VERSION' 2>/dev/null || true)"
|
||||
if [ "${current_ruby_version}" = "${RUBY_VERSION}" ]; then
|
||||
echo "Ruby ${RUBY_VERSION} is already available in PATH"
|
||||
return 0
|
||||
download_file() {
|
||||
local url="$1"
|
||||
local output="$2"
|
||||
|
||||
if command_exists wget; then
|
||||
if [ -n "${WEB_PROXY}" ]; then
|
||||
wget \
|
||||
-e use_proxy=yes \
|
||||
-e "http_proxy=${WEB_PROXY}" \
|
||||
-e "https_proxy=${WEB_PROXY}" \
|
||||
-O "${output}" \
|
||||
"${url}"
|
||||
else
|
||||
wget -O "${output}" "${url}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if rvm list strings | grep -Fxq "ruby-${RUBY_VERSION}"; then
|
||||
echo "Ruby ${RUBY_VERSION} is already installed in RVM"
|
||||
if command_exists curl; then
|
||||
if [ -n "${WEB_PROXY}" ]; then
|
||||
curl --proxy "${WEB_PROXY}" -fL -o "${output}" "${url}"
|
||||
else
|
||||
curl -fL -o "${output}" "${url}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
die "neither wget nor curl is available"
|
||||
}
|
||||
|
||||
openssl_installation_ok() {
|
||||
local openssl_bin="${OPENSSL_PREFIX}/bin/openssl"
|
||||
local version_output
|
||||
|
||||
[ -x "${openssl_bin}" ] || return 1
|
||||
[ -d "${OPENSSL_PREFIX}/include/openssl" ] || return 1
|
||||
[ -f "${OPENSSL_PREFIX}/lib/libssl.so" ] || [ -f "${OPENSSL_PREFIX}/lib64/libssl.so" ] || return 1
|
||||
[ -f "${OPENSSL_PREFIX}/lib/libcrypto.so" ] || [ -f "${OPENSSL_PREFIX}/lib64/libcrypto.so" ] || return 1
|
||||
|
||||
version_output="$(
|
||||
LD_LIBRARY_PATH="${OPENSSL_PREFIX}/lib:${OPENSSL_PREFIX}/lib64:${LD_LIBRARY_PATH:-}" \
|
||||
"${openssl_bin}" version 2>/dev/null || true
|
||||
)"
|
||||
|
||||
[[ "${version_output}" == OpenSSL\ ${OPENSSL_VERSION}* ]]
|
||||
}
|
||||
|
||||
ruby_in_path_ok() {
|
||||
local ruby_version openssl_version
|
||||
|
||||
command_exists ruby || return 1
|
||||
|
||||
ruby_version="$(ruby -e 'print RUBY_VERSION' 2>/dev/null || true)"
|
||||
[ "${ruby_version}" = "${TARGET_RUBY_VERSION}" ] || return 1
|
||||
|
||||
openssl_version="$(ruby -ropenssl -e 'print OpenSSL::OPENSSL_VERSION' 2>/dev/null || true)"
|
||||
[[ "${openssl_version}" == OpenSSL\ ${OPENSSL_VERSION}* ]]
|
||||
}
|
||||
|
||||
ruby_in_rvm_present() {
|
||||
rvm list strings | grep -Fxq "ruby-${TARGET_RUBY_VERSION}"
|
||||
}
|
||||
|
||||
ruby_in_rvm_ok() {
|
||||
local ruby_version openssl_version
|
||||
|
||||
ruby_in_rvm_present || return 1
|
||||
|
||||
ruby_version="$(rvm "ruby-${TARGET_RUBY_VERSION}" do ruby -e 'print RUBY_VERSION' 2>/dev/null || true)"
|
||||
[ "${ruby_version}" = "${TARGET_RUBY_VERSION}" ] || return 1
|
||||
|
||||
openssl_version="$(rvm "ruby-${TARGET_RUBY_VERSION}" do ruby -ropenssl -e 'print OpenSSL::OPENSSL_VERSION' 2>/dev/null || true)"
|
||||
[[ "${openssl_version}" == OpenSSL\ ${OPENSSL_VERSION}* ]]
|
||||
}
|
||||
|
||||
ruby_already_installed() {
|
||||
if ruby_in_rvm_ok; then
|
||||
log "Ruby ${TARGET_RUBY_VERSION} is already installed in RVM and linked with OpenSSL ${OPENSSL_VERSION}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ruby_in_path_ok; then
|
||||
log "Ruby ${TARGET_RUBY_VERSION} is already available in PATH and linked with OpenSSL ${OPENSSL_VERSION}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -62,29 +218,86 @@ ruby_already_installed() {
|
||||
}
|
||||
|
||||
install_build_dependencies() {
|
||||
echo "[1/6] Installing build dependencies"
|
||||
log "[1/6] Checking build dependencies"
|
||||
|
||||
local missing_packages=()
|
||||
local packages=(
|
||||
curl
|
||||
wget
|
||||
tar
|
||||
xz
|
||||
bzip2
|
||||
git
|
||||
perl-core
|
||||
pkgconfig
|
||||
zlib-devel
|
||||
readline-devel
|
||||
libyaml-devel
|
||||
libffi-devel
|
||||
gdbm-devel
|
||||
ncurses-devel
|
||||
gmp-devel
|
||||
autoconf
|
||||
automake
|
||||
libtool
|
||||
bison
|
||||
)
|
||||
|
||||
local pkg
|
||||
for pkg in "${packages[@]}"; do
|
||||
if ! package_installed "${pkg}"; then
|
||||
missing_packages+=("${pkg}")
|
||||
fi
|
||||
done
|
||||
|
||||
local need_devtools=0
|
||||
if ! command_exists gcc || ! command_exists g++ || ! command_exists make; then
|
||||
need_devtools=1
|
||||
fi
|
||||
|
||||
if [ "${need_devtools}" -eq 0 ] && [ "${#missing_packages[@]}" -eq 0 ]; then
|
||||
log "All required build dependencies are already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${need_devtools}" -eq 1 ]; then
|
||||
log "Installing missing group: Development Tools"
|
||||
dnf groupinstall -y "Development Tools"
|
||||
dnf install -y \
|
||||
curl tar xz bzip2 git perl-core pkgconfig \
|
||||
zlib-devel readline-devel libyaml-devel libffi-devel \
|
||||
gdbm-devel ncurses-devel gmp-devel autoconf automake libtool bison
|
||||
fi
|
||||
|
||||
if [ "${#missing_packages[@]}" -gt 0 ]; then
|
||||
log "Installing missing packages: ${missing_packages[*]}"
|
||||
dnf install -y "${missing_packages[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
install_openssl() {
|
||||
echo "[2/6] Preparing OpenSSL ${OPENSSL_VERSION}"
|
||||
local tarball="openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
local srcdir="openssl-${OPENSSL_VERSION}"
|
||||
local url="https://www.openssl.org/source/old/1.1.1/${tarball}"
|
||||
|
||||
if [ "${FORCE_OPENSSL}" -eq 0 ] && openssl_installation_ok; then
|
||||
log "[2/6] OpenSSL ${OPENSSL_VERSION} already exists and works in ${OPENSSL_PREFIX}, skipping"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "[2/6] Preparing OpenSSL ${OPENSSL_VERSION}"
|
||||
mkdir -p "${SRC_DIR}"
|
||||
mkdir -p "${OPENSSL_PREFIX}"
|
||||
cd "${SRC_DIR}"
|
||||
|
||||
if [ ! -f "openssl-${OPENSSL_VERSION}.tar.gz" ]; then
|
||||
curl -fLO "https://www.openssl.org/source/old/1.1.1/openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
if [ ! -f "${tarball}" ] || [ "${FORCE_OPENSSL}" -eq 1 ]; then
|
||||
rm -f "${tarball}"
|
||||
download_file "${url}" "${tarball}"
|
||||
else
|
||||
log "Using existing source archive: ${SRC_DIR}/${tarball}"
|
||||
fi
|
||||
|
||||
rm -rf "openssl-${OPENSSL_VERSION}"
|
||||
tar xf "openssl-${OPENSSL_VERSION}.tar.gz"
|
||||
cd "openssl-${OPENSSL_VERSION}"
|
||||
rm -rf "${srcdir}"
|
||||
tar xf "${tarball}"
|
||||
cd "${srcdir}"
|
||||
|
||||
echo "[3/6] Building OpenSSL into ${OPENSSL_PREFIX}"
|
||||
log "[3/6] Building OpenSSL into ${OPENSSL_PREFIX}"
|
||||
./config \
|
||||
--prefix="${OPENSSL_PREFIX}" \
|
||||
--openssldir="${OPENSSL_PREFIX}" \
|
||||
@@ -93,41 +306,80 @@ install_openssl() {
|
||||
make -j"$(nproc)"
|
||||
rm -rf "${OPENSSL_PREFIX:?}/"*
|
||||
make install_sw
|
||||
|
||||
openssl_installation_ok || die "OpenSSL ${OPENSSL_VERSION} verification failed after build"
|
||||
}
|
||||
|
||||
install_ruby_with_rvm() {
|
||||
echo "[4/6] Configuring RVM build environment"
|
||||
local -a rvm_args
|
||||
local action="install"
|
||||
|
||||
log "[4/6] Configuring RVM build environment"
|
||||
rvm autolibs disable
|
||||
|
||||
export CPPFLAGS="-I${OPENSSL_PREFIX}/include"
|
||||
export CFLAGS="-I${OPENSSL_PREFIX}/include"
|
||||
export LDFLAGS="-L${OPENSSL_PREFIX}/lib -Wl,-rpath,${OPENSSL_PREFIX}/lib"
|
||||
export PKG_CONFIG_PATH="${OPENSSL_PREFIX}/lib/pkgconfig"
|
||||
export LDFLAGS="-L${OPENSSL_PREFIX}/lib -L${OPENSSL_PREFIX}/lib64 -Wl,-rpath,${OPENSSL_PREFIX}/lib -Wl,-rpath,${OPENSSL_PREFIX}/lib64"
|
||||
export PKG_CONFIG_PATH="${OPENSSL_PREFIX}/lib/pkgconfig:${OPENSSL_PREFIX}/lib64/pkgconfig"
|
||||
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=${OPENSSL_PREFIX}"
|
||||
|
||||
echo "[5/6] Installing Ruby ${RUBY_VERSION} with RVM"
|
||||
rvm install "${RUBY_VERSION}" --with-openssl-dir="${OPENSSL_PREFIX}"
|
||||
if ruby_in_rvm_present; then
|
||||
action="reinstall"
|
||||
fi
|
||||
|
||||
rvm_args=("${action}" "${TARGET_RUBY_VERSION}" "--with-openssl-dir=${OPENSSL_PREFIX}")
|
||||
|
||||
if [ -n "${WEB_PROXY}" ]; then
|
||||
rvm_args+=("--proxy" "${WEB_PROXY}")
|
||||
fi
|
||||
|
||||
log "[5/6] ${action^}ing Ruby ${TARGET_RUBY_VERSION} with RVM"
|
||||
rvm "${rvm_args[@]}"
|
||||
}
|
||||
|
||||
verify_installation() {
|
||||
echo "[6/6] Verifying installation"
|
||||
rvm use "${RUBY_VERSION}" >/dev/null
|
||||
log "[6/6] Verifying installation"
|
||||
|
||||
local installed_ruby_version installed_openssl_version
|
||||
|
||||
if ruby_in_rvm_ok; then
|
||||
installed_ruby_version="$(rvm "ruby-${TARGET_RUBY_VERSION}" do ruby -e 'print RUBY_VERSION')"
|
||||
installed_openssl_version="$(rvm "ruby-${TARGET_RUBY_VERSION}" do ruby -ropenssl -e 'print OpenSSL::OPENSSL_VERSION')"
|
||||
elif ruby_in_path_ok; then
|
||||
installed_ruby_version="$(ruby -e 'print RUBY_VERSION')"
|
||||
installed_openssl_version="$(ruby -ropenssl -e 'print OpenSSL::OPENSSL_VERSION')"
|
||||
else
|
||||
die "Ruby ${TARGET_RUBY_VERSION} verification failed"
|
||||
fi
|
||||
|
||||
echo "Installed Ruby version: ${installed_ruby_version}"
|
||||
echo "Linked OpenSSL version: ${installed_openssl_version}"
|
||||
log "Installed Ruby version: ${installed_ruby_version}"
|
||||
log "Linked OpenSSL version: ${installed_openssl_version}"
|
||||
}
|
||||
|
||||
load_rvm
|
||||
main() {
|
||||
[ "${EUID}" -eq 0 ] || die "run this script as root"
|
||||
|
||||
if ruby_already_installed; then
|
||||
echo "Nothing to do"
|
||||
parse_args "$@"
|
||||
log "Requested Ruby version: ${TARGET_RUBY_VERSION}"
|
||||
apply_proxy_env
|
||||
load_rvm
|
||||
|
||||
if ruby_already_installed; then
|
||||
log "Nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
install_build_dependencies
|
||||
install_openssl
|
||||
install_ruby_with_rvm
|
||||
verify_installation
|
||||
install_build_dependencies
|
||||
install_openssl
|
||||
|
||||
if ruby_already_installed; then
|
||||
log "Ruby is already installed after OpenSSL verification/build, skipping RVM build"
|
||||
verify_installation
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install_ruby_with_rvm
|
||||
verify_installation
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user