2021-12-05 16:13:09 +00:00
#!/bin/bash /usr/lib/turtle/turtle_module
# Title: LANTurtle OpenWRT Extroot configuration
# Description: Simplified SD card storage
# Author: jrwimmer
2021-12-21 03:34:20 +00:00
# Props: The OpenWrt community
2021-12-05 16:13:09 +00:00
# Version: 1.0
# Category: General
# Target: N/A
# Attackmodes: N/A
2021-12-05 16:56:22 +00:00
# Constants
2021-12-05 16:13:09 +00:00
VERSION="1.0"
DESCRIPTION="Simplified SD card storage"
2021-12-05 16:56:22 +00:00
REQUIRED_PACKAGES="block-mount kmod-fs-ext4 e2fsprogs fdisk"
2021-12-05 16:13:09 +00:00
CONF=/tmp/extroot.form
# All "dialog" functionality is related to the Turtle shell
: ${DIALOG_OK=0}
: ${DIALOG_CANCEL=1}
: ${DIALOG_HELP=2}
: ${DIALOG_EXTRA=3}
: ${DIALOG_ITEM_HELP=4}
: ${DIALOG_ESC=255}
function configure {
2021-12-21 03:49:41 +00:00
dialog --title "Extroot: Info" --msgbox "::: NOTICE :::\n\nThis module is intended for use on freshly-imaged devices. Any customizations already made are not guaranteed to persist through extroot configuration." 14 72
2021-12-21 03:30:41 +00:00
2021-12-21 03:49:41 +00:00
dialog --title "Extroot: WARNING" --defaultno --yesno "::: WARNING :::\n\n\nThis Operation WILL ERASE THE ATTACHED SD CARD \n\nAre you sure you wish to continue?" 14 72
2021-12-21 03:30:41 +00:00
return=$?
case $return in
2021-12-21 05:02:23 +00:00
"$DIALOG_OK")
2021-12-21 03:30:41 +00:00
perform_migration;;
2021-12-21 05:02:23 +00:00
"$DIALOG_CANCEL")
2021-12-21 04:32:06 +00:00
dialog --title "Extroot" --msgbox "Operation cancelled" 14 72
exit 0;;
2021-12-21 05:02:23 +00:00
"$DIALOG_ESC")
2021-12-21 04:32:06 +00:00
dialog --title "Extroot" --msgbox "Operation cancelled" 14 72
exit 0;;
2021-12-21 03:30:41 +00:00
esac
2021-12-05 16:13:09 +00:00
}
2021-12-21 04:32:06 +00:00
function check_space {
# Get block size for the root partition
rootfs_blocksize=$(df -P / | awk '{print $2}' | tail -n+2)
rootfs_humansize=$(df -h / | awk '{print $2}' | tail -n+2)
# Check if the root partition is larger than 256 MB
if (( $rootfs_blocksize > 256000 )); then
dialog --title "Extroot: WARNING" --defaultno --yesno "::: WARNING :::\n\n\nThe root partition appears to be larger than 256MB in size (Seen: $rootfs_humansize)\n\nThis may indicate that the overlay configuration process has already been performed on this installation.\n\nAre you sure you wish to continue?" 14 72
return=$?
case $return in
2021-12-21 05:02:23 +00:00
"$DIALOG_OK")
2021-12-21 04:32:06 +00:00
return 0;;
2021-12-21 05:02:23 +00:00
"$DIALOG_CANCEL")
2021-12-21 04:32:06 +00:00
dialog --title "Extroot" --msgbox "Operation cancelled" 14 72
exit 0;;
2021-12-21 05:02:23 +00:00
"$DIALOG_ESC")
2021-12-21 04:32:06 +00:00
dialog --title "Extroot" --msgbox "Operation cancelled" 14 72
exit 0;;
esac
fi
}
2021-12-05 16:56:22 +00:00
function check_network {
# Check for Internet connection by attempting to contact an opkg repository server
# First, extract a server URL from distfeeds.conf
opkg_baseurl=$(sed -E -n "s/^[^#]*(http:\/\/[^\/]*)\/.*/\1/p;q" /etc/opkg/distfeeds.conf) &> /dev/null
if [[ $? -ne 0 ]]; then
2021-12-21 03:42:19 +00:00
echo "\nCould not extract an opkg repo from distfeeds.conf\n\nIf this is unexpected, you may need to upgrade or restore the firmware." > $1
return 1
2021-12-05 16:56:22 +00:00
fi
# ...then, use wget to determine if the server can be reached
2021-12-21 03:42:19 +00:00
wget -q --tries 3 --spider "$opkg_baseurl" &> /dev/null
wget_returncode=$?
if [[ $wget_returncode -ne 0 ]]; then
echo "\nLAN Turtle could not connect to $opkg_baseurl\nVerify the device's internet connection and try again (wget error $wget_returncode)" > $1
return 1
2021-12-05 16:56:22 +00:00
fi
}
function install_dependencies {
2021-12-21 03:42:19 +00:00
echo "Updating opkg"
2021-12-21 03:49:41 +00:00
opkg update
2021-12-21 03:42:19 +00:00
echo "Checking/installing dependencies"
2021-12-21 03:49:41 +00:00
opkg install $REQUIRED_PACKAGES
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
sleep 3
2021-12-05 16:56:22 +00:00
}
function remount_rootfsdata {
# Identify flash memory device containing current overlay
rootfsdata_dev="$(sed -n -e "/\s\/overlay\s.*$/s///p" /etc/mtab)"
# Create remount entry
uci -q delete fstab.rwm
uci set fstab.rwm="mount"
uci set fstab.rwm.device="${rootfsdata_dev}"
uci set fstab.rwm.target="/rwm"
uci commit fstab
2021-12-21 03:42:19 +00:00
sleep 3
2021-12-05 16:56:22 +00:00
}
function format_sdcard {
2021-12-21 03:42:19 +00:00
echo "Checking SD card presence"
2021-12-05 16:56:22 +00:00
[[ "$(ls /dev/sd* 2> /dev/null | wc -l)" == "0" ]] && {
2021-12-21 03:42:19 +00:00
echo "\nError: No SD card is inserted or the card is not supported\n\nAdditional Details:\nCould not find a device with prefix 'sd'" > $1
return 1
2021-12-05 16:56:22 +00:00
}
2021-12-21 03:42:19 +00:00
sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1)
echo "New overlay device identified as: $sdcard_device"
echo "Unmounting any active external storage"
2021-12-05 16:56:22 +00:00
block umount &> /dev/null
2021-12-21 03:42:19 +00:00
echo "Partitioning SD card"
2021-12-21 05:02:23 +00:00
echo -e "o\nn\np\n2\n\n+1024M\nn\np\n1\n\np\n\nw\n" | fdisk "$sdcard_device" 2>/dev/null
mkfs.ext4 -F "${sdcard_device}1"
mkswap "${sdcard_device}2"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
echo "Restarting the storage bus"
echo "1-0:1.0" > /sys/bus/usb/drivers/hub/unbind 2>/dev/null
echo "1-0:1.0" > /sys/bus/usb/drivers/hub/bind 2>/dev/null
2021-12-05 16:56:22 +00:00
sleep 3
2021-12-21 03:42:19 +00:00
echo "Commit/activate swap and remove existing SD card mounts"
2021-12-05 16:56:22 +00:00
block detect > /etc/config/fstab
uci -q delete fstab.@mount[0]
uci commit fstab
block mount &> /dev/null
2021-12-21 03:42:19 +00:00
sleep 3
2021-12-05 16:56:22 +00:00
}
function make_extroot {
sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1)1
2021-12-21 03:42:19 +00:00
echo "New overlay partition identified as: $sdcard_device"
2021-12-05 16:56:22 +00:00
2021-12-21 05:02:23 +00:00
eval $(block info "${sdcard_device}" | grep -o -e "UUID=\S*")
2021-12-21 03:42:19 +00:00
echo "New overlay partition has a UUID of: $UUID"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
echo "Recreating overlay fstab entry"
2021-12-05 16:56:22 +00:00
uci -q delete fstab.overlay
uci set fstab.overlay="mount"
uci set fstab.overlay.uuid="${UUID}"
uci set fstab.overlay.target="/overlay"
uci commit fstab
2021-12-21 03:42:19 +00:00
sleep 3
2021-12-05 16:56:22 +00:00
}
function migrate_overlay {
sdcard_device=$(ls /dev/sd* 2> /dev/null | head -n1)1
2021-12-21 03:42:19 +00:00
echo "New overlay partition identified as: $sdcard_device"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
echo "Creating temporary mount point directory at: /tmp/cproot"
2021-12-05 16:56:22 +00:00
mkdir -p /tmp/cproot
2021-12-21 03:42:19 +00:00
echo "Binding active overlay to: /tmp/cproot"
2021-12-05 16:56:22 +00:00
mount --bind /overlay /tmp/cproot
2021-12-21 03:42:19 +00:00
echo "Mounting new overlay parition at: /mnt"
2021-12-21 05:02:23 +00:00
mount "${sdcard_device}" /mnt
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
echo "Copying data; please wait..."
tar -C /tmp/cproot -cvf - . 2>/dev/null | tar -C /mnt -xf - 2>/dev/null
echo "Copy process complete"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
echo "Unmounting new overlay and removing bind"
2021-12-05 16:56:22 +00:00
umount /tmp/cproot /mnt
2021-12-21 03:42:19 +00:00
sleep 3
}
function finalize {
2021-12-21 03:49:41 +00:00
dialog --title "Extroot: Info" --msgbox "::: NOTICE :::\n\nOperation complete. To finalize changes, the system will now reboot." 14 72
2021-12-21 03:42:19 +00:00
reboot
}
function perform_step {
# Create a tmpfile in which we can store error data
active_tmpfile=$(mktemp)
# Default error data to 0
2021-12-21 05:02:23 +00:00
echo 0 > "$active_tmpfile"
2021-12-21 03:42:19 +00:00
# Perform the requested step
2021-12-21 05:02:23 +00:00
eval "$1" | dialog --progressbox "$2" 14 72
2021-12-21 03:42:19 +00:00
# Retrieve the last error written to the tmpfile
2021-12-21 05:02:23 +00:00
last_return_code=$(cat "$active_tmpfile")
2021-12-21 03:42:19 +00:00
# Delete the tmpfile
2021-12-21 05:02:23 +00:00
rm "$active_tmpfile"
2021-12-21 03:42:19 +00:00
# Determine if an error occurred
if [[ "$last_return_code" != 0 ]]; then
# Notify the user of the problem
2021-12-21 03:49:41 +00:00
dialog --title "Extroot: Error" --msgbox "$last_return_code" 9 72
2021-12-21 03:42:19 +00:00
exit 1
fi
2021-12-05 16:56:22 +00:00
}
function perform_migration {
2021-12-21 04:32:06 +00:00
check_space
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "check_network" "Checking network connectivity"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "install_dependencies" "Installing requried dependencies"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "remount_rootfsdata" "Creating backup mount for current overlay"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "format_sdcard" "Formatting SD card"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "make_extroot" "Configuring new overlay"
2021-12-05 16:56:22 +00:00
2021-12-21 03:42:19 +00:00
perform_step "migrate_overlay" "Migrating overlay data"
finalize
2021-12-05 16:56:22 +00:00
}
2021-12-05 16:13:09 +00:00
function start {
2021-12-21 03:30:41 +00:00
echo "This module is used via the 'Configure' option"
2021-12-05 16:13:09 +00:00
}