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.
403 lines
15 KiB
403 lines
15 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
|
|
|
|
# display 3 secs logo - try to kickstart LCD
|
|
# see https://github.com/rootzoll/raspiblitz/issues/195#issuecomment-469918692
|
|
sudo fbi -a -T 1 -d /dev/fb1 --noverbose /home/admin/raspiblitz/pictures/logoraspiblitz.png
|
|
sleep 5
|
|
sudo killall -3 fbi
|
|
|
|
# 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}
|
|
|
|
# Emergency cleaning logs when over 1GB (to prevent SD card filling up)
|
|
# see https://github.com/rootzoll/raspiblitz/issues/418#issuecomment-472180944
|
|
echo "*** Checking Log Size ***"
|
|
logsMegaByte=$(sudo du -c -m /var/log | grep "total" | awk '{print $1;}')
|
|
if [ ${logsMegaByte} -gt 1000 ]; then
|
|
echo "WARN !! Logs /var/log in are bigger then 1GB"
|
|
echo "ACTION --> DELETED ALL LOGS"
|
|
sudo rm -r /var/log/*
|
|
sleep 3
|
|
echo "WARN !! Logs in /var/log in were bigger then 1GB and got emergency delete to prevent fillup."
|
|
echo "If you see this in the logs please report to the GitHub issues, so LOG config needs to hbe optimized."
|
|
else
|
|
echo "OK - logs are at ${logsMegaByte} MB - within safety limit"
|
|
fi
|
|
echo ""
|
|
|
|
################################
|
|
# 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)
|
|
|
|
# sanity check on IP data
|
|
# see https://github.com/rootzoll/raspiblitz/issues/371#issuecomment-472416349
|
|
echo "-> sanity check of IP data: ${freshPublicIP}"
|
|
if [[ $freshPublicIP =~ ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$ ]]; then
|
|
echo "OK IPv6"
|
|
elif [[ $freshPublicIP =~ ^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]; then
|
|
echo "OK IPv4"
|
|
else
|
|
echo "FAIL - not an IPv4 or IPv6 address"
|
|
freshPublicIP=""
|
|
fi
|
|
|
|
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
|