Files
raspiblitz/home.admin/config.scripts/blitz.data.sh
2025-06-17 08:47:49 +02:00

2466 lines
101 KiB
Bash

#!/bin/bash
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then
>&2 echo "# managing the data drive(s) with new bootable setups for RaspberryPi, VMs and Laptops"
>&2 echo "# blitz.data.sh status [-inspect] # auto detect the old/best drives to use for storage, system and data"
>&2 echo "# blitz.data.sh mount # mounts all drives and link all data folders"
>&2 echo "# blitz.data.sh link # (re)create all symlinks to files and folders (also mapping old layout to new layout)"
>&2 echo "# blitz.data.sh setup STOARGE [device] combinedData=[0|1] addSystemPartition=[0|1]"
>&2 echo "# blitz.data.sh setup SYSTEM [device]"
>&2 echo "# blitz.data.sh setup DATA [device]"
>&2 echo "# blitz.data.sh clean STOARGE [device] combinedData=[0|1] addSystemPartition=[0|1]"
>&2 echo "# blitz.data.sh clean SYSTEM [device]"
>&2 echo "# blitz.data.sh clean DATA [device]"
>&2 echo "# blitz.data.sh copy-system [device] [system|storage]"
>&2 echo "# blitz.data.sh recover STOARGE [device] combinedData=[0|1] bootFromStorage=[0|1]"
>&2 echo "# blitz.data.sh recover SYSTEM [device]"
>&2 echo "# blitz.data.sh recover DATA [device]"
>&2 echo "# blitz.data.sh kill-boot [device] # deactivate boot function from install medium"
>&2 echo "# blitz.data.sh migration [umbrel|citadel|mynode] [partition] [-test] # will migrate partition to raspiblitz"
>&2 echo "# blitz.data.sh migration hdd [menu-prepare|run]"
>&2 echo "# blitz.data.sh uasp-fix [-info] # deactivates UASP for non supported USB HDD Adapters"
>&2 echo "# blitz.data.sh swap on # creates and activates an 8GB swapfile in / (Debian 12 only)"
>&2 echo "# blitz.data.sh swap off # deactivates and removes the swapfile"
>&2 echo "# blitz.data.sh reset # deletes all data & partitions on the storage device"
>&2 echo "# blitz.data.sh expand [partition] # expands the partition to use all available space"
echo "error='missing parameters'"
exit 1
fi
###################
# BASICS
###################
# For the new data drive setup starting v1.12.0 we have 4 areas of data can be stored in different configurations
# A) INSTALL - inital install medium (SDcard, USB thumbdrive)
# B) SYSTEM - root drive of the linux system
# C) DATA - critical & configuration data of system & apps (formally app_data)
# D) STORAGE - data that is temp or can be redownloaded or generated like blockhain or indexes (formally app_storage)
# On a old RaspiBlitz setup INTSALL+SYSTEM would be the same on the sd card and DATA+STORAGE on the USB conncted HDD.
# On RaspberryPi5+NVMe or Laptop the SYSTEM is one partition while DATA+STORAGE on another, while INSTALL is started once from SD or thumb drive.
# On a VM all 4 areas can be on separate virtual ext4 drives, stored eg by Proxmox with different redundancies & backup strategies.
# This script should help to setup & manage those different configurations.
# file to print debug info on longer processes to
logFile="/home/admin/raspiblitz.log"
# minimal storage sizes (recommended sizes can get checked by UI)
storagePrunedMinGB=128
storageFullMinGB=890
dataMinGB=32
systemMinGB=32
# swap file path
swapFilePath="/swapfile"
# check if started with sudo
if [ "$EUID" -ne 0 ]; then
echo "error='run as root'"
exit 1
fi
# gather info on hardware
source <(/home/admin/config.scripts/blitz.hardware.sh status)
if [ ${#computerType} -eq 0 ]; then
echo "error='hardware not detected'"
exit 1
fi
action=$1
echo "# blitz.data.sh ${action}"
if [ ${#action} -eq 0 ]; then
echo "error='missing action'"
exit 1
fi
###################
# SWAP MANAGEMENT
###################
if [ "$action" = "swap" ]; then
swapAction=$2
swapSizeGB=8
if [ "$swapAction" = "on" ]; then
echo "# blitz.data.sh swap on"
# check if swap is already active
if swapon --show | grep -q "${swapFilePath}"; then
echo "error='swapfile ${swapFilePath} already active'"
exit 1
fi
# check if file exists
if [ -f "${swapFilePath}" ]; then
echo "error='file ${swapFilePath} already exists but is not active swap'"
exit 1
fi
echo "# Creating ${swapSizeGB}GB swapfile at ${swapFilePath} ..."
fallocate -l ${swapSizeGB}G ${swapFilePath}
if [ $? -ne 0 ]; then
echo "error='failed to allocate space for swapfile'"
rm -f ${swapFilePath} 2>/dev/null
exit 1
fi
chmod 600 ${swapFilePath}
mkswap ${swapFilePath}
if [ $? -ne 0 ]; then
echo "error='failed to format swapfile'"
rm -f ${swapFilePath} 2>/dev/null
exit 1
fi
swapon ${swapFilePath}
if [ $? -ne 0 ]; then
echo "error='failed to activate swapfile'"
rm -f ${swapFilePath} 2>/dev/null
exit 1
fi
# make permanent
if ! grep -q "${swapFilePath}" /etc/fstab; then
echo "${swapFilePath} none swap sw 0 0" >> /etc/fstab
echo "# Added swapfile to /etc/fstab"
fi
echo "result='swapfile created and activated'"
exit 0
elif [ "$swapAction" = "off" ]; then
echo "# blitz.data.sh swap off"
# check if swap is active
if swapon --show | grep -q "${swapFilePath}"; then
echo "# Deactivating swapfile ${swapFilePath} ..."
swapoff ${swapFilePath}
if [ $? -ne 0 ]; then
echo "error='failed to deactivate swapfile'"
# continue trying to remove from fstab and delete file
fi
else
echo "# Swapfile ${swapFilePath} is not active."
fi
# remove from fstab
if grep -q "${swapFilePath}" /etc/fstab; then
echo "# Removing swapfile entry from /etc/fstab ..."
sed -i "\#^${swapFilePath}#d" /etc/fstab
fi
# delete file
if [ -f "${swapFilePath}" ]; then
echo "# Deleting swapfile ${swapFilePath} ..."
rm -f ${swapFilePath}
if [ $? -ne 0 ]; then
echo "warning='failed to delete swapfile ${swapFilePath}'"
fi
else
echo "# Swapfile ${swapFilePath} not found."
fi
echo "result='swapfile deactivated and removed'"
exit 0
else
echo "error='unknown swap action'"
exit 1
fi
fi
###################
# STATUS
###################
if [ "$action" = "status" ]; then
# optional: parameter
userWantsInspect=0
if [ "$2" = "-inspect" ]; then
userWantsInspect=1
fi
##########################
# CHECK SWAP STATUS
swapActive=0
if swapon --show | grep -q "${swapFilePath}"; then
swapActive=1
fi
##########################
# FIND INSTALL DEVICE
# find the first device (sd card, usb, cd rom) with a boot partition
installDevice=""
possibleInstallDevices=$(lsblk -o NAME,TRAN -d | grep -E 'mmc|usb|sr' | cut -d' ' -f1)
for device in ${possibleInstallDevices}; do
echo "# check device(${device}) for boot partition"
if parted --script "/dev/${device}" print 2>/dev/null | grep "^ *[0-9]" | grep -q "boot\|esp\|lba"; then
installDevice="${device}"
break
fi
done
# check if any partition of install device is mounted as root
installDeviceActive=0
if [ ${#installDevice} -gt 0 ]; then
rootPartition=$(lsblk -no NAME,MOUNTPOINT "/dev/${installDevice}"| awk '$2 == "/"' | sed 's/[└├]─//g' | cut -d' ' -f1)
if [ ${#rootPartition} -gt 0 ]; then
installDeviceActive=1
fi
fi
# check if install device is read-only
installDeviceReadOnly=0
if [ ${#installDevice} -gt 0 ]; then
if [ -f "/sys/block/${installDevice}/ro" ] && [ "$(cat /sys/block/${installDevice}/ro)" = "1" ]; then
installDeviceReadOnly=1
fi
fi
# check if some drive is already mounted on /mnt/temp
mountPath=$(findmnt -n -o TARGET "/mnt/temp" 2>/dev/null)
if [ -n "${mountPath}" ]; then
echo "error='a drive already mounted on /mnt/temp'"
exit 1
fi
##########################
# CHECK EXISTING DRIVES
# initial values for drives & state to determine
storageDevice=""
systemDevice=""
dataDevice=""
storageBlockchainGB=0
dataInspectSuccess=0
dataConfigFound=0
combinedDataStorage=0
# get a list of all existing ext4 partitions of connected storage drives (sdX, nvmeX) - sorted by size (smallest first, then by name)
ext4Partitions=$(lsblk -b -n -l -o NAME,SIZE,FSTYPE,TYPE | grep "part" | grep "ext4" | grep -E "^(sd|nvme)" | awk '{print $1, $2}' | sort -k2,2n -k1,1)
if [ ${#ext4Partitions} -eq 0 ]; then
echo "# no ext4 partitions found"
fi
# check every partition if it has data to recover
while IFS= read -r line; do
if [ -n "$line" ]; then
name=$(echo "$line" | awk '{print $1}')
size=$(echo "$line" | awk '{printf "%.0f", $2/(1024*1024*1024)}')
# if user already set a migration source device - ignore it in the list
source <(/home/admin/_cache.sh get hddMigrateDeviceFrom)
if [ ${#hddMigrateDeviceFrom} -gt 0 ]; then
# check if the device is in the list of devices
if echo "${name}" | grep -q "${hddMigrateDeviceFrom}"; then
# remove the device from the list
echo "# skipping device ${name} - migration source device set"
continue
fi
fi
# mount partition if not already mounted
needsUnmount=0
mountPath=$(findmnt -n -o TARGET "/dev/${name}" 2>/dev/null)
if [ -z "${mountPath}" ]; then
# create temp mount point if not exists
mkdir -p /mnt/temp 2>/dev/null
# try to mount
if ! mount "/dev/${name}" /mnt/temp 2>/dev/null; then
echo "error='cannot mount /dev/${name}'"
continue
fi
mountPath="/mnt/temp"
needsUnmount=1
fi
dataInspectPartition=0
deviceName=$(echo "${name}" | sed -E 's/p?[0-9]+$//')
echo "# Checking partition ${name} (${size}GB) on ${deviceName} mounted at ${mountPath}"
# Check STORAGE DRIVE
if [ -d "${mountPath}/app-storage" ]; then
# set data
echo "# - STORAGE partition"
storageDevice="${deviceName}"
storageSizeGB="${size}"
storagePartition="${name}"
if [ "${needsUnmount}" = "0" ]; then
storageMountedPath="${mountPath}"
fi
# check if its a combined data & storage partition
if [ -d "${mountPath}/app-data" ]; then
if [ ${#dataDevice} -eq 0 ]; then
combinedDataStorage=1
dataPartition="${name}"
fi
dataInspectPartition=1
else
combinedDataStorage=0
fi
# check blochain data
storageBlockchainGB=$(du -s ${mountPath}/app-storage/bitcoin/blocks 2>/dev/null| awk '{printf "%.0f", $1/(1024*1024)}')
if [ "${storageBlockchainGB}" = "" ]; then
# check old location
storageBlockchainGB=$(du -s ${mountPath}/bitcoin/blocks 2>/dev/null| awk '{printf "%.0f", $1/(1024*1024)}')
fi
if [ "${storageBlockchainGB}" = "" ]; then
# if nothing found - set to numeric 0
storageBlockchainGB=0
fi
# Check DATA DRIVE
elif [ -d "${mountPath}/app-data" ] && [ ${size} -gt 7 ]; then
# check for unclean setups
if [ -d "${mountPath}/app-storage" ]; then
echo "# there might be two old storage drives connected"
echo "error='app-storage found on app-data partition'"
exit 1
fi
# set data
echo "# - DATA partition"
combinedDataStorage=0
dataInspectPartition=1
dataDevice="${deviceName}"
dataSizeGB="${size}"
dataPartition="${name}"
if [ "${needsUnmount}" = "0" ]; then
dataMountedPath="${mountPath}"
fi
# Check SYSTEM DRIVE
elif [ -d "${mountPath}/boot" ] && [ -d "${mountPath}/home/admin/raspiblitz" ] && [ ${size} -gt 7 ]; then
# check for unclean setups
if [ -d "${mountPath}/app-storage" ]; then
echo "error='system partition mixed with storage'"
exit 1
fi
if [ -d "${mountPath}/app-data" ]; then
echo "error='system partition mixed with data'"
exit 1
fi
# check if system is install device (sd card or thumb drive)
if [ "${installDevice}" = "${deviceName}" ]; then
echo "# - INSTALL partition"
else
# set data
echo "# - SYSTEM partition"
systemDevice="${deviceName}"
systemSizeGB="${size}"
systemPartition="${name}"
systemMountedPath="${mountPath}"
fi
# Check MIGRATION: UMBREL
elif [ -f "${mountPath}/umbrel/info.json" ]; then
echo "# - UMBREL data detected - use 'blitz.data.sh migration'"
storageMigration="umbrel"
# Check MIGRATION: CITADEL
elif [ -f "${mountPath}/citadel/info.json" ]; then
echo "# - CITADEL data detected - use 'blitz.data.sh migration'"
storageMigration="citadel"
# Check MIGRATION: MYNODE
elif [ -f "${mountPath}/mynode/bitcoin/bitcoin.conf" ]; then
echo "# - MYNODE data detected - use 'blitz.data.sh migration'"
storageMigration="mynode"
else
echo "# - no data found on partition"
fi
# Check: CONFIG FILE
if [ -f "${mountPath}/raspiblitz.conf" ] || [ -f "${mountPath}/app-data/raspiblitz.conf" ]; then
dataConfigFound=1
echo "# * found raspiblitz.conf"
fi
# Datainspect: copy setup relevant data from partition to temp location
if [ "$dataInspectPartition" = "1" ]; then
if [ "$userWantsInspect" = "0" ]; then
echo "# - skipping data inspect - use '-inspect' to copy data to RAMDISK for inspection"
elif [ ! -d "/var/cache/raspiblitz" ]; then
echo "# - skipping data inspect - RAMDISK not found"
else
echo "# - RUN INSPECT -> RAMDISK: /var/cache/raspiblitz/hdd-inspect"
mkdir /var/cache/raspiblitz/hdd-inspect 2>/dev/null
dataInspectSuccess=1
# make copy of raspiblitz.conf to RAMDISK (try old and new path)
cp -a ${mountPath}/raspiblitz.conf /var/cache/raspiblitz/hdd-inspect/raspiblitz.conf 2>/dev/null
cp -a ${mountPath}/app-data/raspiblitz.conf /var/cache/raspiblitz/hdd-inspect/raspiblitz.conf 2>/dev/null
if [ -f "/var/cache/raspiblitz/hdd-inspect/raspiblitz.conf" ]; then
echo "# * raspiblitz.conf copied to RAMDISK"
fi
# make copy of WIFI config to RAMDISK (if available)
cp -a ${mountPath}/app-data/wifi /var/cache/raspiblitz/hdd-inspect/ 2>/dev/null
if [ -d "/var/cache/raspiblitz/hdd-inspect/wifi" ]; then
echo "# * WIFI config copied to RAMDISK"
fi
# make copy of SSH keys to RAMDISK (if available)
cp -a ${mountPath}/app-data/sshd /var/cache/raspiblitz/hdd-inspect 2>/dev/null
cp -a ${mountPath}/app-data/ssh-root /var/cache/raspiblitz/hdd-inspect 2>/dev/null
if [ -d "/var/cache/raspiblitz/hdd-inspect/sshd" ] || [ -d "/var/cache/raspiblitz/hdd-inspect/ssh-root" ]; then
echo "# * SSH keys copied to RAMDISK"
fi
# make copy of raspiblitz.setup to RAMDISK (if available from former systemcopy)
cp -a ${mountPath}/app-data/raspiblitz.setup /var/cache/raspiblitz/hdd-inspect/raspiblitz.setup 2>/dev/null
if [ -f "/var/cache/raspiblitz/hdd-inspect/raspiblitz.setup" ]; then
echo "# * raspiblitz.setup copied to RAMDISK"
fi
fi
fi
# cleanup if we mounted
if [ "${needsUnmount}" = "1" ]; then
umount /mnt/temp
rm -r /mnt/temp
fi
fi
done <<< "${ext4Partitions}"
# check boot situation
bootFromStorage=0
bootFromSD=$(lsblk | grep mmcblk | grep -c /boot)
if [ ${bootFromSD} -eq 0 ] && [ -n "${storageDevice}" ] && [ "${storageDevice}" = "${systemDevice}" ]; then
# system runs from storage device
bootFromStorage=1
bootFromSD=0
fi
# if there is an existing storage device
biggerDevice=""
biggerSizeGB=""
if [ -n "${storageDevice}" ]; then
# get a list of all connected drives >7GB ordered by size (biggest first)
listOfBiggerDevices=$(lsblk -dno NAME,SIZE | grep -E "^(sd|nvme)" | \
awk '{
size=$2
if(size ~ /T/) {
sub("T","",size); size=size*1024
} else if(size ~ /G/) {
sub("G","",size); size=size*1
} else if(size ~ /M/) {
sub("M","",size); size=size/1024
}
# Must be strictly bigger than current storage and not the storage device itself
if (size > '"$storageSizeGB"' && $1 != "'"$storageDevice"'") printf "%s %.0f\n", $1, size
}' | sort -k2,2nr -k1,1 )
biggerDevice=$(echo "${listOfBiggerDevices}" | head -n1 | awk '{print $1}')
biggerSizeGB=$(echo "${listOfBiggerDevices}" | head -n1 | awk '{print $2}')
fi
echo "# RESULT AFTER DETECTION"
echo "# dataDevice: ${dataDevice} (${dataSizeGB}GB) (${dataMountedPath})"
echo "# storageDevice: ${storageDevice} (${storageSizeGB}GB) (${storageMountedPath})"
echo "# systemDevice: ${systemDevice} (${systemSizeGB}GB) (${systemMountedPath})"
echo "# installDevice: ${installDevice} (${installDeviceActive}) (${installDeviceReadOnly})"
echo "# biggerDevice: ${biggerDevice} (${biggerSizeGB}GB)"
echo "# combinedDataStorage: ${combinedDataStorage}"
########################
# PROPOSE LAYOUT
# decide if we need to propose a layout
proposeLayout=0
if [ ${combinedDataStorage} -eq 0 ]; then
if [ ${#dataDevice} -eq 0 ] || [ ${#storageDevice} -eq 0 ]; then
proposeLayout=1
fi
else
if [ ${#storageDevice} -eq 0 ]; then
proposeLayout=1
fi
fi
if [ ${proposeLayout} -eq 1 ]; then
echo "# PROPOSING LAYOUT ..."
# get a list of all connected drives >31GB ordered by size (biggest first)
listOfDevices=$(lsblk -dno NAME,SIZE | grep -E "^(sd|nvme)" | \
awk '{
size=$2
if(size ~ /T/) {
sub("T","",size); size=size*1024
} else if(size ~ /G/) {
sub("G","",size); size=size*1
} else if(size ~ /M/) {
sub("M","",size); size=size/1024
}
if (size >= 31) printf "%s %.0f\n", $1, size
}' | sort -k2,2nr -k1,1 )
echo "listOfDevices='${listOfDevices}'"
# if there is a migration device set - remove it from the list
source <(/home/admin/_cache.sh get hddMigrateDeviceFrom)
if [ ${#hddMigrateDeviceFrom} -gt 0 ]; then
# check if the device is in the list of devices
if echo "${listOfDevices}" | grep -q "${hddMigrateDeviceFrom}"; then
# remove the device from the list
listOfDevices=$(echo "${listOfDevices}" | grep -v "${hddMigrateDeviceFrom}")
echo "# skipping device ${hddMigrateDeviceFrom} - migration source device set"
fi
fi
# Set STORAGE (the biggest drive)
storageDevice=$(echo "${listOfDevices}" | head -n1 | awk '{print $1}')
storageSizeGB=$(echo "${listOfDevices}" | head -n1 | awk '{print $2}')
# remove the storage device from the list
listOfDevices=$(echo "${listOfDevices}" | grep -v "${storageDevice}")
if [ ${#storageDevice} -gt 0 ] && [ "${computerType}" = "pc" ]; then
echo "# on bare metal PC - storage device is the system boot device"
bootFromStorage=1
bootFromSD=0
fi
# no storage device found (system seems only device)
if [ "${systemDevice}" = "${storageDevice}" ]; then
scenario="error:no-storage"
storageDevice=""
storageSizeGB=""
# Set SYSTEM
elif [ ${#systemDevice} -eq 0 ]; then
# when no system device yet: take the next biggest drive as the system drive
systemDevice=$(echo "${listOfDevices}" | head -n1 | awk '{print $1}')
systemSizeGB=$(echo "${listOfDevices}" | head -n1 | awk '{print $2}')
# if there is was no spereated system drive left
if [ ${#systemDevice} -eq 0 ]; then
# force RaspberryPi with no NVMe to boot from SD
if [ "${computerType}" == "raspberrypi" ] && [ ${gotNVMe} -lt 1 ] ; then
echo "# RaspberryPi with no NVMe - keep booting from SD card"
bootFromStorage=0
bootFromSD=1
# force RaspberryPi with small NVMe to boot from SD (old NVMe 1TB setups)
elif [ "${computerType}" == "raspberrypi" ] && [ ${#storageSizeGB} -gt 0 ] && [ ${storageSizeGB} -lt $((storageFullMinGB + dataMinGB + systemMinGB)) ]; then
echo "# NVMe too small to also host system - keep booting from SD card"
storageWarning='too-small-for-boot'
bootFromStorage=0
bootFromSD=1
# all other systems boot from storage
else
echo "# all other systems boot from storage"
bootFromStorage=1
bootFromSD=0
fi
# when seperate system drive is found - check size
else
# if there is a system drive but its smaller than systemMinGB - boot from storage
if [ ${systemSizeGB} -lt ${systemMinGB} ] && [ ${storageSizeGB} -gt ${storagePrunedMinGB} ]; then
echo "# seprate system too small - boot from storage"
bootFromSD=0
bootFromStorage=1
systemDevice=""
systemSizeGB=""
# dont use install device in proposed layout
elif [ "${systemDevice}" = "${installDevice}" ]; then
systemDevice=""
systemSizeGB=""
# otherwise remove the system device from the list
else
listOfDevices=$(echo "${listOfDevices}" | grep -v "${systemDevice}")
fi
fi
fi
# Set DATA (check last, because its more common to have STORAGE & DATA combined)
#echo "# Selecting DATA device:"
#echo "# - so far dataDevice(${dataDevice}) / storageDevice(${storageDevice})"
if [ ${#dataDevice} -eq 0 ] || [ "${dataDevice}" = "${storageDevice}" ]; then
# when no data device yet: take the second biggest drive as the data drive
dataDevice=$(echo "${listOfDevices}" | head -n1 | awk '{print $1}')
dataSizeGB=$(echo "${listOfDevices}" | head -n1 | awk '{print $2}')
listOfDevices=$(echo "${listOfDevices}" | grep -v "${dataDevice}")
#echo "# - seleted dataDevice: ${dataDevice} (${dataSizeGB}GB)"
# ignore system device if choosen as data device
if [ "${dataDevice}" = "${systemDevice}" ]; then
echo "# - dataDevice(${dataDevice}) is the same as system device - ignore it, check next in list"
dataDevice=$(echo "${listOfDevices}" | head -n1 | awk '{print $1}')
dataSizeGB=$(echo "${listOfDevices}" | head -n1 | awk '{print $2}')
listOfDevices=$(echo "${listOfDevices}" | grep -v "${dataDevice}")
fi
# dont use install device in proposed layout
if [ "${dataDevice}" = "${installDevice}" ]; then
echo "# - dataDevice(${dataDevice}) is the same as install device - ignore it, check next in list"
dataDevice=$(echo "${listOfDevices}" | head -n1 | awk '{print $1}')
dataSizeGB=$(echo "${listOfDevices}" | head -n1 | awk '{print $2}')
listOfDevices=$(echo "${listOfDevices}" | grep -v "${dataDevice}")
fi
# if there is was no spereated data drive - run combine data & storage partiton
if [ ${#dataDevice} -eq 0 ]; then
combinedDataStorage=1
# when data drive but no storage
elif [ ${#storageDevice} -eq 0 ]; then
echo "# ERROR: data drive but no storage"
scenario="error:system-bigger-than-storage"
# if there is a data drive but its smaller than dataMinGB & storage drive is big enough - combine data & storage partiton
elif [ ${dataSizeGB} -lt ${dataMinGB} ] && [ ${storageSizeGB} -gt ${storagePrunedMinGB} ]; then
combinedDataStorage=1
# remove the data device from the list
else
listOfDevices=$(echo "${listOfDevices}" | grep -v "${dataDevice}")
fi
else
echo "# - dataDevice(${dataDevice}) already set - skip selection"
fi
else
echo "# NO LAYOUT PROPOSAL ... using existing drive layout"
fi
#################
# Check Mininimal Sizes
# in case of combined data & storage partition
if [ ${combinedDataStorage} -eq 1 ]; then
# add dataMinGB to storagePrunedMinGB
storagePrunedMinGB=$((${storagePrunedMinGB} + ${dataMinGB}))
# add dataMinGB to storageFullMinGB
storageFullMinGB=$((${storageFullMinGB} + ${dataMinGB}))
fi
# in case of booting from storage
if [ ${bootFromStorage} -eq 1 ]; then
# add systemMinGB to storagePrunedMinGB
storagePrunedMinGB=$((${storagePrunedMinGB} + ${systemMinGB}))
# add systemMinGB to storageFullMinGB
storageFullMinGB=$((${storageFullMinGB} + ${systemMinGB}))
fi
# STORAGE
if [ ${#storageDevice} -gt 0 ]; then
if [ ${storageSizeGB} -lt ${storageFullMinGB} ]; then
storageWarning='only-pruned'
fi
if [ ${storageSizeGB} -lt ${storagePrunedMinGB} ]; then
storageWarning='too-small'
fi
fi
# SYSTEM
if [ ${#systemDevice} -gt 0 ] && [ ${bootFromStorage} -eq 0 ]; then
if [ ${systemSizeGB} -lt ${systemMinGB} ]; then
systemWarning='too-small'
fi
fi
# DATA
if [ ${#dataDevice} -gt 0 ]; then
if [ ${dataSizeGB} -lt ${dataMinGB} ]; then
dataWarning='too-small'
fi
fi
#################
# Device Names
# use: find_by_id_filename [DEVICENAME]
find_by_id_filename() {
local device="$1"
for dev in /dev/disk/by-id/*; do
if [ "$(readlink -f "$dev")" = "/dev/$device" ]; then
basename "$dev"
fi
done | sort | head -n1
}
# STORAGE
if [ ${#storageDevice} -gt 0 ]; then
storageDeviceName=$(find_by_id_filename "${storageDevice}")
fi
# SYSTEM
if [ ${#systemDevice} -gt 0 ]; then
systemDeviceName=$(find_by_id_filename "${systemDevice}")
fi
# DATA
if [ ${#dataDevice} -gt 0 ]; then
dataDeviceName=$(find_by_id_filename "${dataDevice}")
fi
# BIGGER
if [ ${#biggerDevice} -gt 0 ]; then
biggerDeviceName=$(find_by_id_filename "${biggerDevice}")
fi
# count number of partitions
storagePartitionsCount=0
systemPartitionsCount=0
dataPartitionsCount=0
if [ ${#storageDevice} -gt 0 ]; then
storagePartitionsCount=$(partx -g /dev/"${storageDevice}" 2>/dev/null | wc -l)
fi
if [ ${#systemDevice} -gt 0 ]; then
systemPartitionsCount=$(partx -g /dev/"${systemDevice}" 2>/dev/null | wc -l)
fi
if [ ${#dataDevice} -gt 0 ]; then
dataPartitionsCount=$(partx -g /dev/"${dataDevice}" 2>/dev/null | wc -l)
fi
#################
# Define Scenario
# Initialize systemCopy flag to default 0
systemCopy=0
# migration: detected data from another node implementation
if [ ${#scenario} -gt 0 ]; then
echo "# scenario already set by analysis above to: ${scenario}"
elif [ ${#storageMigration} -gt 0 ]; then
scenario="migration"
if [ "${systemMountedPath}" != "/" ] && [ ${bootFromSD} -eq 0 ]; then
systemCopy=1
fi
# nodata: no drives >64GB connected
elif [ ${#biggerDevice} -gt 0 ]; then
scenario="biggerdevice"
# nodata: no drives >64GB connected
elif [ ${#storageDevice} -eq 0 ]; then
scenario="error:no-storage"
# ready: Proxmox VM with all seperated drives mounted
elif [ ${#storageMountedPath} -gt 0 ] && [ ${#dataMountedPath} -gt 0 ] && [ ${#systemMountedPath} -gt 0 ]; then
scenario="ready"
# ready: RaspberryPi, Laptop or VM with patched thru USB drive
elif [ ${#storageMountedPath} -gt 0 ] && [ ${combinedDataStorage} -eq 1 ]; then
scenario="ready"
# recover: drives there but unmounted & blitz config exists (check raspiblitz.conf with -inspect if its update)
elif [ ${#storageDevice} -gt 0 ] && [ ${#storageMountedPath} -eq 0 ] && [ ${dataConfigFound} -eq 1 ]; then
scenario="recover"
# when not bootet from sd card and device system is not already running
if [ ${bootFromSD} -eq 0 ] && [ "${systemMountedPath}" != "/" ]; then
systemCopy=1
fi
# when storagePartition > 2 (signals that the first partions are available for system)
if [ ${#storagePartition} -gt 0 ] && [ ${storagePartitionsCount} -gt 2 ] ; then
systemCopy=1
fi
# setup: drives there but unmounted & no blitz config exists & booted from install media
elif [ ${#storageDevice} -gt 0 ] && [ ${#storageMountedPath} -eq 0 ] && [ ${dataConfigFound} -eq 0 ] && [ "${systemMountedPath}" != "/" ] && [ ${bootFromSD} -eq 0 ]; then
scenario="setup"
systemCopy=1
# setup: drives there but unmounted & no blitz config exists
elif [ ${#storageDevice} -gt 0 ] && [ ${#storageMountedPath} -eq 0 ] && [ ${dataConfigFound} -eq 0 ]; then
scenario="setup"
# UNKNOWN SCENARIO
else
scenario="error:unknown-state"
fi
# no system copy on RaspberryPi <=4
if [ "${computerType}" = "raspberrypi" ]; then
rpiVersion=$(strings /proc/device-tree/model | grep -o 'Raspberry Pi [0-9]\+' | grep -o '[0-9]\+')
if [ "${rpiVersion}" != "" ] && [ ${rpiVersion} -lt 5 ]; then
echo "# RaspberryPi4 - set systemCopy to 0"
systemCopy=0
fi
fi
# copy data mounted path on combined storage
if [ "${storagePartition}" = "${dataPartition}" ] && [ ${#dataMountedPath} -eq 0 ] && [ ${combinedDataStorage} -eq 1 ]; then
dataMountedPath="${storageMountedPath}"
fi
#echo "# Used Space"
# get used space on drives in GB
storageUsePercent=""
if [ ${#storagePartition} -gt 0 ]; then
storageUsePercent=$(df "/dev/${storagePartition}" 2>/dev/null | awk 'NR==2 {sub(/%/, "", $5); print $5}')
fi
dataUsePercent=""
if [ ${#dataPartition} -gt 0 ]; then
dataUsePercent=$(df "/dev/${dataPartition}" 2>/dev/null | awk 'NR==2 {sub(/%/, "", $5); print $5}')
elif [ ${combinedDataStorage} -eq 1 ] && [ ${#storagePartition} -gt 0 ]; then
dataUsePercent="${storageUsePercent}"
fi
systemUsePercent=""
if [ ${#systemPartition} -gt 0 ]; then
systemUsePercent=$(df "/dev/${systemPartition}" 2>/dev/null | awk 'NR==2 {sub(/%/, "", $5); print $5}')
fi
#echo "# Free Space"
# get free space on drives
if [ ${#storagePartition} -gt 0 ]; then
storageFreeKB=$(df -k | grep "/dev/${storagePartition}" 2>/dev/null | awk '{print $4}' | tail -n 1)
fi
if [ ${#dataPartition} -gt 0 ]; then
dataFreeKB=$(df -k | grep "/dev/${dataPartition}" 2>/dev/null | awk '{print $4}' | tail -n 1)
elif [ $combinedDataStorage -eq 1 ]; then
dataFreeKB="${storageFreeKB}"
fi
if [ ${#systemPartition} -gt 0 ]; then
systemFreeKB=$(df -k | grep "/dev/${systemPartition}" 2>/dev/null | awk '{print $4}' | tail -n 1)
fi
#echo "# Temperature"
# get Temperature of drives
if [ ${#storageDevice} -gt 0 ]; then
storageCelsius=$(smartctl -A /dev/${storageDevice} 2>/dev/null | grep -E '^Temperature:|Temperature Sensor' | awk '{print $(NF-1)}' | head -n 1)
fi
if [ ${#dataDevice} -gt 0 ]; then
dataCelsius=$(smartctl -A /dev/${dataDevice} 2>/dev/null | grep -E '^Temperature:|Temperature Sensor' | awk '{print $(NF-1)}' | head -n 1)
elif [ $combinedDataStorage -eq 1 ]; then
dataCelsius="${storageCelsius}"
fi
if [ ${#systemDevice} -gt 0 ]; then
systemCelsius=$(smartctl -A /dev/${systemDevice} 2>/dev/null | grep -E '^Temperature:|Temperature Sensor' | awk '{print $(NF-1)}' | head -n 1)
fi
#echo "# Unused Space"
# get unused space on drives
storageUnusedPercent=0
dataUnusedPercent=0
systemUnusedPercent=0
if [ ${#storageDevice} -gt 0 ]; then
storageUnusedPercent=$(parted -s /dev/${storageDevice} unit % print free 2>/dev/null | awk '/Free Space/ {v=$(NF-2); gsub(/[^0-9.]/, "", v)} END{print int(v)}')
fi
if [ ${#dataDevice} -gt 0 ]; then
dataUnusedPercent=$(parted -s /dev/${dataDevice} unit % print free 2>/dev/null | awk '/Free Space/ {v=$(NF-2); gsub(/[^0-9.]/, "", v)} END{print int(v)}')
fi
if [ ${#systemDevice} -gt 0 ]; then
systemUnusedPercent=$(parted -s /dev/${systemDevice} unit % print free 2>/dev/null | awk '/Free Space/ {v=$(NF-2); gsub(/[^0-9.]/, "", v)} END{print int(v)}')
fi
#echo "# RESULTS"
# output the result
echo "scenario='${scenario}'"
echo "scenarioSystemCopy='${systemCopy}'"
echo "storageDevice='${storageDevice}'"
echo "storageDeviceName='${storageDeviceName}'"
echo "storageSizeGB='${storageSizeGB}'"
echo "storagePrunedMinGB='${storagePrunedMinGB}'"
echo "storageFullMinGB='${storageFullMinGB}'"
echo "storageFreeKB='${storageFreeKB}'"
echo "storageUsePercent='${storageUsePercent}'"
echo "storageCelsius='${storageCelsius}'"
echo "storageWarning='${storageWarning}'"
echo "storagePartition='${storagePartition}'"
echo "storagePartitionsCount='${storagePartitionsCount}'"
echo "storageMountedPath='${storageMountedPath}'"
echo "storageBlockchainGB='${storageBlockchainGB}'"
echo "storageMigration='${storageMigration}'"
echo "storageUnusedSpacePercent='${storageUnusedPercent}'"
echo "systemDevice='${systemDevice}'"
echo "systemDeviceName='${systemDeviceName}'"
echo "systemSizeGB='${systemSizeGB}'"
echo "systemMinGB='${systemMinGB}'"
echo "systemFreeKB='${systemFreeKB}'"
echo "systemWarning='${systemWarning}'"
echo "systemUsePercent='${systemUsePercent}'"
echo "systemCelsius='${systemCelsius}'"
echo "systemPartition='${systemPartition}'"
echo "systemPartitionsCount='${systemPartitionsCount}'"
echo "systemMountedPath='${systemMountedPath}'"
echo "systemUnusedSpacePercent='${systemUnusedPercent}'"
echo "dataDevice='${dataDevice}'"
echo "dataDeviceName='${dataDeviceName}'"
echo "dataSizeGB='${dataSizeGB}'"
echo "dataMinGB='${dataMinGB}'"
echo "dataFreeKB='${dataFreeKB}'"
echo "dataWarning='${dataWarning}'"
echo "dataUsePercent='${dataUsePercent}'"
echo "dataCelsius='${dataCelsius}'"
echo "dataPartition='${dataPartition}'"
echo "dataPartitionsCount='${dataPartitionsCount}'"
echo "dataMountedPath='${dataMountedPath}'"
echo "dataConfigFound='${dataConfigFound}'"
echo "dataInspectSuccess='${dataInspectSuccess}'"
echo "dataUnusedSpacePercent='${dataUnusedPercent}'"
echo "installDevice='${installDevice}'"
echo "installDeviceActive='${installDeviceActive}'"
echo "installDeviceReadOnly='${installDeviceReadOnly}'"
echo "biggerDevice='${biggerDevice}'"
echo "biggerDeviceName='${biggerDeviceName}'"
echo "biggerSizeGB='${biggerSizeGB}'"
echo "combinedDataStorage='${combinedDataStorage}'"
echo "bootFromStorage='${bootFromStorage}'"
echo "bootFromSD='${bootFromSD}'"
echo "swapActive='${swapActive}'"
# save to cache when -inspect
if [ ${userWantsInspect} -eq 1 ]; then
echo "# saving values to cache as system_setup_*"
/home/admin/_cache.sh set "system_setup_bootFromStorage" "${bootFromStorage}"
/home/admin/_cache.sh set "system_setup_combinedDataStorage" "${combinedDataStorage}"
/home/admin/_cache.sh set "system_setup_storageDevice" "${storageDevice}"
/home/admin/_cache.sh set "system_setup_storageDeviceName" "${storageDeviceName}"
/home/admin/_cache.sh set "system_setup_storageSizeGB" "${storageSizeGB}"
/home/admin/_cache.sh set "system_setup_storageWarning" "${storageWarning}"
/home/admin/_cache.sh set "system_setup_storageBlockchainGB" "${storageBlockchainGB}"
/home/admin/_cache.sh set "system_setup_storageMigration" "${storageMigration}"
/home/admin/_cache.sh set "system_setup_storagePartitionsCount" "${storagePartitionsCount}"
/home/admin/_cache.sh set "system_setup_systemDevice" "${systemDevice}"
/home/admin/_cache.sh set "system_setup_systemDeviceName" "${storageDeviceName}"
/home/admin/_cache.sh set "system_setup_systemSizeGB" "${systemSizeGB}"
/home/admin/_cache.sh set "system_setup_systemWarning" "${systemWarning}"
/home/admin/_cache.sh set "system_setup_dataDevice" "${dataDevice}"
/home/admin/_cache.sh set "system_setup_dataDeviceName" "${dataDeviceName}"
/home/admin/_cache.sh set "system_setup_dataSizeGB" "${dataSizeGB}"
/home/admin/_cache.sh set "system_setup_dataWarning" "${dataWarning}"
/home/admin/_cache.sh set "system_setup_installDevice" "${installDevice}"
/home/admin/_cache.sh set "system_setup_installDeviceReadOnly" "${installDeviceReadOnly}"
fi
if [ "$action" = "status" ]; then
exit 0
fi
fi
##############################
# MOUNT
# perma mount all devices
#############################
if [ "$action" = "mount" ]; then
mainMountPoint="/mnt/hdd"
storageMountPoint="/mnt/disk_storage"
dataMountPoint="/mnt/disk_data"
# Source status to get drive configuration
source <(/home/admin/config.scripts/blitz.data.sh status)
# check directories are already mounted
if [ $(df | grep -c "${storageMountPoint}") -gt 0 ]; then
echo "# Already mounted: ${storageMountPoint}"
exit 1
fi
if [ ${combinedDataStorage} -eq 0 ] && [ $(df | grep -c "${dataMountPoint}") -gt 0 ]; then
echo "# Already mounted: ${dataMountPoint}"
exit 1
fi
# check partitions were found
if [ ${#storagePartition} -eq 0 ]; then
echo "error='storagePartition not detected'"
exit 1
fi
if [ ${#dataPartition} -eq 0 ] && [ ${combinedDataStorage} -eq 0 ]; then
echo "error='dataPartition not detected'"
exit 1
fi
# debug info
echo "# storagePartition: ${storagePartition}"
echo "# dataPartition: ${dataPartition}"
# check if partititions are already mounted
if [ $(findmnt -n -o SOURCE,TARGET | grep -c "/dev/${storagePartition}") -gt 0 ]; then
echo "# Already mounted: ${storagePartition}"
exit 1
fi
if [ ${combinedDataStorage} -eq 0 ] && [ $(findmnt -n -o SOURCE,TARGET | grep -c "/dev/${dataPartition}") -gt 0 ]; then
echo "# Already mounted: ${dataPartition}"
exit 1
fi
# determine UUID of storage partition
storageUUID=$(blkid -s UUID -o value "/dev/${storagePartition}")
if [ "${storageUUID}" = "" ]; then
echo "# storageUUID not found with blkid - trying lsblk"
storageUUID=$(lsblk -n -o UUID "/dev/${storagePartition}")
fi
if [ "${storageUUID}" = "" ]; then
echo "error='Could not find UUID for storage partition ${storagePartition} (${storageUUID})'"
exit 1
fi
# determine UUID of data partition (if needed)
dataUUID=""
if [ ${combinedDataStorage} -eq 0 ]; then
dataUUID=$(blkid -s UUID -o value "/dev/${dataPartition}")
if [ "${dataUUID}" = "" ]; then
echo "# dataUUID not found with blkid - trying lsblk"
dataUUID=$(lsblk -n -o UUID "/dev/${dataPartition}")
fi
if [ "${dataUUID}" = "" ]; then
echo "error='Could not find UUID for data partition ${dataPartition} (${dataUUID})'"
exit 1
fi
fi
# debug info
echo "# storageUUID: ${storageUUID}"
echo "# dataUUID: ${dataUUID}"
echo "# storageMountPoint: ${storageMountPoint}"
echo "# dataMountPoint: ${dataMountPoint}"
echo "# mainMountPoint: ${mainMountPoint}"
echo "# combinedDataStorage: ${combinedDataStorage}"
# update fstab
sed -i "\#${storageMountPoint}#d" /etc/fstab
sed -i "/UUID=${storageUUID}/d" /etc/fstab
echo "# Updating fstab for ${storagePartition} (${storageUUID}) -> ${storageMountPoint}"
echo "UUID=${storageUUID} ${storageMountPoint} ext4 defaults,noexec 0 2" >> /etc/fstab
echo "# combinedDataStorage: ${combinedDataStorage}"
if [ ${combinedDataStorage} -eq 0 ]; then
sed -i "\#${dataMountPoint}#d" /etc/fstab
sed -i "/UUID=${dataUUID}/d" /etc/fstab
echo "# Also Updating fstab for ${dataPartition} (${dataUUID}) -> ${dataMountPoint}"
echo "UUID=${dataUUID} ${dataMountPoint} ext4 defaults,noexec 0 2" >> /etc/fstab
fi
# Ensure all potential mount points exist
echo "# Running mount -a"
sync
systemctl daemon-reload
mkdir -p ${storageMountPoint} ${dataMountPoint} ${mainMountPoint}
chmod 000 ${storageMountPoint} ${dataMountPoint} ${mainMountPoint}
mount -a
sleep 2
# Verify mounts after attempt
if [ $(df | grep -c "${storageMountPoint}") -eq 0 ]; then
echo "error='Failed to mount ${storagePartition} on ${storageMountPoint} after fstab update'"
exit 1
fi
if [ ${combinedDataStorage} -eq 0 ] && [ $(df | grep -c "${dataMountPoint}") -eq 0 ]; then
echo "error='Failed to mount ${dataPartition} on ${dataMountPoint} after fstab update'"
exit 1
fi
echo "# Mount successful." >> ${logFile}
exit 0
fi
###################
# LINK
###################
if [ "$action" = "link" ]; then
mainMountPoint="/mnt/hdd"
# Source status to get drive configuration
source <(/home/admin/config.scripts/blitz.data.sh status)
# check drive pathes are available
if [ ${#storageMountedPath} -eq 0 ]; then
echo "error='storageMountedPath not detected'"
exit 1
fi
if [ ${combinedDataStorage} -eq 1 ]; then
dataMountedPath="${storageMountedPath}"
else
if [ ${#dataMountedPath} -eq 0 ]; then
echo "error='dataMountedPath not detected'"
exit 1
fi
fi
echo "# storageMountedPath: ${storageMountedPath}"
echo "# dataMountedPath: ${dataMountedPath}"
echo "# mainMountPoint: ${mainMountPoint}"
####################################
# combine storage & data
echo "# adding main folders to ${mainMountPoint}"
mkdir -p ${mainMountPoint}
# /app-storage
unlink ${mainMountPoint}/app-storage 2>/dev/null
if [ -d "${mainMountPoint}/app-storage" ]; then
echo "error='${mainMountPoint}/app-storage is real directory'"
exit 1
fi
ln -s ${storageMountedPath}/app-storage ${mainMountPoint}/app-storage
chown bitcoin:bitcoin ${storageMountedPath}/app-storage ${mainMountPoint}/app-storage
chmod 755 ${storageMountedPath}/app-storage ${mainMountPoint}/app-storage
chmod o+x ${storageMountedPath}
chmod o+x ${storageMountedPath}/app-storage
# /app-data
unlink ${mainMountPoint}/app-data 2>/dev/null
if [ -d "${mainMountPoint}/app-data" ];then
echo "error='${mainMountPoint}/app-data is real directory'"
exit 1
fi
ln -s ${dataMountedPath}/app-data ${mainMountPoint}/app-data
chown bitcoin:bitcoin ${dataMountedPath}/app-data ${mainMountPoint}/app-data
mkdir -p /mnt/hdd/app-data/bitcoin/wallets 2>/dev/null
chown -R bitcoin:bitcoin ${dataMountedPath}/app-data/bitcoin
chmod 755 ${dataMountedPath}/app-data ${mainMountPoint}/app-data
chmod o+x ${dataMountedPath}
chmod o+x ${dataMountedPath}/app-data
# /temp
mkdir -p ${storageMountedPath}/temp 2>/dev/null
unlink ${mainMountPoint}/temp 2>/dev/null
ln -s ${storageMountedPath}/temp ${mainMountPoint}/temp
chown bitcoin:bitcoin ${mainMountPoint}/temp
chmod 777 ${storageMountedPath}/temp
chmod 777 ${mainMountPoint}/temp
# /mnt/hdd/bitcoin directory (move old data if needed & link for backwards compatibility)
mkdir -p "${storageMountedPath}/app-storage/bitcoin"
mkdir -p "${dataMountedPath}/app-data/bitcoin"
chown bitcoin:bitcoin "${dataMountedPath}/app-data/bitcoin"
if [ -d "${storageMountedPath}/bitcoin" ]; then
echo "# moving old data from ${storageMountedPath}/bitcoin to ${storageMountedPath}/app-storage/bitcoin"
rsync -a --remove-source-files --prune-empty-dirs ${storageMountedPath}/bitcoin/ ${storageMountedPath}/app-storage/bitcoin/
if [ $? -ne 0 ]; then
echo "error='failed to move ${storageMountedPath}/bitcoin/* to ${storageMountedPath}/app-storage/bitcoin/'"
else
rm -rf ${storageMountedPath}/bitcoin
fi
fi
if [ -d "${storageMountedPath}/app-storage/bitcoin/wallet.dat" ]; then
echo "# moving old wallet from ${storageMountedPath}/app-storage/bitcoin/wallet.dat to ${dataMountedPath}/app-data/bitcoin/wallets/wallet.dat"
mv --force ${storageMountedPath}/app-storage/bitcoin/wallet.dat ${dataMountedPath}/app-data/bitcoin/wallets/wallet.dat
if [ $? -ne 0 ]; then
echo "error='failed to move ${storageMountedPath}/app-storage/bitcoin/wallet.dat to ${dataMountedPath}/app-data/bitcoin/wallets/wallet.dat'"
fi
fi
if [ -f "${storageMountedPath}/app-storage/bitcoin/bitcoin.conf" ] && [ ! -L "${storageMountedPath}/app-storage/bitcoin/bitcoin.conf" ]; then
if [ ! -f "${dataMountedPath}/app-data/bitcoin/bitcoin.conf" ]; then
echo "# moving bitcoin config file from ${storageMountedPath}/app-storage/bitcoin to ${dataMountedPath}/app-data/bitcoin"
mv --force ${storageMountedPath}/app-storage/bitcoin/bitcoin.conf ${dataMountedPath}/app-data/bitcoin/bitcoin.conf
if [ $? -ne 0 ]; then
echo "error='failed to move ${storageMountedPath}/app-storage/bitcoin/bitcoin.conf to ${dataMountedPath}/app-data/bitcoin/bitcoin.conf'"
fi
else
echo "error='there is ${storageMountedPath}/app-storage/bitcoin/bitcoin.conf AND ${dataMountedPath}/app-data/bitcoin/bitcoin.conf'"
fi
fi
unlink ${mainMountPoint}/app-storage/bitcoin/bitcoin.conf 2>/dev/null
echo "# For backwards compatibility: Liniking ${mainMountPoint}/bitcoin"
unlink ${mainMountPoint}/bitcoin 2>/dev/null
ln -s ${storageMountedPath}/app-storage/bitcoin ${mainMountPoint}/bitcoin
chown bitcoin:bitcoin ${mainMountPoint}/bitcoin
chmod 777 ${mainMountPoint}/bitcoin
# /mnt/hdd/lnd directory (move old data if needed & link for backwards compatibility)
mkdir -p "${dataMountedPath}/app-data/lnd"
chown bitcoin:bitcoin "${dataMountedPath}/app-data/lnd"
if [ -d "${storageMountedPath}/lnd" ]; then
echo "# moving old data from ${storageMountedPath}/lnd to ${dataMountedPath}/app-data/lnd"
rsync -a --remove-source-files --prune-empty-dirs ${storageMountedPath}/lnd/ ${dataMountedPath}/app-data/lnd/
if [ $? -ne 0 ]; then
echo "error='failed to rsync /app-data/lnd/'"
else
rm -rf ${storageMountedPath}/lnd
fi
fi
echo "# For backwards compatibility: Liniking ${mainMountPoint}/lnd"
unlink ${mainMountPoint}/lnd 2>/dev/null
if [ -d "${mainMountPoint}/lnd" ]; then
echo "error='${mainMountPoint}/lnd is real directory'"
exit 1
fi
ln -s ${dataMountedPath}/app-data/lnd ${mainMountPoint}/lnd
chown bitcoin:bitcoin ${mainMountPoint}/lnd
chmod 770 ${mainMountPoint}/lnd
# /mnt/hdd/tor directory (move old data if needed & link for backwards compatibility)
mkdir -p "${dataMountedPath}/app-data/tor"
chown debian-tor:debian-tor "${dataMountedPath}/app-data/tor"
if [ -d "${storageMountedPath}/tor" ]; then
echo "# moving old data from ${storageMountedPath}/tor to ${dataMountedPath}/app-data/tor"
rsync -a --remove-source-files --prune-empty-dirs ${storageMountedPath}/tor/ ${dataMountedPath}/app-data/tor/
if [ $? -ne 0 ]; then
echo "error='failed to rsync /app-data/tor/'"
else
rm -rf ${storageMountedPath}/tor
fi
fi
echo "# For backwards compatibility: Liniking ${mainMountPoint}/tor"
unlink ${mainMountPoint}/tor 2>/dev/null
if [ -d "${mainMountPoint}/tor" ]; then
echo "error='${mainMountPoint}/tor is real directory'"
exit 1
fi
chown -R debian-tor:debian-tor ${mainMountPoint}/app-data/tor
chmod -R 700 ${mainMountPoint}/app-data/tor
ln -s ${dataMountedPath}/app-data/tor ${mainMountPoint}/tor
chown debian-tor:debian-tor ${mainMountPoint}/tor
chmod 700 ${mainMountPoint}/tor
# /mnt/hdd/aspiblitz.conf (move old file if needed & link for backwards compatibility)
if [ -f "${storageMountedPath}/raspiblitz.conf" ] && [ ! -L "${storageMountedPath}/raspiblitz.conf" ]; then
echo "# moving old config from ${storageMountedPath}/raspiblitz.conf to ${dataMountedPath}/app-data/raspiblitz.conf"
mv --force ${storageMountedPath}/raspiblitz.conf ${dataMountedPath}/app-data/raspiblitz.conf
fi
if [ -f "${mainMountPoint}/raspiblitz.conf" ] && [ ! -L "${mainMountPoint}/raspiblitz.conf" ]; then
mv --force ${mainMountPoint}/raspiblitz.conf ${mainMountPoint}/app-data/raspiblitz.conf
fi
echo "you find bitcoin.conf now in ${mainMountPoint}/app-data/bitcoin/bitcoin.conf" > ${mainMountPoint}/bitcoin/bitcoin-conf.info
if [ -f "${mainMountPoint}/.tmux.conf.local" ] && [ ! -L "${mainMountPoint}/.tmux.conf.local" ]; then
mv --force ${mainMountPoint}/.tmux.conf.local ${mainMountPoint}/app-data/.tmux.conf.local
fi
if [ -f "${storageMountedPath}/.tmux.conf.local" ] && [ ! -L "${storageMountedPath}/.tmux.conf.local" ]; then
mv --force ${storageMountedPath}/.tmux.conf.local ${mainMountPoint}/app-data/.tmux.conf.local
fi
### bitcoin user symbol links
echo "# bitcoin user symbol link: /home/bitcoin/.bitcoin"
unlink /home/bitcoin/.bitcoin 2>/dev/null
ln -s /mnt/hdd/app-data/bitcoin /home/bitcoin/.bitcoin
chown bitcoin:bitcoin /home/bitcoin/.bitcoin
echo "# bitcoin user symbol link: /home/bitcoin/.lnd"
unlink /home/bitcoin/.lnd 2>/dev/null
ln -s /mnt/hdd/app-data/lnd /home/bitcoin/.lnd
chown bitcoin:bitcoin /home/bitcoin/.lnd
### admin user symbol links
echo "# admin user symbol link: /home/admin/.bitcoin"
unlink /home/admin/.bitcoin 2>/dev/null
ln -s /mnt/hdd/app-data/bitcoin /home/admin/.bitcoin
echo "# admin user symbol link: /home/admin/.lnd"
unlink /home/admin/.lnd 2>/dev/null
ln -s /mnt/hdd/app-data/lnd /home/admin/.lnd
chmod -R g+X /home/admin/.lnd
# set permissions on complete lnd macaroon folder path
chmod a+rx ${mainMountPoint} 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data/chain 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data/chain/bitcoin 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data/chain/bitcoin/mainnet 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data/chain/bitcoin/testnet 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/data/chain/bitcoin/signet 2>/dev/null
chmod a+rx ${mainMountPoint}/app-data/lnd/tls.cert 2>/dev/null
exit 0
fi
###################
# COPY-SYSTEM
###################
if [ "$action" = "copy-system" ]; then
actionDevice=$2
actionDeviceType=$(echo "$3" | tr '[:upper:]' '[:lower:]')
echo "STARTED blitz.data.sh ${action} (${actionDevice})..." >> ${logFile}
# check that device is set & exists & not mounted
if [ ${#actionDevice} -eq 0 ]; then
echo "error='missing device'"
echo "error='missing device'" >> ${logFile}
exit 1
fi
if ! lsblk -no NAME | grep -q "${actionDevice}$"; then
echo "error='device not found'"
echo "error='device not found'" >> ${logFile}
exit 1
fi
if findmnt -n -o TARGET "/dev/${actionDevice}" 2>/dev/null; then
echo "error='device is mounted'"
echo "error='device is mounted'" >> ${logFile}
exit 1
fi
# determine the partition base name
actionDevicePartitionBase=${actionDevice}
if [[ "${actionDevice}" =~ nvme ]]; then
actionDevicePartitionBase="${actionDevice}p"
fi
if [ "${actionDeviceType}" != "system" ] && [ "${actionDeviceType}" != "storage" ]; then
echo "# actionDeviceType(${actionDeviceType}) UNKOWN" >> ${logFile}
echo "error='type not supported'"
exit 1
fi
if [ "${actionDeviceType}" = "system" ]; then
systemPartition="${actionDevicePartitionBase}2"
fi
if [ "${actionDeviceType}" = "storage" ]; then
systemPartition="${actionDevicePartitionBase}2"
fi
# debug info
echo "# actionDevice(${actionDevice})" >> ${logFile}
echo "# actionDevicePartitionBase(${actionDevicePartitionBase})" >> ${logFile}
echo "# actionDeviceType(${actionDeviceType})" >> ${logFile}
echo "# systemPartition(${systemPartition})" >> ${logFile}
echo "# computerType(${computerType})" >> ${logFile}
##########################
# MAKE BOOTABLE
echo "# MAKE BOOTABLE" >> ${logFile}
# RASPBERRY PI
if [ "${computerType}" = "raspberrypi" ]; then
echo "# RaspberryPi - set LBA flag" >> ${logFile}
parted /dev/${actionDevice} --script set 1 lba on
isFlagSetLBA=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*lba')
if [ ${isFlagSetLBA} -eq 0 ]; then
echo "error='failed to set LBA flag'"
exit 1
fi
echo "# RaspberryPi - Bootorder" >> ${logFile}
isBootOrderSet=$(sudo rpi-eeprom-config | grep -cx "BOOT_ORDER=0xf461")
if [ ${isBootOrderSet} -eq 0 ]; then
echo "# .. changeing Bootorder" >> ${logFile}
rpi-eeprom-config --out bootconf.txt
sed -i '/^BOOT_ORDER=/d' ./bootconf.txt && sudo sh -c 'echo "BOOT_ORDER=0xf461" >> ./bootconf.txt'
rpi-eeprom-config --apply bootconf.txt
rm bootconf.txt
else
echo "# .. Bootorder already set" >> ${logFile}
fi
# VM & PC
else
echo "# VM & PC - set BOOT/ESP flag" >> ${logFile}
parted /dev/${actionDevice} --script set 1 boot on
parted /dev/${actionDevice} --script set 1 esp on
isFlagSetBOOT=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*boot')
if [ ${isFlagSetBOOT} -eq 0 ]; then
echo "error='failed to set BOOT flag'"
exit 1
fi
isFlagSetESP=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*esp')
if [ ${isFlagSetESP} -eq 0 ]; then
echo "error='failed to set ESP flag'"
exit 1
fi
fi
##########################
# COPY SYSTEM
echo "# SYSTEM COPY" >> ${logFile}
# copy the boot drive
bootPath="/boot/efi"
bootPathEscpaed="\/boot\/efi"
if [ "${computerType}" = "raspberrypi" ]; then
bootPath="/boot/firmware/"
bootPathEscpaed="\/boot\/firmware"
fi
rm -rf /mnt/disk_boot 2>/dev/null
mkdir -p /mnt/disk_boot 2>/dev/null
mount /dev/${actionDevicePartitionBase}1 /mnt/disk_boot
if ! findmnt -n -o TARGET "/mnt/disk_boot" 2>/dev/null; then
echo "error='boot partition not mounted'"
exit 1
fi
if [ "${computerType}" = "raspberrypi" ]; then
echo "# .. boot rsync start" >> ${logFile}
echo "boot" > /var/cache/raspiblitz/temp/progress.txt
rsync -axHAX --delete --info=progress2 ${bootPath} /mnt/disk_boot/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='fail on boot copy'"
exit 1
fi
echo "# OK - Boot copied" >> ${logFile}
fi
# copy the system drive
echo "# .. copy system" >> ${logFile}
rm -rf /mnt/disk_system 2>/dev/null
mkdir -p /mnt/disk_system 2>/dev/null
mount /dev/${actionDevicePartitionBase}2 /mnt/disk_system
if ! findmnt -n -o TARGET "/mnt/disk_system" 2>/dev/null; then
echo "error='system partition not mounted'"
exit 1
fi
echo "# .. system rsync start" >> ${logFile}
echo "system" > /var/cache/raspiblitz/temp/progress.txt
rsync -axHAX --delete\
--exclude=/dev/* \
--exclude=/proc/* \
--exclude=/sys/* \
--exclude=/tmp/* \
--exclude=/run/* \
--exclude=/mnt/* \
--exclude=/media/* \
--exclude=${bootPath}/* \
--exclude=/lost+found \
--exclude=/var/cache/* \
--exclude=/var/tmp/* \
--exclude=/var/log/* \
--info=progress2 / /mnt/disk_system/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='fail on system copy'"
exit 1
fi
echo "# OK - System copied" >> ${logFile}
# needed after fixes
mkdir -p /mnt/disk_system/var/log/redis
touch /mnt/disk_system/var/log/redis/redis-server.log
chown redis:redis /mnt/disk_system/var/log/redis/redis-server.log
chmod 644 /mnt/disk_system/var/log/redis/redis-server.log
# fstab link & command.txt
echo "# Perma mount boot & system drives" >> ${logFile}
BOOT_UUID=$(blkid -s UUID -o value /dev/${actionDevicePartitionBase}1)
ROOT_UUID=$(blkid -s UUID -o value /dev/${actionDevicePartitionBase}2)
ROOT_PARTUUID=$(sudo blkid -s PARTUUID -o value /dev/${actionDevicePartitionBase}2)
echo "# - BOOT_UUID(${BOOT_UUID})" >> ${logFile}
echo "# - ROOT_UUID(${ROOT_UUID})" >> ${logFile}
if [ "${computerType}" = "raspberrypi" ]; then
echo "# - RaspberryPi - edit command.txt" >> ${logFile}
sed -i "s|PARTUUID=[^ ]*|PARTUUID=$ROOT_PARTUUID|" /mnt/disk_boot/cmdline.txt
fi
cat > /mnt/disk_system/etc/fstab << EOF
# /etc/fstab: static file system information
#
# <file system> <mount point> <type> <options> <dump> <pass>
UUID=${ROOT_UUID} / ext4 defaults,noatime 0 1
UUID=${BOOT_UUID} ${bootPath} vfat defaults,noatime,umask=0077 0 2
EOF
# install EFI GRUB for VM & PC
if [ "${computerType}" != "raspberrypi" ]; then
echo "# EFI GRUB" >> ${logFile}
DISK_SYSTEM="/mnt/disk_system"
BOOT_PARTITION="/dev/${actionDevicePartitionBase}1"
ROOT_PARTITION="/dev/${actionDevicePartitionBase}2"
echo "# Mounting root and boot partitions..." >> ${logFile}
umount /mnt/disk_boot 2>/dev/null
mkdir -p $DISK_SYSTEM/boot/efi 2>/dev/null
mount $BOOT_PARTITION $DISK_SYSTEM/boot/efi || { echo "Failed to mount boot partition"; exit 1; }
echo "# Bind mounting system directories..." >> ${logFile}
mount --bind /dev $DISK_SYSTEM/dev || { echo "Failed to bind /dev"; exit 1; }
mount --bind /sys $DISK_SYSTEM/sys || { echo "Failed to bind /sys"; exit 1; }
mount --bind /proc $DISK_SYSTEM/proc || { echo "Failed to bind /proc"; exit 1; }
rm $DISK_SYSTEM/etc/resolv.conf
cp /etc/resolv.conf $DISK_SYSTEM/etc/resolv.conf || { echo "Failed to copy resolv.conf"; exit 1; }
echo "# Entering chroot and setting up GRUB..." >> ${logFile}
chroot $DISK_SYSTEM /bin/bash <<EOF
apt-get install -y grub-efi-amd64 efibootmgr
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck
update-grub
EOF
umount $DISK_SYSTEM/boot/efi
umount $DISK_SYSTEM
fi
rm /var/cache/raspiblitz/temp/progress.txt
echo "# OK - ${action} done" >> ${logFile}
exit 0
fi
###################
# FORMAT
###################
if [ "$action" = "setup" ]; then
echo "STARTED blitz.data.sh ${action} ..." >> ${logFile}
# check that it is a valid setup type: STORAGE, DATA, SYSTEM
actionType=$2
if [ "${actionType}" != "STORAGE" ] && [ "${actionType}" != "DATA" ] && [ "${actionType}" != "SYSTEM" ]; then
echo "# actionType(${actionType})"
echo "error='setup type not supported'"
echo "error='setup type not supported'" >> ${logFile}
exit 1
fi
# check that device is set & exists & not mounted
actionDevice=$3
if [ ${#actionDevice} -eq 0 ]; then
echo "error='missing device'"
echo "error='missing device'" >> ${logFile}
exit 1
fi
if ! lsblk -no NAME | grep -q "${actionDevice}$"; then
echo "error='device not found'"
echo "error='device not found'" >> ${logFile}
exit 1
fi
if findmnt -n -o TARGET "/dev/${actionDevice}" 2>/dev/null; then
echo "error='device is mounted'"
echo "error='device is mounted'" >> ${logFile}
exit 1
fi
# check if data should also be combined with storage
actionCombinedData=$4
if [ ${#actionCombinedData} -gt 0 ] && [ "${actionCombinedData}" != "combinedData=1" ] && [ "${actionCombinedData}" != "0" ] && [ "${actionCombinedData}" != "1" ]; then
echo "error='combinedData(${actionCombinedData})'" >> ${logFile}
echo "error='combinedData value not supported'"
exit 1
fi
if [ "${actionCombinedData}" = "combinedData=1" ] || [ "${actionCombinedData}" = "1" ]; then
actionCombinedData=1
else
actionCombinedData=0
fi
# check if boot should be from storage (create system partition)
actionCreateSystemPartition=$5
if [ ${#actionCreateSystemPartition} -gt 0 ] && [ "${actionCreateSystemPartition}" != "addSystemPartition=0" ] && [ "${actionCreateSystemPartition}" != "addSystemPartition=1" ] && [ "${actionCreateSystemPartition}" != "0" ] && [ "${actionCreateSystemPartition}" != "1" ]; then
echo "error='addSystemPartition(${actionCreateSystemPartition})'" >> ${logFile}
echo "error='addSystemPartition value not supported'"
exit 1
fi
if [ "${actionCreateSystemPartition}" = "addSystemPartition=1" ] || [ "${actionCreateSystemPartition}" = "1" ]; then
actionCreateSystemPartition=1
else
actionCreateSystemPartition=0
fi
# determine the partition base name
actionDevicePartitionBase=${actionDevice}
if [[ "${actionDevice}" =~ ^nvme ]]; then
actionDevicePartitionBase="${actionDevice}p"
fi
source <(/home/admin/config.scripts/blitz.data.sh status)
# debug info
echo "# actionType(${actionType})" >> ${logFile}
echo "# actionDevice(${actionDevice})" >> ${logFile}
echo "# actionDevicePartitionBase(${actionDevicePartitionBase})" >> ${logFile}
echo "# actionCombinedData(${actionCombinedData})" >> ${logFile}
echo "# actionCreateSystemPartition(${actionCreateSystemPartition})" >> ${logFile}
##########################
# PARTITION & FORMAT
# SYSTEM (single drive)
if [ "${actionType}" = "SYSTEM" ]; then
if [ ${systemMountedPath} = "/" ]; then
echo "# SYSTEM -> partitioning & format because its running & mounted system" >> ${logFile}
else
echo "# SYSTEM partitioning" >> ${logFile}
sfdisk --delete /dev/${actionDevice} 2>/dev/null
wipefs -a /dev/${actionDevice} 2>/dev/null
parted /dev/${actionDevice} --script mklabel msdos
parted /dev/${actionDevice} --script mkpart primary fat32 1MiB 513MiB
parted /dev/${actionDevice} --script mkpart primary ext4 541MB 100%
partprobe /dev/${actionDevice}
wipefs -a /dev/${actionDevicePartitionBase}1 2>/dev/null
mkfs.fat -F 32 /dev/${actionDevicePartitionBase}1
wipefs -a /dev/${actionDevicePartitionBase}2 2>/dev/null
mkfs -t ext4 /dev/${actionDevicePartitionBase}2
# MAKE BOOTABLE
echo "# MAKE BOOTABLE" >> ${logFile}
# RASPBERRY PI
if [ "${computerType}" = "raspberrypi" ]; then
echo "# RaspberryPi - set LBA flag" >> ${logFile}
parted /dev/${actionDevice} --script set 1 lba on
isFlagSetLBA=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*lba')
if [ ${isFlagSetLBA} -eq 0 ]; then
echo "error='failed to set LBA flag'"
exit 1
fi
echo "# RaspberryPi - Bootorder" >> ${logFile}
isBootOrderSet=$(sudo rpi-eeprom-config | grep -cx "BOOT_ORDER=0xf461")
if [ ${isBootOrderSet} -eq 0 ]; then
echo "# .. changeing Bootorder" >> ${logFile}
rpi-eeprom-config --out bootconf.txt
sed -i '/^BOOT_ORDER=/d' ./bootconf.txt && sudo sh -c 'echo "BOOT_ORDER=0xf461" >> ./bootconf.txt'
rpi-eeprom-config --apply bootconf.txt
rm bootconf.txt
else
echo "# .. Bootorder already set" >> ${logFile}
fi
# VM & PC
else
echo "# VM & PC - set BOOT/ESP flag" >> ${logFile}
parted /dev/${actionDevice} --script set 1 boot on
parted /dev/${actionDevice} --script set 1 esp on
isFlagSetBOOT=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*boot')
if [ ${isFlagSetBOOT} -eq 0 ]; then
echo "error='failed to set BOOT flag'"
exit 1
fi
isFlagSetESP=$(parted /dev/${actionDevice} --script print | grep -c 'fat32.*esp')
if [ ${isFlagSetESP} -eq 0 ]; then
echo "error='failed to set ESP flag'"
exit 1
fi
fi
fi
# STOARGE with System partition (if addSystemPartition=1)
elif [ "${actionType}" = "STORAGE" ] && [ ${actionCreateSystemPartition} -eq 1 ]; then
echo "# STORAGE partitioning (with boot)" >> ${logFile}
sfdisk --delete /dev/${actionDevice} >> ${logFile}
wipefs -a /dev/${actionDevice} >> ${logFile}
parted /dev/${actionDevice} --script mklabel msdos >> ${logFile}
parted /dev/${actionDevice} --script mkpart primary fat32 1MiB 513MiB >> ${logFile}
parted /dev/${actionDevice} --script mkpart primary ext4 541MB 65GB >> ${logFile}
parted /dev/${actionDevice} --script mkpart primary ext4 65GB 100% >> ${logFile}
partprobe /dev/${actionDevice}
echo "# .. formating" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}1 2>/dev/null >> ${logFile}
mkfs.fat -F 32 /dev/${actionDevicePartitionBase}1 >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}2 2>/dev/null >> ${logFile}
mkfs -t ext4 /dev/${actionDevicePartitionBase}2 >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}3 2>/dev/null >> ${logFile}
mkfs -t ext4 /dev/${actionDevicePartitionBase}3 >> ${logFile}
rm -rf /mnt/disk_storage 2>/dev/null
mkdir -p /mnt/disk_storage 2>/dev/null
mount /dev/${actionDevicePartitionBase}3 /mnt/disk_storage
mkdir -p /mnt/disk_storage/app-storage
if [ ${actionCombinedData} -eq 1 ]; then
mkdir -p /mnt/disk_storage/app-data
fi
umount /mnt/disk_storage >> ${logFile}
echo "storagePartition='${actionDevicePartitionBase}3'"
echo "# storagePartition(${actionDevicePartitionBase}3)" >> ${logFile}
# STORAGE without System partition (if addSystemPartition=0 or not set)
elif [ "${actionType}" = "STORAGE" ] && [ ${actionCreateSystemPartition} -eq 0 ]; then
echo "# STORAGE partitioning (no boot)" >> ${logFile}
sfdisk --delete /dev/${actionDevice} >> ${logFile}
wipefs -a /dev/${actionDevice} >> ${logFile}
parted /dev/${actionDevice} --script mklabel msdos >> ${logFile}
parted /dev/${actionDevice} --script mkpart primary ext4 1MB 100% >> ${logFile}
partprobe /dev/${actionDevice}
echo "# .. formating" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}1 >> ${logFile}
mkfs -t ext4 /dev/${actionDevicePartitionBase}1 >> ${logFile}
rm -rf /mnt/disk_storage 2>/dev/null
mkdir -p /mnt/disk_storage 2>/dev/null
mount /dev/${actionDevicePartitionBase}1 /mnt/disk_storage
mkdir -p /mnt/disk_storage/app-storage
if [ ${actionCombinedData} -eq 1 ]; then
mkdir -p /mnt/disk_storage/app-data
fi
umount /mnt/disk_storage
echo "storagePartition='${actionDevicePartitionBase}1'"
echo "# storagePartition(${actionDevicePartitionBase}1)" >> ${logFile}
# DATA (single drive)
elif [ "${actionType}" = "DATA" ]; then
echo "# DATA partitioning" >> ${logFile}
sfdisk --delete /dev/${actionDevice} 2>/dev/null
wipefs -a /dev/${actionDevice} 2>/dev/null
parted /dev/${actionDevice} --script mklabel msdos
parted /dev/${actionDevice} --script mkpart primary ext4 1MB 100%
partprobe /dev/${actionDevice}
echo "# .. formating" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}1 2>/dev/null
mkfs -t ext4 /dev/${actionDevicePartitionBase}1
rm -rf /mnt/disk_data 2>/dev/null
mkdir -p /mnt/disk_data 2>/dev/null
mount /dev/${actionDevicePartitionBase}1 /mnt/disk_data
mkdir -p /mnt/disk_data/app-data
umount /mnt/disk_data
fi
echo "# OK - ${action} done" >> ${logFile}
exit 0
fi
###################
# RECOVER / CLEAN
###################
if [ "$action" = "recover" ] || [ "$action" = "clean" ]; then
echo "STARTED blitz.data.sh ${action} ..." >> ${logFile}
# check that it is a valid setup type: STORAGE, DATA, SYSTEM
actionType=$2
if [ "${actionType}" != "STORAGE" ] && [ "${actionType}" != "DATA" ] && [ "${actionType}" != "SYSTEM" ]; then
echo "# actionType(${actionType})"
echo "error='setup type not supported'"
echo "error='setup type not supported'" >> ${logFile}
exit 1
fi
# check that device is set & exists & not mounted
actionDevice=$3
if [ ${#actionDevice} -eq 0 ]; then
echo "error='missing device'"
echo "error='missing device'" >> ${logFile}
exit 1
fi
if ! lsblk -no NAME | grep -q "${actionDevice}$"; then
echo "error='device not found'"
echo "error='device not found'" >> ${logFile}
exit 1
fi
if findmnt -n -o TARGET "/dev/${actionDevice}" 2>/dev/null; then
echo "error='device is mounted'"
echo "error='device is mounted'" >> ${logFile}
exit 1
fi
# check if data should also be combined with storage
actionCombinedData=$4
if [ ${#actionCombinedData} -gt 0 ] && [ "${actionCombinedData}" != "combinedData=1" ] && [ "${actionCombinedData}" != "0" ] && [ "${actionCombinedData}" != "1" ]; then
echo "error='combinedData(${actionCombinedData})'" >> ${logFile}
echo "error='combinedData value not supported'"
exit 1
fi
if [ "${actionCombinedData}" = "combinedData=1" ] || [ "${actionCombinedData}" = "1" ]; then
actionCombinedData=1
else
actionCombinedData=0
fi
# check if boot should be from storage
actionCreateSystemPartition=$5
if [ ${#actionCreateSystemPartition} -gt 0 ] && [ "${actionCreateSystemPartition}" != "addSystemPartition=0" ] && [ "${actionCreateSystemPartition}" != "addSystemPartition=1" ] && [ "${actionCreateSystemPartition}" != "0" ] && [ "${actionCreateSystemPartition}" != "1" ]; then
echo "error='addSystemPartition(${actionCreateSystemPartition})'" >> ${logFile}
echo "error='addSystemPartition value not supported'"
exit 1
fi
if [ "${actionCreateSystemPartition}" = "addSystemPartition=1" ] || [ "${actionCreateSystemPartition}" = "1" ]; then
actionCreateSystemPartition=1
else
actionCreateSystemPartition=0
fi
# determine the partition base name
actionDevicePartitionBase=${actionDevice}
if [[ "${actionDevice}" =~ ^nvme ]]; then
actionDevicePartitionBase="${actionDevice}p"
fi
# debug info
echo "# actionType(${actionType})" >> ${logFile}
echo "# actionDevice(${actionDevice})" >> ${logFile}
echo "# actionDevicePartitionBase(${actionDevicePartitionBase})" >> ${logFile}
echo "# actionCreateSystemPartition(${actionCreateSystemPartition})" >> ${logFile}
echo "# actionCombinedData(${actionCombinedData})" >> ${logFile}
if [ "${action}" = "clean" ]; then
# clean means the devices exist with partitions
# all data should get deleted only keep blockchain data
if [ "${actionType}" = "SYSTEM" ]; then
# system gets full wipe - same as format
/home/admin/config.scripts/blitz.data.sh setup SYSTEM ${actionDevice}
exit $?
fi
if [ "${actionType}" = "DATA" ]; then
# data gets full wipe - same as format
/home/admin/config.scripts/blitz.data.sh setup DATA ${actionDevice}
exit $?
fi
if [ "${actionType}" = "STORAGE" ]; then
# check first partition for storage
mkdir -p /mnt/disk_storage 2>/dev/null
mount /dev/${actionDevicePartitionBase}1 /mnt/disk_storage 2>/dev/null
# check if /mnt/disk_storage/app-storage exists
if [ ! -d "/mnt/disk_storage/app-storage" ]; then
# multi partion layout
unmount /mnt/disk_storage
echo "# .. formating boot & system partition" >> ${logFile}
echo "# - format: boot(/dev/${actionDevicePartitionBase}1)" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}1 >> ${logFile}
mkfs.fat -F 32 /dev/${actionDevicePartitionBase}1 >> ${logFile}
echo "# - format: system(/dev/${actionDevicePartitionBase}2)" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}2 >> ${logFile}
mkfs -t ext4 /dev/${actionDevicePartitionBase}2 >> ${logFile}
echo "# - mount: storage(/dev/${actionDevicePartitionBase}3)" >> ${logFile}
mount /dev/${actionDevicePartitionBase}3 /mnt/disk_storage >> ${logFile}
echo "storagePartition='${actionDevicePartitionBase}3'"
echo "# storagePartition(${actionDevicePartitionBase}3)" >> ${logFile}
if [ $? -ne 0 ]; then
echo "error='failed to mount /dev/${actionDevicePartitionBase}3'" >> ${logFile}
echo "error='failed to mount storage partition (1)'"
exit 1
fi
if [ ! -d "/mnt/disk_storage/app-storage" ]; then
echo "error='to /app-storage on /dev/${actionDevicePartitionBase}3'" >> ${logFile}
echo "error='failed to mount storage partition (2)'"
exit 1
fi
else
echo "storagePartition='${actionDevicePartitionBase}1'"
echo "# storagePartition(${actionDevicePartitionBase}1)" >> ${logFile}
fi
# in both setups /mnt/disk_storage/app-storage should exist
# delete all data in /mnt/disk_storage except for /mnt/disk_storage/app-storage
echo "# Cleaning storage partition - preserving app-storage" >> ${logFile}
# TODO: This is not working yet .. refactor later
find /mnt/disk_storage -maxdepth 1 -not -name "app-storage" -not -name "." -not -name ".." -exec rm -rf {} \;
find /mnt/disk_storage/app-storage -maxdepth 1 -not -name "bitcoin" -not -name "." -not -name ".." -exec rm -rf {} \;
find /mnt/disk_storage/app-storage/bitcoin -maxdepth 1 -not -name "blocks" -name "chainstate" -not -name "." -not -name ".." -exec rm -rf {} \;
ls -la /mnt/disk_storage >> ${logFile}
ls -la /mnt/disk_storage/app-storage >> ${logFile}
ls -la /mnt/disk_storage/app-storage/bitcoin >> ${logFile}
# Create fresh app-data directory if needed with combined data
if [ ${actionCombinedData} -eq 1 ]; then
mkdir -p /mnt/disk_storage/app-data
fi
# Unmount after cleaning
umount /mnt/disk_storage
rm -rf /mnt/disk_storage
fi
fi
if [ "${action}" = "recover" ]; then
if [ "${actionType}" = "SYSTEM" ]; then
# system gets full wipe on recover - same as format
/home/admin/config.scripts/blitz.data.sh setup SYSTEM ${actionDevice}
exit $?
fi
if [ "${actionType}" = "DATA" ]; then
echo "# .. data just keep as is" >> ${logFile}
fi
if [ "${actionType}" = "STORAGE" ]; then
# get number of partions of device
numPartitions=$(lsblk -no NAME /dev/${actionDevice} | grep -c "${actionDevicePartitionBase}")
if [ ${numPartitions} -eq 3 ]; then
if [ "${actionCreateSystemPartition}" == "1" ]; then
echo "# .. formating boot & system partition" >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}1 >> ${logFile}
mkfs.fat -F 32 /dev/${actionDevicePartitionBase}1 >> ${logFile}
wipefs -a /dev/${actionDevicePartitionBase}2 >> ${logFile}
mkfs -t ext4 /dev/${actionDevicePartitionBase}2 >> ${logFile}
else
echo "# dont format boot & system partition .. actionCreateSystemPartition(${actionCreateSystemPartition})" >> ${logFile}
fi
echo "storagePartition='${actionDevicePartitionBase}3'"
echo "# storagePartition(${actionDevicePartitionBase}3)" >> ${logFile}
else
echo "storagePartition='${actionDevicePartitionBase}1'"
echo "# storagePartition(${actionDevicePartitionBase}1)" >> ${logFile}
echo "# .. storage has ${numPartitions} partitions - just keep as is" >> ${logFile}
fi
fi
fi
echo "# DONE - blitz.data.sh ${action} ${actionType}" >> ${logFile}
exit 0
fi
###################
# UNABLE BOOT
###################
if [ "$1" = "kill-boot" ]; then
device=$2
if [ ${#device} -eq 0 ]; then
echo "error='missing device'"
exit 1
fi
# check that device is valid and not a partition
isValidDevice=$(lsblk -no NAME 2>/dev/null | grep -c "^${device}")
if [ ${isValidDevice} -eq 0 ]; then
echo "error='device not valid'"
exit 1
fi
# detect partition naming scheme
if [[ "${device}" =~ nvme|mmcblk ]]; then
separator="p"
else
separator=""
fi
# find boot partion of device
bootPartition=""
partitionNumber=""
for partNumber in $(parted -s "/dev/${device}" print | grep "^ *[0-9]" | awk '{print $1}'); do
partitionPath="/dev/${device}${separator}${partNumber}"
if blkid "${partitionPath}" | grep -q "TYPE=\"vfat\"" && \
parted "/dev/${device}" print | grep "^ *${partNumber}" | grep -q "boot\|esp\|lba"; then
bootPartition="${device}${separator}${partNumber}"
partitionNumber="${partNumber}"
break
fi
done
# fallback to first partition if no boot partition found
if [ -z "${bootPartition}" ]; then
bootPartition=$(lsblk -no NAME "/dev/${device}" | grep "^${device}p\?[0-9]" | head -1)
fi
# check if boot partition was found
if [ -z "${bootPartition}" ]; then
echo "error='boot partition not found'"
exit 1
fi
# killing boot partition (needs to remove to also work on raspberrypi)
echo "# killing boot partition (${bootPartition})"
umount "/dev/${bootPartition}" 2>/dev/null
parted --script "/dev/${device}" rm "${partitionNumber}"
if [ $? -ne 0 ]; then
echo "error='failed to remove boot partition'"
exit 1
else
echo "# OK - boot partition removed" >> ${logFile}
exit 0
fi
fi
###################
# MIGRATION
###################
if [ "$1" = "migration" ] && [ "$2" = "hdd" ]; then
action=$3
if [ "${action}" = "menu-prepare" ]; then
# give user prepare information
dialog --title " Migrate Data to new HDD/SSD/NVMe " --yes-label "Start Migration" --no-label "Back" --yesno "\nTo migrate your RaspiBlitz data from your old HDD/SSD/NVMe to a new bigger drive, please make sure of the following:\n\n- If you run lightning make sure to have a\n rescue backup downloaded.\n\n- Have your old drive replaced with the new one\n or start with complete new hardware.\n\n- Have your old drive connected via USB3\n where you may need an USB adapter and on\n RasperryPi4 power old drive seperately.\n\nChoose 'Start Migration' if everything is setup or go back." 20 70
if [ $? -gt 0 ]; then
# user canceled
exit 1
fi
# check if a bigger replacement drive exists
source <(/home/admin/config.scripts/blitz.data.sh status)
if [ ${#biggerDevice} -eq 0 ]; then
dialog --msgbox "\nNo old drive with RaspiBlitz data found.\n\nMaybe you need to reset new bigger drive first:\nDisconnect old drive and use on terminal 'reset'.\nThen 'restart' and try again." 11 60
exit 1
fi
# confirm selection
storageDeviceNameTrunc="${storageDeviceName:0:35}"
biggerDeviceNameTrunc="${biggerDeviceName:0:35}"
dialog --title " Migrate Data to new HDD/SSD/NVMe " --yes-label "Continue" --no-label "Abort" --yesno "\nYou are about to migrate your RaspiBlitz data from:\n\n- ${storageSizeGB}GB ${storageDeviceNameTrunc} \n\nto:\n\n- ${biggerSizeGB}GB ${biggerDeviceNameTrunc}\n\nAll data on target drive will be deleted! Is this correct?" 17 70
if [ $? -gt 0 ]; then
# user canceled
exit 1
fi
# set migration info to cache
/home/admin/_cache.sh set hddMigrateDeviceFrom "${storageDevice}"
/home/admin/_cache.sh set hddMigrateDeviceTo "${biggerDevice}"
/home/admin/_cache.sh set system_setup_storageBlockchainGB "0"
/home/admin/_cache.sh set system_setup_askSystemCopy "${scenarioSystemCopy}"
# return 0 to indicate success and let calling script finish
exit 0
fi
if [ "${action}" = "run" ]; then
echo "### MIGRATING HDD"
echo "# see /var/cache/raspiblitz/temp/progress.txt for progress"
# get source hdd of migration
hddMigrateDeviceFrom=$4
echo "# hddMigrateDeviceFrom(${hddMigrateDeviceFrom})"
if [ ${#hddMigrateDeviceFrom} -eq 0 ]; then
echo "error='missing parameter'"
exit 1
fi
# set source hdd of migration in cache & get latest disk info
/home/admin/_cache.sh set hddMigrateDeviceFrom "${hddMigrateDeviceFrom}"
source <(/home/admin/config.scripts/blitz.data.sh status -inspect)
# check that target partion is formatted
if [ "${storagePartition}" = "" ]; then
echo "error='storage drive not formatted'"
exit 1
fi
# check that target partion is formatted
if [ "${combinedDataStorage}" = "1" ]; then
dataPartition="${storagePartition}"
fi
if [ "${dataPartition}" = "" ]; then
echo "error='data drive not formatted'"
exit 1
fi
# get the biggest partition of the source hdd (thats the data or storage partition with data)
sourcePartition=$(lsblk -no NAME,SIZE,TYPE | grep "${hddMigrateDeviceFrom}" | grep "part" | sort -k2 -h | tail -1 | awk '{print $1}' | sed 's/[^[:alnum:]]//g')
if [ ${#sourcePartition} -eq 0 ]; then
echo "error='no source partition found'"
exit 1
fi
# get UUID of source partition
sourceUUID=$(lsblk -n -o UUID "/dev/${sourcePartition}")
if [ ${#sourceUUID} -eq 0 ]; then
echo "error='no source partition UUID found'"
exit 1
fi
# check that partition is not mounted
if findmnt -n -o TARGET "/dev/${sourcePartition}" 2>/dev/null; then
echo "# sourcePartition(${sourcePartition})"
echo "# make sure the partition is not mounted"
echo "# sudo umount /dev/${sourcePartition}"
echo "error='source partition is mounted'"
exit 1
fi
# check partition data is not mounted
if findmnt -n -o TARGET "/dev/${dataPartition}" 2>/dev/null; then
echo "# dataPartition(${dataPartition})"
echo "# make sure the partition is not mounted"
echo "# sudo umount /dev/${dataPartition}"
echo "error='data partition is mounted'"
exit 1
fi
# check storage is not mounted
if findmnt -n -o TARGET "/dev/${storagePartition}" 2>/dev/null; then
echo "# storagePartition(${storagePartition})"
echo "# make sure the partition is not mounted"
echo "# sudo umount /dev/${storagePartition}"
echo "error='storage partition is mounted'"
exit 1
fi
# mount source partition
mkdir -p /mnt/migrate_source 2>/dev/null
echo "# mount /mnt/migrate_source -> ${sourcePartition} uuid(${sourceUUID})..."
mount -U "${sourceUUID}" /mnt/migrate_source
if ! findmnt -n -o TARGET "/mnt/migrate_source" 2>/dev/null; then
echo "error='source partition not mounted uuid(${sourceUUID})'"
exit 1
fi
##############
# SYNC STORAGE
# mount target partition storage
mkdir -p /mnt/migrate_storage 2>/dev/null
echo "# mount /mnt/migrate_storage -> ${storagePartition} ..."
mount "/dev/${storagePartition}" /mnt/migrate_storage
if ! findmnt -n -o TARGET "/mnt/migrate_storage" 2>/dev/null; then
echo "error='storage partition not mounted'"
exit 1
fi
echo "# rsync storage from source to target ..."
echo "chain" > /var/cache/raspiblitz/temp/progress.txt
mkdir -p /mnt/migrate_storage/app-storage 2>/dev/null
rsync -ah --info=progress2 /mnt/migrate_source/app-storage/ /mnt/migrate_storage/app-storage/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='failed to rsync storage'"
exit 1
fi
# old layout: bitcoin directory is still outside of app-storage
if [ -d /mnt/migrate_source/bitcoin ] && [ ! -L /mnt/migrate_source/bitcoin ]; then
echo "# rsync bitcoin from source to target ..."
mkdir -p /mnt/migrate_storage/app-storage/bitcoin 2>/dev/null
echo "bitcoin" > /var/cache/raspiblitz/temp/progress.txt
rsync -ah --info=progress2 /mnt/migrate_source/bitcoin/ /mnt/migrate_storage/app-storage/bitcoin/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='failed to rsync bitcoin'"
exit 1
fi
fi
# add flag to indicate that data was migrated
touch /mnt/migrate_storage/app-storage/.migrated
chmod 777 /mnt/migrate_storage/app-storage/.migrated
# unmount storage partition
umount /mnt/migrate_storage
if [ $? -ne 0 ]; then
echo "error='failed to unmount storage partition'"
exit 1
fi
##############
# SYNC DATA
# mount target partition data
mkdir -p /mnt/migrate_data 2>/dev/null
echo "# mount /mnt/migrate_data -> ${dataPartition} ..."
mount "/dev/${dataPartition}" /mnt/migrate_data
if ! findmnt -n -o TARGET "/mnt/migrate_data" 2>/dev/null; then
echo "error='data partition not mounted'"
exit 1
fi
echo "# rsync data from source to target ..."
mkdir -p /mnt/migrate_data/app-data 2>/dev/null
echo "data" > /var/cache/raspiblitz/temp/progress.txt
rsync -ah --info=progress2 /mnt/migrate_source/app-data/ /mnt/migrate_data/app-data/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='failed to rsync data'"
exit 1
fi
# old layout: lnd directory is still outside of app-data
if [ -d /mnt/migrate_source/lnd ] && [ ! -L /mnt/migrate_source/lnd ]; then
echo "# rsync lnd from source to target ..."
mkdir -p /mnt/migrate_data/app-data/lnd 2>/dev/null
echo "lnd" > /var/cache/raspiblitz/temp/progress.txt
rsync -ah --info=progress2 /mnt/migrate_source/lnd/ /mnt/migrate_data/app-data/lnd/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='failed to rsync lnd'"
exit 1
fi
else
echo "# no old lnd directory found"
fi
# old layout: tor directory is still outside of app-data
if [ -d /mnt/migrate_source/tor ] && [ ! -L /mnt/migrate_source/tor ]; then
echo "# rsync tor from source to target ..."
rm -f /mnt/migrate_source/tor/*.log*
mkdir -p /mnt/migrate_data/app-data/tor 2>/dev/null
echo "tor" > /var/cache/raspiblitz/temp/progress.txt
rsync -ah --info=progress2 /mnt/migrate_source/tor/ /mnt/migrate_data/app-data/tor/ 2>&1 | stdbuf -oL tr '\r' '\n' | grep --line-buffered '%' | stdbuf -oL sed -n 's/.* \([0-9]\+\)% .*/\1%/p' >> /var/cache/raspiblitz/temp/progress.txt
if [ $? -ne 0 ]; then
echo "error='failed to rsync tor'"
exit 1
fi
else
echo "# no old tor directory found"
fi
# old layout: raspiblitz.conf file is still outside of app-data
if [ -f /mnt/migrate_source/raspiblitz.conf ] && [ ! -L /mnt/migrate_source/raspiblitz.conf ]; then
echo "# copy raspiblitz.conf from source to target ..."
mkdir -p /mnt/migrate_data/app-data 2>/dev/null
cp /mnt/migrate_source/raspiblitz.conf /mnt/migrate_data/app-data/raspiblitz.conf
cp /mnt/migrate_source/.tmux.conf.local /mnt/migrate_data/app-data/.tmux.conf.local 2>/dev/null
if [ $? -ne 0 ]; then
echo "error='failed to rsync raspiblitz.conf'"
exit 1
fi
else
echo "# no old raspiblitz.conf file found"
fi
# unmount data partition
umount /mnt/migrate_data
if [ $? -ne 0 ]; then
echo "error='failed to unmount data partition'"
exit 1
fi
# unmount source device
umount /mnt/migrate_source
if [ $? -ne 0 ]; then
echo "error='failed to unmount source partition'"
exit 1
fi
# clean up
rm -rf /mnt/migrate_source
rm -rf /mnt/migrate_storage
rm -rf /mnt/migrate_data
rm -rf /var/cache/raspiblitz/temp/progress.txt
exit 0
fi
echo "error='missing parameter'"
exit 1
fi
if [ "$1" = "migration" ]; then
echo "# blitz.data.sh migration" >> ${logFile}
# check if all needed parameters are set
if [ $# -lt 3 ]; then
echo "error='missing parameters'"
exit 1
fi
# check that partition exists
if ! lsblk -no NAME | grep -q "${dataPartition}$"; then
echo "# dataPartition(${dataPartition})"
echo "error='partition not found'"
exit 1
fi
# check that partition is not mounted
if findmnt -n -o TARGET "/dev/${dataPartition}" 2>/dev/null; then
echo "# dataPartition(${dataPartition})"
echo "# make sure the partition is not mounted"
echo "error='partition is mounted'"
exit 1
fi
onlyTestIfMigratioinPossible=0
if [ "$4" = "-test" ]; then
echo "# ... only testing if migration is possible"
onlyTestIfMigratioinPossible=1
fi
mountPath="/mnt/temp"
mkdir -p "${mountPath}" 2>/dev/null
if ! mount "/dev/${name}" "${mountPath}"; then
echo "error='cannot mount partition'"
exit 1
fi
echo "error='TODO migration'"
#####################
# MIGRATION: UMBREL
# if [ "$2" = "umbrel" ]; then
# # TODO: Detect and output Umbrel Version
# if [ ${onlyTestIfMigratioinPossible} -eq 1 ]; then
# # provide information about the versions
# btcVersion=$(grep "lncm/bitcoind" ${mountPath}/umbrel/app-data/bitcoin/docker-compose.yml 2>/dev/null | sed 's/.*bitcoind://' | sed 's/@.*//')
# clnVersion=$(grep "lncm/clightning" ${mountPath}/umbrel/app-data/core-lightning/docker-compose.yml 2>/dev/null | sed 's/.*clightning://' | sed 's/@.*//')
# lndVersion=$(grep "lightninglabs/lnd" ${mountPath}/umbrel/app-data/lightning/docker-compose.yml 2>/dev/null | sed 's/.*lnd://' | sed 's/@.*//')
# echo "btcVersion='${btcVersion}'"
# echo "clnVersion='${clnVersion}'"
# echo "lndVersion='${lndVersion}'"
# else
# echo "error='TODO migration'"
# fi
#####################
# MIGRATION: CITADEL
#elif [ "$2" = "citadel" ]; then
# # TODO: Detect and output Citadel Version
# if [ ${onlyTestIfMigratioinPossible} -eq 1 ]; then
# # provide information about the versions
# lndVersion=$(grep "lightninglabs/lnd" ${mountPath}/citadel/docker-compose.yml 2>/dev/null | sed 's/.*lnd://' | sed 's/@.*//')
# echo "lndVersion='${lndVersion}'"
# else
# echo "error='TODO migration'"
# fi
#####################
# MIGRATION: MYNODE
#elif [ "$2" = "mynode" ]; then
# echo "error='TODO'"
#else
# echo "error='migration type not supported'"
#fi
# unmount partition
umount ${mountPath}
rm -r ${mountPath}
exit 0
fi
#############
# UASP-fix
#############
if [ "$1" = "reset" ]; then
source <(/home/admin/config.scripts/blitz.data.sh status)
if [ "${storageDevice}" = "" ]; then
echo "error='no storage device found'"
exit 1
fi
# ask user to confirm
echo "# WARNING: This will delete all data on ${storageDevice}"
echo "# Are you really sure? (y/n)"
read -r answer
if [ "${answer}" != "y" ]; then
echo "# User canceled"
exit 1
fi
echo "# Are you REALLY REALLY sure? (Y/N)"
read -r answer
if [ "${answer}" != "Y" ]; then
echo "# User canceled"
exit 1
fi
echo "# Deleting all partitions on ${storageDevice} ..."
apt-get install -y gdisk
sgdisk --zap-all /dev/${storageDevice}
echo "# DONE"
exit 0
fi
#############
# UASP-fix
#############
if [ "$1" = "uasp-fix" ]; then
echo "# blitz.data.sh uasp-fix"
# optional: parameter
onlyInfo=0
if [ "$2" = "-info" ]; then
echo
onlyInfo=1
fi
# check is running on RaspiOS
if [ "${computerType}" != "raspberrypi" ]; then
echo "error='only on RaspberryPi'"
exit 1
fi
# HDD Adapter UASP support --> https://www.pragmaticlinux.com/2021/03/fix-for-getting-your-ssd-working-via-usb-3-on-your-raspberry-pi/
hddAdapter=$(lsusb | grep "SATA" | head -1 | cut -d " " -f6)
if [ "${hddAdapter}" == "" ]; then
hddAdapter=$(lsusb | grep "GC Protronics" | head -1 | cut -d " " -f6)
fi
if [ "${hddAdapter}" == "" ]; then
hddAdapter=$(lsusb | grep "ASMedia Technology" | head -1 | cut -d " " -f6)
fi
# check if HDD ADAPTER is on UASP WHITELIST (tested devices)
hddAdapterUASP=0
if [ "${hddAdapter}" == "174c:55aa" ]; then
# UGREEN 2.5" External USB 3.0 Hard Disk Case with UASP support
hddAdapterUASP=1
fi
if [ "${hddAdapter}" == "174c:1153" ]; then
# UGREEN 2.5" External USB 3.0 Hard Disk Case with UASP support, 2021+ version
hddAdapterUASP=1
fi
if [ "${hddAdapter}" == "0825:0001" ] || [ "${hddAdapter}" == "174c:0825" ]; then
# SupTronics 2.5" SATA HDD Shield X825 v1.5
hddAdapterUASP=1
fi
if [ "${hddAdapter}" == "2109:0715" ]; then
# ICY BOX IB-247-C31 Type-C Enclosure for 2.5inch SATA Drives
hddAdapterUASP=1
fi
if [ "${hddAdapter}" == "174c:235c" ]; then
# Cable Matters USB 3.1 Type-C Gen2 External SATA SSD Enclosure
hddAdapterUASP=1
fi
if [ -f "/boot/firmware/uasp.force" ]; then
# or when user forces UASP by flag file on sd card
hddAdapterUASP=1
fi
if [ ${onlyInfo} -eq 1 ]; then
echo "# the ID of the HDD Adapter:"
echo "hddAdapter='${hddAdapter}'"
echo "# if HDD Adapter supports UASP:"
echo "hddAdapterUASP='${hddAdapterUASP}'"
exit 0
fi
# https://www.pragmaticlinux.com/2021/03/fix-for-getting-your-ssd-working-via-usb-3-on-your-raspberry-pi/
cmdlineFileExists=$(ls /boot/firmware/cmdline.txt 2>/dev/null | grep -c "cmdline.txt")
if [ ${cmdlineFileExists} -eq 0 ]; then
echo "error='no /boot/firmware/cmdline.txt'"
exit 1
elif [ ${#hddAdapter} -eq 0 ]; then
echo "# Skipping UASP deactivation - no USB HDD Adapter found"
echo "neededReboot=0"
elif [ ${hddAdapterUASP} -eq 1 ]; then
echo "# Skipping UASP deactivation - USB HDD Adapter is on UASP WHITELIST"
echo "neededReboot=0"
else
echo "# UASP deactivation - because USB HDD Adapter is not on UASP WHITELIST ..."
usbQuirkDone=$(cat /boot/firmware/cmdline.txt | grep -c "usb-storage.quirks=${hddAdapter}:u")
if [ ${usbQuirkDone} -eq 0 ]; then
# remove any old usb-storage.quirks
sed -i "s/usb-storage.quirks=[^ ]* //g" /boot/firmware/cmdline.txt 2>/dev/null
# add new usb-storage.quirks
sed -i "s/^/usb-storage.quirks=${hddAdapter}:u /" /boot/firmware/cmdline.txt
# go into reboot to activate new setting
echo "# DONE deactivating UASP for ${hddAdapter}"
echo "neededReboot=1"
else
echo "# Already UASP deactivated for ${hddAdapter}"
echo "neededReboot=0"
fi
fi
exit 0
fi
#############
# Expand
#############
if [ "$1" = "expand" ]; then
echo "# blitz.data.sh expand"
# get partition name
partitionName=$2
if [ ${#partitionName} -eq 0 ]; then
echo "error='missing partition name'"
exit 1
fi
# spereate device name and partition number
partitionNumber=$(echo "${partitionName}" | grep -o '[0-9]*$')
deviceName=$(echo "${partitionName}" | sed "s/${partitionNumber}$//")
if [ ${#deviceName} -eq 0 ]; then
echo "error='missing device name'"
exit 1
fi
if [ ${#partitionNumber} -eq 0 ]; then
echo "error='missing partition number'"
exit 1
fi
echo "# deviceName(${deviceName})"
echo "# partitionNumber(${partitionNumber})"
# read partition table
partprobe /dev/${deviceName}
if [ $? -ne 0 ]; then
echo "error='failed to read partition table'"
exit 1
fi
# grow partition
apt install -y --no-install-recommends cloud-guest-utils
growpart /dev/${deviceName} ${partitionNumber}
if [ $? -ne 0 ]; then
echo "error='failed to grow partition'"
exit 1
fi
# resize filesystem
apt-get install -y --no-install-recommends e2fsprogs
resize2fs /dev/${partitionName}
if [ $? -ne 0 ]; then
echo "error='failed to resize filesystem'"
exit 1
fi
echo "# DONE check: df -h"
exit 0
fi