You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

368 lines
13 KiB

#!/bin/bash
# This script runs on every start called by boostrap.service
# It makes sure that the system is configured like the
# default values or as in the config.
# For more details see background_raspiblitzSettings.md
# use to detect multiple starts of service
#uid=$(date +%s)
#echo "started" > /home/admin/${uid}.boot
# load codeVersion
source /home/admin/_version.info
################################
# FILES TO WORK WITH
################################
# CONFIGFILE - configuration of RaspiBlitz
# used by fresh SD image to recover configuration
# and delivers basic config info for scripts
# make raspiblitz.conf if not there
sudo touch /mnt/hdd/raspiblitz.conf
configFile="/mnt/hdd/raspiblitz.conf"
# LOGFILE - store debug logs of bootstrap
# resets on every start
logFile="/home/admin/raspiblitz.log"
# INFOFILE - state data from bootstrap
# used by display and later setup steps
infoFile="/home/admin/raspiblitz.info"
echo "Writing logs to: ${logFile}"
echo "" > $logFile
echo "***********************************************" >> $logFile
echo "Running RaspiBlitz Bootstrap ${codeVersion}" >> $logFile
date >> $logFile
echo "***********************************************" >> $logFile
# set default values for raspiblitz.info
network=""
chain=""
setupStep=0
# try to load old values if available (overwrites defaults)
source ${infoFile} 2>/dev/null
# resetting info file
echo "Resetting the InfoFile: ${infoFile}"
echo "state=starting" > $infoFile
echo "message=" >> $infoFile
echo "network=${network}" >> $infoFile
echo "chain=${chain}" >> $infoFile
echo "setupStep=${setupStep}" >> $infoFile
if [ "${setupStep}" != "100" ]; then
echo "hostname=${hostname}" >> $infoFile
fi
sudo chmod 777 ${infoFile}
################################
# GENERATE UNIQUE SSH PUB KEYS
# on first boot up
################################
numberOfPubKeys=$(sudo ls /etc/ssh/ | grep -c 'ssh_host_')
if [ ${numberOfPubKeys} -eq 0 ]; then
echo "*** Generating new SSH PubKeys" >> $logFile
sudo dpkg-reconfigure openssh-server
echo "OK" >> $logFile
fi
################################
# AFTER BOOT SCRIPT
# when a process needs to
# execute stuff after a reboot
# it should in file
# /home/admin/setup.sh
################################
# check for after boot script
afterSetupScriptExists=$(ls /home/admin/setup.sh 2>/dev/null | grep -c setup.sh)
if [ ${afterSetupScriptExists} -eq 1 ]; then
echo "*** SETUP SCRIPT DETECTED ***"
# echo out script to journal logs
sudo cat /home/admin/setup.sh
# execute the after boot script
sudo /home/admin/setup.sh
# delete the after boot script
sudo rm /home/admin/setup.sh
# reboot again
echo "DONE wait 6 secs ... one more reboot needed ... "
sudo shutdown -r now
sleep 100
fi
################################
# HDD CHECK & PRE-INIT
################################
# waiting for HDD to connect
hddExists=$(lsblk | grep -c sda1)
while [ ${hddExists} -eq 0 ]
do
# display will ask user to connect a HDD
sed -i "s/^state=.*/state=nohdd/g" ${infoFile}
sed -i "s/^message=.*/message='Connect the Hard Drive'/g" ${infoFile}
sleep 5
# retry to find HDD
hddExists=$(lsblk | grep -c sda1)
done
# check if the HDD is auto-mounted ( auto-mounted = setup-done)
hddIsAutoMounted=$(sudo cat /etc/fstab | grep -c '/mnt/hdd')
if [ ${hddIsAutoMounted} -eq 0 ]; then
echo "HDD is there but not AutoMounted yet." >> $logFile
echo "Analysing the situation ..." >> $logFile
# detect for correct device name (the biggest partition)
hddDeviceName="sda1"
hddSecondPartitionExists=$(lsblk | grep -c sda2)
if [ ${hddSecondPartitionExists} -eq 1 ]; then
echo "HDD has a second partition - choosing the bigger one ..." >> $logFile
# get both with size
size1=$(lsblk -o NAME,SIZE -b | grep "sda1" | awk '{ print substr( $0, 12, length($0)-2 ) }' | xargs)
echo "sda1(${size1})" >> $logFile
size2=$(lsblk -o NAME,SIZE -b | grep "sda2" | awk '{ print substr( $0, 12, length($0)-2 ) }' | xargs)
echo "sda2(${size2})" >> $logFile
# chosse to run with the bigger one
if [ ${size2} -gt ${size1} ]; then
echo "sda2 is BIGGER - run with this one" >> $logFile
hddDeviceName="sda2"
else
echo "sda1 is BIGGER - run with this one" >> $logFile
hddDeviceName="sda1"
fi
fi
# check if HDD is formatted EXT4
hddExt4=$(lsblk -o NAME,FSTYPE -b /dev/${hddDeviceName} | grep -c "ext4")
if [ ${hddExt4} -eq 0 ]; then
echo "HDD is NOT formatted in ext4." >> $logFile
# stop the bootstrap here ...
# display will ask user to run setup
sed -i "s/^state=.*/state=waitsetup/g" ${infoFile}
sed -i "s/^message=.*/message='HDD needs SetUp (1)'/g" ${infoFile}
exit 0
fi
# temp-mount the HDD
echo "temp-mounting the HDD .." >> $logFile
sudo mkdir /mnt/hdd
sudo mount -t ext4 /dev/${hddDeviceName} /mnt/hdd
mountOK=$(lsblk | grep -c '/mnt/hdd')
if [ ${mountOK} -eq 0 ]; then
echo "FAIL - not able to temp-mount HDD" >> $logFile
sed -i "s/^state=.*/state=waitsetup/g" ${infoFile}
sed -i "s/^message=.*/message='HDD failed Mounting'/g" ${infoFile}
# no need to unmount the HDD, it failed mounting
exit 0
else
echo "OK - HDD available under /mnt/hdd" >> $logFile
fi
# UPDATE MIGRATION & CONFIG PROVISIONING
# check if HDD contains already a configuration
echo "Check if HDD contains already a configuration .." >> $logFile
configExists=$(ls ${configFile} | grep -c '.conf')
if [ ${configExists} -eq 1 ]; then
echo "Found existing configuration" >> $logFile
source ${configFile}
# check if config files contains basic: version
if [ ${#raspiBlitzVersion} -eq 0 ]; then
echo "Invalid Config: missing raspiBlitzVersion in (${configFile})!" >> ${logFile}
configExists=0
fi
# check if config files contains basic: network
if [ ${#network} -eq 0 ]; then
echo "Invalid Config: missing network in (${configFile})!" >> ${logFile}
configExists=0
fi
# check if config files contains basic: chain
if [ ${#chain} -eq 0 ]; then
echo "Invalid Config: missing chain in (${configFile})!" >> ${logFile}
configExists=0
fi
if [ ${configExists} -eq 0 ]; then
echo "Moving invalid config to raspiblitz.invalid.conf" >> ${logFile}
sudo mv ${configFile} /mnt/hdd/raspiblitz.invalid.conf
fi
fi
# if config is still valid ...
if [ ${configExists} -eq 1 ]; then
echo "Found valid configuration" >> $logFile
sed -i "s/^state=.*/state=recovering/g" ${infoFile}
sed -i "s/^message=.*/message='Starting Recover'/g" ${infoFile}
echo "Calling Data Migration .." >> $logFile
sudo /home/admin/_bootstrap.migration.sh
echo "Calling Provisioning .." >> $logFile
sudo /home/admin/_bootstrap.provision.sh
sed -i "s/^state=.*/state=recovered/g" ${infoFile}
sed -i "s/^message=.*/message='Done Recover'/g" ${infoFile}
echo "rebooting" >> $logFile
# set flag that system is freshly recovered and needs setup dialogs
echo "state=recovered" >> /home/admin/raspiblitz.recover.info
# save log file for inspection before reboot
cp $logFile /home/admin/raspiblitz.recover.log
sudo shutdown -r now
exit 0
else
echo "OK - No config file found: ${configFile}" >> $logFile
fi
# check if HDD contains existing LND data (old RaspiBlitz Version)
echo "Check if HDD contains existing LND data .." >> $logFile
lndDataExists=$(ls /mnt/hdd/lnd/lnd.conf | grep -c '.conf')
if [ ${lndDataExists} -eq 1 ]; then
echo "Found existing LND data - old RaspiBlitz?" >> $logFile
sed -i "s/^state=.*/state=olddata/g" ${infoFile}
sed -i "s/^message=.*/message='No Auto-Update possible'/g" ${infoFile}
# keep HDD mounted if user wants to copy data
exit 0
else
echo "OK - No LND data found" >> $logFile
fi
# check if HDD contains pre-loaded blockchain data
echo "Check if HDD contains pre-loaded blockchain data .." >> $logFile
litecoinDataExists=$(ls /mnt/hdd/litecoin/blocks/blk00000.dat 2>/dev/null | grep -c '.dat')
bitcoinDataExists=$(ls /mnt/hdd/bitcoin/blocks/blk00000.dat 2>/dev/null | grep -c '.dat')
# check if node can go into presync (only for bitcoin)
if [ ${bitcoinDataExists} -eq 1 ]; then
# update info file
sed -i "s/^state=.*/state=presync/g" ${infoFile}
sed -i "s/^message=.*/message='starting presync'/g" ${infoFile}
# activating presync
# so that on a hackathon you can just connect a RaspiBlitz
# to the network and have it up-to-date for setting up
echo "Found pre-loaded blockchain" >> $logFile
# check if pre-sync was already activated on last power-on
#presyncActive=$(systemctl status bitcoind | grep -c 'could not be found')
echo "starting pre-sync in background" >> $logFile
# make sure that debug file is clean, so just pre-sync gets analysed on stop
sudo rm /mnt/hdd/bitcoin/debug.log
# starting in background, because this scripts is part of systemd
# so to change systemd needs to happen after delay in seperate process
sudo chown -R bitcoin:bitcoin /mnt/hdd/bitcoin 2>> $logFile
sudo -u bitcoin /usr/local/bin/bitcoind -daemon -conf=/home/admin/assets/bitcoin.conf -pid=/mnt/hdd/bitcoin/bitcoind.pid 2>> $logFile
echo "OK Started bitcoind for presync" >> $logFile
sudo sed -i "s/^message=.*/message='running presync'/g" ${infoFile}
# after admin login, presync will be stopped and HDD unmounted
exit 0
else
echo "OK - No bitcoin blockchain data found" >> $logFile
fi
# if it got until here: HDD is empty ext4
echo "Waiting for SetUp." >> $logFile
sed -i "s/^state=.*/state=waitsetup/g" ${infoFile}
sed -i "s/^message=.*/message='HDD needs SetUp (2)'/g" ${infoFile}
# unmount HDD to be ready for auto-mount during setup
sudo umount -l /mnt/hdd
exit 0
fi # END - no automount
#####################################
# UPDATE HDD CONFIG FILE (if exists)
# needs to be done before starting LND
# so that environment info is fresh
#####################################
echo "Check if HDD contains configuration .." >> $logFile
configExists=$(ls ${configFile} | grep -c '.conf')
if [ ${configExists} -eq 1 ]; then
# load values
echo "load and update publicIP" >> $logFile
source ${configFile}
# update public IP on boot
# wait otherwise looking for publicIP fails
sleep 5
freshPublicIP=$(curl -s http://v4.ipv6-test.com/api/myip.php)
if [ ${#freshPublicIP} -eq 0 ]; then
# prevent having no publicIP set at all and LND getting stuck
# https://github.com/rootzoll/raspiblitz/issues/312#issuecomment-462675101
if [ ${#publicIP} -eq 0 ]; then
localIP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
echo "WARNING: No publicIP information at all - working with placeholder: ${localIP}" >> $logFile
freshPublicIP="${localIP}"
fi
fi
if [ ${#freshPublicIP} -eq 0 ]; then
echo "WARNING: Was not able to determine external IP on startup." >> $logFile
else
publicIPValueExists=$( sudo cat ${configFile} | grep -c 'publicIP=' )
if [ ${publicIPValueExists} -gt 1 ]; then
# remove one
echo "more then one publiIp entry - removing one" >> $logFile
sed -i "s/^publicIP=.*//g" ${configFile}
publicIPValueExists=$( sudo cat ${configFile} | grep -c 'publicIP=' )
fi
if [ ${publicIPValueExists} -eq 0 ]; then
echo "create value (${freshPublicIP})" >> $logFile
echo "publicIP=${freshPublicIP}" >> $configFile
else
echo "update value (${freshPublicIP})" >> $logFile
sed -i "s/^publicIP=.*/publicIP=${freshPublicIP}/g" ${configFile}
fi
fi
fi
#################################
# FIX BLOCKCHAINDATA OWNER (just in case)
# https://github.com/rootzoll/raspiblitz/issues/239#issuecomment-450887567
#################################
sudo chown bitcoin:bitcoin -R /mnt/hdd/bitcoin 2>/dev/null
################################
# DETECT FRESHLY RECOVERED SD
################################
recoveredInfoExists=$(ls /home/admin/raspiblitz.recover.info | grep -c '.info')
if [ ${recoveredInfoExists} -eq 1 ]; then
sed -i "s/^state=.*/state=recovered/g" ${infoFile}
sed -i "s/^message=.*/message='login to finish'/g" ${infoFile}
exit 0
fi
################################
# SD INFOFILE BASICS
################################
# state info
sed -i "s/^state=.*/state=ready/g" ${infoFile}
sed -i "s/^message=.*/message='waiting login'/g" ${infoFile}
# determine network and chain from system
# check for BITCOIN
loaded=$(sudo systemctl status bitcoind | grep -c 'loaded')
if [ ${loaded} -gt 0 ]; then
sed -i "s/^network=.*/network=bitcoin/g" ${infoFile}
source /mnt/hdd/bitcoin/bitcoin.conf
if [ ${testnet} -gt 0 ]; then
sed -i "s/^chain=.*/chain=test/g" ${infoFile}
else
sed -i "s/^chain=.*/chain=main/g" ${infoFile}
fi
fi
# check for LITECOIN
loaded=$(sudo systemctl status litecoind | grep -c 'loaded')
if [ ${loaded} -gt 0 ]; then
sed -i "s/^network=.*/network=litecoin/g" ${infoFile}
sed -i "s/^chain=.*/chain=main/g" ${infoFile}
fi
echo "DONE BOOTSTRAP" >> $logFile
exit 0