Add base files
This commit is contained in:
parent
7e331d60df
commit
d632ebedcd
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
env
|
34
README.md
Normal file
34
README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# borg-remote-android
|
||||
A utility for easy android backups using rsync (locally) and borg (on a remote).
|
||||
|
||||
## Motivation
|
||||
I was having trouble installing borg (even though there was [borgbackup_on_android](https://github.com/ravenschade/borgbackup_on_android)) and running borg was slow since I was using lzma compression.
|
||||
|
||||
I created this tool so that the copy to the server could be quick, then the server could perform the heavy lifting of encryption/compression. This also allows for less required time on WiFi, since the only network-intensive operations are on the resumable rsync transfer.
|
||||
|
||||
## Usage
|
||||
In Termux, run:
|
||||
```bash
|
||||
./backup-android.sh
|
||||
```
|
||||
|
||||
and it will notify you when complete.
|
||||
|
||||
Alternatively, you can add a Termux widget to your home screen (`./setup.sh` auto-installs in the `.shortcuts` directory), so backups can be made with a single tap from the home screen.
|
||||
|
||||
## Installation
|
||||
Quick, 4 line installation:
|
||||
```bash
|
||||
apt update
|
||||
apt install -y git rsync openssh
|
||||
git clone https://gitea.austenwares.com/stonewareslord/borg-remote-android
|
||||
env bash borg-remote-android/setup.sh
|
||||
```
|
||||
|
||||
Same installation as a one-liner
|
||||
```bash
|
||||
apt update && apt install -y git rsync openssh && git clone https://gitea.austenwares.com/stonewareslord/borg-remote-android && env bash borg-remote-android/setup.sh
|
||||
```
|
||||
|
||||
## Updating
|
||||
The entire config is stored in `env`, which is in `.gitignore`, so running a simple `git pull` will update without losing custom changes.
|
57
backup-android.sh
Executable file
57
backup-android.sh
Executable file
@ -0,0 +1,57 @@
|
||||
#!/data/data/com.termux/files/usr/bin/bash
|
||||
# Initialize
|
||||
ABSPATH="$(readlink -f "$BASH_SOURCE")"
|
||||
cd "${ABSPATH%/*}" || { echo "Cannot change directory" >&2; exit 1; }
|
||||
test -f ./env && source ./env || { echo "Unable to source user variables in $PWD"; exit 1; }
|
||||
|
||||
# From https://serverfault.com/a/799198
|
||||
# Since Termux has no uuidgen command, we need to create one randomly
|
||||
function uuidgen() {
|
||||
od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
|
||||
}
|
||||
|
||||
# From https://unix.stackexchange.com/a/27014
|
||||
function time_diff {
|
||||
# Find the time difference between the two arguments (in seconds)
|
||||
local T="$(( "$1" - "$2" ))"
|
||||
local D=$((T/60/60/24))
|
||||
local H=$((T/60/60%24))
|
||||
local M=$((T/60%60))
|
||||
local S=$((T%60))
|
||||
(( $D > 0 )) && printf '%dd ' $D
|
||||
(( $H > 0 )) && printf '%dh ' $H
|
||||
(( $M > 0 )) && printf '%dm ' $M
|
||||
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and '
|
||||
printf '%ds\n' $S
|
||||
}
|
||||
|
||||
function backup() {
|
||||
# First, we need to rsync our changes to the host
|
||||
echo "Running rsync..."
|
||||
$RSYNC_COMMAND "$SOURCE_LOCATION" "$REMOTE_HOST:$DESTINATION_LOCATION" || return 1
|
||||
|
||||
# Next, instruct the host to create a borg
|
||||
echo "Running borg..."
|
||||
./run_remote.sh nohup sh -c "cd \"$DESTINATION_LOCATION\"; $BORG_COMMAND \"$BORG_REPO::$HOSTNAME-$(uuidgen)\" \"$DESTINATION_LOCATION\"" || return 2
|
||||
}
|
||||
|
||||
# Take wakelock so we don't fall asleep
|
||||
termux-wake-lock
|
||||
START_TIME="$(date +%s)"
|
||||
|
||||
# Perform the backup
|
||||
backup
|
||||
RESULT=$?
|
||||
DURATION="$(time_diff "$(date +%s)" "$START_TIME" )"
|
||||
|
||||
echo "Completed $(date +%F-%T)"
|
||||
echo "Duration: $DURATION"
|
||||
|
||||
if (( RESULT == 0 )); then
|
||||
termux-notification --title "Backup completed successfully in $DURATION"
|
||||
else
|
||||
termux-notification --title "Backup failed in $DURATION"
|
||||
fi
|
||||
|
||||
# Remove our wakelock
|
||||
termux-wake-unlock
|
19
doc/state-diagram.txt
Normal file
19
doc/state-diagram.txt
Normal file
@ -0,0 +1,19 @@
|
||||
@startuml
|
||||
Android -> Android: Take wakelock
|
||||
|
||||
note right of rsync
|
||||
The borg and rsync servers can be the server.
|
||||
""BORG_REPO"" and ""REMOTE_HOST"" are configurable.
|
||||
end note
|
||||
|
||||
Android -> "Rsync Server" as rsync: rsync data to temporary location
|
||||
rsync --> Android: rsync complete
|
||||
Android -> rsync: nohup spawn borg backup
|
||||
|
||||
rsync -> "Borg Server" as borg: borg backup temporary directory
|
||||
borg --> rsync: borg complete
|
||||
rsync --> Android: borg complete
|
||||
|
||||
Android -> Android: Show success notification
|
||||
Android -> Android: Release wakelock
|
||||
@enduml
|
5
run_remote.sh
Executable file
5
run_remote.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/data/data/com.termux/files/usr/bin/bash
|
||||
ABSPATH="$(readlink -f "$BASH_SOURCE")"
|
||||
cd "${ABSPATH%/*}" || { echo "Cannot change directory" >&2; exit 1; }
|
||||
test -f ./env && source ./env || { echo "Unable to source user variables"; exit 1; }
|
||||
ssh "$REMOTE_HOST" -- "$@"
|
75
setup.sh
Executable file
75
setup.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#!/data/data/com.termux/files/usr/bin/bash
|
||||
ABSPATH="$(readlink -f "$BASH_SOURCE")"
|
||||
cd "${ABSPATH%/*}" || { echo "Cannot change directory" >&2; exit 1; }
|
||||
|
||||
function ask() {
|
||||
echo -n "$1 [Y/n]? "
|
||||
read RESP
|
||||
if [ -z "$RESP" ] || [ "${RESP,,}" = "y" ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Read a variable
|
||||
function configure_var() {
|
||||
# If the variable already exists, continue without asking questions
|
||||
if [ ! -z "${!1}" ]; then
|
||||
echo "It is ${!1}"
|
||||
return
|
||||
fi
|
||||
|
||||
DEFAULT="$2"
|
||||
echo -n "export $1= ($2): "
|
||||
read RESP
|
||||
RESP="${RESP:-$DEFAULT}"
|
||||
# Save the variable
|
||||
#TODO: This introduces possible bugs when quotes are involved with RESP
|
||||
echo "# Line added on $(date +%F-%T)" >>env
|
||||
echo "export $1=\"$RESP\"" >>env
|
||||
# Load the variable for use in this script
|
||||
export "$1"="$RESP"
|
||||
}
|
||||
|
||||
# Begin configuration
|
||||
echo
|
||||
echo "Asking config questions..."
|
||||
echo "IMPORTANT: Trailing slashes matter for paths. Consult the rsync manual for details."
|
||||
echo "It is recommended to use trailing slashes for all _LOCATION variables."
|
||||
echo "Also, paths can be relative or absolute"
|
||||
echo
|
||||
|
||||
# Load existing configurations
|
||||
test -f env && source env
|
||||
|
||||
configure_var LOCAL_HOSTNAME android1
|
||||
configure_var REMOTE_HOST user@example.com
|
||||
configure_var SOURCE_LOCATION "/storage/emulated/0/"
|
||||
configure_var DESTINATION_LOCATION "tmp/borg/$LOCAL_HOSTNAME/"
|
||||
configure_var BORG_REPO "ssh://$REMOTE_HOST/~/borg-backups"
|
||||
configure_var BORG_COMMAND "borg create --verbose --progress --stats --one-file-system --exclude-caches --compression=auto,lzma --exclude=storage/emulated/0/Android"
|
||||
configure_var RSYNC_COMMAND "rsync --relative --recursive --links --times --human-readable --partial --info=progress2 --delete --delete-excluded --exclude=storage/emulated/0/Android"
|
||||
|
||||
# Install borg-backup into ~/.shortcuts
|
||||
mkdir -p ~/.shortcuts
|
||||
if [ -L ~/.shortcuts/borg-backup ]; then
|
||||
rm ~/.shortcuts/borg-backup
|
||||
fi
|
||||
ln -s "$(readlink -f backup-android.sh)" ~/.shortcuts/borg-backup || echo "Unable to link to ~/.shortcuts" >&2
|
||||
|
||||
# Ask about authentication
|
||||
SSH_KEYGEN_COMMAND="ssh-keygen -b 512 -t ed25519 -f $HOME/.ssh/id_ed25519 -N ''"
|
||||
ask "Generate a new ssh key ($SSH_KEYGEN_COMMAND)" && $SSH_KEYGEN_COMMAND
|
||||
ask "Run ssh-copy-id on host" && ssh-copy-id "$HOST"
|
||||
|
||||
# Create destination location
|
||||
echo "Creating DESTINATION_LOCATION"
|
||||
./run_remote.sh mkdir -p "$DESTINATION_LOCATION"
|
||||
|
||||
# Exclude file
|
||||
touch exclude
|
||||
ask "Edit exclude file with vi" && vi exclude
|
||||
|
||||
# Run final checks
|
||||
ask "Check if borg command exists (on remote)" && { ./run_remote.sh command -v borg || echo "Borg command not found on remote host"; }
|
||||
ask "Run borg list (on remote)" && ./run_remote.sh borg list "$BORG_REPO"
|
Loading…
Reference in New Issue
Block a user