Browse Source

Refactor external storage logic (#93)

mount-script-check
Luke Childs 4 years ago
committed by GitHub
parent
commit
7f3be94b61
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 0
      .umbrel
  2. 51
      scripts/umbrel-os/boot
  3. 144
      scripts/umbrel-os/external-storage-mounter
  4. 10
      scripts/umbrel-os/is-on-external-storage

0
.umbrel

51
scripts/umbrel-os/boot

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
UMBREL_ROOT="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))/../.." UMBREL_ROOT="$(dirname $(readlink -f "${BASH_SOURCE[0]}"))/../.."
UMBREL_OS_SCRIPTS="${UMBREL_ROOT}/scripts/umbrel-os"
# Check for statuses directory # Check for statuses directory
if [ ! -d "$UMBREL_ROOT"/statuses ]; then if [ ! -d "$UMBREL_ROOT"/statuses ]; then
@ -10,18 +11,8 @@ if [ ! -d "$UMBREL_ROOT"/statuses ]; then
chmod 777 "$UMBREL_ROOT"/statuses chmod 777 "$UMBREL_ROOT"/statuses
fi fi
# Check for disk partition status # Mount and/or format external storage
if [ ! -f "$UMBREL_ROOT"/statuses/disk-partitioned ]; then "${UMBREL_OS_SCRIPTS}/external-storage-mounter" || exit 1
if [ -f "$UMBREL_ROOT"/contrib/partitioner/partitioner.py ]; then
echo "Run partition tool or quit out if unavailable"
"$UMBREL_ROOT"/contrib/partitioner/partitioner.py || exit 1
touch "$UMBREL_ROOT"/statuses/disk-partitioned
chown -R umbrel.umbrel "$UMBREL_ROOT"/statuses/disk-partitioned
else
echo "Could not find partition tool - some steps might be skipped"
fi
fi
if [ ! -f "$UMBREL_ROOT"/statuses/service-configured ]; then if [ ! -f "$UMBREL_ROOT"/statuses/service-configured ]; then
if [ -f "$UMBREL_ROOT"/scripts/configure ]; then if [ -f "$UMBREL_ROOT"/scripts/configure ]; then
@ -35,26 +26,22 @@ if [ ! -f "$UMBREL_ROOT"/statuses/service-configured ]; then
# Next stage, check if service-configured # Next stage, check if service-configured
echo "Service configured.. Checking for partitioned state" echo "Service configured.. Checking for partitioned state"
if [ -f "$UMBREL_ROOT"/statuses/disk-partitioned ]; then if [ ! -f /etc/rc2.d/S01umbrel ]; then
if [ ! -f /etc/rc2.d/S01umbrel ]; then echo "Set up symlinks"
echo "Set up symlinks" ln -s /etc/init.d/umbrel /etc/rc2.d/S01umbrel
ln -s /etc/init.d/umbrel /etc/rc2.d/S01umbrel ln -s /etc/init.d/umbrel /etc/rc3.d/S01umbrel
ln -s /etc/init.d/umbrel /etc/rc3.d/S01umbrel ln -s /etc/init.d/umbrel /etc/rc4.d/S01umbrel
ln -s /etc/init.d/umbrel /etc/rc4.d/S01umbrel ln -s /etc/init.d/umbrel /etc/rc5.d/S01umbrel
ln -s /etc/init.d/umbrel /etc/rc5.d/S01umbrel ln -s /etc/init.d/umbrel /etc/rc0.d/K01umbrel
ln -s /etc/init.d/umbrel /etc/rc0.d/K01umbrel ln -s /etc/init.d/umbrel /etc/rc1.d/K01umbrel
ln -s /etc/init.d/umbrel /etc/rc1.d/K01umbrel ln -s /etc/init.d/umbrel /etc/rc6.d/K01umbrel
ln -s /etc/init.d/umbrel /etc/rc6.d/K01umbrel # Do partitioning at first boot
# Do partitioning at first boot echo "Enabling defaults for umbrel"
echo "Enabling defaults for umbrel" update-rc.d umbrel defaults || exit 1
update-rc.d umbrel defaults || exit 1 echo "Enabling startup for umbrel box"
echo "Enabling startup for umbrel box" update-rc.d umbrel enable || exit 1
update-rc.d umbrel enable || exit 1 echo "starting up umbrel get it started now)"
echo "starting up umbrel get it started now)" /etc/init.d/umbrel start
/etc/init.d/umbrel start
fi
else
echo "Disk not partitioned, will not start umbrel framework (Please do it manually)"
fi fi
fi fi

144
scripts/umbrel-os/external-storage-mounter

@ -0,0 +1,144 @@
#!/usr/bin/env bash
set -euo pipefail
# This script will:
# - Look for external storage devices
# - Check if they contain an Umbrel install
# - If yes
# - - Mount it
# - If no
# - - Format it
# - - Mount it
# - - Install Umbrel on it
# - Bind mount the external installation on top of the local installation
UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../..)"
MOUNT_POINT="/mnt/data"
EXTERNAL_UMBREL_ROOT="${MOUNT_POINT}/umbrel"
check_root () {
if [[ $UID != 0 ]]; then
echo "This script must be run as root"
exit 1
fi
}
check_dependencies () {
for cmd in "$@"; do
if ! command -v $cmd >/dev/null 2>&1; then
echo "This script requires \"${cmd}\" to be installed"
exit 1
fi
done
}
# Returns a list of block device paths
list_block_devices () {
# We use "2>/dev/null || true" to swallow errors if there are
# no block devices. In that case the function just returns nothing
# instead of an error which is what we want.
#
# sed 's!.*/!!' is to return the device path so we get sda
# instead of /sys/block/sda
(ls -d /sys/block/sd* 2>/dev/null || true) | sed 's!.*/!!'
}
# Returns the vendor and model name of a block device
get_block_device_model () {
device="${1}"
vendor=$(cat "/sys/block/${device}/device/vendor")
model=$(cat "/sys/block/${device}/device/model")
# We echo in a subshell without quotes to strip surrounding whitespace
echo "$(echo $vendor) $(echo $model)"
}
# Wipes a block device and reformats it with a single EXT4 partition
format_block_device () {
device="${1}"
device_path="/dev/${device}"
partition_path="${device_path}1"
wipefs -a "${device_path}"
parted --script "${device_path}" mklabel gpt
parted --script "${device_path}" mkpart primary ext4 0% 100%
# We need to run sync here to make sure the filesystem is reflecting the
# the latest changes in /dev/*
sync
mkfs.ext4 -F -L umbrel "${partition_path}"
}
# Mounts the device given in the first argument at $MOUNT_POINT
mount_partition () {
partition_path="${1}"
mkdir -p "${MOUNT_POINT}"
mount "${partition_path}" "${MOUNT_POINT}"
}
# Unmounts $MOUNT_POINT
unmount_partition () {
umount "${MOUNT_POINT}"
}
main () {
echo "Running external storage mount script..."
check_root
check_dependencies sed wipefs parted mount sync
block_devices=$(list_block_devices)
no_of_block_devices=$(list_block_devices | wc -l)
if [[ $no_of_block_devices -lt 1 ]]; then
echo "No block devices found"
echo "Exiting mount script without doing anything"
exit
fi
if [[ $no_of_block_devices -gt 1 ]]; then
echo "Multiple block devices found, only one drive is supported"
echo "Exiting mount script without doing anything"
exit 1
fi
# At this point we know there is only one block device attached
block_device=$block_devices
partition_path="/dev/${block_device}1"
block_device_model=$(get_block_device_model $block_device)
echo "Found device \"${block_device_model}\""
echo "Checking if device contains an Umbrel install..."
mount_partition "${partition_path}"
if [[ -f "${EXTERNAL_UMBREL_ROOT}"/.umbrel ]]; then
echo "Yes, it does"
else
echo "No, it doesn't"
echo "Unmounting partition..."
unmount_partition
echo "Formatting device..."
format_block_device $block_device
echo "Mounting partition..."
mount_partition "${partition_path}"
echo "Copying Umbrel install to external storage..."
mkdir -p "${EXTERNAL_UMBREL_ROOT}"
cp --recursive \
--archive \
--no-target-directory \
"${UMBREL_ROOT}" "${EXTERNAL_UMBREL_ROOT}"
fi
echo "Bind mounting external storage over local Umbrel installation..."
mount --bind "${EXTERNAL_UMBREL_ROOT}" "${UMBREL_ROOT}"
echo "Checking Umbrel root is now on external storage..."
sync
sleep 1
"${UMBREL_ROOT}/scripts/umbrel-os/is-on-external-storage"
echo "Mount script completed successfully!"
}
main

10
scripts/umbrel-os/is-on-external-storage

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
# This script returns a non-zero exit code if $UMBREL_ROOT is NOT
# mounted on external storage.
UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../..)"
df -h "${UMBREL_ROOT}" | grep --quiet '/dev/sd'
Loading…
Cancel
Save