2025-08-07 18:46:06 +02:00
2025-08-07 16:11:48 +02:00
2025-08-07 16:11:48 +02:00
2025-08-07 16:11:48 +02:00
2025-08-07 18:46:06 +02:00

Backup helpers

With the right tooling (I use restic for instance), taking backups is very easy, so is distributing them to multiple locations including cloud storage. It is so easy, that the main challenge for me is keeping track of them. Questions such as Where can I find the most recent backup of X or even Am I taking backups according to the schedule or is anything missing are more and more difficult to answer. It is supported by the fact that some storage locations aren't always online.

The goal of this project is to provide a collection of simple scripts to keep an offline list of that is backed up where, perform simple queries on the list and evaluate, whether it fulfills simple criteria (such as whether there is a recent enough backup of specified files). It is designed to keep the information in a simple format (actually JSON files scattered across a couple of directories) to be easily queryable and editable directly and so that it can easily be synchronized across multiple devices (Git, Syncthing, …). It deliberately doesn't provide any encryption; your backups should be protected by the actual backup software and the metadata gathered by these scripts are probably gonna be stored on your laptop or similar, so if it is breached, you have a much more urgent problem (like someone replacing you gpg binary with their shell script).

Importing backups

The only currently implemented import mechanism is for restic. If you are brave enough however, you can write the files by hand. Every storage, that can hold some backups, is called a repo and has a configuration file in repos/<repo-name>. The configuration is needed only for the import, which then creates backups/<repo-name>/<backup-id> for each backup in the repository.

For restic repos, the config looks like

{
	"name": "<repo-name>",
	"type": "restic",
	"restic-path": "<What one passes to `-r` to restic>"
}

and you can import the backups with

./import.sh <repo-name>

Make sure to always call the script with the root of this repository as your working directory

Declaring backup targets

The files/directories you want to back up are called targets. You configure each one of them by creating a file targets/<target-name>, where you list the source machine's hostname and the local path to the file/directory. Together it looks like

{
	"name": "<target-name>",
	"hostname": "<hostname>",
	"path": "<path>"
}

The hostname and path values do not necessarily have to be real, it is just something we match on the backups in repos to recognize what's what.

Checking freshness

When we have all the metadata downloaded, we can evaluate whether they match our expectations. This can be done offline without access to the repositories and should be resource non-intensive in general.

We can define the rules in check.sh by appending them at the bottom of the file (between the markers in comments). If we then execute the checks with

./check.sh
``

it prints those that didn't pass. The return code is 0 on successful execution and all checks passing, 2 on successful execution but some checks non-passing and other exit codes signify a failure.

**Again make sure to always call the script with the root of this repository as your working directory**

The only currently implemented check is `isRecentInRepo <repo-name> <target-name> <maxAge>` where the first two arguments are the filenames of the corresponding configuration files and the last one is maximum age in whole seconds to still consider the backup to be fresh.
Description
No description provided
Readme 39 KiB
Languages
Shell 100%