Add base files

This commit is contained in:
Austen Adler 2018-09-21 17:27:49 -04:00
parent 7e331d60df
commit d632ebedcd
7 changed files with 191 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
env

34
README.md Normal file
View 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
View 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
View 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

0
env.dist Normal file
View File

5
run_remote.sh Executable file
View 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
View 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"