mirror of
https://github.com/raspiblitz/raspiblitz.git
synced 2025-11-19 18:37:41 +01:00
2466 lines
101 KiB
Bash
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 |