mirror of
https://github.com/planetmint/planetmint.git
synced 2025-03-30 15:08:31 +00:00
360 lines
11 KiB
Bash
Executable File
360 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Save trace setting
|
|
_XTRACE_FUNCTIONS_COMMON=$(set +o | grep xtrace)
|
|
set +o xtrace
|
|
|
|
# Distro Functions
|
|
# ================
|
|
|
|
# Determine OS Vendor, Release and Update
|
|
|
|
#
|
|
# NOTE : For portability, you almost certainly do not want to use
|
|
# these variables directly! The "is_*" functions defined below this
|
|
# bundle up compatible platforms under larger umbrellas that we have
|
|
# determinted are compatible enough (e.g. is_ubuntu covers Ubuntu &
|
|
# Debian, is_fedora covers RPM-based distros). Higher-level functions
|
|
# such as "install_package" further abstract things in better ways.
|
|
#
|
|
# ``os_VENDOR`` - vendor name: ``Ubuntu``, ``Fedora``, etc
|
|
# ``os_RELEASE`` - major release: ``16.04`` (Ubuntu), ``23`` (Fedora)
|
|
# ``os_PACKAGE`` - package type: ``deb`` or ``rpm``
|
|
# ``os_CODENAME`` - vendor's codename for release: ``xenial``
|
|
|
|
#declare -g os_VENDOR os_RELEASE os_PACKAGE os_CODENAME
|
|
|
|
# Make a *best effort* attempt to install lsb_release packages for the
|
|
# user if not available. Note can't use generic install_package*
|
|
# because they depend on this!
|
|
function _ensure_lsb_release {
|
|
if [[ -x $(command -v lsb_release 2>/dev/null) ]]; then
|
|
return
|
|
fi
|
|
|
|
if [[ -x $(command -v apt-get 2>/dev/null) ]]; then
|
|
sudo apt-get install -y lsb-release
|
|
elif [[ -x $(command -v zypper 2>/dev/null) ]]; then
|
|
sudo zypper -n install lsb-release
|
|
elif [[ -x $(command -v dnf 2>/dev/null) ]]; then
|
|
sudo dnf install -y redhat-lsb-core
|
|
elif [[ -x $(command -v yum 2>/dev/null) ]]; then
|
|
# all rh patforms (fedora, centos, rhel) have this pkg
|
|
sudo yum install -y redhat-lsb-core
|
|
else
|
|
die $LINENO "Unable to find or auto-install lsb_release"
|
|
fi
|
|
}
|
|
|
|
# GetOSVersion
|
|
# Set the following variables:
|
|
# - os_RELEASE
|
|
# - os_CODENAME
|
|
# - os_VENDOR
|
|
# - os_PACKAGE
|
|
function GetOSVersion {
|
|
# We only support distros that provide a sane lsb_release
|
|
_ensure_lsb_release
|
|
|
|
os_RELEASE=$(lsb_release -r -s)
|
|
os_CODENAME=$(lsb_release -c -s)
|
|
os_VENDOR=$(lsb_release -i -s)
|
|
|
|
if [[ $os_VENDOR =~ (Debian|Ubuntu|LinuxMint) ]]; then
|
|
os_PACKAGE="deb"
|
|
else
|
|
os_PACKAGE="rpm"
|
|
fi
|
|
|
|
typeset -xr os_VENDOR
|
|
typeset -xr os_RELEASE
|
|
typeset -xr os_PACKAGE
|
|
typeset -xr os_CODENAME
|
|
}
|
|
|
|
# Translate the OS version values into common nomenclature
|
|
# Sets global ``DISTRO`` from the ``os_*`` values
|
|
#declare -g DISTRO
|
|
|
|
function GetDistro {
|
|
GetOSVersion
|
|
if [[ "$os_VENDOR" =~ (Ubuntu) || "$os_VENDOR" =~ (Debian) || \
|
|
"$os_VENDOR" =~ (LinuxMint) ]]; then
|
|
# 'Everyone' refers to Ubuntu / Debian / Mint releases by
|
|
# the code name adjective
|
|
DISTRO=$os_CODENAME
|
|
elif [[ "$os_VENDOR" =~ (Fedora) ]]; then
|
|
# For Fedora, just use 'f' and the release
|
|
DISTRO="f$os_RELEASE"
|
|
elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then
|
|
DISTRO="opensuse-$os_RELEASE"
|
|
elif [[ "$os_VENDOR" =~ (SUSE LINUX) ]]; then
|
|
# just use major release
|
|
DISTRO="sle${os_RELEASE%.*}"
|
|
elif [[ "$os_VENDOR" =~ (Red.*Hat) || \
|
|
"$os_VENDOR" =~ (CentOS) || \
|
|
"$os_VENDOR" =~ (Scientific) || \
|
|
"$os_VENDOR" =~ (OracleServer) || \
|
|
"$os_VENDOR" =~ (Virtuozzo) ]]; then
|
|
# Drop the . release as we assume it's compatible
|
|
# XXX re-evaluate when we get RHEL10
|
|
DISTRO="rhel${os_RELEASE::1}"
|
|
elif [[ "$os_VENDOR" =~ (XenServer) ]]; then
|
|
DISTRO="xs${os_RELEASE%.*}"
|
|
elif [[ "$os_VENDOR" =~ (kvmibm) ]]; then
|
|
DISTRO="${os_VENDOR}${os_RELEASE::1}"
|
|
else
|
|
die $LINENO "Unable to determine DISTRO, can not continue."
|
|
fi
|
|
typeset -xr DISTRO
|
|
}
|
|
|
|
# Utility function for checking machine architecture
|
|
# is_arch arch-type
|
|
function is_arch {
|
|
[[ "$(uname -m)" == "$1" ]]
|
|
}
|
|
|
|
|
|
# Determine if current distribution is a Fedora-based distribution
|
|
# (Fedora, RHEL, CentOS, etc).
|
|
# is_fedora
|
|
function is_fedora {
|
|
if [[ -z "$os_VENDOR" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
[ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || \
|
|
[ "$os_VENDOR" = "RedHatEnterpriseServer" ] || \
|
|
[ "$os_VENDOR" = "CentOS" ]
|
|
}
|
|
|
|
|
|
# Determine if current distribution is a SUSE-based distribution
|
|
# (openSUSE, SLE).
|
|
# is_suse
|
|
function is_suse {
|
|
if [[ -z "$os_VENDOR" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
[[ "$os_VENDOR" =~ (openSUSE) || "$os_VENDOR" == "SUSE LINUX" ]]
|
|
}
|
|
|
|
|
|
# Determine if current distribution is an Ubuntu-based distribution
|
|
# It will also detect non-Ubuntu but Debian-based distros
|
|
# is_ubuntu
|
|
function is_ubuntu {
|
|
if [[ -z "$os_PACKAGE" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
[ "$os_PACKAGE" = "deb" ]
|
|
}
|
|
|
|
# Package Functions
|
|
# =================
|
|
|
|
# Wrapper for ``apt-get update`` to try multiple times on the update
|
|
# to address bad package mirrors (which happen all the time).
|
|
function apt_get_update {
|
|
# only do this once per run
|
|
if [[ "$REPOS_UPDATED" == "True" && "$RETRY_UPDATE" != "True" ]]; then
|
|
return
|
|
fi
|
|
|
|
# bail if we are offline
|
|
[[ "$OFFLINE" = "True" ]] && return
|
|
|
|
local sudo="sudo"
|
|
[[ "$(id -u)" = "0" ]] && sudo="env"
|
|
|
|
# time all the apt operations
|
|
time_start "apt-get-update"
|
|
|
|
local proxies="http_proxy=${http_proxy:-} https_proxy=${https_proxy:-} no_proxy=${no_proxy:-} "
|
|
local update_cmd="$sudo $proxies apt-get update"
|
|
if ! timeout 300 sh -c "while ! $update_cmd; do sleep 30; done"; then
|
|
die $LINENO "Failed to update apt repos, we're dead now"
|
|
fi
|
|
|
|
REPOS_UPDATED=True
|
|
# stop the clock
|
|
time_stop "apt-get-update"
|
|
}
|
|
|
|
# Wrapper for ``apt-get`` to set cache and proxy environment variables
|
|
# Uses globals ``OFFLINE``, ``*_proxy``
|
|
# apt_get operation package [package ...]
|
|
function apt_get {
|
|
local xtrace result
|
|
xtrace=$(set +o | grep xtrace)
|
|
set +o xtrace
|
|
|
|
[[ "$OFFLINE" = "True" || -z "$@" ]] && return
|
|
local sudo="sudo"
|
|
[[ "$(id -u)" = "0" ]] && sudo="env"
|
|
|
|
# time all the apt operations
|
|
time_start "apt-get"
|
|
|
|
$xtrace
|
|
|
|
$sudo DEBIAN_FRONTEND=noninteractive \
|
|
http_proxy=${http_proxy:-} https_proxy=${https_proxy:-} \
|
|
no_proxy=${no_proxy:-} \
|
|
apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" < /dev/null
|
|
result=$?
|
|
|
|
# stop the clock
|
|
time_stop "apt-get"
|
|
return $result
|
|
}
|
|
|
|
|
|
# Distro-agnostic package installer
|
|
# Uses globals ``NO_UPDATE_REPOS``, ``REPOS_UPDATED``, ``RETRY_UPDATE``
|
|
# install_package package [package ...]
|
|
function update_package_repo {
|
|
NO_UPDATE_REPOS=${NO_UPDATE_REPOS:-False}
|
|
REPOS_UPDATED=${REPOS_UPDATED:-False}
|
|
RETRY_UPDATE=${RETRY_UPDATE:-False}
|
|
|
|
if [[ "$NO_UPDATE_REPOS" = "True" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
if is_ubuntu; then
|
|
apt_get_update
|
|
fi
|
|
}
|
|
|
|
function real_install_package {
|
|
if is_ubuntu; then
|
|
apt_get install "$@"
|
|
elif is_fedora; then
|
|
yum_install "$@"
|
|
elif is_suse; then
|
|
zypper_install "$@"
|
|
else
|
|
exit_distro_not_supported "installing packages"
|
|
fi
|
|
}
|
|
|
|
# Distro-agnostic package installer
|
|
# install_package package [package ...]
|
|
function install_package {
|
|
update_package_repo
|
|
if ! real_install_package "$@"; then
|
|
RETRY_UPDATE=True update_package_repo && real_install_package "$@"
|
|
fi
|
|
}
|
|
|
|
# Distro-agnostic function to tell if a package is installed
|
|
# is_package_installed package [package ...]
|
|
function is_package_installed {
|
|
if [[ -z "$@" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$os_PACKAGE" ]]; then
|
|
GetOSVersion
|
|
fi
|
|
|
|
if [[ "$os_PACKAGE" = "deb" ]]; then
|
|
dpkg -s "$@" > /dev/null 2> /dev/null
|
|
elif [[ "$os_PACKAGE" = "rpm" ]]; then
|
|
rpm --quiet -q "$@"
|
|
else
|
|
exit_distro_not_supported "finding if a package is installed"
|
|
fi
|
|
}
|
|
|
|
# Distro-agnostic package uninstaller
|
|
# uninstall_package package [package ...]
|
|
function uninstall_package {
|
|
if is_ubuntu; then
|
|
apt_get purge "$@"
|
|
elif is_fedora; then
|
|
sudo ${YUM:-yum} remove -y "$@" ||:
|
|
elif is_suse; then
|
|
sudo zypper remove -y "$@" ||:
|
|
else
|
|
exit_distro_not_supported "uninstalling packages"
|
|
fi
|
|
}
|
|
|
|
# Wrapper for ``yum`` to set proxy environment variables
|
|
# Uses globals ``OFFLINE``, ``*_proxy``, ``YUM``
|
|
# yum_install package [package ...]
|
|
function yum_install {
|
|
local result parse_yum_result
|
|
time_start "yum_install"
|
|
|
|
# This is a bit tricky, because yum -y assumes missing or failed
|
|
# packages are OK (see [1]). We want devstack to stop if we are
|
|
# installing missing packages.
|
|
#
|
|
# Thus we manually match on the output (stack.sh runs in a fixed
|
|
# locale, so lang shouldn't change).
|
|
#
|
|
# If yum returns !0, we echo the result as "YUM_FAILED" and return
|
|
# that from the awk (we're subverting -e with this trick).
|
|
# Otherwise we use awk to look for failure strings and return "2"
|
|
# to indicate a terminal failure.
|
|
#
|
|
# [1] https://bugzilla.redhat.com/show_bug.cgi?id=965567
|
|
parse_yum_result=' \
|
|
BEGIN { result=0 } \
|
|
/^YUM_FAILED/ { result=$2 } \
|
|
/^No package/ { result=2 } \
|
|
/^Failed:/ { result=2 } \
|
|
//{ print } \
|
|
END { exit result }'
|
|
(sudo_with_proxies "${YUM:-yum}" install -y "$@" 2>&1 || echo YUM_FAILED $?) \
|
|
| awk "$parse_yum_result" && result=$? || result=$?
|
|
|
|
time_stop "yum_install"
|
|
|
|
# if we return 1, then the wrapper functions will run an update
|
|
# and try installing the package again as a defense against bad
|
|
# mirrors. This can hide failures, especially when we have
|
|
# packages that are in the "Failed:" section because their rpm
|
|
# install scripts failed to run correctly (in this case, the
|
|
# package looks installed, so when the retry happens we just think
|
|
# the package is OK, and incorrectly continue on).
|
|
if [ "$result" == 2 ]; then
|
|
die "Detected fatal package install failure"
|
|
fi
|
|
|
|
return "$result"
|
|
}
|
|
|
|
# zypper wrapper to set arguments correctly
|
|
# Uses globals ``OFFLINE``, ``*_proxy``
|
|
# zypper_install package [package ...]
|
|
function zypper_install {
|
|
local sudo="sudo"
|
|
[[ "$(id -u)" = "0" ]] && sudo="env"
|
|
$sudo http_proxy="${http_proxy:-}" https_proxy="${https_proxy:-}" \
|
|
no_proxy="${no_proxy:-}" \
|
|
zypper --non-interactive install --auto-agree-with-licenses "$@"
|
|
}
|
|
|
|
function install_tendermint_bin {
|
|
wget https://s3-us-west-2.amazonaws.com/tendermint/binaries/tendermint/v${TM_VERSION}/tendermint_${TM_VERSION}_linux_amd64.zip
|
|
unzip tendermint_${TM_VERSION}_linux_amd64.zip
|
|
sudo mv tendermint /usr/local/bin
|
|
}
|
|
|
|
# Find out if a process exists by partial name.
|
|
# is_running name
|
|
function is_running {
|
|
local name=$1
|
|
ps auxw | grep -v grep | grep ${name} > /dev/null
|
|
local exitcode=$?
|
|
return $exitcode
|
|
}
|
|
|
|
# Restore xtrace
|
|
$_XTRACE_FUNCTIONS_COMMON |