#!/bin/bash # Evernode host setup tool to manage Sashimono installation and host registration. # This script is also used as the 'evernode' cli alias after the installation. # usage: ./setup.sh install # surrounding braces are needed make the whole script to be buffered on client before execution. { evernode="Evernode Beta v2" maxmind_creds="687058:FtcQjM0emHFMEfgI" cgrulesengd_default="cgrulesengd" alloc_ratio=80 ramKB_per_instance=524288 instances_per_core=3 evernode_alias=/usr/bin/evernode log_dir=/tmp/evernode-beta cloud_storage="https://stevernode.blob.core.windows.net/evernode-beta" setup_script_url="$cloud_storage/setup.sh" installer_url="$cloud_storage/installer.tar.gz" licence_url="$cloud_storage/licence.txt" nodejs_url="$cloud_storage/node" jshelper_url="$cloud_storage/setup-jshelper.tar.gz" installer_version_timestamp_file="installer.version.timestamp" setup_version_timestamp_file="setup.version.timestamp" default_rippled_server="wss://hooks-testnet-v2.xrpl-labs.com" setup_helper_dir="/tmp/evernode-setup-helpers" nodejs_temp_bin="$setup_helper_dir/node" jshelper_temp_bin="$setup_helper_dir/jshelper/index.js" # export vars used by Sashimono installer. export USER_BIN=/usr/bin export SASHIMONO_BIN=/usr/bin/sashimono export MB_XRPL_BIN=$SASHIMONO_BIN/mb-xrpl export DOCKER_BIN=$SASHIMONO_BIN/dockerbin export SASHIMONO_DATA=/etc/sashimono export MB_XRPL_DATA=$SASHIMONO_DATA/mb-xrpl export SASHIMONO_SERVICE="sashimono-agent" export CGCREATE_SERVICE="sashimono-cgcreate" export MB_XRPL_SERVICE="sashimono-mb-xrpl" export SASHIADMIN_GROUP="sashiadmin" export SASHIUSER_GROUP="sashiuser" export SASHIUSER_PREFIX="sashi" export MB_XRPL_USER="sashimbxrpl" export CG_SUFFIX="-cg" export EVERNODE_REGISTRY_ADDRESS="r3cNR2bdao1NyvQ5ZuQvCUgqkoWGmgF34E" export EVERNODE_AUTO_UPDATE_SERVICE="evernode-auto-update" export MIN_EVR_BALANCE=5120 # Private docker registry (not used for now) export DOCKER_REGISTRY_USER="sashidockerreg" export DOCKER_REGISTRY_PORT=0 # We execute some commands as unprivileged user for better security. # (we execute as the user who launched this script as sudo) noroot_user=${SUDO_USER:-$(whoami)} # Helper to print multi line text. # (When passed as a parameter, bash auto strips spaces and indentation which is what we want) function echomult() { echo -e $1 } function confirm() { echo -en $1" [Y/n] " local yn="" read yn /dev/null; then version=$(node -v | cut -d '.' -f1) version=${version:1} if [[ $version -lt 16 ]]; then echo "$evernode requires NodeJs 16.x or later. You system has NodeJs $version installed. Either remove the NodeJs installation or upgrade to NodeJs 16.x." exit 1 fi fi } function check_sys_req() { # Assign sys resource info to global vars since these will also be used for instance allocation later. ramKB=$(free | grep Mem | awk '{print $2}') swapKB=$(free | grep Swap | awk '{print $2}') diskKB=$(df | grep -w /home | head -1 | awk '{print $4}') [ -z "$diskKB" ] && diskKB=$(df | grep -w / | head -1 | awk '{print $4}') [ "$SKIP_SYSREQ" == "1" ] && echo "System requirements check skipped." && return 0 local proc1=$(ps --no-headers -o comm 1) if [ "$proc1" != "systemd" ]; then echo "$evernode host installation requires systemd. Your system does not have systemd running. Aborting." exit 1 fi local os=$(grep -ioP '^ID=\K.+' /etc/os-release) local osversion=$(grep -ioP '^VERSION_ID=\K.+' /etc/os-release) local errors="" ([ "$os" != "ubuntu" ] || [ "$osversion" != '"20.04"' ]) && errs=" OS: $os $osversion (required: Ubuntu 20.04)\n" [ $ramKB -lt 2000000 ] && errors="$errors RAM: $(GB $ramKB) (required: 2 GB RAM)\n" [ $swapKB -lt 2000000 ] && errors="$errors Swap: $(GB $swapKB) (required: 2 GB Swap)\n" [ $diskKB -lt 4000000 ] && errors="$errors Disk space (/home): $(GB $diskKB) (required: 4 GB)\n" if [ -z "$errors" ]; then echo "System check complete. Your system is capable of becoming an $evernode host." else echomult "Your system does not meet following $evernode system requirements:\n $errors" echomult "$evernode host registration requires Ubuntu 20.04 with minimum 2 GB RAM, 2 GB Swap and 4 GB free disk space for /home. Aborting setup." exit 1 fi } function init_setup_helpers() { echo "Downloading setup support files..." local jshelper_dir=$(dirname $jshelper_temp_bin) rm -r $jshelper_dir >/dev/null 2>&1 sudo -u $noroot_user mkdir -p $jshelper_dir [ ! -f "$nodejs_temp_bin" ] && sudo -u $noroot_user curl $nodejs_url --output $nodejs_temp_bin [ ! -f "$nodejs_temp_bin" ] && echo "Could not download nodejs for setup checks." && exit 1 chmod +x $nodejs_temp_bin if [ ! -f "$jshelper_temp_bin" ]; then pushd $jshelper_dir >/dev/null 2>&1 sudo -u $noroot_user curl $jshelper_url --output jshelper.tar.gz sudo -u $noroot_user tar zxf jshelper.tar.gz --strip-components=1 rm jshelper.tar.gz popd >/dev/null 2>&1 fi [ ! -f "$jshelper_temp_bin" ] && echo "Could not download helper tool for setup checks." && exit 1 echo -e "Done.\n" } function exec_jshelper() { # Create fifo file to read response data from the helper script. local resp_file=$setup_helper_dir/helper_fifo [ -p $resp_file ] || sudo -u $noroot_user mkfifo $resp_file # Execute js helper asynchronously while collecting response to fifo file. sudo -u $noroot_user RESPFILE=$resp_file $nodejs_temp_bin $jshelper_temp_bin "$@" >/dev/null 2>&1 & local pid=$! local result=$(cat $resp_file) && [ "$result" != "-" ] && echo $result # Wait for js helper to exit and reflect the error exit code in this function return. wait $pid && [ $? -eq 0 ] && rm $resp_file && return 0 rm $resp_file && return 1 } function resolve_filepath() { # name reference the variable name provided as first argument. local -n filepath=$1 local option=$2 local prompt="${*:3} " while [ -z "$filepath" ]; do read -p "$prompt" filepath /dev/null 2>&1 && return 0 inetaddr="" && return 1 } function validate_inet_addr() { # inert address cannot be empty and cannot contain spaces. [ -z "$inetaddr" ] || [[ $inetaddr = *" "* ]] && inetaddr="" && return 1 # Attempt to resolve ip (in case inetaddr is a DNS address) # This will resolve correctly if inetaddr is a valid ip or dns address. local resolved=$(getent hosts $inetaddr | head -1 | awk '{ print $1 }') # If invalid, reset inetaddr and return with non-zero code. [ -z "$resolved" ] && inetaddr="" && return 1 return 0 } function validate_positive_decimal() { ! [[ $1 =~ ^(0*[1-9][0-9]*(\.[0-9]+)?|0+\.[0-9]*[1-9][0-9]*)$ ]] && return 1 return 0 } function validate_rippled_url() { ! [[ $1 =~ ^(wss?:\/\/)([^\/|^:|^ ]{3,})(:([0-9]{1,5}))?$ ]] && echo "Rippled URL must be a valid URL that starts with 'wss://'" && return 1 echo "Checking server $1..." ! exec_jshelper validate-server $1 && echo "Could not communicate with the rippled server." && return 1 return 0 } function set_inet_addr() { if $interactive && [ "$NO_DOMAIN" == "" ] ; then echo "" while [ -z "$inetaddr" ]; do read -p "Please specify the domain name that this host is reachable at: " inetaddr &1 \ | tee -a $logfile | stdbuf --output=L grep "STAGE" | cut -d ' ' -f 2- && install_failure fi # Create evernode cli alias at the begining. # So, if the installation attempt failed user can uninstall the failed installation using evernode commands. ! create_evernode_alias && install_failure # Adding ip address as the host description. # Currently the domain address saved only in account_info and an empty value in Hook states ) description="" echo "Installing Sashimono on Evernode Beta V2 (Disabled Network)..." # Filter logs with STAGE prefix and ommit the prefix when echoing. # If STAGE log contains -p arg, move the cursor to previous log line and overwrite the log. ! UPGRADE=$upgrade ./sashimono-install.sh $inetaddr $init_peer_port $init_user_port $countrycode $alloc_instcount \ $alloc_cpu $alloc_ramKB $alloc_swapKB $alloc_diskKB $lease_amount $rippled_server $xrpl_account_address $xrpl_account_secret $email_address $tls_key_file $tls_cert_file $tls_cabundle_file $description 2>&1 \ | tee -a $logfile | stdbuf --output=L grep "STAGE\|ERROR" \ | while read line ; do [[ $line =~ ^STAGE[[:space:]]-p(.*)$ ]] && echo -e \\e[1A\\e[K"${line:9}" || echo ${line:6} ; done \ && remove_evernode_alias && install_failure set +o pipefail rm -r $tmp # Write the verison timestamp to a file for later updated version comparison. echo $installer_version_timestamp > $SASHIMONO_DATA/$installer_version_timestamp_file echo $setup_version_timestamp > $SASHIMONO_DATA/$setup_version_timestamp_file } function uninstall_evernode() { local upgrade=$1 # Check for existing contract instances. local users=$(cut -d: -f1 /etc/passwd | grep "^$SASHIUSER_PREFIX" | sort) readarray -t userarr <<<"$users" local sashiusers=() for user in "${userarr[@]}"; do [ ${#user} -lt 24 ] || [ ${#user} -gt 32 ] || [[ ! "$user" =~ ^$SASHIUSER_PREFIX[0-9]+$ ]] && continue sashiusers+=("$user") done local ucount=${#sashiusers[@]} if [ "$upgrade" == "0" ] ; then $interactive && [ $ucount -gt 0 ] && ! confirm "This will delete $ucount contract instances. \n\nDo you still want to continue?" && exit 1 ! $interactive && echo "$ucount contract instances will be deleted." fi if ! $transfer ; then [ "$upgrade" == "0" ] && echo "Uninstalling..." || echo "Uninstalling for upgrade..." ! UPGRADE=$upgrade TRANSFER=0 $SASHIMONO_BIN/sashimono-uninstall.sh $2 && uninstall_failure else echo "Intiating Transfer..." echo "Uninstalling for transfer..." ! UPGRADE=$upgrade TRANSFER=1 $SASHIMONO_BIN/sashimono-uninstall.sh $2 && uninstall_failure fi # Remove the evernode alias at the end. # So, if the uninstallation failed user can try uninstall again with evernode commands. remove_evernode_alias } function update_evernode() { echo "Checking for updates..." local latest_installer_script_version=$(online_version_timestamp $installer_url) local latest_setup_script_version=$(online_version_timestamp $setup_script_url) [ -z "$latest_installer_script_version" ] && echo "Could not check for updates. Online installer not found." && exit 1 local current_installer_script_version=$(cat $SASHIMONO_DATA/$installer_version_timestamp_file) local current_setup_script_version=$(cat $SASHIMONO_DATA/$setup_version_timestamp_file) [ "$latest_installer_script_version" == "$current_installer_script_version" ] && [ "$latest_setup_script_version" == "$current_setup_script_version" ] && echo "Your $evernode installation is up to date." && exit 0 echo "New $evernode update available. Setup will re-install $evernode with updated software. Your account and contract instances will be preserved." $interactive && ! confirm "\nDo you want to install the update?" && exit 1 echo "Starting upgrade..." # Alias for setup.sh is created during 'install_evernode' too. # If only the setup.sh is updated but not the installer, then the alias should be created again. if [ "$latest_installer_script_version" != "$current_installer_script_version" ] ; then uninstall_evernode 1 install_evernode 1 elif [ "$latest_setup_script_version" != "$current_setup_script_version" ] ; then [ -d $log_dir ] || mkdir -p $log_dir logfile="$log_dir/installer-$(date +%s).log" remove_evernode_alias ! create_evernode_alias && echo "Alias creation failed." echo $latest_setup_script_version > $SASHIMONO_DATA/$setup_version_timestamp_file fi echo "Upgrade complete." } function init_evernode_transfer() { if ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN transfer $transferee_address && [ "$force" != "-f" ] && [ -f $mb_service_path ]; then echo "Evernode transfer initiation was failed. Try again later." && exit 1 fi } function create_log() { tempfile=$(mktemp /tmp/evernode.XXXXXXXXX.log) { echo "System:" uname -r lsb_release -a echo "" echo "sa.cfg:" cat "$SASHIMONO_DATA/sa.cfg" echo "" echo "mb-xrpl.cfg:" cat "$MB_XRPL_DATA/mb-xrpl.cfg" echo "" echo "Sashimono log:" journalctl -u sashimono-agent.service | tail -n 200 echo "" echo "Message board log:" sudo -u sashimbxrpl bash -c journalctl --user -u sashimono-mb-xrpl | tail -n 200 echo "" echo "Auto updater service log:" journalctl -u evernode-auto-update | tail -n 200 } > "$tempfile" 2>&1 echo "Evernode log saved to $tempfile" } # Create a copy of this same script as a command. function create_evernode_alias() { ! curl -fsSL $setup_script_url --output $evernode_alias >> $logfile 2>&1 && echo "Error in creating alias." && return 1 ! chmod +x $evernode_alias >> $logfile 2>&1 && echo "Error in changing permission for the alias." && return 1 return 0 } function remove_evernode_alias() { rm $evernode_alias } function check_installer_pending_finish() { if [ -f /run/reboot-required.pkgs ] && [ -n "$(grep sashimono /run/reboot-required.pkgs)" ]; then echo "Your system needs to be rebooted in order to complete Sashimono installation." $interactive && confirm "Reboot now?" && reboot ! $interactive && echo "Rebooting..." && reboot return 0 else # If reboot not required, check whether re-login is required in case the setup was run with sudo. # This is because the user account gets added to sashiadmin group and re-login is needed for group permission to apply. # without this, user cannot run "sashi" cli commands without sudo. if [ "$mode" == "install" ] && [ -n "$SUDO_USER" ] ; then echo "You need to logout and log back in, to complete Sashimono installation." return 0 else return 1 fi fi } function reg_info() { echo "" if MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN reginfo ; then echo -e "\nYour account details are stored in $MB_XRPL_DATA/mb-xrpl.cfg and $MB_XRPL_DATA/secret.cfg." fi } function apply_ssl() { [ "$EUID" -ne 0 ] && echo "Please run with root privileges (sudo)." && exit 1 local tls_key_file=$1 local tls_cert_file=$2 local tls_cabundle_file=$3 ([ ! -f "$tls_key_file" ] || [ ! -f "$tls_cert_file" ] || \ ([ "$tls_cabundle_file" != "" ] && [ ! -f "$tls_cabundle_file" ])) && echo -e "One or more invalid files provided.\nusage: applyssl " && exit 1 echo "Applying new SSL certificates for $evernode" echo "Key: $tls_key_file" && cp $tls_key_file $SASHIMONO_DATA/contract_template/cfg/tlskey.pem || exit 1 echo "Cert: $tls_cert_file" && cp $tls_cert_file $SASHIMONO_DATA/contract_template/cfg/tlscert.pem || exit 1 # ca bundle is optional. [ "$tls_cabundle_file" != "" ] && echo "CA bundle: $tls_cabundle_file" && (cat $tls_cabundle_file >> $SASHIMONO_DATA/contract_template/cfg/tlscert.pem || exit 1) sashi list | jq -rc '.[]' | while read -r inst; do \ local instuser=$(echo $inst | jq -r '.user'); \ local instname=$(echo $inst | jq -r '.name'); \ echo -e "\nStopping contract instance $instname" && sashi stop -n $instname && \ echo "Updating SSL certificates" && \ cp $SASHIMONO_DATA/contract_template/cfg/tlskey.pem $SASHIMONO_DATA/contract_template/cfg/tlscert.pem /home/$instuser/$instname/cfg/ && \ chmod 644 /home/$instuser/$instname/cfg/tlscert.pem && chmod 600 /home/$instuser/$instname/cfg/tlskey.pem && \ chown -R $instuser:$instuser /home/$instuser/$instname/cfg/*.pem && \ echo -e "Starting contract instance $instname" && sashi start -n $instname; \ done echo "Done." } function reconfig_sashi() { echomult "Configuaring sashimono...\n" ! $SASHIMONO_BIN/sagent reconfig $SASHIMONO_DATA $alloc_instcount $alloc_cpu $alloc_ramKB $alloc_swapKB $alloc_diskKB && echomult "There was an error in updating sashimono configuration." && return 1 # Update cgroup allocations. ( [[ $alloc_ramKB -gt 0 ]] || [[ $alloc_swapKB -gt 0 ]] || [[ $alloc_instcount -gt 0 ]] ) && echomult "Updating the cgroup configuration..." && ! $SASHIMONO_BIN/user-cgcreate.sh $SASHIMONO_DATA && echomult "Error occured while upgrading cgroup allocations" && return 1 # Update disk quotas. if ( [[ $alloc_diskKB -gt 0 ]] || [[ $alloc_instcount -gt 0 ]] ) ; then echomult "Updating the disk quotas..." users=$(cut -d: -f1 /etc/passwd | grep "^$SASHIUSER_PREFIX" | sort) readarray -t userarr <<<"$users" sashiusers=() for user in "${userarr[@]}"; do [ ${#user} -lt 24 ] || [ ${#user} -gt 32 ] || [[ ! "$user" =~ ^$SASHIUSER_PREFIX[0-9]+$ ]] && continue sashiusers+=("$user") done max_storage_kbytes=$(jq '.system.max_storage_kbytes' $saconfig) max_instance_count=$(jq '.system.max_instance_count' $saconfig) disk=$(expr $max_storage_kbytes / $max_instance_count) ucount=${#sashiusers[@]} if [ $ucount -gt 0 ]; then for user in "${sashiusers[@]}"; do setquota -g -F vfsv0 "$user" "$disk" "$disk" 0 0 / done fi fi return 0 } function reconfig_mb() { echomult "Configuaring message board...\n" ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN reconfig $lease_amount $alloc_instcount $rippled_server && echo "There was an error in updating message board configuration." && return 1 return 0 } function config() { [ "$EUID" -ne 0 ] && echo "Please run with root privileges (sudo)." && exit 1 alloc_instcount=0 alloc_cpu=0 alloc_ramKB=0 alloc_swapKB=0 alloc_diskKB=0 lease_amount=0 rippled_server='' local saconfig="$SASHIMONO_DATA/sa.cfg" local max_instance_count=$(jq '.system.max_instance_count' $saconfig) local max_mem_kbytes=$(jq '.system.max_mem_kbytes' $saconfig) local max_swap_kbytes=$(jq '.system.max_swap_kbytes' $saconfig) local max_storage_kbytes=$(jq '.system.max_storage_kbytes' $saconfig) local mbconfig="$MB_XRPL_DATA/mb-xrpl.cfg" local cfg_lease_amount=$(jq '.xrpl.leaseAmount' $mbconfig) local cfg_rippled_server=$(jq -r '.xrpl.rippledServer' $mbconfig) local update_sashi=0 local update_mb=0 local sub_mode=${1} if [ "$sub_mode" == "resources" ] ; then local ramMB=${2} # memory to allocate for contract instances. local swapMB=${3} # Swap to allocate for contract instances. local diskMB=${4} # Disk space to allocate for contract instances. local instcount=${5} # Total contract instance count. [ -z $ramMB ] && [ -z $swapMB ] && [ -z $diskMB ] && [ -z $instcount ] && echomult "Your current resource allocation is: \n Memory: $(GB $max_mem_kbytes) \n Swap: $(GB $max_swap_kbytes) \n Disk space: $(GB $max_storage_kbytes) \n Instance count: $max_instance_count\n" && exit 0 local help_text="Usage: evernode config resources | evernode config resources \n" [ ! -z $ramMB ] && [[ $ramMB != 0 ]] && ! validate_positive_decimal $ramMB && echomult "Invalid memory size.\n $help_text" && exit 1 [ ! -z $swapMB ] && [[ $swapMB != 0 ]] && ! validate_positive_decimal $swapMB && echomult "Invalid swap size.\n $help_text" && exit 1 [ ! -z $diskMB ] && [[ $diskMB != 0 ]] && ! validate_positive_decimal $diskMB && echomult "Invalid disk size.\n $help_text" && exit 1 [ ! -z $instcount ] && [[ $instcount != 0 ]] && ! validate_positive_decimal $instcount && echomult "Invalid instance count.\n $help_text" && exit 1 [ -z $instcount ] && instcount=0 alloc_instcount=$instcount alloc_ramKB=$(( ramMB * 1000 )) alloc_swapKB=$(( swapMB * 1000 )) alloc_diskKB=$(( diskMB * 1000 )) ( ( [[ $alloc_instcount -eq 0 ]] || [[ $max_instance_count == $alloc_instcount ]] ) && ( [[ $alloc_ramKB -eq 0 ]] || [[ $max_mem_kbytes == $alloc_ramKB ]] ) && ( [[ $alloc_swapKB -eq 0 ]] || [[ $max_swap_kbytes == $alloc_swapKB ]] ) && ( [[ $alloc_diskKB -eq 0 ]] || [[ $max_storage_kbytes == $alloc_diskKB ]] ) ) && echomult "Resource configuration values are already configured!\n" && exit 0 echomult "Using allocation" [[ $alloc_ramKB -gt 0 ]] && echomult "$(GB $alloc_ramKB) memory" [[ $alloc_swapKB -gt 0 ]] && echomult "$(GB $alloc_swapKB) Swap" [[ $alloc_diskKB -gt 0 ]] && echomult "$(GB $alloc_diskKB) disk space" [[ $alloc_instcount -gt 0 ]] && echomult "Distributed among $alloc_instcount contract instances" update_sashi=1 [[ $alloc_instcount -gt 0 ]] && update_mb=1 elif [ "$sub_mode" == "leaseamt" ] ; then local amount=${2} # Contract instance lease amount in EVRs. [ -z $amount ] && echomult "Your current lease amount is: $cfg_lease_amount EVRs.\n" && exit 0 ! validate_positive_decimal $amount && echomult "Invalid lease amount.\n Usage: evernode config leaseamt | evernode config leaseamt \n" && exit 1 lease_amount=$amount [[ $cfg_lease_amount == $lease_amount ]] && echomult "Lease amount is already configured!\n" && exit 0 echomult "Using lease amount $lease_amount EVRs." update_mb=1 elif [ "$sub_mode" == "rippled" ] ; then local server=${2} # Rippled server URL [ -z $server ] && echomult "Your current rippled server is: $cfg_rippled_server\n" && exit 0 ! validate_rippled_url $server && echomult "\nUsage: evernode config rippled | evernode config rippled \n" && exit 1 rippled_server=$server [[ $cfg_rippled_server == $rippled_server ]] && echomult "Rippled server is already configured!\n" && exit 0 echomult "Using the rippled address '$rippled_server'." update_mb=1 else echomult "Invalid arguments.\n Usage: evernode config [resources|leaseamt|rippled] [arguments]\n" && exit 1 fi local mb_user_id=$(id -u "$MB_XRPL_USER") local mb_user_runtime_dir="/run/user/$mb_user_id" local has_error=0 echomult "\nStaring the reconfiguration...\n" # Stop the message board service. echomult "Stopping the message board..." sudo -u "$MB_XRPL_USER" XDG_RUNTIME_DIR="$mb_user_runtime_dir" systemctl --user stop $MB_XRPL_SERVICE # Stop the sashimono service. if [ $update_sashi == 1 ] ; then echomult "Stopping the sashimono..." systemctl stop $SASHIMONO_SERVICE ! reconfig_sashi && has_error=1 echomult "Starting the sashimono..." systemctl start $SASHIMONO_SERVICE fi if [ $has_error == 0 ] && [ $update_mb == 1 ] ; then ! reconfig_mb && has_error=1 fi echomult "Starting the message board..." sudo -u "$MB_XRPL_USER" XDG_RUNTIME_DIR="$mb_user_runtime_dir" systemctl --user start $MB_XRPL_SERVICE [ $has_error == 1 ] && echomult "\nChanging the configuration exited with an error.\n" && exit 1 echomult "\nSuccessfully changed the configuration!\n" } function delete_instance() { [ "$EUID" -ne 0 ] && echo "Please run with root privileges (sudo)." && exit 1 instance_name=$1 echo "Deleting instance $instance_name" ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN delete $instance_name && echo "There was an error in deleting the instance." && exit 1 # Restart the message board to update the instance count local mb_user_id=$(id -u "$MB_XRPL_USER") local mb_user_runtime_dir="/run/user/$mb_user_id" sudo -u "$MB_XRPL_USER" XDG_RUNTIME_DIR="$mb_user_runtime_dir" systemctl --user restart $MB_XRPL_SERVICE echo "Instance deletion completed." } # Begin setup execution flow -------------------- echo "Thank you for trying out $evernode!" if [ "$mode" == "install" ]; then if ! $interactive ; then inetaddr=${3} # IP or DNS address. init_peer_port=${4} # Starting peer port for instances. init_user_port=${5} # Starting user port for instances. countrycode=${6} # 2-letter country code. alloc_cpu=${7} # CPU microsec to allocate for contract instances (max 1000000). alloc_ramKB=${8} # Memory to allocate for contract instances. alloc_swapKB=${9} # Swap to allocate for contract instances. alloc_diskKB=${10} # Disk space to allocate for contract instances. alloc_instcount=${11} # Total contract instance count. lease_amount=${12} # Contract instance lease amount in EVRs. rippled_server=${13} # Rippled server URL xrpl_account_address=${14} # XRPL account secret. xrpl_account_secret=${15} # XRPL account secret. email_address=${16} # User email address tls_key_file=${17} # File path to the tls private key. tls_cert_file=${18} # File path to the tls certificate. tls_cabundle_file=${19} # File path to the tls ca bundle. fi $interactive && ! confirm "This will install Sashimono, Evernode's contract instance management software, and register your system as an $evernode host. \nMake sure your system does not currently contain any other workloads important to you since we will be making modifications to your system configuration. \n\nContinue?" && exit 1 check_sys_req check_prereq # Check bc command is installed. if ! command -v bc &>/dev/null; then echo "bc command not found. Installing.." apt-get -y install bc >/dev/null fi # Display licence file and ask for concent. printf "\n*****************************************************************************************************\n\n" curl --silent $licence_url | cat printf "\n\n*****************************************************************************************************\n" $interactive && ! confirm "\nDo you accept the terms of the licence agreement?" && exit 1 if [ "$NO_MB" == "" ]; then init_setup_helpers set_rippled_server echo -e "Using Rippled server '$rippled_server'.\n" set_host_xrpl_account echo -e "Using xrpl account $xrpl_account_address with the specified secret.\n" fi set_email_address echo -e "Using the contact email address '$email_address'.\n" set_inet_addr echo -e "Using '$inetaddr' as host internet address.\n" set_country_code echo -e "Using '$countrycode' as country code.\n" set_cgrules_svc echo -e "Using '$cgrulesengd_service' as cgroups rules engine service.\n" set_instance_alloc echo -e "Using allocation $(GB $alloc_ramKB) memory, $(GB $alloc_swapKB) Swap, $(GB $alloc_diskKB) disk space, distributed among $alloc_instcount contract instances.\n" set_init_ports echo -e "Using peer port range $init_peer_port-$((init_peer_port + alloc_instcount)) and user port range $init_user_port-$((init_user_port + alloc_instcount))).\n" if [ "$NO_MB" == "" ]; then set_lease_amount echo -e "Lease amount set as $lease_amount EVRs per Moment.\n" fi $interactive && ! confirm "\n\nSetup will now begin the installation. Continue?" && exit 1 echo "Starting installation..." install_evernode 0 rm -r $setup_helper_dir >/dev/null 2>&1 echomult "Installation successful! Installation log can be found at $logfile \n\nYour system is now registered on $evernode. You can check your system status with 'evernode status' command." elif [ "$mode" == "uninstall" ]; then # echomult "\nWARNING! Uninstalling will deregister your host from $evernode and you will LOSE YOUR XRPL ACCOUNT credentials # stored in '$MB_XRPL_DATA/mb-xrpl.cfg' and '$MB_XRPL_DATA/secret.cfg'. This is irreversible. Make sure you have your account address and # secret elsewhere before proceeding.\n" # $interactive && ! confirm "\nHave you read above warning and backed up your account credentials?" && exit 1 $interactive && ! confirm "\nAre you sure you want to uninstall $evernode?" && exit 1 # Force uninstall on quiet mode. $interactive && uninstall_evernode 0 || uninstall_evernode 0 -f echo "Uninstallation complete!" elif [ "$mode" == "transfer" ]; then $interactive && ! confirm "\nThis will uninstall and deregister this host from $evernode while allowing you to transfer the registration to a preferred transferee. \n\nAre you sure you want to transfer $evernode registration from this host?" && exit 1 if ! $interactive ; then transferee_address=${3} # Address of the transferee. fi set_transferee_address init_evernode_transfer uninstall_evernode 0 echo "Transfer process was sucessfully initiated. You can now install and register $evernode using the account $transferee_address." elif [ "$mode" == "status" ]; then reg_info elif [ "$mode" == "list" ]; then sashi list elif [ "$mode" == "update" ]; then update_evernode elif [ "$mode" == "log" ]; then create_log elif [ "$mode" == "applyssl" ]; then apply_ssl $2 $3 $4 elif [ "$mode" == "config" ]; then config $2 $3 $4 $5 $6 elif [ "$mode" == "delete" ]; then [ -z "$2" ] && echomult "A contract instance name must be specified (see 'evernode list').\n Usage: evernode delete " && exit 1 delete_instance "$2" fi [ "$mode" != "uninstall" ] && check_installer_pending_finish exit 0 # surrounding braces are needed make the whole script to be buffered on client before execution. }