From da97f13f1cf77f0a61a50b4764d10013bdab546b Mon Sep 17 00:00:00 2001 From: Dvir S Date: Mon, 29 Apr 2024 15:49:44 -0400 Subject: [PATCH] Update data-export Supporting SMB, USB, SCP --- scripts/data-export | 294 ++++++++++++++------------------------------ 1 file changed, 92 insertions(+), 202 deletions(-) diff --git a/scripts/data-export b/scripts/data-export index 6a1a6994d..56d8b190c 100755 --- a/scripts/data-export +++ b/scripts/data-export @@ -2,19 +2,8 @@ set -euo pipefail -# This script will: -# - Look for an internal Umbrel install -# - Ask the user to confirm the location or enter a new one -# - Exit and print error if no valid Umbrel install detected -# - Look for USB storage device -# - Ask the user to confirm the device or enter a new one -# - Exit and print error if no valid USB storage device detected -# - Check size of external storage is large enough for Umbrel install -# - Check we have write permissions on external drive -# - Stop Umbrel if it's running -# - Copy Umbrel install to external drive +# Dependencies: jq, rsync, lsblk, mount, umount, cifs-utils, sshpass, parted, wipefs, mkfs.ext4, docker -# Bail if not running as root check_root() { if [[ $UID != 0 ]]; then echo "This script must be run as root" @@ -22,29 +11,20 @@ check_root() { fi } -# Check depndencies are installed check_dependencies () { for cmd in "$@"; do if ! command -v $cmd >/dev/null 2>&1; then echo "This script requires \"${cmd}\" to be installed" - echo - echo "You can try running: sudo apt-get install ${cmd}" exit 1 fi done } -# Interactively confirm a value with the user. The user can press enter to accept the default value -# or enter a new value. confirm_value_with_user() { local prompt="${1}" local default_value="${2}" local user_input - - # Prompt the user and get input - read -p "$prompt " user_input /dev/null || true + wipefs -a "${usb_block_device}" + parted --script "${usb_block_device}" mklabel gpt + parted --script "${usb_block_device}" mkpart primary ext4 0% 100% sync - echo - format_block_device "${usb_block_device}" - echo + mkfs.ext4 -F -L umbrel "${usb_block_device}1" - local usb_partition="${usb_block_device}1" - echo "Mounting ${usb_partition}..." + echo "Mounting USB storage device..." local usb_mount_path=$(mktemp --directory --suffix -umbrel-usb-mount) - mount "${usb_partition}" "${usb_mount_path}" + mount "${usb_block_device}1" "${usb_mount_path}" - # Make sure no matter what, this gets unmounted - trap "umount ${usb_mount_path} 2> /dev/null || true" EXIT + echo "Stopping Umbrel to prepare for data export..." + "${umbrel_install}/scripts/stop" || docker stop $(docker ps -aq) || { echo "Error: Could not stop Umbrel"; exit 1; } - # Check we can write + echo "Copying data to USB..." local temporary_copy_path="${usb_mount_path}/umbrel-data-export-temporary-${RANDOM}-$(date +%s)" mkdir "${temporary_copy_path}" - if [[ ! -d "${temporary_copy_path}" ]] - then - echo "Error: Could not write to the USB storage device $(get_block_device_model ${usb_block_device#/dev/}). Please re-connect a compatible USB storage device and run this script again." - exit 1 - fi - - # Stop Umbrel if it's running so we can safely copy data - echo "Stopping Umbrel to prepare for data export..." - echo - "${umbrel_install}/scripts/stop" || { - # If the stop script fails try heavy handedly stopping all Docker containers to ensure - docker stop $(docker ps -aq) || { - echo "Error: Could not stop Umbrel" - exit 1 - } - } - echo - - # Copy data - echo "Exporting your Umbrel data to the USB storage device $(get_block_device_model ${usb_block_device#/dev/}), this may take a while..." - local final_path="${usb_mount_path}/umbrel" rsync --archive --delete "${umbrel_install}/" "${temporary_copy_path}" - mv "${temporary_copy_path}" "${final_path}" + mv "${temporary_copy_path}" "${usb_mount_path}/umbrel" - # Ensure fs caches are flushed and unmount echo "Export complete, unmounting USB storage device..." sync - umount ${usb_mount_path} + umount "${usb_mount_path}" - echo - echo "Done! Your Umbrel data has been exported to your external USB storage device $(get_block_device_model ${usb_block_device#/dev/})." - echo - echo "Next steps:" - echo " 1. Shutdown your device." - echo " 2. Flash umbrelOS 1.1.1 on its internal storage." - echo " 3. Boot up with the USB storage device $(get_block_device_model ${usb_block_device#/dev/}) connected to your device." - echo " 4. Open http://umbrel.local" - echo - echo "For detailed instructions, visit:" - echo " https://link.umbrel.com/linux-update" + echo "Done! Your Umbrel data has been exported to your external USB storage device." +} + +backup_to_smb() { + local smb_server=$(confirm_value_with_user "Enter SMB server address (e.g., 192.168.1.100):" "") + local smb_share=$(confirm_value_with_user "Enter SMB share name:" "") + local smb_user=$(confirm_value_with_user "Enter SMB username:" "") + local smb_password=$(confirm_value_with_user "Enter SMB password:" "") + + local mount_point=$(mktemp --directory --suffix -umbrel-smb-mount) + mount -t cifs -o username="${smb_user}",password="${smb_password}" "//${smb_server}/${smb_share}" "${mount_point}" + + echo "Exporting your Umbrel data to the SMB share, this may take a while..." + rsync --archive --delete "${umbrel_install}/" "${mount_point}" + sync + + echo "Export complete, unmounting SMB share..." + umount "${mount_point}" + + echo "Done! Your Umbrel data has been exported to the SMB share." +} + +backup_to_scp() { + local scp_server=$(confirm_value_with_user "Enter SCP server address (e.g., user@192.168.1.100):" "") + local scp_path=$(confirm_value_with_user "Enter the SCP destination path (e.g., /path/to/backup):" "") + local scp_password=$(confirm_value_with_user "Enter your SCP password:" "") + local scp_port=$(confirm_value_with_user "Enter SCP port (default 22):" "22") + + echo "Exporting your Umbrel data to the SCP server, this may take a while..." + sshpass -p "${scp_password}" rsync -avz -e "ssh -p ${scp_port}" "${umbrel_install}/" "${scp_server}:${scp_path}" + echo "Export complete." + + echo "Done! Your Umbrel data has been exported to the SCP server." +} + +main() { + check_root + check_dependencies jq rsync lsblk mount umount cifs-utils sshpass parted wipefs mkfs.ext4 docker + local umbrel_install=$(find_umbrel_install) + select_backup_method } -main \ No newline at end of file +main