Skip to content
This repository was archived by the owner on Jan 23, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions remote-backup/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ FROM $BUILD_FROM
ENV LANG C.UTF-8

# Setup base
RUN apk add --no-cache jq openssh-client zip
RUN apk add --no-cache jq openssh-client zip sshpass rsync

# Hass.io CLI
ARG BUILD_ARCH
ARG CLI_VERSION
RUN apk add --no-cache curl \
&& curl -Lso /usr/bin/hassio https://github.com/home-assistant/hassio-cli/releases/download/1.2.1/hassio_${BUILD_ARCH} \
&& curl -Lso /usr/bin/hassio https://github.com/home-assistant/hassio-cli/releases/download/2.2.0/hassio_${BUILD_ARCH} \
&& chmod a+x /usr/bin/hassio

# Copy data
Expand Down
20 changes: 16 additions & 4 deletions remote-backup/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,42 @@
"name": "Remote Backup",
"version": "dev",
"slug": "remote_backup",
"description": "Exploit snapshots and SCP to create remote backups to specified server",
"description": "Exploit snapshots and SCP/rsync to create remote backups to specified server",
"url": "https://github.com/overkill32/hassio-remote-backup",
"startup": "once",
"boot": "manual",
"hassio_api": true,
"hassio_role": "backup",
"map": ["backup:rw"],
"map": ["config", "addons", "share", "ssl", "backup:rw"],
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"options": {
"ssh_enabled": true,
"ssh_host": "",
"ssh_port": 22,
"ssh_user": "",
"ssh_key": [],
"remote_directory": "",
"zip_password": "",
"keep_local_backup": ""
"keep_local_backup": "",
"rsync_enabled": false,
"rsync_host": "",
"rsync_rootfolder": "hassio-sync",
"rsync_user": "",
"rsync_password": ""
},
"schema": {
"ssh_enabled": "bool",
"ssh_host": "str",
"ssh_port": "int",
"ssh_user": "str",
"ssh_key": ["str"],
"remote_directory": "str",
"zip_password": "str",
"keep_local_backup": "match(^(all|[+]?\\d*)$)"
"keep_local_backup": "match(^(all|[+]?\\d*)$)",
"rsync_enabled": "bool",
"rsync_host": "str",
"rsync_rootfolder": "str",
"rsync_user": "str",
"rsync_password": "str"
}
}
98 changes: 67 additions & 31 deletions remote-backup/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -e
CONFIG_PATH=/data/options.json

# parse inputs from options
SSH_ENABLED=$(jq --raw-output ".ssh_enabled" $CONFIG_PATH)
SSH_HOST=$(jq --raw-output ".ssh_host" $CONFIG_PATH)
SSH_PORT=$(jq --raw-output ".ssh_port" $CONFIG_PATH)
SSH_USER=$(jq --raw-output ".ssh_user" $CONFIG_PATH)
Expand All @@ -12,41 +13,51 @@ REMOTE_DIRECTORY=$(jq --raw-output ".remote_directory" $CONFIG_PATH)
ZIP_PASSWORD=$(jq --raw-output '.zip_password' $CONFIG_PATH)
KEEP_LOCAL_BACKUP=$(jq --raw-output '.keep_local_backup' $CONFIG_PATH)

RSYNC_ENABLED=$(jq --raw-output ".rsync_enabled" $CONFIG_PATH)
RSYNC_HOST=$(jq --raw-output ".rsync_host" $CONFIG_PATH)
RSYNC_ROOTFOLDER=$(jq --raw-output ".rsync_rootfolder" $CONFIG_PATH)
RSYNC_USER=$(jq --raw-output ".rsync_user" $CONFIG_PATH)
RSYNC_PASSWORD=$(jq --raw-output ".rsync_password" $CONFIG_PATH)

# create variables
SSH_ID="${HOME}/.ssh/id"

function add-ssh-key {
echo "Adding SSH key"
mkdir -p ~/.ssh
(
echo "Host remote"
echo " IdentityFile ${HOME}/.ssh/id"
echo " HostName ${SSH_HOST}"
echo " User ${SSH_USER}"
echo " Port ${SSH_PORT}"
echo " StrictHostKeyChecking no"
) > "${HOME}/.ssh/config"

while read -r line; do
echo "$line" >> ${HOME}/.ssh/id
done <<< "$SSH_KEY"

chmod 600 "${HOME}/.ssh/config"
chmod 600 "${HOME}/.ssh/id"

if [ "$SSH_ENABLED" = true ] ; then
echo "Adding SSH key"
mkdir -p ~/.ssh
(
echo "Host remote"
echo " IdentityFile ${HOME}/.ssh/id"
echo " HostName ${SSH_HOST}"
echo " User ${SSH_USER}"
echo " Port ${SSH_PORT}"
echo " StrictHostKeyChecking no"
) > "${HOME}/.ssh/config"

while read -r line; do
echo "$line" >> ${HOME}/.ssh/id
done <<< "$SSH_KEY"

chmod 600 "${HOME}/.ssh/config"
chmod 600 "${HOME}/.ssh/id"
fi
}

