#!/usr/bin/env bash # This script is exposed via: curl -sL https://export.umbrel.sh | sudo bash # Which resolves to this file at the 1.1.1 tag in this repo 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 # Bail if not running as root check_root() { if [[ $UID != 0 ]]; then echo "This script must be run as root" exit 1 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 sync echo format_block_device "${usb_block_device}" echo local usb_partition="${usb_block_device}1" echo "Mounting ${usb_partition}..." local usb_mount_path=$(mktemp --directory --suffix -umbrel-usb-mount) mount "${usb_partition}" "${usb_mount_path}" # Make sure no matter what, this gets unmounted trap "umount ${usb_mount_path} 2> /dev/null || true" EXIT # Check we can write 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}" # Ensure fs caches are flushed and unmount echo "Export complete, unmounting USB storage device..." sync 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" } main