#!/usr/bin/env bash
#
# Copyright (C) 2019 Rise Vision PLC
# Copyright (C) 2017 Lisk Foundation
#
# 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 .
######################################################################
# Make sure that if anything fails the command script stops executing
set -e
DOWNLOAD_BASEURL=${DOWNLOAD_BASEURL:-"https://downloads.rise.vision/core/"}
INSTALL_DIR="./rise"
LOG_FILE=install.out
MINSPACE=`df -k --output=avail "$PWD" | tail -n1`
GC="$(tput setaf 2)√$(tput sgr0)"
RX="$(tput setaf 1)X$(tput sgr0)"
YE="$(tput setaf 3)‼$(tput sgr0)"
if [[ $EUID -eq 0 ]]; then
echo "$RX This script should not be run using sudo or as root. Please run it as a regular user."
exit 1
fi
if [ "$(uname)" != "Linux" ]; then
echo "$RX $(uname) is not an allowed operating system"
exit 1
fi
if [[ $MINSPACE -lt 2621440 ]]; then
echo -e "$RX Not enough free space in $PWD to install the node."
exit 1
fi;
case "$(uname -m)" in
"x86_64") ARCH="x86" ;;
"armv7l") ARCH="arm" ;;
"aarch64") ARCH="arm64" ;;
*)
echo "$RX $(uname -m) is an invalid architecture."
exit 1
;;
esac
# Setup logging
exec > >(tee -ia $LOG_FILE)
exec 2>&1
# export LC_ALL=en_US.UTF-8
# export LANG=en_US.UTF-8
# export LANGUAGE=en_US.UTF-8
check_prerequisites() {
if [[ ! -f /usr/bin/sudo ]]; then
echo "$RX Install sudo as root user before continuing."
echo "Ubuntu Issue: apt-get install sudo"
echo "Redhat/Centos Issue: yum install sudo"
echo "Also make sure that your user has sudo access."
exit 2
fi
if ! sudo -n true 2>/dev/null; then
echo "Please provide sudo password for validation"
if sudo -Sv -p ''; then
echo -e "Sudo authenticated.\t\t\t\t\t$(tput setaf 2)Passed$(tput sgr0)"
else
echo -e "Unable to authenticate Sudo.\t\t\t\t\t$(tput setaf 1)Failed$(tput sgr0)"
exit 2
fi
fi
if [ -f /etc/redhat-release ]; then
packageList="epel-release jq wget curl tar"
for packageName in $packageList; do
rpm --quiet --query $packageName || sudo yum install -q -y $packageName > /dev/null 2>&1
done
fi
if [ -f /etc/lsb-release ]; then
packageList="wget curl tar coreutils"
for packageName in $packageList; do
apt -qq list $packageName 2>&1 >/dev/null| grep install || sudo apt-get --yes install $packageName
done
fi
}
command_check() {
if [ ! -x "$(command -v "$1")" ]; then
echo "$RX $1 executable cannot be found. Please install"
exit 1
fi
}
usage() {
echo "Usage: $0 [-r ] [-n] [-t] [-u ]"
echo "install -- install"
echo "upgrade -- upgrade"
echo " -r -- choose mainnet or testnet"
echo " -u -- release url"
echo " -n -- install ntp"
}
parse_option() {
OPTIND=2
while getopts :d:r:u:hn0: OPT; do
case "$OPT" in
r) NETWORK="$OPTARG" ;;
n) INSTALL_NTP=1 ;;
u) URL="$OPTARG" ;;
esac
done
if [ "$NETWORK" ]; then
if [[ "$NETWORK" != "testnet" && "$NETWORK" != "mainnet" ]]; then
echo "-r "
usage
exit 1
fi
else
if [ -f "${INSTALL_DIR}/etc/.network" ]; then
NETWORK=$(head -1 "${INSTALL_DIR}/etc/.network");
else
NETWORK="mainnet"
fi
fi
if [ "$URL" == "" ]; then
FILE_BASE=$([ "$ARCH" == "arm" ] && echo "latest.arm" || ([ "$ARCH" == "arm64" ] && echo "latest.arm64" || echo "latest.x86_64"))
URL="${DOWNLOAD_BASEURL}${NETWORK}/${FILE_BASE}.tar.gz"
fi
FILE=$(basename "$URL")
}
ntp() {
if [ $(systemd-detect-virt -c) != "none" ]; then
echo "$YE Your host is running in a Docker, LXC or OpenVZ container, and NTP is not compatible."
echo " Your node may lose blocks or stay behind due to wrong clock sync."
elif [[ -f "/etc/debian_version" && ! -f "/proc/user_beancounters" ]]; then
if sudo pgrep -x "ntpd" > /dev/null; then
echo "$GC NTP is running"
else
echo "$RX NTP is not running"
[ "$INSTALL_NTP" ] || read -r -n 1 -p "Would like to install NTP? (y/n): " REPLY
if [[ "$INSTALL_NTP" || "$REPLY" =~ ^[Yy]$ ]]; then
echo -e "\nInstalling NTP.\n"
sudo apt-get install ntp ntpdate -yyq
sudo service ntp stop
sudo ntpdate pool.ntp.org
sudo service ntp start
if sudo pgrep -x "ntpd" > /dev/null; then
echo "$GC NTP is running"
else
echo -e "\nCore requires NTP running on Debian based systems. Please check /etc/ntp.conf and correct any issues."
exit 0
fi
else
echo -e "\nCore requires NTP on Debian based systems, exiting."
exit 0
fi
fi # End Debian Checks
elif [[ -f "/etc/redhat-RELEASE" && ! -f "/proc/user_beancounters" ]]; then
if sudo pgrep -x "ntpd" > /dev/null; then
echo "$GC NTP is running"
else
if sudo pgrep -x "chronyd" > /dev/null; then
echo "$GC Chrony is running"
else
echo "$RX NTP and Chrony are not running"
[ "$INSTALL_NTP" ] || read -r -n 1 -p "Would like to install NTP? (y/n): " REPLY
if [[ "$INSTALL_NTP" || "$REPLY" =~ ^[Yy]$ ]]; then
echo -e "\nInstalling NTP, please provide sudo password.\n"
sudo yum -yq install ntp ntpdate ntp-doc
sudo chkconfig ntpd on
sudo service ntpd stop
sudo ntpdate pool.ntp.org
sudo service ntpd start
if pgrep -x "ntpd" > /dev/null; then
echo "$GC NTP is running"
else
echo -e "\nCore requires NTP running on Debian based systems. Please check /etc/ntp.conf and correct any issues."
exit 0
fi
else
echo -e "\nCore requires NTP or Chrony on RHEL based systems, exiting."
exit 0
fi
fi
fi # End Redhat Checks
elif [[ -f "/proc/user_beancounters" ]]; then
echo "$YE Running OpenVZ VM, NTP and Chrony are not compatible"
fi
}
download() {
if [ -f "$FILE" ]; then
echo "Removing old download file: $FILE"
rm $FILE;
fi
if [ -f "$FILE.sha1" ]; then
echo "Removing old download file: $FILE.sha1"
rm $FILE.sha1;
fi
echo "Downloading core from ${URL}"
wget -q --show-progress --progress=bar:force $URL
wget -q "${URL}.sha1" >> /dev/null
if [ -f "$FILE" ]; then
echo "$GC Core downloaded!"
fi
sha1sum -c ${FILE}.sha1 > /dev/null
if [ ! "$?" -eq 0 ]; then
echo "$RX sha1sum does not match";
exit 1
else
echo "$GC Checksum matches. Proceeding...";
fi
}
install() {
if [ ! -f "$FILE" ]; then
echo "$RX tar.gz does not exist!"
exit 1
fi
if [ ! -d "$INSTALL_DIR" ]; then
mkdir "$INSTALL_DIR"
fi
echo "Extracting core code"
tar -zxf "$FILE" -C "$INSTALL_DIR"
if [ "$?" -eq 0 ]; then
echo "$GC Core code files extracted"
else
echo "$RX Failure when extracting files"
exit 1
fi
}
start_node() {
echo "Starting node."
pushd . > /dev/null
cd ${INSTALL_DIR}
./manager.sh start all > /dev/null
sleep 8
if ! (./manager.sh status | grep -q "NODE is running") ; then
echo "$RX Node is not running :("
exit 1
fi
if ! (./manager.sh status | grep -q "DB is running") ; then
echo "$RX DB is not running :("
exit 1
fi
if ! (./manager.sh status | grep -q "Redis is running") ; then
echo "$RX Redis is not running :("
exit 1
fi
echo "$GC Core and dependencies running"
popd > /dev/null
}
cleanup() {
rm -f ${FILE} ${FILE}.sha1
rm -f $LOG_FILE
rm -f $0
}
case $1 in
"install")
parse_option "$@"
check_prerequisites
ntp
download
install
# set the network file.
if [ ! -f "${INSTALL_DIR}/etc/.network" ]; then
echo $NETWORK > "${INSTALL_DIR}/etc/.network"
fi
start_node
cleanup
echo "Installation completed"
;;
"upgrade")
pushd . > /dev/null
parse_option "$@"
download
cd ${INSTALL_DIR}
./manager.sh stop all
popd > /dev/null
echo "Creating backup"
tar -czf backup.tgz ${INSTALL_DIR} --exclude "${INSTALL_DIR}/data/backups" >> /dev/null 2>&1
echo "$GC Backup created"
if [ -d "${INSTALL_DIR}-old" ]; then
echo "Removing old backup..."
rm -rf ${INSTALL_DIR}-old
fi
mv ${INSTALL_DIR} ${INSTALL_DIR}-old
install
# copy all data
cp -a ${INSTALL_DIR}-old/data/. ${INSTALL_DIR}/data
cp -a ${INSTALL_DIR}-old/etc/. ${INSTALL_DIR}/etc
cp -a ${INSTALL_DIR}-old/.pm2 ${INSTALL_DIR}/
start_node
cleanup
;;
*)
usage
;;
esac