#!/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 cointains 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 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