diff --git a/.github/workflows/homeassistant-publish.yml b/.github/workflows/homeassistant-publish.yml new file mode 100644 index 0000000..b63f524 --- /dev/null +++ b/.github/workflows/homeassistant-publish.yml @@ -0,0 +1,29 @@ +name: 'Publish' + +on: + release: + types: [published] + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Publish + uses: home-assistant/builder@master + with: + args: | + --all \ + --target remote-backup \ + --image hassio-remote-backup-{arch} \ + --version ${{ github.event.release.tag_name }} \ + --docker-hub nigelm + +# end \ No newline at end of file diff --git a/.github/workflows/homeassistant-test.yml b/.github/workflows/homeassistant-test.yml new file mode 100644 index 0000000..cb239f6 --- /dev/null +++ b/.github/workflows/homeassistant-test.yml @@ -0,0 +1,22 @@ +name: 'Test' + +on: [push, pull_request] + +jobs: + build: + name: Test build + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + - name: Test build + uses: home-assistant/builder@master + with: + args: | + --test \ + --all \ + --target remote-backup \ + --image hassio-remote-backup-{arch} \ + --docker-hub nigelm + +# end \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 80bbbba..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -sudo: required -services: -- docker -script: -- "$TRAVIS_BUILD_DIR/build.sh" -env: - global: - secure: I1qaPNCHzZ0rntK1/aMMSCI50zhIdHO+V2UPwimUHmlQ8YdW1dUnuictFFoGEbp2S7owub9U4cwm5LHp8VjtrnDxoDEBuzb50RMTQ8vNWE4SAILawe9TWKfHQKqgCgONQsv9O4Bh8moqwDD+PrqnoGvqEsRjiS6Icx8jk1zCvy7WDzpgnZIHIzytAudRTNwVb/nIJWGMfG29ekxqLgX1YXQ6XsZfQm+JSt8a8dGLdYoYQZRbrriznanYkeMrBanwkKQgbmA1MirIwfcprvnXad1aX8l6/uKomvehc1PbUH6DXUqq8lzuu42gF+J9W3aL4YtbWYtzOItq2Hi0nnj26EvUyn1yIGzfCXv4j3eNA6cqplPKePZ9dYREx0bEiQP412T6w1WviRrhB4THSeCmn6HCkb/k2quTX4vLT1lQWOv4CRe0Qp5kHExbe2kGREJONiUsXU/6zKtT4S+iF9g5EalCaG8beFIwYllkbcSIsle/mfjHKTvwwQ8vI0cnRb7aKLI1pLgb6fQVIRN5ia+fwOvd/S/phy30wAzqtAjuxehbJ8dmnaS0Q21CRUmMAsRJ09x4KUTRMg0hBVib7JJ6jPQIvGgyILe4aJtBFZ5upxwPtk3eEc29RV/FbgJzPa7419boPflIpPY20a+VkfUpSjD4UcS/Xvd+6bjOecT9Fh4= diff --git a/CHANGELOG.md b/CHANGELOG.md index f980126..ba973cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,50 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog][keep-a-changelog] this project adheres to [Semantic Versioning][semantic-versioning]. +## [v0.4.3++] (????-??-??) + +[Full Changelog](https://github.com/nigelm/hassio-remote-backup/compare/v0.3.2...master) + +### Fixed + +## [v0.4.3] (2021-02-27) + +- Updated `hassio-cli` to version 3.1.1 +- Modified `run.sh` hassio calls to work with version 3.1.1 +- Converted snapshot removal selection logic to a jq filter +- Merged in changes from rccoleman - https://github.com/rccoleman/hassio-remote-backup + - Updated `hassio-cli` to 4.3.0 + - Added README notes + - Reformatted run.sh for change of `hassio-cli` binary name +- Updated `hassio-cli` to 4.10.1 +- Since the previous maintainers do not appear to be keeping up with this, and + have not got available docker builds, I have updated the references to point + to my repositories. +- Fixed updating changelog on release :-) + +## [v0.3.2] (2018-10-12) + +[Full Changelog](https://github.com/overkill32/hassio-remote-backup/compare/v0.3.1...v0.3.2) + +### Fixed + +- Role-based permissions in hassio - use `backup` permissions + +## [v0.3.1] (2018-10-12) + +[Full Changelog](https://github.com/overkill32/hassio-remote-backup/compare/v0.3.0...v0.3.1) + +### Fixed + +- Fix `config.json` for multidigit `keep_local_backup` values +- Role-based permissions in hassio - use `manager` permissions + ## [v0.3.0] (2018-03-12) -[Full Changelog](https://github.com/mr-bjerre/hassio-remote-backup/compare/v0.2.1...v0.3.0) +[Full Changelog](https://github.com/overkill32/hassio-remote-backup/compare/v0.2.1...v0.3.0) ### Added @@ -13,7 +52,7 @@ The format is based on [Keep a Changelog][keep-a-changelog] this project adheres ## [v0.2.1] (2018-03-11) -[Full Changelog](https://github.com/mr-bjerre/hassio-remote-backup/compare/v0.2.0...v0.2.1) +[Full Changelog](https://github.com/overkill32/hassio-remote-backup/compare/v0.2.0...v0.2.1) ### Fixed @@ -22,7 +61,7 @@ The format is based on [Keep a Changelog][keep-a-changelog] this project adheres ## [v0.2.0] (2018-03-07) -[Full Changelog](https://github.com/mr-bjerre/hassio-remote-backup/compare/v0.1.0...v0.2.0) +[Full Changelog](https://github.com/overkill32/hassio-remote-backup/compare/v0.1.0...v0.2.0) ### Added @@ -36,4 +75,4 @@ The format is based on [Keep a Changelog][keep-a-changelog] this project adheres [keep-a-changelog]: http://keepachangelog.com/en/1.0.0/ [semantic-versioning]: http://semver.org/spec/v2.0.0.html -[addons-repo]: https://github.com/mr-bjerre/hassio-addons/blob/master/remote-backup/config.json +[addons-repo]: https://github.com/overkill32/hassio-addons/blob/master/remote-backup/config.json diff --git a/README.md b/README.md index 6703b9e..ba4c169 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ - # Remote Backup [![GitHub Release][releases-shield]][releases] -[![Build Status][travis-build-shield]][travis-build] +[![Build Status](https://github.com/nigelm/hassio-remote-backup/actions/workflows/homeassistant-test.yml/badge.svg) +[![Release Status](https://github.com/nigelm/hassio-remote-backup/actions/workflows/homeassistant-publish.yml/badge.svg) [![GitHub license][license-shield]](LICENSE.md) > Automatically create Hass.io snapshots to remote server location using `SCP`. -
+---- ## Table of Contents @@ -15,12 +15,14 @@ * [Installation](#installation) * [Configuration](#configuration) * [Example](#example) +* [Issues](#issues) * [Changelog & Releases](#changelog) * [Docker status](#docker) ## About When the add-on is started the following happens: + 1. Snapshot are being created locally with a timestamp name, e.g. *Automatic backup 2018-03-04 04:00*. 1. The snapshot are copied to the specified remote location using `SCP`. @@ -30,7 +32,7 @@ _Note_ the filenames of the backup are given by their assigned slug. ## Installation -1. Add the add-ons repository to your Hass.io instance: `https://github.com/overkill32/hassio-addons`. +1. Add the add-ons repository to your Hass.io instance: `https://github.com/nigelm/hassio-addons`. 1. Install the Remote Backup add-on. 1. Configure the add-on with your SSH credentials and desired output directory (see configuration below). @@ -49,6 +51,10 @@ See my [repository of addons][hassio-addons] for more information. |`zip_password`|No|If set then the backup will be contained in a password protected zip| |`keep_local_backup`|No|Control how many local backups you want to preserve. Default (`""`) is to keep no local backups created from this addon. If `all` then all loocal backups will be preserved. A positive integer will determine how many of the latest backups will be preserved. Note this will delete other local backups created outside this addon. +Remember that no matter what `keep_local_backup` is set to, you will add one +new snapshot backup file to the remote location each time this is run. You +may wish to have some form of expiry of these snapshots. + ## Example: daily backups at 4 AM Personally I've added the following automation to make a daily backup. It is password-protected and the last two weeks of snapshots are kept locally as well. @@ -88,6 +94,17 @@ _Add-on configuration_: **Note**: _This is just an example, don't copy and past it! Create your own!_ +## Issues + +*Note: For anyone using this as a local addon, it appears that the latest base +image now requires updating to the new "OPENSSH" private key format. If you +were previously using a private key that started "RSA PRIVATE KEY", you'll +need to follow the instructions +[here](https://serverfault.com/questions/854208/ssh-suddenly-returning-invalid-format/960647) +to update your private key and add the new key in the addon config. Using +the older key format will result in "Load pubkey "xxx": Invalid format" as +described at the link.* + ## Changelog & Releases This repository keeps a [change log](CHANGELOG.md). The format of the log @@ -126,37 +143,37 @@ based on the following: [aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg -[aarch64-dockerhub]: https://hub.docker.com/r/fixated/remote-backup-aarch64 -[aarch64-layers-shield]: https://images.microbadger.com/badges/image/fixated/remote-backup-aarch64.svg -[aarch64-microbadger]: https://microbadger.com/images/fixated/remote-backup-aarch64 -[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/fixated/remote-backup-aarch64.svg -[aarch64-version-shield]: https://images.microbadger.com/badges/version/fixated/remote-backup-aarch64.svg +[aarch64-dockerhub]: https://hub.docker.com/r/nigelm/hassio-remote-backup-aarch64 +[aarch64-layers-shield]: https://images.microbadger.com/badges/image/nigelm/hassio-remote-backup-aarch64.svg +[aarch64-microbadger]: https://microbadger.com/images/nigelm/hassio-remote-backup-aarch64 +[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/nigelm/hassio-remote-backup-aarch64.svg +[aarch64-version-shield]: https://images.microbadger.com/badges/version/nigelm/hassio-remote-backup-aarch64.svg [amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg -[amd64-dockerhub]: https://hub.docker.com/r/fixated/remote-backup-amd64 -[amd64-layers-shield]: https://images.microbadger.com/badges/image/fixated/remote-backup-amd64.svg -[amd64-microbadger]: https://microbadger.com/images/fixated/remote-backup-amd64 -[amd64-pulls-shield]: https://img.shields.io/docker/pulls/fixated/remote-backup-amd64.svg -[amd64-version-shield]: https://images.microbadger.com/badges/version/fixated/remote-backup-amd64.svg +[amd64-dockerhub]: https://hub.docker.com/r/nigelm/hassio-remote-backup-amd64 +[amd64-layers-shield]: https://images.microbadger.com/badges/image/nigelm/hassio-remote-backup-amd64.svg +[amd64-microbadger]: https://microbadger.com/images/nigelm/hassio-remote-backup-amd64 +[amd64-pulls-shield]: https://img.shields.io/docker/pulls/nigelm/hassio-remote-backup-amd64.svg +[amd64-version-shield]: https://images.microbadger.com/badges/version/nigelm/hassio-remote-backup-amd64.svg [armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg -[armhf-dockerhub]: https://hub.docker.com/r/fixated/remote-backup-armhf -[armhf-layers-shield]: https://images.microbadger.com/badges/image/fixated/remote-backup-armhf.svg -[armhf-microbadger]: https://microbadger.com/images/fixated/remote-backup-armhf -[armhf-pulls-shield]: https://img.shields.io/docker/pulls/fixated/remote-backup-armhf.svg -[armhf-version-shield]: https://images.microbadger.com/badges/version/fixated/remote-backup-armhf.svg +[armhf-dockerhub]: https://hub.docker.com/r/nigelm/hassio-remote-backup-armhf +[armhf-layers-shield]: https://images.microbadger.com/badges/image/nigelm/hassio-remote-backup-armhf.svg +[armhf-microbadger]: https://microbadger.com/images/nigelm/hassio-remote-backup-armhf +[armhf-pulls-shield]: https://img.shields.io/docker/pulls/nigelm/hassio-remote-backup-armhf.svg +[armhf-version-shield]: https://images.microbadger.com/badges/version/nigelm/hassio-remote-backup-armhf.svg [i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg -[i386-dockerhub]: https://hub.docker.com/r/fixated/remote-backup-i386 -[i386-layers-shield]: https://images.microbadger.com/badges/image/fixated/remote-backup-i386.svg -[i386-microbadger]: https://microbadger.com/images/fixated/remote-backup-i386 -[i386-pulls-shield]: https://img.shields.io/docker/pulls/fixated/remote-backup-i386.svg -[i386-version-shield]: https://images.microbadger.com/badges/version/fixated/remote-backup-i386.svg - -[license-shield]: https://img.shields.io/github/license/overkill32/hassio-remote-backup.svg -[releases]: https://github.com/overkill32/hassio-remote-backup/releases -[releases-shield]: https://img.shields.io/github/release/overkill32/hassio-remote-backup.svg -[travis-build]: https://travis-ci.org/overkill32/hassio-remote-backup -[travis-build-shield]: https://travis-ci.org/overkill32/hassio-remote-backup.svg?branch=master +[i386-dockerhub]: https://hub.docker.com/r/nigelm/hassio-remote-backup-i386 +[i386-layers-shield]: https://images.microbadger.com/badges/image/nigelm/hassio-remote-backup-i386.svg +[i386-microbadger]: https://microbadger.com/images/nigelm/hassio-remote-backup-i386 +[i386-pulls-shield]: https://img.shields.io/docker/pulls/nigelm/hassio-remote-backup-i386.svg +[i386-version-shield]: https://images.microbadger.com/badges/version/nigelm/hassio-remote-backup-i386.svg + +[license-shield]: https://img.shields.io/github/license/nigelm/hassio-remote-backup.svg +[releases]: https://github.com/nigelm/hassio-remote-backup/releases +[releases-shield]: https://img.shields.io/github/release/nigelm/hassio-remote-backup.svg +[travis-build]: https://travis-ci.org/nigelm/hassio-remote-backup +[travis-build-shield]: https://travis-ci.org/nigelm/hassio-remote-backup.svg?branch=master [keepchangelog]: http://keepachangelog.com/en/1.0.0/ [semver]: http://semver.org/spec/v2.0.0.html -[hassio-addons]: https://github.com/overkill32/hassio-addons +[hassio-addons]: https://github.com/nigelm/hassio-addons diff --git a/build.sh b/build.sh deleted file mode 100755 index 5a9d80d..0000000 --- a/build.sh +++ /dev/null @@ -1,31 +0,0 @@ -set -ev -docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD" - -if [ -z ${TRAVIS_TAG} ]; then - echo "Untagged build found. Building to test." - docker run -it --rm --privileged --name "${ADDON_NAME}" \ - -v ~/.docker:/root/.docker \ - -v "$(pwd)":/docker \ - hassioaddons/build-env:latest \ - --target "${ADDON_NAME}" \ - --git \ - --all \ - --from "homeassistant/{arch}-base" \ - --author "Nicolai Bjerre Pedersen " \ - --doc-url "${GITHUB_URL}" \ - --image "fixated/${ADDON_NAME}-{arch}" -else - echo "New git tagged build found. Building to distribute." - docker run -it --rm --privileged --name "${ADDON_NAME}" \ - -v ~/.docker:/root/.docker \ - -v "$(pwd)":/docker \ - hassioaddons/build-env:latest \ - --target "${ADDON_NAME}" \ - --git \ - --all \ - --push \ - --from "homeassistant/{arch}-base" \ - --author "Nicolai Bjerre Pedersen " \ - --doc-url "${GITHUB_URL}" \ - --image "fixated/${ADDON_NAME}-{arch}" -fi diff --git a/remote-backup/Dockerfile b/remote-backup/Dockerfile index 094f41c..4677b06 100644 --- a/remote-backup/Dockerfile +++ b/remote-backup/Dockerfile @@ -11,8 +11,8 @@ RUN apk add --no-cache jq openssh-client zip 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} \ - && chmod a+x /usr/bin/hassio + && curl -Lso /usr/bin/ha https://github.com/home-assistant/cli/releases/download/4.10.1/ha_${BUILD_ARCH} \ + && chmod a+x /usr/bin/ha # Copy data COPY run.sh / @@ -32,12 +32,12 @@ LABEL \ io.hass.arch="${BUILD_ARCH}" \ io.hass.type="addon" \ io.hass.version=${BUILD_VERSION} \ - maintainer="Nicolai Bjerre Pedersen " \ + maintainer="Nigel Metheringham " \ org.label-schema.description="Automatically create Hass.io snapshots to remote server location using `SCP`." \ org.label-schema.build-date=${BUILD_DATE} \ org.label-schema.name="Remote Backup" \ org.label-schema.schema-version="1.0" \ - org.label-schema.usage="https://github.com/overkill32/hassio-remote-backup/tree/master/README.md" \ + org.label-schema.usage="https://github.com/nigelm/hassio-remote-backup/tree/master/README.md" \ org.label-schema.vcs-ref=${BUILD_REF} \ - org.label-schema.vcs-url="https://github.com/overkill32/hassio-remote-backup/" \ - org.label-schema.vendor="Hass.io add-ons by Nicolai" + org.label-schema.vcs-url="https://github.com/nigelm/hassio-remote-backup/" \ + org.label-schema.vendor="Hass.io add-ons by Nigel Metheringham" diff --git a/remote-backup/run.sh b/remote-backup/run.sh index dbd25b4..fb3cf8c 100755 --- a/remote-backup/run.sh +++ b/remote-backup/run.sh @@ -1,7 +1,10 @@ #!/bin/bash +# hassio remote-backup main script +# formatted with: shfmt -i 4 -l set -e CONFIG_PATH=/data/options.json +HA=/usr/bin/ha # parse inputs from options SSH_HOST=$(jq --raw-output ".ssh_host" $CONFIG_PATH) @@ -25,11 +28,11 @@ function add-ssh-key { echo " User ${SSH_USER}" echo " Port ${SSH_PORT}" echo " StrictHostKeyChecking no" - ) > "${HOME}/.ssh/config" + ) >"${HOME}/.ssh/config" while read -r line; do - echo "$line" >> ${HOME}/.ssh/id - done <<< "$SSH_KEY" + echo "$line" >>${HOME}/.ssh/id + done <<<"$SSH_KEY" chmod 600 "${HOME}/.ssh/config" chmod 600 "${HOME}/.ssh/id" @@ -38,49 +41,60 @@ function add-ssh-key { 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}" + 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" + 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 } function delete-local-backup { - hassio snapshots reload + ${HA} snapshots reload if [[ ${KEEP_LOCAL_BACKUP} == "all" ]]; then : elif [[ -z ${KEEP_LOCAL_BACKUP} ]]; then echo "Deleting local backup: ${slug}" - hassio snapshots remove -name "${slug}" + ${HA} snapshots remove ${slug} else - - last_date_to_keep=$(hassio snapshots list | 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 - 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)" - fi + ## jq filter used to select required snapshots to delete. + ## Expanded form given here with explanation... + # # Remove outer containers to leave an array of snapshot objects + # .data.snapshots + # # select out snapshots that are not protected + # | map(select(.protected==false)) + # # sort the objects by date - oldest first + # | sort_by(.date) + # # reverse the sort - now oldest last + # | reverse + # # select all items after the fist ${KEEP_LOCAL_BACKUP} items + # | .[${KEEP_LOCAL_BACKUP}:] + # # output just the slug entry for each snapshot + # | .[].slug + for slug in $( + ${HA} snapshots list --raw-json | + jq -r ".data.snapshots | map(select(.protected==false)) | sort_by(.date) | reverse | .[${KEEP_LOCAL_BACKUP}:] | .[].slug" + ); do + echo "Deleting local backup: ${slug}" + ${HA} snapshots remove ${slug} done fi + echo Exiting } 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=$(${HA} snapshots new --raw-json --name="${name}" --no-progress | jq --raw-output '.data.slug') echo "Backup created: ${slug}" } - add-ssh-key create-local-backup copy-backup-to-remote