Merge pull request #65 from erikw/fix/49
Truly support custom `PREFIX=` install
This commit is contained in:
4
.github/workflows/linter.yml
vendored
4
.github/workflows/linter.yml
vendored
@@ -7,13 +7,13 @@ on:
|
||||
paths:
|
||||
- '**.sh'
|
||||
- '.github/workflows/linter.yml'
|
||||
- 'usr/local/sbin/**'
|
||||
- 'bin/**'
|
||||
pull_request:
|
||||
branches: master
|
||||
paths:
|
||||
- '**.sh'
|
||||
- '.github/workflows/linter.yml'
|
||||
- 'usr/local/sbin/**'
|
||||
- 'bin/**'
|
||||
jobs:
|
||||
build:
|
||||
name: Lint Code Base
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
# Prevent check-in of these sensitive files. Instead they are generated from the corresponding *.template file.
|
||||
etc/restic/pw.txt
|
||||
etc/restic/_global.env
|
||||
etc/restic/default.env
|
||||
# make install
|
||||
/build
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- `resticw` wrapper for working with different profiles without the need to source the profiles first.
|
||||
- `$ make install-systemd` will now make a timestamped backup of any existing `/etc/restic/*` files before installing a newer version.
|
||||
- `$ make install-cron` for installing the cron-job.
|
||||
|
||||
### Changed
|
||||
- **BREAKING CHANGE** moved systemd installation with makefile from `/etc/systemd/system` to `/usr/lib/systemd/system` as this is what packages should do. This is to be able to simplify the arch [PKGBUILD](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=restic-systemd-automatic-backup) so that it does not need to do anything else than `make install`.
|
||||
- If you upgrade form an existing install, you should disable and then re-enable the timer, so that the symlink is pointing to the new location of the timer.
|
||||
```console
|
||||
# systemctl disable restic-backup@<profile>.timer
|
||||
# systemctl enable restic-backup@<profile>.timer
|
||||
```
|
||||
- **BREAKING CHANGE** moved script installation with makefile from `/usr/local/sbin` to `/bin` to have a simpler interface to work with `$PREFIX`.
|
||||
- Renamed top level make install targets. The old `$ make install` is now `$ make install-systemd`
|
||||
|
||||
### Fixed
|
||||
- Installation with custom `PREFIX` now works properly with Make: `$ PREFIX=/usr/local make install` whill now install everything at the expected location. With this, it's easy to use this script as non-root user on e.g. an macOS system.
|
||||
|
||||
## [4.0.0] - 2022-02-01
|
||||
### Fixed
|
||||
@@ -46,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
- `restic_backup.sh` now finds `.backup_exclude` files on each backup path as intended.
|
||||
- Install executeables to `$PREFIX/sbin` instead of `$PREFIX/user/local/sbin`, so that `$ PREFIX=/usr/local make install` does what is expected.
|
||||
|
||||
## [1.0.1] - 2021-12-03
|
||||
### Fixed
|
||||
|
||||
174
Makefile
174
Makefile
@@ -1,60 +1,140 @@
|
||||
# Not file targets.
|
||||
.PHONY: help install install-scripts install-conf install-systemd uninstall
|
||||
#### Notes ####################################################################
|
||||
# This build process is done in three stages (out-of-source build):
|
||||
# 1. copy source files to the local build directory.
|
||||
# 2. build dir: replace the string "$INSTALL_PREFIX" with the value of $PREFIX
|
||||
# 3. install files from the build directory to the target directory.
|
||||
#
|
||||
# Why this dance?
|
||||
# * To fully support that a user can install this project to a custom path e.g.
|
||||
# $(PREFIX=/usr/local make install), we need to modify the files that refer
|
||||
# to other files on disk. We do this by having a placeholder
|
||||
# "$INSTALL_PREFIX" that is substituted with the value of $PREFIX when
|
||||
# installed.
|
||||
# * We don't want to modify the files that are controlled by git, thus let's
|
||||
# copy them to a build directory and then modify.
|
||||
|
||||
### Macros ###
|
||||
SRCS_SCRIPTS = $(filter-out %cron_mail, $(wildcard usr/local/sbin/*))
|
||||
# $(sort) remove duplicates that comes from running make install >1 times.
|
||||
SRCS_CONF = $(sort $(patsubst %.template, %, $(wildcard etc/restic/*)))
|
||||
SRCS_SYSTEMD = $(wildcard etc/systemd/system/*)
|
||||
#### Non-file targets #########################################################
|
||||
.PHONY: help clean uninstall \
|
||||
install-systemd install-cron \
|
||||
install-targets-script install-targets-conf install-targets-systemd \
|
||||
install-targets-cron
|
||||
|
||||
# To change the installation root path, set the PREFIX variable in your shell's environment, like:
|
||||
# $ PREFIX=/usr/local make install
|
||||
# $ PREFIX=/tmp/test make install
|
||||
DEST_SCRIPTS = $(PREFIX)/usr/local/sbin
|
||||
DEST_CONF = $(PREFIX)/etc/restic
|
||||
DEST_SYSTEMD = $(PREFIX)/etc/systemd/system
|
||||
#### Macros ###################################################################
|
||||
NOW := $(shell date +%Y-%m-%d_%H:%M:%S)
|
||||
|
||||
INSTALLED_FILES = $(addprefix $(PREFIX)/, $(SRCS_SCRIPTS) $(SRCS_CONF) $(SRCS_SYSTEMD))
|
||||
# GNU and macOS install have incompatible command line arguments.
|
||||
GNU_INSTALL := $(shell install --version 2>/dev/null | \
|
||||
grep -q GNU && echo true || echo false)
|
||||
ifeq ($(GNU_INSTALL),true)
|
||||
BAK_SUFFIX = --suffix=.$(NOW).bak
|
||||
else
|
||||
BAK_SUFFIX = -B .$(NOW).bak
|
||||
endif
|
||||
|
||||
### Targets ###
|
||||
# target: all - Default target.
|
||||
all: install
|
||||
# Create parent directories of a file, if not existing.
|
||||
# Reference: https://stackoverflow.com/a/25574592/265508
|
||||
MKDIR_PARENTS=sh -c '\
|
||||
dir=$$(dirname $$1); \
|
||||
test -d $$dir || mkdir -p $$dir \
|
||||
' MKDIR_PARENTS
|
||||
|
||||
# target: help - Display all targets.
|
||||
# Source directories.
|
||||
DIR_SCRIPT = bin
|
||||
DIR_CONF = etc/restic
|
||||
DIR_SYSTEMD = usr/lib/systemd/system
|
||||
DIR_CRON = etc/cron.d
|
||||
|
||||
# Source files.
|
||||
SRCS_SCRIPT = $(filter-out %cron_mail, $(wildcard $(DIR_SCRIPT)/*))
|
||||
SRCS_CONF = $(wildcard $(DIR_CONF)/*)
|
||||
SRCS_SYSTEMD = $(wildcard $(DIR_SYSTEMD)/*)
|
||||
SRCS_CRON = $(wildcard $(DIR_CRON)/*)
|
||||
|
||||
# Local build directory. Sources will be copied here,
|
||||
# modified and then installed from this directory.
|
||||
BUILD_DIR := build
|
||||
BUILD_DIR_SCRIPT = $(BUILD_DIR)/$(DIR_SCRIPT)
|
||||
BUILD_DIR_CONF = $(BUILD_DIR)/$(DIR_CONF)
|
||||
BUILD_DIR_SYSTEMD = $(BUILD_DIR)/$(DIR_SYSTEMD)
|
||||
BUILD_DIR_CRON = $(BUILD_DIR)/$(DIR_CRON)
|
||||
|
||||
# Sources copied to build directory.
|
||||
BUILD_SRCS_SCRIPT = $(addprefix $(BUILD_DIR)/, $(SRCS_SCRIPT))
|
||||
BUILD_SRCS_CONF = $(addprefix $(BUILD_DIR)/, $(SRCS_CONF))
|
||||
BUILD_SRCS_SYSTEMD = $(addprefix $(BUILD_DIR)/, $(SRCS_SYSTEMD))
|
||||
BUILD_SRCS_CRON = $(addprefix $(BUILD_DIR)/, $(SRCS_CRON))
|
||||
|
||||
# Destination directories
|
||||
DEST_DIR_SCRIPT = $(PREFIX)/$(DIR_SCRIPT)
|
||||
DEST_DIR_CONF = $(PREFIX)/$(DIR_CONF)
|
||||
DEST_DIR_SYSTEMD = $(PREFIX)/$(DIR_SYSTEMD)
|
||||
DEST_DIR_CRON = $(PREFIX)/$(DIR_CRON)
|
||||
|
||||
# Destination file targets.
|
||||
DEST_TARGS_SCRIPT = $(addprefix $(PREFIX)/, $(SRCS_SCRIPT))
|
||||
DEST_TARGS_CONF = $(addprefix $(PREFIX)/, $(SRCS_CONF))
|
||||
DEST_TARGS_SYSTEMD = $(addprefix $(PREFIX)/, $(SRCS_SYSTEMD))
|
||||
DEST_TARGS_CRON = $(addprefix $(PREFIX)/, $(SRCS_CRON))
|
||||
|
||||
INSTALLED_FILES = $(DEST_TARGS_SCRIPT) $(DEST_TARGS_CONF) \
|
||||
$(DEST_TARGS_SYSTEMD) $(DEST_TARGS_CRON)
|
||||
|
||||
|
||||
#### Targets ##################################################################
|
||||
# target: help - Default target; displays all targets.
|
||||
help:
|
||||
@egrep "#\starget:" [Mm]akefile | sed 's/\s-\s/\t\t\t/' | cut -d " " -f3- | sort -d
|
||||
@egrep "#\starget:" [Mm]akefile | cut -d " " -f3- | sort -d
|
||||
|
||||
# target: install - Install all files
|
||||
install: install-scripts install-conf install-systemd
|
||||
# target: clean - Remove build files.
|
||||
clean:
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
|
||||
# target: install-scripts - Install executables.
|
||||
install-scripts:
|
||||
install -d $(DEST_SCRIPTS)
|
||||
install -m 0744 $(filter-out %/resticw, $(SRCS_SCRIPTS)) $(DEST_SCRIPTS)
|
||||
install -m 0755 usr/local/sbin/resticw $(DEST_SCRIPTS)
|
||||
|
||||
# Copy templates to new files with restricted permissions.
|
||||
# Why? Because the non-template files are git-ignored to prevent that someone who clones or forks this repo checks in their sensitive data like the B2 password!
|
||||
etc/restic/_global.env etc/restic/default.env etc/restic/pw.txt:
|
||||
install -m 0600 $@.template $@
|
||||
|
||||
# target: install-conf - Install restic configuration files.
|
||||
# will create these files locally only if they don't already exist
|
||||
# `|` means that dependencies are order-only, i.e. only created if they don't already exist.
|
||||
install-conf: | $(SRCS_CONF)
|
||||
install -d $(DEST_CONF)
|
||||
install -b -m 0600 $(SRCS_CONF) $(DEST_CONF)
|
||||
$(RM) etc/restic/_global.env etc/restic/default.env etc/restic/pw.txt
|
||||
|
||||
# target: install-systemd - Install systemd timer and service files.
|
||||
install-systemd:
|
||||
install -d $(DEST_SYSTEMD)
|
||||
install -m 0644 $(SRCS_SYSTEMD) $(DEST_SYSTEMD)
|
||||
|
||||
# target: uninstall - Uninstall ALL files from the install targets.
|
||||
# target: uninstall - Uninstall ALL files from all install targets.
|
||||
uninstall:
|
||||
@for file in $(INSTALLED_FILES); do \
|
||||
echo $(RM) $$file; \
|
||||
$(RM) $$file; \
|
||||
done
|
||||
|
||||
# To change the installation root path,
|
||||
# set the PREFIX variable in your shell's environment, like:
|
||||
# $ PREFIX=/usr/local make install-systemd
|
||||
# $ PREFIX=/tmp/test make install-systemd
|
||||
# target: install-systemd - Install systemd setup.
|
||||
install-systemd: install-targets-script install-targets-conf install-targets-systemd
|
||||
|
||||
# target: install-cron - Install cron setup.
|
||||
install-cron: install-targets-script install-targets-conf install-targets-cron
|
||||
|
||||
# Install targets. Prereq build sources as well,
|
||||
# so that build dir is re-created if deleted.
|
||||
install-targets-script: $(DEST_TARGS_SCRIPT) $(BUILD_SRCS_SCRIPT)
|
||||
install-targets-conf: $(DEST_TARGS_CONF) $(BUILD_SRCS_CONF)
|
||||
install-targets-systemd: $(DEST_TARGS_SYSTEMD) $(BUILD_SRCS_SYSTEMD)
|
||||
install-targets-cron: $(DEST_TARGS_CRON) $(BUILD_SRCS_CRON)
|
||||
|
||||
# Copies sources to build directory & replace "$INSTALL_PREFIX".
|
||||
$(BUILD_DIR)/% : %
|
||||
@${MKDIR_PARENTS} $@
|
||||
cp $< $@
|
||||
sed -i.bak -e 's|$$INSTALL_PREFIX|$(PREFIX)|g' $@; rm $@.bak
|
||||
|
||||
# Install destination script files.
|
||||
$(DEST_DIR_SCRIPT)/%: $(BUILD_DIR_SCRIPT)/%
|
||||
@${MKDIR_PARENTS} $@
|
||||
install -m 0744 $< $@
|
||||
|
||||
# Install destination conf files. Additionally backup existing files.
|
||||
$(DEST_DIR_CONF)/%: $(BUILD_DIR_CONF)/%
|
||||
@${MKDIR_PARENTS} $@
|
||||
install -m 0600 -b $(BAK_SUFFIX) $< $@
|
||||
|
||||
# Install destination systemd files.
|
||||
$(DEST_DIR_SYSTEMD)/%: $(BUILD_DIR_SYSTEMD)/%
|
||||
@${MKDIR_PARENTS} $@
|
||||
install -m 0644 $< $@
|
||||
|
||||
# Install destination cron files.
|
||||
$(DEST_DIR_CRON)/%: $(BUILD_DIR_CRON)/%
|
||||
@${MKDIR_PARENTS} $@
|
||||
install -m 0644 $< $@
|
||||
|
||||
104
README.md
104
README.md
@@ -32,19 +32,33 @@ The scope for this is not to be a full-fledged super solution that solves all th
|
||||
|
||||
Nevertheless the project should work out of the box, be minimal but still open the doors for configuration and extensions by users.
|
||||
|
||||
## Navigate this README
|
||||
Tip: use the Section icon in the top left of this document to navigate the sections.
|
||||
|
||||

|
||||
|
||||
|
||||
# Requirements
|
||||
* `restic >=v0.9.6`
|
||||
* (recommended) `make` if you want an automated install
|
||||
* Arch: part of the `base-devel` meta package, Debian/Ubuntu: part of the `build-essential` meta package, macOS: preinstalled make works)
|
||||
* (recommended) GNU `make` if you want an automated install
|
||||
* Arch: part of the `base-devel` meta package, Debian/Ubuntu: part of the `build-essential` meta package, macOS: use the preinstalled or a more recent with Homebrew)
|
||||
|
||||
# TL;DR Setup
|
||||
|
||||
|
||||
# Setup
|
||||
Depending on your system, the setup will look different. Choose one of
|
||||
* [Linux + Systemd](#setup-linux-systemd)
|
||||
* [Cron](#setup-cron) - for any system having a cron daemon. Tested on FreeBSD and macOS.
|
||||
|
||||
## Setup Linux Systemd
|
||||
### TL;DR Setup
|
||||
1. Create B2 credentials as instructed [below](#1-create-backblaze-b2-account)
|
||||
1. Install config and scripts:
|
||||
```console
|
||||
$ sudo make install
|
||||
$ sudo make install-systemd
|
||||
```
|
||||
☝ **Note**: `sudo` is required here, as some files are installed into system directories (`/etc/`
|
||||
and `/usr/sbin`). Have a look to the `Makefile` to know more.
|
||||
and `/usr/bin`). Have a look to the `Makefile` to know more.
|
||||
1. Fill out configuration values (edit with sudo):
|
||||
* `/etc/restic/pw.txt` - Contains the password (single line) to be used by restic to encrypt the repository files. Should be different than your B2 password!
|
||||
* `/etc/restic/_global.env` - Global environment variables.
|
||||
@@ -52,11 +66,10 @@ Nevertheless the project should work out of the box, be minimal but still open t
|
||||
* `/etc/restic/backup_exclude.txt` - List of file patterns to ignore. This will trim down your backup size and the speed of the backup a lot when done properly!
|
||||
1. Initialize remote repo as described [below](#3-initialize-remote-repo)
|
||||
1. Configure [how often](https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events) back up should be made.
|
||||
* Edit if needed `OnCalendar` in `/etc/systemd/system/restic-check@.timer`.
|
||||
* Edit if needed `OnCalendar` in `/usr/lib/systemd/system/restic-backup@.timer`.
|
||||
1. Enable automated backup for starting with the system (`enable` creates symlinks):
|
||||
```console
|
||||
$ sudo systemctl start restic-backup@default.timer
|
||||
$ sudo systemctl enable restic-backup@default.timer
|
||||
$ sudo systemctl enable --now restic-backup@default.timer
|
||||
```
|
||||
1. And run an immediate backup if you want (if not, it will run on daily basis):
|
||||
```console
|
||||
@@ -75,34 +88,45 @@ Nevertheless the project should work out of the box, be minimal but still open t
|
||||
1. (optional) Define multiple profiles: just make a copy of the `default.env` and use the defined profile name in place of `default` to run backups or enable timers. Notice that the value after `@` works as a parameter.
|
||||
1. (optional) Enable the check job that verifies that the backups for the profile are all intact.
|
||||
```console
|
||||
$ sudo systemctl start restic-check@default.timer
|
||||
$ sudo systemctl enable restic-check@default.timer
|
||||
$ sudo systemctl enable --now restic-check@default.timer
|
||||
````
|
||||
1. (optional) Setup email on failure as described [here](#8-email-notification-on-failure)
|
||||
|
||||
|
||||
# Step-by-step and manual setup
|
||||
### Step-by-step and manual setup
|
||||
This is a more detailed explanation than the TL;DR section that will give you more understanding in the setup, and maybe inspire you to develop your own setup based on this one even!
|
||||
|
||||
Tip: The steps in this section will instruct you to copy files from this repo to system directories. If you don't want to do this manually, you can use the Makefile:
|
||||
|
||||
```console
|
||||
$ git clone https://github.com/erikw/restic-systemd-automatic-backup.git && cd $(basename "$_" .git)
|
||||
$ sudo make install
|
||||
$ sudo make install-systemd
|
||||
````
|
||||
|
||||
If you want to install everything manually, we will install files to `/etc`, `/bin`, and not use the `$make install-systemd` command, then you need to clean up a placeholder `$INSTALL_PREFIX` in the souce files first by running:
|
||||
```console
|
||||
$ find etc bin -type f -exec sed -i.bak -e 's|$INSTALL_PREFIX||g' {} \; -exec rm {}.bak \;
|
||||
```
|
||||
and you should now see that all files have been changed like e.g.
|
||||
```diff
|
||||
-export RESTIC_PASSWORD_FILE="$INSTALL_PREFIX/etc/restic/pw.txt"
|
||||
+export RESTIC_PASSWORD_FILE="/etc/restic/pw.txt"
|
||||
```
|
||||
This prefix is there so that `make` users can set a different `$PREFIX` when installing like `PREFIX=/usr/local make install-systemd`. So if we don't use the makefile, we need to remove this prefix with the command above just.
|
||||
|
||||
|
||||
Arch Linux users can install the aur package [restic-systemd-automatic-backup](https://aur.archlinux.org/packages/restic-systemd-automatic-backup/) e.g.:
|
||||
```console
|
||||
$ yaourt -S restic-systemd-automatic-backup
|
||||
````
|
||||
|
||||
## 1. Create Backblaze B2 Account, Bucket and keys
|
||||
#### 1. Create Backblaze B2 Account, Bucket and keys
|
||||
First, see this official Backblaze [tutorial](https://help.backblaze.com/hc/en-us/articles/4403944998811-Quickstart-Guide-for-Restic-and-Backblaze-B2-Cloud-Storage) on restic, and follow the instructions ("Create Backblaze account with B2 enabled") there on how to create a new B2 bucket. In general, you'd want a private bucket, without B2 encryption (restic does the encryption client side for us) and without the object lock feature.
|
||||
|
||||
For restic to be able to connect to your bucket, you want to in the B2 settings create a pair of keyID and applicationKey. It's a good idea to create a separate pair of ID and Key with for each bucket that you will use, with limited read&write access to only that bucket.
|
||||
|
||||
|
||||
## 2. Configure your B2 credentials locally
|
||||
#### 2. Configure your B2 credentials locally
|
||||
> **Attention!** Going the manual way requires that most of the following commands are run as root.
|
||||
|
||||
Put these files in `/etc/restic/`:
|
||||
@@ -117,7 +141,7 @@ Put these files in `/etc/restic/`:
|
||||
$ openssl rand -base64 128 | tr -d '\n' > /etc/restic/pw.txt
|
||||
```
|
||||
|
||||
## 3. Initialize remote repo
|
||||
#### 3. Initialize remote repo
|
||||
Now we must initialize the repository on the remote end:
|
||||
```console
|
||||
$ sudo -i
|
||||
@@ -125,24 +149,24 @@ $ source /etc/restic/default.env
|
||||
$ restic init
|
||||
```
|
||||
|
||||
## 4. Script for doing the backup
|
||||
Put this file in `/usr/local/sbin`:
|
||||
#### 4. Script for doing the backup
|
||||
Put this file in `/bin`:
|
||||
* `restic_backup.sh`: A script that defines how to run the backup. The intention is that you should not need to edit this script yourself, but be able to control everything from the `*.env` profiles.
|
||||
|
||||
Restic support exclude files. They list file pattern paths to exclude from you backups, files that just occupy storage space, backup-time, network and money. `restic_backup.sh` allows for a few different exclude files.
|
||||
* `/etc/restic/backup_exclude.txt` - global exclude list. You can use only this one if your setup is easy. This is set in `_global.env`. If you need a different file for another profile, you can override the envvar `RESTIC_BACKUP_EXCLUDE_FILE` in this profile.
|
||||
* `.backup_exclude.txt` per backup path. If you have e.g. an USB disk mounted at /mnt/media and this path is included in the `$RESTIC_BACKUP_PATHS`, you can place a file `/mnt/media/.backup_exclude.txt` and it will automatically picked up. The nice thing about this is that the backup paths are self-contained in terms of what they shoud exclude!
|
||||
|
||||
## 5. Make first backup
|
||||
#### 5. Make first backup
|
||||
Now see if the backup itself works, by running as root
|
||||
|
||||
```console
|
||||
$ sudo -i
|
||||
$ source /etc/restic/default.env
|
||||
$ /usr/local/sbin/restic_backup.sh
|
||||
$ /bin/restic_backup.sh
|
||||
````
|
||||
|
||||
## 6. Verify the backup
|
||||
#### 6. Verify the backup
|
||||
As the `default.env` is already sourced in your root shell, you can now just list the snapshos
|
||||
```console
|
||||
$ sudo -i
|
||||
@@ -156,11 +180,10 @@ $ restic mount /mnt/restic
|
||||
$ ls /mnt/restic
|
||||
```
|
||||
|
||||
## 7. Backup automatically; systemd service + timer
|
||||
#### 7. Backup automatically; systemd service + timer
|
||||
Now we can do the modern version of a cron-job, a systemd service + timer, to run the backup every day!
|
||||
|
||||
Put these files in `/etc/systemd/system/`:
|
||||
|
||||
Put these files in `/etc/systemd/system` (note that the Makefile installs as package to `/usr/lib/systemd/system`)
|
||||
* `restic-backup@.service`: A service that calls the backup script with the specified profile. The profile is specified
|
||||
by the value after `@` when running it (see below).
|
||||
* `restic-backup@.timer`: A timer that starts the former backup every day (same thing about profile here).
|
||||
@@ -168,8 +191,7 @@ Put these files in `/etc/systemd/system/`:
|
||||
|
||||
Now simply enable the timer with:
|
||||
```console
|
||||
$ systemctl start restic-backup@default.timer
|
||||
$ systemctl enable restic-backup@default.timer
|
||||
$ sudo systemctl enable --now restic-backup@default.timer
|
||||
````
|
||||
|
||||
☝ **Note**: You can run it with different values instead of `default` if you use multiple profiles.
|
||||
@@ -201,10 +223,10 @@ $ journalctl -f -u restic-backup@default.service
|
||||
|
||||
|
||||
|
||||
## 8. Email notification on failure
|
||||
#### 8. Email notification on failure
|
||||
We want to be aware when the automatic backup fails, so we can fix it. Since my laptop does not run a mail server, I went for a solution to set up my laptop to be able to send emails with [postfix via my Gmail](https://easyengine.io/tutorials/linux/ubuntu-postfix-gmail-smtp/). Follow the instructions over there.
|
||||
|
||||
Put this file in `/usr/local/sbin`:
|
||||
Put this file in `/bin`:
|
||||
* `systemd-email`: Sends email using sendmail(1). This script also features time-out for not spamming Gmail servers and getting my account blocked.
|
||||
|
||||
Put this files in `/etc/systemd/system/`:
|
||||
@@ -213,25 +235,23 @@ Put this files in `/etc/systemd/system/`:
|
||||
As you maybe noticed already before, `restic-backup.service` is configured to start `status-email-user.service` on failure.
|
||||
|
||||
|
||||
## 9. Optional: automated backup checks
|
||||
#### 9. Optional: automated backup checks
|
||||
Once in a while it can be good to do a health check of the remote repository, to make sure it's not getting corrupt. This can be done with `$ restic check`.
|
||||
|
||||
There is companion scripts, service and timer (`*check*`) to restic-backup.sh that checks the restic backup for errors; look in the repo in `etc/systemd/system` and `usr/local/sbin` and copy what you need over to their corresponding locations.
|
||||
There is companion scripts, service and timer (`*check*`) to restic-backup.sh that checks the restic backup for errors; look in the repo in `usr/lib/systemd/system/` and `bin/` and copy what you need over to their corresponding locations.
|
||||
|
||||
```console
|
||||
$ sudo -i
|
||||
$ systemctl start restic-check@default.timer
|
||||
$ systemctl enable restic-check@default.timer
|
||||
$ sudo systemctl enable --now restic-check@default.timer
|
||||
````
|
||||
|
||||
## 10. Optional: 🏃 Restic wrapper
|
||||
#### 10. Optional: 🏃 Restic wrapper
|
||||
For convenience there's a `restic` wrapper script that makes loading profiles and **running restic**
|
||||
straightforward (it needs to run with sudo to read environment). Just run:
|
||||
|
||||
- `sudo resticw WHATEVER` (e.g. `sudo resticw snapshots`) to use the default profile.
|
||||
- You can run the wrapper by passing a specific profile: `resticw -p anotherprofile snapshots`.
|
||||
|
||||
### Useful commands
|
||||
##### Useful commands
|
||||
|
||||
| Command | Description |
|
||||
|---------------------------------------------------|-------------------------------------------------------------------|
|
||||
@@ -241,15 +261,17 @@ straightforward (it needs to run with sudo to read environment). Just run:
|
||||
| `resticw mount /mnt/restic` | Mount your remote repository |
|
||||
|
||||
|
||||
# Cron?
|
||||
## Setup Cron
|
||||
If you want to run an all-classic cron job instead, do like this:
|
||||
|
||||
* `etc/cron.d/restic`: Depending on your system's cron, put this in `/etc/cron.d/` or similar, or copy the contents to $(sudo crontab -e). The format of this file is tested under FreeBSD, and might need adaptions depending on your cron.
|
||||
* `usr/local/sbin/cron_mail`: A wrapper for running cron jobs, that sends output of the job as an email using the mail(1) command.
|
||||
1. Follow the main setup from [Step-by-step and manual setup](#step-by-step-and-manual-setup) but skip the systemd parts.
|
||||
1. `etc/cron.d/restic`: Depending on your system's cron, put this in `/etc/cron.d/` or similar, or copy the contents to $(sudo crontab -e). The format of this file is tested under FreeBSD, and might need adaptions depending on your cron.
|
||||
* You can use `$ make install-cron` to copy it over to `/etc/cron.d`.
|
||||
1. (Optional) `bin/cron_mail`: A wrapper for running cron jobs, that sends output of the job as an email using the mail(1) command.
|
||||
|
||||
|
||||
# Uninstall
|
||||
|
||||
There is a make target to remove all files (scripts and configs) that were installed by `sudo make install`. Just run:
|
||||
There is a make target to remove all files (scripts and configs) that were installed by `sudo make install-*`. Just run:
|
||||
|
||||
```console
|
||||
$ sudo make uninstall
|
||||
@@ -262,12 +284,12 @@ A list of variations of this setup:
|
||||
# Development
|
||||
* To not mess up your real installation when changing the `Makefile` simply install to a `$PREFIX` like
|
||||
```console
|
||||
$ PREFIX=/tmp/restic-test make install
|
||||
$ PREFIX=/tmp/restic-test make install-systemd
|
||||
```
|
||||
* **Updating the `resticw` parser:** If you ever update the usage `DOC`, you will need to refresh the auto-generated parser:
|
||||
```console
|
||||
$ pip install doctopt.sh
|
||||
$ doctopt.sh usr/local/sbin/resticw
|
||||
$ doctopt.sh usr/local/bin/resticw
|
||||
```
|
||||
|
||||
# Releasing
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Why? Because of FreeBSD the system cron uses sendmail, and I want to use ssmtp.
|
||||
# Make your crontab files like:
|
||||
#SHELL=/bin/sh
|
||||
#PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin
|
||||
#PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:$INSTALL_PREFIX/bin
|
||||
#@daily root cron_mail freebsd-update cron
|
||||
|
||||
mail_target=root
|
||||
@@ -1,8 +1,8 @@
|
||||
SHELL=/bin/sh
|
||||
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/:/usr/local/sbin/
|
||||
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/:$INSTALL_PREFIX/bin/
|
||||
# Order of crontab fields
|
||||
# minute hour mday month wday command
|
||||
# Reference: https://www.freebsd.org/doc/handbook/configtuning-cron.html
|
||||
# Reference: crontab(5).
|
||||
@midnight root cron_mail restic_backup.sh
|
||||
@monthly root cron_mail restic_check.sh
|
||||
@midnight root . $INSTALL_PREFIX/etc/restic/default.sh && cron_mail restic_backup.sh
|
||||
@monthly root . $INSTALL_PREFIX/etc/restic/default.sh && cron_mail restic_check.sh
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
|
||||
# The restic repository encryption key
|
||||
export RESTIC_PASSWORD_FILE="/etc/restic/pw.txt"
|
||||
export RESTIC_PASSWORD_FILE="$INSTALL_PREFIX/etc/restic/pw.txt"
|
||||
# The global restic exclude file
|
||||
export RESTIC_BACKUP_EXCLUDE_FILE="/etc/restic/backup_exclude.txt"
|
||||
export RESTIC_BACKUP_EXCLUDE_FILE="$INSTALL_PREFIX/etc/restic/backup_exclude.txt"
|
||||
|
||||
# Backblaze B2 credentials keyID & applicationKey pair.
|
||||
# Restic environment variables are documented at https://restic.readthedocs.io/en/latest/040_backup.html#environment-variables
|
||||
@@ -9,7 +9,7 @@
|
||||
# Thus you don't have to provide all the arguments like
|
||||
# $ restic --repo ... --password-file ...
|
||||
|
||||
source /etc/restic/_global.env
|
||||
source $INSTALL_PREFIX/etc/restic/_global.env
|
||||
|
||||
# Below envvar will override those in _global.env
|
||||
|
||||
BIN
img/readme_sections.png
Normal file
BIN
img/readme_sections.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -3,5 +3,4 @@ Description=Check if the current NetworkManager connection is metered
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/nm-unmetered-connection.sh
|
||||
|
||||
ExecStart=$INSTALL_PREFIX/bin/nm-unmetered-connection.sh
|
||||
@@ -10,4 +10,4 @@ Nice=10
|
||||
Environment="HOME=/root"
|
||||
# The random sleep (in seconds) is in the case of multiple backup profiles. Many restic instances started at the same time could case high load or network bandwith usage.
|
||||
# `systemd-cat` allows showing the restic output to the systemd journal
|
||||
ExecStart=bash -c 'sleep $(shuf -i 0-300 -n 1) && source /etc/restic/%I.env && /usr/local/sbin/restic_backup.sh | systemd-cat'
|
||||
ExecStart=bash -c 'ps cax | grep -q restic && sleep $(shuf -i 0-300 -n 1); source $INSTALL_PREFIX/etc/restic/%I.env && $INSTALL_PREFIX/bin/restic_backup.sh | systemd-cat'
|
||||
@@ -8,4 +8,4 @@ Requires=nm-unmetered-connection.service
|
||||
Type=simple
|
||||
Nice=10
|
||||
# `systemd-cat` allows showing the restic output to the systemd journal
|
||||
ExecStart=bash -c 'source /etc/restic/%I.env && /usr/local/sbin/restic_check.sh | systemd-cat'
|
||||
ExecStart=bash -c 'source $INSTALL_PREFIX/etc/restic/%I.env && $INSTALL_PREFIX/bin/restic_check.sh | systemd-cat'
|
||||
@@ -6,6 +6,6 @@ Description=Send status email for %i to user
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/systemd-email abc@gmail.com %i
|
||||
ExecStart=$INSTALL_PREFIX/bin/systemd-email abc@gmail.com %i
|
||||
User=root
|
||||
Group=systemd-journal
|
||||
Reference in New Issue
Block a user