diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6e7e933 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# Configuration file for GitHub Dependabot + +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + assignees: + - "ceskyDJ" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..c975abb --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,33 @@ +name: deploy + +on: + workflow_dispatch: + push: + tags: ['v*'] + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + name: Build and deploy add-on + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2.1.0 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build add-on and publish it to GitHub Container Registry + uses: home-assistant/builder@2024.08.2 + with: + args: | + --all \ + --target . \ + --docker-hub "ghcr.io/${{ github.repository_owner }}" diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 200e3f3..e9d2d75 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -7,35 +7,16 @@ on: pull_request: branches: - master - schedule: - - cron: "0 0 * * *" jobs: - find: - name: Find add-ons - runs-on: ubuntu-latest - outputs: - addons: ${{ steps.addons.outputs.addons_list }} - steps: - - name: ⤵️ Check out code from GitHub - uses: actions/checkout@v3.5.0 - - - name: 🔍 Find add-on directories - id: addons - uses: home-assistant/actions/helpers/find-addons@master - lint: - name: Lint add-on ${{ matrix.path }} + name: Lint add-on config file runs-on: ubuntu-latest - needs: find - strategy: - matrix: - path: ${{ fromJson(needs.find.outputs.addons) }} steps: - name: ⤵️ Check out code from GitHub - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v4 - name: 🚀 Run Home Assistant Add-on Lint - uses: frenck/action-addon-linter@v2.11 + uses: frenck/action-addon-linter@v2.18.0 with: - path: "./${{ matrix.path }}" + path: "." diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 7ed2d00..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: ci - -on: - push: - branches: - - "master" - pull_request: - branches: - - "master" - -env: - BUILD_ARGS: "--test" - MONITORED_FILES: "build.yaml config.yaml Dockerfile rootfs" - -jobs: - init: - runs-on: ubuntu-latest - name: Initialize builds - outputs: - changed_addons: ${{ steps.changed_addons.outputs.addons }} - changed: ${{ steps.changed_addons.outputs.changed }} - steps: - - name: Check out the repository - uses: actions/checkout@v3.5.0 - - - name: Get changed files - id: changed_files - uses: jitterbit/get-changed-files@v1 - - - name: Find add-on directories - id: addons - uses: home-assistant/actions/helpers/find-addons@master - - - name: Get changed add-ons - id: changed_addons - run: | - declare -a changed_addons - for addon in ${{ steps.addons.outputs.addons }}; do - if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon ]]; then - for file in ${{ env.MONITORED_FILES }}; do - if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon/$file ]]; then - if [[ ! "${changed_addons[@]}" =~ $addon ]]; then - changed_addons+=("\"${addon}\","); - fi - fi - done - fi - done - - changed=$(echo ${changed_addons[@]} | rev | cut -c 2- | rev) - - if [[ -n ${changed} ]]; then - echo "Changed add-ons: $changed"; - echo "changed=true" >> $GITHUB_OUTPUT; - echo "addons=[$changed]" >> $GITHUB_OUTPUT; - else - echo "No add-on had any monitored files changed (${{ env.MONITORED_FILES }})"; - fi - build: - needs: init - runs-on: ubuntu-latest - if: needs.init.outputs.changed == 'true' - name: Build ${{ matrix.arch }} ${{ matrix.addon }} add-on - strategy: - matrix: - addon: ${{ fromJson(needs.init.outputs.changed_addons) }} - arch: ["aarch64", "amd64", "armhf", "armv7", "i386"] - - steps: - - name: Check out repository - uses: actions/checkout@v3.5.0 - - - name: Get information - id: info - uses: home-assistant/actions/helpers/info@master - with: - path: "./${{ matrix.addon }}" - - - name: Check if add-on should be built - id: check - run: | - if [[ "${{ steps.info.outputs.architectures }}" =~ ${{ matrix.arch }} ]]; then - echo "build_arch=true" >> $GITHUB_OUTPUT; - echo "image=$(echo ${{ steps.info.outputs.image }} | cut -d'/' -f3)" >> $GITHUB_OUTPUT; - if [[ -z "${{ github.head_ref }}" ]] && [[ "${{ github.event_name }}" == "push" ]]; then - echo "BUILD_ARGS=" >> $GITHUB_ENV; - fi - else - echo "${{ matrix.arch }} is not a valid arch for ${{ matrix.addon }}, skipping build"; - echo "build_arch=false" >> $GITHUB_OUTPUT; - fi - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to GitHub Container Registry - if: env.BUILD_ARGS != '--test' - uses: docker/login-action@v2.1.0 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build ${{ matrix.addon }} add-on ghcr - if: steps.check.outputs.build_arch == 'true' - uses: home-assistant/builder@2023.03.0 - with: - args: | - ${{ env.BUILD_ARGS }} \ - --${{ matrix.arch }} \ - --target /data/${{ matrix.addon }} \ - --image "${{ steps.check.outputs.image }}" \ - --docker-hub "ghcr.io/${{ github.repository_owner }}" \ - --addon - - - name: Build ${{ matrix.addon }} add-on docker hub - if: steps.check.outputs.build_arch == 'true' - uses: home-assistant/builder@2023.03.0 - with: - args: | - ${{ env.BUILD_ARGS }} \ - --${{ matrix.arch }} \ - --target /data/${{ matrix.addon }} \ - --image "${{ steps.check.outputs.image }}" \ - --addon diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fcf43c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# IDE files +.idea/ diff --git a/Dockerfile b/Dockerfile index c85b325..123b40a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,21 @@ ARG BUILD_FROM FROM $BUILD_FROM -ENV LANG C.UTF-8 +ENV LANG=C.UTF-8 RUN apk add --no-cache \ borgbackup \ openssh-keygen \ - openssh-client + openssh-client \ + tar # Home Assistant CLI ARG BUILD_ARCH -ARG CLI_VERSION -RUN curl -Lso /usr/bin/ha \ - "https://github.com/home-assistant/cli/releases/download/${CLI_VERSION}/ha_${BUILD_ARCH}" \ - && chmod a+x /usr/bin/ha +RUN curl -Lso /usr/bin/ha "https://github.com/home-assistant/cli/releases/latest/download/ha_${BUILD_ARCH}" +RUN chmod +x /usr/bin/ha # Copy required data for add-on COPY run.sh / -RUN chmod a+x /run.sh +RUN chmod +x /run.sh CMD [ "/run.sh" ] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c863951 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +SHELL=/bin/bash + +.PHONY: build run dev-deploy + +build: + docker run \ + --rm \ + -it \ + --name builder \ + --privileged \ + -v .:/data \ + -v /var/run/docker.sock:/var/run/docker.sock:ro \ + ghcr.io/home-assistant/amd64-builder \ + -t /data \ + --all \ + --test \ + -i home-assistant-borg-backup-dev \ + -d local + +run: build + docker run --rm -v ./data:/data local/home-assistant-borg-backup-dev + +dev-deploy: + scp -r ../home-assistant-borg-backup steve:/addons diff --git a/README.md b/README.md index d110733..b0a2cc9 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,139 @@ -# borg based backup for home assistant +# Borg-based Backup for Home Assistant ## About -Home assistant is very nice system, but every system can crash or disks it resides on can stop spinning eventually, so we need to keep configuration and -data safe with some kind of backup, this addon provides exactly that. More about borgbackup could be found at [borgbackup](https://www.borgbackup.org/) website -Few things this addon provides to you are: -- automation of backups -- compression of backups -- deduplication of backups +Home assistant is a very nice system, but every system can crash or disks it resides on can stop spinning eventually. +So we need to keep configuration and data safe with some kind of backup, this add-on provides exactly that. +You can find more about BorgBackup at [BorgBackup's website](https://www.borgbackup.org/). -first part is done by home assistant but last two are benefits that [borgbackup](https://www.borgbackup.org/) provides. +This add-on provides a few things: +- automation of backups, +- compression of backups, +- deduplication of backups. -## Install -1) Add https://github.com/bmanojlovic/home-assistant-addons into supervisor addons-store -2) Install Borg-Backup addon -3) configure system and addon for backups +The first part is done by home assistant itself, but the last two are benefits that +[BorgBackup](https://www.borgbackup.org/) provides. -## Configuration +This add-on is a fork of [bmanojlovic/home-assistant-borg-backup](https://github.com/bmanojlovic/home-assistant-borg-backup). +So, big thanks go to [bmanojlovic](https://github.com/bmanojlovic)! -there are two ways to configure borg repository path, using borg repository uri, or using "manual" way of setting it up using **borg_hostname** **borg_user** and **borg_reponame** parameters. -it could look to something like + + +## Installation + +Installation consists of these steps: + +1) Add repository https://github.com/ceskyDJ/home-assistant-addons into supervisor's add-ons store. + See [official guide](https://www.home-assistant.io/common-tasks/os#installing-a-third-party-add-on-repository) for help. +2) Install Borg-Backup add-on. +3) Configure add-on (see [Add-on Configuration](#add-on-configuration)). +4) Add a generated public SSH key to target Borg repository's server (see [SSH Key Authentication](#ssh-key-authentication)). +5) Set up automatic backing up via Home Assistant's automation (see [Setup Automation](#setup-automation)). + + +### Add-on Configuration + +This section describes how to properly configure this add-on. + +#### Path to Borg Repository + +You need to specify a path to Borg repository you want to use. +This is just SSH credentials and path to the folder, where borg repository should be stored at the server. +It could look to something like (for Hetzner's StorageBox): ```yaml -borg_hostname: host -borg_user: user -borg_reponame: path/to/repo +borg_hostname: u100000-sub1.your-storagebox.de +borg_user: u100000-sub1 +borg_repo_name: /./home-assistant ``` -or -set **borg_repo_url** to something like +If you have some special requirements for SSH connection (e.g., different port), you can set a list of SSH arguments. +It could look like this for Hetzner's StorageBox: ```yaml -borg_repo_url: user@host:path/to/repo +borg_ssh_params: -p 23 ``` +This is optional, so configure it ONLY in case you need to, and you know what you are doing! +If you configure add-on from GUI, you need to toggle on the "Show unused optional configuration options" option. -Please be aware that you are supposed to use only one way of doing it, as if both are used addon will exit with error. +#### Passphrase -When first run addon will provide in its logs information of ssh key that you should set on borg backup server. Example key how it should look like is shown bellow. +Now, insert some (prefer randomly generated) string that will be used as passphrase for encryption: +```yaml +borg_passphrase: some-random-string---CHANGE-IT! +``` + +#### Configuration Done + +When you have filled all the required fields, you're done here! +Feel free to run the add-on and go to Logs, as there you will find generated public key you will need in the next step. + +### SSH Key Authentication + +This add-on uses SSH key authentication, when logs in to Borg repository. +It automatically generates its keypair, so all you need to do is add generated public key to Borg repository's server. + +When first run, add-on will provide a generated SSH key in its logs. It looks like this: ``` [00:01:07] INFO: Your ssh key to use for borg backup host [00:01:07] INFO: ************ SNIP ********************** ssh-rsa AAAAB3N... root@local-borg-backup [00:01:07] INFO: ************ SNIP ********************** - -``` -## Automation -In Automation add something like this in Configuration -> Automations -1) click + symbol -2) skip Almond if you have it -3) add Name `Automatic borg backup` -4) in trigger section set "trigger type" to `Time` -5) on line stating "At" set time at which you would like backup to be done ``` -02:02:02 -``` -6) in actions set `call service` if not already set -7) for service set `hassio.start_addon` -8) in "Service data" add above installed addon. Exact name of "`xxxx_borg-backup`" in configuration - should be provided to you by system when you open from "supervisor dashboard" and going to addon page (look at URL of borg-backup ) -``` -addon: xxxx_borg-backup -``` -9) save, sit and relax as it should work now :) + +Alternatively you could find the key under `/addon-config/XXXXXXXX_borg_backup/keys/borg_backup.pub`. +You need to have SSH access to Home Assistant instance or some other way, how to access add-on config directory. + +#### Adding Key to the Server + +You need to add the copied key to the server somehow. +There is no definitive guide for this. +You need to google a bit or see documentation of your Borg repository's provider. + +For Hetzner's StorageBox you can use this list of SSH commands that should be run from some Unix-like terminal +(of course you need to replace `u100000-sub1` with your StorageBox's account name): + +- `cd /tmp` +- `nano id_borg_backup.pub` +- Paste the copied public key here and save editor (CTRL + X, Y, ENTER) +- `cat ./id_borg_backup.pub | ssh -p 23 u100000-sub1@u100000-sub1.your-storagebox.de install-ssh-key` +- `rm id_borg_backup.pub` + +You can find Hetzner's official guide here: https://docs.hetzner.com/storage/storage-box/backup-space-ssh-keys/. + +#### Public SSH Key Added to the Server + +If you are done with adding the public key to the server, where you host your Borg repository, you are definitely done +with configuration at the add-on side. +Now turn on the add-on one more time and go to Logs again. +If it succeeded (no error message will be there, and you will see "End borg create --stats..."), you can continue +to next step. + +### Setup Automation + +You need to create new automation to run backups regularly in an automated manner. + +Go to [Automations & scenes](https://my.home-assistant.io/redirect/automations) in your Home Assistant instance. +You can click on the link or go to Settings --> Automations & scenes. + +Create new automation by following this guide: + +1) Click the "CREATE AUTOMATION" button to open the Create automation dialog. +2) Click the "Create new automation" button to create automation from scratch. +3) Click the "ADD TRIGGER" button. +4) Search for "Time" (start typing until you see "Time" in the list) and select it from the list (click on it). +5) Set the time you want to automatically create Borg backups (e.g. `02:02:02`). +6) Scroll down a bit and click on "ADD ACTION" button. +7) Search for "Start add-on" and select "Home Assistant Supervisor: Start add-on" from the list (click on it). +8) Click into the "Add-on" field and select "Borg-based Backup for Home Assistant" from the list. +9) Click the "SAVE" button. +10) Give automation a name, e.g., `Automatic Borg backup` and optionally a description. +11) Click the "SAVE" button. + +Now, you should have everything set up! + -# Contact and issues +## Issues and Troubleshooting -Use [issue tracker](https://github.com/bmanojlovic/home-assistant-borg-backup/issues) on github for any issue with this addon. \ No newline at end of file +If you encounter any problems during the guided installation setup, feel free to create +[issue on GitHub](https://github.com/ceskyDJ/home-assistant-borg-backup/issues). +Of course, you can use GitHub issues for feature requests or general bug reporting, too. diff --git a/build.yaml b/build.yaml deleted file mode 100644 index e625c5c..0000000 --- a/build.yaml +++ /dev/null @@ -1,9 +0,0 @@ -build_from: - aarch64: homeassistant/aarch64-base:latest - amd64: homeassistant/amd64-base:latest - armhf: homeassistant/armhf-base:latest - armv7: homeassistant/armv7-base:latest - i386: homeassistant/i386-base:latest - -args: - CLI_VERSION: "4.23.0" diff --git a/config.yaml b/config.yaml index 7a56dfd..fa62d4b 100644 --- a/config.yaml +++ b/config.yaml @@ -1,38 +1,31 @@ -name: "Borgbackup for homeassistant" -version: "1.2" +name: "Borg-based Backup for Home Assistant" +version: "2.0.0" slug: "borg_backup" -description: "Borgbackup!" -url: "https://github.com/bmanojlovic/home-assistant-borg-backup/" -image: "bmanojlovic/{arch}-borg-backup" +description: "Add-on providing access to Borg in automations. So, you can easily create compressed deduplicated remote backups" +url: "https://github.com/ceskyDJ/home-assistant-borg-backup/" +image: "ghcr.io/ceskydj/{arch}-borg-backup" arch: - aarch64 - amd64 - armhf - armv7 - i386 +init: false startup: "services" boot: "manual" hassio_role: "backup" hassio_api: true homeassistant_api: true map: - - config:rw + - addon_config:rw - backup:rw options: - borg_user: "" - borg_repo_url: "" - borg_host: "" - borg_ssh_params: "" - borg_passphrase: "" - borg_reponame: "" - borg_compression: "" - borg_backup_keep_snapshots: 5 + borg_backup_debug: false schema: borg_user: "str" - borg_repo_url: "str" borg_host: "str" - borg_ssh_params: "str" + borg_repo_name: "str" borg_passphrase: "str" - borg_reponame: "str" - borg_compression: "str" - borg_backup_keep_snapshots: "int" + borg_ssh_params: "str?" + borg_compression: "str?" + borg_backup_debug: "bool" diff --git a/docker_build.sh b/docker_build.sh deleted file mode 100755 index 6fbb07c..0000000 --- a/docker_build.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -export ADDON_NAME="borg-backup" -export GITHUB_URL="https://github.com/bmanojlovic/home-assistant-borg-backup/" -export AUTHOR="Boris Manojlovic " -export DOCKER_USER="bmanojlovic" - -#docker run -it --rm --privileged --name "${ADDON_NAME}" \ -# -v ~/.docker:/root/.docker \ -# -v "$(pwd)":/docker \ -# hassioaddons/build-env:latest \ -# --target . \ -# --tag-test \ -# --all \ -# --from "homeassistant/{arch}-base" \ -# --author "${AUTHOR}" \ -# --doc-url "${GITHUB_URL}" \ -# --image "${DOCKER_USER}/{arch}-${ADDON_NAME}" \ -# --parallel - -docker run --rm --privileged \ - -v ~/.docker:/root/.docker \ - homeassistant/amd64-builder --all -t borg_backup \ - -r https://github.com/bmanojlovic/home-assistant-addons -b master \ No newline at end of file diff --git a/local_deploy_sshfs.sh b/local_deploy_sshfs.sh deleted file mode 100755 index 86d9f0c..0000000 --- a/local_deploy_sshfs.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -function _log { -D=$(date +"%Y%m%dT%H:%M:%S") - echo -e $D "$@" -} -function log_error { - _log "\e[0;31mERROR\e[0m : $@" - exit -1 -} - -function log_warn { - ISSUE=$(($ISSUE + 1 )) - _log "\e[0;33mWARN\e[0m : $@" -} -function log_info { - _log "\e[1;32mINFO\e[0m : $@" -} - -function remote_exec { - ssh -t $REMOTE_HOST "sh -lc \"set -e;$@\"" -} - -####### CONFIGURATION ####### -export MOUNT_POINT=/home/steki/addons -export REMOTE_HOST=hassio -#### END CONFIGURATION ###### - - -L=$(LANG=C df -h ${MOUNT_POINT}|grep -c hassio) - -if [ $L -eq 1 ]; then - #replace... - log_info "already mounted" -else - log_info "mounting sshfs" - sshfs ${REMOTE_HOST}:/addons ${MOUNT_POINT} || ( log_error "failed sshfs mount" ) -fi - -rm -rf ${MOUNT_POINT}/borg-backup ||: -mkdir -p ${MOUNT_POINT}/borg-backup -cp -a * ${MOUNT_POINT}/borg-backup/ -log_info "deployed source" - -CMD="ha addons reload" -remote_exec "$CMD" - -CMD="ha addons rebuild local_borg-backup" -remote_exec "$CMD" - - -CMD="ha addons restart local_borg-backup" -remote_exec "$CMD" - -sleep 2 -CMD="ha addons logs local_borg-backup" -remote_exec "$CMD" diff --git a/run.sh b/run.sh index 281b5e8..2fc7440 100644 --- a/run.sh +++ b/run.sh @@ -1,87 +1,55 @@ -#!/usr/bin/env bashio +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash set +u -export BORG_BASE_DIR=/config/borg +export BORG_BASE_DIR=/config export BORG_CACHE_DIR=${BORG_BASE_DIR}/cache export BORG_PASSPHRASE=$(bashio::config 'borg_passphrase') export BORG_REPO="" + export _BORG_TOBACKUP=/backup/borg_unpacked export _BORG_SSH_KNOWN_HOSTS=${BORG_BASE_DIR}/known_hosts export _BORG_SSH_KEY=${BORG_BASE_DIR}/keys/borg_backup -export _BORG_REPO_URL=$(bashio::config 'borg_repo_url') export _BORG_USER=$(bashio::config 'borg_user') export _BORG_HOST=$(bashio::config 'borg_host') -export _BORG_REPONAME=$(bashio::config 'borg_reponame') +export _BORG_REPO_NAME=$(bashio::config 'borg_repo_name') export _BORG_COMPRESSION=$(bashio::config 'borg_compression') export _BORG_BACKUP_DEBUG="$(bashio::config 'borg_backup_debug')" -export _BORG_BACKUP_KEEP_SNAPSHOTS="$(bashio::config 'borg_backup_keep_snapshots')" export _BORG_DEBUG='' + export borg_error=0 -export BORG_RSH="ssh -o UserKnownHostsFile=${_BORG_SSH_KNOWN_HOSTS} -i ${_BORG_SSH_KEY} $(bashio::config 'borg_ssh_params')" +export BORG_RSH="ssh -o UserKnownHostsFile=${_BORG_SSH_KNOWN_HOSTS} -o StrictHostKeyChecking=accept-new -i ${_BORG_SSH_KEY} $(bashio::config 'borg_ssh_params' "--")" -mkdir -p $(dirname ${_BORG_SSH_KEY}) ${BORG_CACHE_DIR} +mkdir -p "$(dirname "${_BORG_SSH_KEY}")" ${BORG_CACHE_DIR} ##### passwords crap -if [ ${#BORG_PASSPHRASE} -eq 0 ];then +if [[ $BORG_PASSPHRASE == "null" ]]; then export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes unset BORG_PASSPHRASE fi # set zstd as default compression -if [ ${#_BORG_COMPRESSION} -eq 0 ];then +if [[ "$_BORG_COMPRESSION" == "null" ]]; then _BORG_COMPRESSION="zstd" fi -if [ ${#BORG_BACKUP_DEBUG} -ne 0 ];then +if [[ "$_BORG_BACKUP_DEBUG" == "true" ]]; then _BORG_DEBUG="--debug" fi -function sanity_checks { - if [[ ( ${#_BORG_REPO_URL} -eq 0 ) && ( ${#_BORG_HOST} -eq 0 )]];then - bashio::log.error "both 'borg_repo_url' 'borg_host' undefined" - bashio::log.error "please define one of them" - borg_error=$(($borg_error + 1)) - elif [[ ( ${#_BORG_REPO_URL} -gt 0 ) && ( ${#_BORG_HOST} -gt 0 )]];then - bashio::log.error "'borg_repo_url' and 'borg_host' are definded" - bashio::log.error "please define only one of them" - borg_error=$(($borg_error + 1)) - else - bashio::log.info "sanity preserved" - fi -} - function set_borg_repo_path { bashio::log.debug "Setting BORG_REPO" - if [ ${#_BORG_REPO_URL} -gt 0 ]; then - BORG_REPO=${_BORG_REPO_URL} - bashio::log.debug "BORG_REPO set" - return - elif [ ${#_BORG_USER} -gt 0 ];then - BORG_REPO+="${_BORG_USER}@" - fi - if [ ${#_BORG_USER} -eq 0 ];then - BORG_REPO+="${_BORG_HOST}/${_BORG_REPONAME}" + + # Construct repository URL from parts + if [[ $_BORG_USER != "null" ]]; then + BORG_REPO="${_BORG_USER}@${_BORG_HOST}:${_BORG_REPO_NAME}" else - BORG_REPO+="${_BORG_HOST}:${_BORG_REPONAME}" + BORG_REPO="${_BORG_HOST}/${_BORG_REPO_NAME}" fi bashio::log.debug "BORG_REPO set" return } -function add_borg_host_to_known_hosts { - bashio::log.info "in add_borg_host_to_known_hosts" - if ! bashio::fs.file_exists ${_BORG_SSH_KNOWN_HOSTS}; then - if [[ ( ${#_BORG_USER} -gt 0 ) ]];then - bashio::log.info "Adding host $1 into ${_BORG_SSH_KNOWN_HOSTS}" - ssh-keyscan ${_BORG_HOST} >> ${_BORG_SSH_KNOWN_HOSTS} - else - bashio::log.info "Local path ignoring ssh and unseting BORG_RSH" - unset BORG_RSH - fi - fi -} - - function generate_ssh_key { if ! bashio::fs.file_exists "${_BORG_SSH_KEY}"; then bashio::log.info "Generating borg backup ssh keys..." @@ -113,9 +81,9 @@ function borg_create_backup { bashio::log.info "Snapshot done" export SNAP_RES=$(jq < /tmp/borg_backup_$$ .result -r) # if it is not ok something failed and should be logged anyway - if [ $SNAP_RES != 'ok' ];then + if [[ "$SNAP_RES" != "ok" ]]; then bashio::log.error "Failed creating ha snapshot" - exit -1 + exit 1 fi export SNAP_SLUG=$(jq < /tmp/borg_backup_$$ -r .data.slug) mkdir -p ${_BORG_TOBACKUP}/${SNAP_SLUG} @@ -130,36 +98,19 @@ function borg_create_backup { bashio::log.info "Start borg create" borg create ${_BORG_DEBUG} --compression ${_BORG_COMPRESSION} --stats ::"${BACKUP_TIME}" ${_BORG_TOBACKUP}/${SNAP_SLUG} bashio::log.info "End borg create --stats..." + # cleanup rm -rf ${_BORG_TOBACKUP} /tmp/borg_backup_$$ - -} - -function clean_old_backups { - ha backups reload - export ALL_SNAPS=$(ha backups --raw-json|jq '.data.backups[].name' -r| sort | wc -l) - export DISCARD_SNAPS=$(($ALL_SNAPS - $_BORG_BACKUP_KEEP_SNAPSHOTS)) - export ALL_SNAPS=$(ha backups --raw-json|jq '.data.backups[].name' -r| sort | head -n ${DISCARD_SNAPS}) - for snap in $ALL_SNAPS ; do - SLUG=$(ha backups --raw-json |jq -r '.data.backups[]|select (.name=="'${snap}'")|.slug') - bashio::log.info "Removing snapshot ${snap} with slug id $SLUG started" - ha backups remove $SLUG - bashio::log.info "Removed snapshot ${snap} with slug id $SLUG" - done - bashio::log.info "Cleanup of old backups done" + ha backups remove "$SNAP_SLUG" } -sanity_checks if [[ $borg_error -gt 0 ]];then bashio::log.warning "error state bailing out..." - exit -1 + exit 1 fi generate_ssh_key set_borg_repo_path -add_borg_host_to_known_hosts init_borg_repo show_ssh_key borg_create_backup -clean_old_backups -#