Skip to main content

BtrUp: Btrfs + Borg backup script

Project description

BtrUp: Btrfs + Borg backup script

:warning: Warning :warning: You use BtrUp at your own risk. You are the only person responsible for any damage caused by the use of BtrUp. :warning:

BtrUp is distributed under the terms of the GPLv3 license. See the LICENSE file for more details.

See CHANGELOG.md for the version history.

Installation

pip install btrup

You must also have a Btrfs filesystem and Borg Backup installed on your computer.

Usage

BtrUp is executed on the command line with a TOML config file as mandatory argument.

btrup CONFIG [-n] [-s]

The option -n will result in a dry run and can be used to test the configuration.

The option -s skips the creation of a new snapshot, which can be useful after a successful snapshot followed by a failed or interrupted Borg backup.

The config file has the following format:

# Datetime format used for snapshot and backup suffixes.
datetime_format = '%Y_%m_%d__%H_%M_%S'
# Time origin to discretize time into bins.
time_origin = '2024_01_01__03_55_00'

# To determine which snapshots and backups to keep,
# time is divided into bins of equal width
# Each [[keeps]] section specifies the bin width as "interval".
# The first bin starts at time_origin in every [[keeps]] section.
# Within one bin, only the oldest snapshot (and backup) is retained.
# When there are multiple [[keeps]] sections,
# a spanshot is kept if it matches the criteria of
# at least one of the [[keeps]] sections.

# With the `time_origin` in this example,
# the daily backup corresponds to the snapshot made at 4am

# The 12 most recent 10-minutely snapshots are retained, not backed up.
[[keeps]]
interval = "10 minutes"
amount = 12

# The 28 most recent hourly snapshot are retained, not backed up.
[[keeps]]
interval = "hour"
amount = 48

# The 14 most recent daily snapshot are retained and backed up.
[[keeps]]
backup = true
interval = "day"
amount = 14

# The 52 most recent weekly snapshot are retained and backed up.
[[keeps]]
backup = true
interval = "7 days"
amount = 52

[btrfs]
# Mount point of the Btrfs volume to take snapshot from, must be mounted.
source_path = "/home"
# Prefix for btrfs snapshot volumes, timestamp is appended.
prefix = "snapshots/home."
# Path where the snapshot volumes will be mounted.
snapshot_mnt = "/mnt"
# The snapshot path will be "{snapshot_mnt}/{prefix}{datetime}".
# The snapshots must be stored in the same Btrfs file system as the source.
# In this example, `/mn/snapshots` must be a Btrfs volume
# in the same filesystem as that of the `/home` volume,

# Commands to be executed before making a snapshot: cleanups, mysqldump, etc.
pre = []
# Commands to be executed after making a snapshot: remove dump etc.
post = []
# Note that each command is a string that is executed without a subshell.

[borg]
# Prefix used for Borg archives
prefix = "home."
# List of borg repositories
repositories = ["/mnt/bigdisk", "offsite:/mnt/storage"]
# The archive name is "{repository}::{prefix}{datetime}" for each repository.

# Dictionary with environment variables set for each Borg command, e.g. BORG_CACHE_DIR
env = {}
# Extra arguments for borg create command, e.g. to define exclusions
extra = []
# Paths inside the subvolume to backup.
paths = ["alice", "bob"]

# If you prefer to disable the borg backup, delete the entire borg section
# or leave the list of repositories empty.

Ideally, backups are performed by a dedicated user account with access to user data and backups. Users, whose data is being backed up, should only have read access to the backups. This way, they (or any malware running in their account) cannot damage the backed up data.

Periodic backups

To run BtrUp on a regular basis, you can write a shell script that calls BtrUp with the desired arguments, and then add this shell script to the crontab of the backup account.

A more modern solution is to create a systemd timer and service. The instructions below should be executed as root.

Start by creating a backup user that will run the backup process:

useradd backup -s /sbin/nologin

Install btrup systemwide, as some Linux distributions (using SELinux) will not allow services to execute programs located in home directories.

pip install btrup

Create two files in /etc/systemd/system/:

/etc/systemd/system/btrup.timer:

[Unit]
Description=Periodic backup with BtrUp

[Timer]
# Every hour. See man systemd.timer(5)
OnCalendar=hourly
Persistent=true
Unit=btrup.service

[Install]
WantedBy=default.target

/etc/systemd/system/btrup.service

[Unit]
Description=Periodic backup with BtrUp

[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/btrup /etc/btrup/config.toml
AmbientCapabilities=CAP_DAC_READ_SEARCH

You also need to create a configuration file /etc/btrup/config.toml. (This can be generalized towards multiple configs and a shell script calling btrup for each config.) For security reasons, it is recommended to use absolute paths for all executables, which may be different on your system.

The flag CAP_DAC_READ_SEARCH gives the backup service account global read-access. In addition, you need to configure sudoers to allow the backup user to manage Btrfs subvolumes. This can be accomplished with the following lines in your sudoers configuration:

backup ALL=(ALL) NOPASSWD: /usr/sbin/btrfs subvolume snapshot -r /home *
backup ALL=(ALL) NOPASSWD: /usr/sbin/btrfs subvolume list /home
backup ALL=(ALL) NOPASSWD: /usr/sbin/btrfs subvolume delete /mnt/snapshots/home.*

Make sure you make these commands match your config file and are specific as possible. By making them more specific, you will reduce the risk of accidental wrong subvolume operations. Also ensure that you use visudo to edit the sudoers file, to avoid that mistakes in your sudoers file will lock you out of the root account.

To enable the backup timer and service, run the following as root:

systemctl daemon-reload
systemctl enable --now btrup.timer

To check the state of the timer:

systemctl list-timers

To test the backup without waiting for the timer

systemctl start btrup.service

To check the backup logs:

journalctl -efu btrup.service

Credits

BtrUp is written by Toon Verstraelen. Most of the magic in BtrUp is provided by two great tools:

  • BtrUp assume your data resides in a Btrfs file system volume, which is used by BtrUp to create snapshots.
  • Backups of the snapshots are made with Borg.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

btrup-1.0.2.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

btrup-1.0.2-py3-none-any.whl (22.5 kB view details)

Uploaded Python 3

File details

Details for the file btrup-1.0.2.tar.gz.

File metadata

  • Download URL: btrup-1.0.2.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for btrup-1.0.2.tar.gz
Algorithm Hash digest
SHA256 6e792a57a84eec9a10d161f8a0343b0e6fb63e2f1d2978d5ce04070262922b38
MD5 41ae087bb65417b48e49ab910497aa6f
BLAKE2b-256 ba81708cd390f2b4fffeb9c5e43ed6c557f3ae914a31ff84089ad458104acbd6

See more details on using hashes here.

Provenance

The following attestation bundles were made for btrup-1.0.2.tar.gz:

Publisher: release.yaml on reproducible-reporting/btrup

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file btrup-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: btrup-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 22.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for btrup-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0d45bf73e697d40d394679114b2b5c4a181b429f4f857ed8675aeeb4585ad29d
MD5 e6acadf6c1000def0bb8d6af28012af0
BLAKE2b-256 c22ac8f0f8d8d2882a90121f88bdbeddb657dcbdd549ce53c140152922d5bfc2

See more details on using hashes here.

Provenance

The following attestation bundles were made for btrup-1.0.2-py3-none-any.whl:

Publisher: release.yaml on reproducible-reporting/btrup

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page