diff --git a/home.admin/00infoLCD.sh b/home.admin/00infoLCD.sh index 41b00d52c..cc19c01cb 100755 --- a/home.admin/00infoLCD.sh +++ b/home.admin/00infoLCD.sh @@ -198,6 +198,15 @@ while : continue fi + if [ "${state}" = "copystation" ]; then + l1="COPYSTATION MODE\n" + l2="${message}\n" + l3="reboot 4 back to normal" + dialog --backtitle "RaspiBlitz ${codeVersion} ${localip}" --infobox "$l1$l2$l3" 6 ${boxwidth} + sleep 2 + continue + fi + # if LND is syncing or scanning lndSynced=$(sudo -u bitcoin /usr/local/bin/lncli --chain=${network} --network=${chain}net getinfo 2>/dev/null | jq -r '.synced_to_chain' | grep -c true) if [ ${lndSynced} -eq 0 ]; then diff --git a/home.admin/XXcopyStation.sh b/home.admin/XXcopyStation.sh new file mode 100755 index 000000000..97e0a1436 --- /dev/null +++ b/home.admin/XXcopyStation.sh @@ -0,0 +1,310 @@ +#!/bin/bash + +# command info +if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then + echo "# Turns the RaspiBlitz into HDD CopyStation Mode" + echo "# lightning is deactivated during CopyStationMode" + echo "# reboot RaspiBlitz to set back to normal mode" + exit 1 +fi + +####### CONFIG ############# + +# where to find the BITCOIN data directory (no trailing /) +pathBitcoinBlockchain="/mnt/hdd/bitcoin" + +# where to find the LITECOIN data directory (no trailing /) +pathLitecoinBlockchain="/mnt/hdd/litecoin" + +# where to find the RaspiBlitz HDD template directory (no trailing /) +pathTemplateHDD="/mnt/hdd/templateHDD" + +# 0 = ask before formatting/init new HDD +# 1 = auto-formatting every new HDD that needs init +autoformat=1 + +# override values if XXcopyStation.conf files exists +# use when you run this outside RaspiBlitz +source ./XXcopyStation.conf 2>/dev/null + +####### SCRIPT ############# + +# check sudo +if [ "$EUID" -ne 0 ]; then + echo "Please run as root (with sudo)" + exit 1 +fi + +# make sure that its running in screen +# call with '-foreground' to prevent running in screen +if [ "$1" != "-foreground" ]; then + screenPID=$(screen -ls | grep "copystation" | cut -d "." -f1 | xargs) + if [ ${#screenPID} -eq 0 ]; then + # start copystation in sreen + echo "starting copystation screen session" + screen -S copystation -dm /home/admin/XXcopyStation.sh -foreground + else + echo "changing into running copystation screen session" + screen -S copystation + fi +fi + +clear +echo "******************************" +echo "RASPIBLITZ COPYSTATION SCRIPT" +echo "******************************" +echo + +echo "*** CHECKING CONFIG" + +# check that path information is valid +if [ -d "$pathBitcoinBlockchain" ]; then + echo "OK found $pathBitcoinBlockchain" +else + echo "FAIL path of 'pathBitcoinBlockchain' does not exists: ${pathBitcoinBlockchain}" + exit 1 +fi + +# check that path information is valid +if [ -d "$pathTemplateHDD" ]; then + echo "OK found $pathTemplateHDD" +else + echo "Creating: ${pathTemplateHDD}" + mkdir ${pathTemplateHDD} + chmod 777 ${pathTemplateHDD} +fi + +# make sure that lnd is stopped (if runnning) +systemctl stop lnd 2>/dev/null +systemctl stop background 2>/dev/null + + +if [ "${autoformat}" == "1" ]; then + echo "setting RaspiBlitz LCD info" + sudo sed -i "s/^state=.*/state=copystation/g" /home/admin/raspiblitz.info 2>/dev/null + sudo sed -i "s/^message=.*/message='Make sure target HDDs are not connected yet.\nContinue after 10 seconds ...'/g" /home/admin/raspiblitz.info 2>/dev/null + sleep 10 +else + echo + echo "*** INIT HDD SCAN" + echo "Please make sure that no HDDs that you want to sync later to are not connected now." + echo "PRESS ENTER when ready." + read key +fi + +# finding system drives (the drives that should not be synced to) +systemDrives=$(lsblk -o NAME | grep "^sd") +echo "OK - the following drives detected as system drives:" +echo "$systemDrives" +echo + +if [ "${autoformat}" == "1" ]; then + sudo sed -i "s/^message=.*/message='Connect now HDDs to sync ..'/g" /home/admin/raspiblitz.info 2>/dev/null + sleep 5 +fi + +# BASIC IDEA: +# 1. get fresh data from bitcoind --> template data +# 2. detect HDDs +# 3. sync HDDs with template data +# repeat + +echo +echo "*** RUNNING ***" +lastBlockchainUpdateTimestamp=1 + +while : +do + + ################################################ + # 1. get fresh data from bitcoind for template data + + # only execute every 30min + nowTimestamp=$(date +%s) + secondsDiff=$(echo "${nowTimestamp}-${lastBlockchainUpdateTimestamp}" | bc) + echo "seconds since last update from bitcoind: ${secondsDiff}" + echo + + if [ ${secondsDiff} -gt 3000 ]; then + + echo "******************************" + echo "Bitcoin Blockchain Update" + echo "******************************" + + # stop blockchains + echo "Stopping Blockchain ..." + systemctl stop bitcoind 2>/dev/null + systemctl stop litecoind 2>/dev/null + sleep 10 + + # sync bitcoin + echo "Syncing Bitcoin ..." + + # make sure the bitcoin directory in template folder exists + if [ ! -d "$pathTemplateHDD/bitcoin" ]; then + echo "creating the bitcoin subfolder in the template folder" + mkdir ${pathTemplateHDD}/bitcoin + chmod 777 ${pathTemplateHDD}/bitcoin + fi + + rsync -a --info=progress2 ${pathBitcoinBlockchain}/chainstate ${pathBitcoinBlockchain}/indexes ${pathBitcoinBlockchain}/blocks ${pathBitcoinBlockchain}/testnet3 ${pathTemplateHDD}/bitcoin + + if [ ! -d "${pathLitecoinBlockchain}" ]; then + + # sync bitcoin + echo "Syncing Litecoin ..." + + # make sure the litecoin directory in template folder exists + if [ ! -d "$pathTemplateHDD/litecoin" ]; then + echo "creating the litecoin subfolder in the template folder" + mkdir ${pathTemplateHDD}/litecoin + chmod 777 ${pathTemplateHDD}/litecoin + fi + + rsync -a --info=progress2 ${pathLitecoinBlockchain}/chainstate ${pathLitecoinBlockchain}/indexes ${pathLitecoinBlockchain}/blocks ${pathTemplateHDD}/litecoin + + fi + + # restart bitcoind (to let further setup while syncing HDDs) + echo "Restarting Blockchain ..." + systemctl start bitcoind 2>/dev/null + systemctl start litecoind 2>/dev/null + + # update timer + lastBlockchainUpdateTimestamp=$(date +%s) + fi + + ################################################ + # 2. detect connected HDDs and loop thru them + + sleep 4 + echo "" > ./.syncinfo.tmp + lsblk -o NAME | grep "^sd" | while read -r detectedDrive ; do + isSystemDrive=$(echo "${systemDrives}" | grep -c "${detectedDrive}") + if [ ${isSystemDrive} -eq 0 ]; then + + # check if drives 1st partition is named BLOCKCHAIN & in EXT4 format + isNamedBlockchain=$(lsblk -o NAME,FSTYPE,LABEL | grep "${detectedDrive}" | grep -c "BLOCKCHAIN") + isFormatExt4=$(lsblk -o NAME,FSTYPE,LABEL | grep "${detectedDrive}" | grep -c "ext4") + + # init a fresh device + if [ ${isNamedBlockchain} -eq 0 ] || [ ${isFormatExt4} -eq 0 ]; then + + echo "*** NEW EMPTY HDD FOUND ***" + echo "Device: ${detectedDrive}" + echo "isNamedBlockchain: ${isNamedBlockchain}" + echo "isFormatExt4:" ${isFormatExt4} + + # check if size is OK + size=$(lsblk -o NAME,SIZE -b | grep "^${detectedDrive}" | awk '$1=$1' | cut -d " " -f 2) + echo "size: ${size}" + if [ ${size} -lt 250000000000 ]; then + read key + whiptail --title "FAIL" --msgbox " +THE DEVICE IS TOO SMALL <250GB +Please remove device and PRESS ENTER + " 9 46 + else + + # find biggest partition + biggestSize=0 + lsblk -o NAME,SIZE -b | grep "─${detectedDrive}" | while read -r partitionLine ; do + partition=$(echo "${partitionLine}" | cut -d ' ' -f 1 | tr -cd "[:alnum:]") + size=$(echo "${partitionLine}" | tr -cd "[0-9]") + if [ ${size} -gt ${biggestSize} ]; then + formatPartition="${partition}" + biggestSize=$size + fi + echo "${formatPartition}" > .formatPartition.tmp + done + + formatPartition=$(cat .formatPartition.tmp) + rm .formatPartition.tmp + + if [ ${#formatPartition} -eq 0 ]; then + whiptail --title "FAIL" --msgbox " +NO PARTITIONS FOUND ON THAT DEVICE +Format on external computer with FAT32 first. +Please remove device now. + " 10 46 + else + + # if config value "autoformat=1" default to format + if [ "${autoformat}" != "1" ]; then + whiptail --title "Format HDD" --yes-button "Format" --no-button "Cancel" --yesno " +Found new HDD. Do you want to FORMAT now? +Please temp lable device with: ${formatPartition} + " 10 54 + choice=$? + else + choice=0 + fi + + # on cancel + if [ "${choice}" != "0" ]; then + whiptail --title "Format HDD" --msgbox " +OK NO FORMAT - Please remove decive now. + " 8 46 + exit 1 + fi + + # format the HDD + echo "Starting Formatting of device ..." + sudo mkfs.ext4 /dev/${formatPartition} -F -L BLOCKCHAIN + + fi + + fi + + fi # end init new HDD + + ################################################ + # 3. sync HDD with template data + + partition=$(lsblk -o NAME,FSTYPE,LABEL | grep "${detectedDrive}" | grep "BLOCKCHAIN" | cut -d ' ' -f 1 | tr -cd "[:alnum:]") + if [ ${#partition} -gt 0 ]; then + + # temp mount device + echo "mounting: ${partition}" + mkdir /mnt/hdd2 2>/dev/null + sudo mount -t ext4 /dev/${partition} /mnt/hdd2 + + # rsync device + mountOK=$(lsblk -o NAME,MOUNTPOINT | grep "${detectedDrive}" | grep -c "/mnt/hdd2") + if [ ${mountOK} -eq 1 ]; then + rsync -a --info=progress2 ${pathTemplateHDD}/* /mnt/hdd2 + chmod -r 777 /mnt/hdd2 + echo "${partition} " >> ./.syncinfo.tmp + else + echo "FAIL: was not able to mount --> ${partition}" + fi + + # unmount device + sudo umount -l /mnt/hdd2 + + fi + + fi + done + + clear + echo "**** SYNC LOOP DONE ****" + synced=$(cat ./.syncinfo.tmp | tr '\r\n' ' ') + echo "HDDs ready synced: ${synced}" + echo "*************************" + echo "Its safe to disconnect/remove HDDs now." + echo "To stop copystation script: CTRL+c" + echo "" + + + if [ "${autoformat}" == "1" ]; then + sudo sed -i "s/^message=.*/message='Ready & Synced HDDs:\n${synced}'/g" /home/admin/raspiblitz.info 2>/dev/null + fi + + sleep 25 + + clear + echo "starting new sync loop" + sleep 5 + +done \ No newline at end of file