function copy-backup-to-remote {

cd /backup/
if [[ -z $ZIP_PASSWORD ]]; then
echo "Copying ${slug}.tar to ${REMOTE_DIRECTORY} on ${SSH_HOST} using SCP"
scp -F "${HOME}/.ssh/config" "${slug}.tar" remote:"${REMOTE_DIRECTORY}"
else
echo "Copying password-protected ${slug}.zip to ${REMOTE_DIRECTORY} on ${SSH_HOST} using SCP"
zip -P "$ZIP_PASSWORD" "${slug}.zip" "${slug}".tar
scp -F "${HOME}/.ssh/config" "${slug}.zip" remote:"${REMOTE_DIRECTORY}" && rm "${slug}.zip"
if [ "$SSH_ENABLED" = true ] ; then
cd /backup/
if [[ -z $ZIP_PASSWORD ]]; then
echo "Copying ${slug}.tar to ${REMOTE_DIRECTORY} on ${SSH_HOST} using SCP"
scp -F "${HOME}/.ssh/config" "${slug}.tar" remote:"${REMOTE_DIRECTORY}"
else
echo "Copying password-protected ${slug}.zip to ${REMOTE_DIRECTORY} on ${SSH_HOST} using SCP"
zip -P "$ZIP_PASSWORD" "${slug}.zip" "${slug}".tar
scp -F "${HOME}/.ssh/config" "${slug}.zip" remote:"${REMOTE_DIRECTORY}" && rm "${slug}.zip"
fi
fi

}

function delete-local-backup {
Expand All @@ -57,16 +68,16 @@ function delete-local-backup {
:
elif [[ -z ${KEEP_LOCAL_BACKUP} ]]; then
echo "Deleting local backup: ${slug}"
hassio snapshots remove -name "${slug}"
hassio snapshots remove "${slug}"
else

last_date_to_keep=$(hassio snapshots list | jq .data.snapshots[].date | sort -r | \
last_date_to_keep=$(hassio snapshots list --raw-json | jq .data.snapshots[].date | sort -r | \
head -n "${KEEP_LOCAL_BACKUP}" | tail -n 1 | xargs date -D "%Y-%m-%dT%T" +%s --date )

hassio snapshots list | jq -c .data.snapshots[] | while read backup; do
hassio snapshots list --raw-json | jq -c .data.snapshots[] | while read backup; do
if [[ $(echo ${backup} | jq .date | xargs date -D "%Y-%m-%dT%T" +%s --date ) -lt ${last_date_to_keep} ]]; then
echo "Deleting local backup: $(echo ${backup} | jq -r .slug)"
hassio snapshots remove -name "$(echo ${backup} | jq -r .slug)"
hassio snapshots remove "$(echo ${backup} | jq -r .slug)"
fi
done

Expand All @@ -76,14 +87,39 @@ function delete-local-backup {
function create-local-backup {
name="Automated backup $(date +'%Y-%m-%d %H:%M')"
echo "Creating local backup: \"${name}\""
slug=$(hassio snapshots new --options name="${name}" | jq --raw-output '.data.slug')
slug=$(hassio snapshots new --raw-json --name="${name}" | jq --raw-output '.data.slug')
echo "Backup created: ${slug}"
}

function rsync_folders {

if [ "$RSYNC_ENABLED" = true ] ; then
rsyncurl="$RSYNC_USER@$RSYNC_HOST::$RSYNC_ROOTFOLDER"
echo "[Info] trying to rsync hassio folders to $rsyncurl"
echo ""
echo "[Info] /config"
sshpass -p $RSYNC_PASSWORD rsync -av --exclude '*.db-shm' --exclude '*.db-wal' /config/ $rsyncurl/config/ --delete
echo ""
echo "[Info] /addons"
sshpass -p $RSYNC_PASSWORD rsync -av /addons/ $rsyncurl/addons/ --delete
echo ""
echo "[Info] /backup"
sshpass -p $RSYNC_PASSWORD rsync -av /backup/ $rsyncurl/backup/ --delete
echo ""
echo "[Info] /share"
sshpass -p $RSYNC_PASSWORD rsync -av /share/ $rsyncurl/share/ --delete
echo ""
echo "[Info] /ssl"
sshpass -p $RSYNC_PASSWORD rsync -av /ssl/ $rsyncurl/ssl/ --delete
echo "[Info] Finished rsync"
fi
}


add-ssh-key
create-local-backup
copy-backup-to-remote
rsync_folders
delete-local-backup

echo "Backup process done!"
Expand Down