1
0
Fork
You've already forked snapsh
0
Btrfs snapshot managing script
  • Shell 100%
Find a file
2024年09月23日 20:49:32 +03:00
LICENSE Initial commit 2020年08月01日 09:29:30 +03:00
README.md Add upstream link to readme 2024年09月23日 20:49:32 +03:00
snapsh 0.2.2, Show error if --umount fails 2024年07月16日 12:54:39 +03:00
snapsh-post-rollback.service Fixed path issue with systemd service, snapsh needs to be in the system $PATH to work 2021年10月29日 09:24:54 +03:00
snapsh.conf Separate config file 2020年08月07日 06:58:16 +03:00

snapsh

Btrfs snapshot managing bash script

Upstream: https://git.oranki.net/jarno/snapsh

Requirements:

  • bash
  • GNU setopt - part of GNU coreutils
  • btrfs-progs- Userspace programs for btrfs

Why not snapper?

  • This is a hobby project, but for my personal usage has been very useful. Hopefully it will be for someone else too.

Installation:

  • To start using snapsh, clone or download the repo and run ./snapsh --install. This will copy the included config file to /etc/snapsh.conf, install the included systemd service (but not enable it), and copy the script itself to /usr/local/bin/snapsh. See the section about rollbacks below for details about the systemd service.

Usage:

General:

  • Script needs the toplevel subvolume (id=5) mounted somewhere. By default snapsh uses /root/btrfs-toplevel, but you can mount it anywhere you like and define it with TOPLEVEL variable in the config file. Toplevel subvolume is unmounted automatically after operation and the mountpoint removed to avoid problems with recursion on daily use. Please note that the toplevel subvolume is not the same thing as the subvolume mounted to /
  • Will create a subvolume named snapshots by default to the toplevel. This subvolume for storing the snapshots can be changed with SNAPSHOTS_LOCATION in the config file.
-h or --help
  • show usage instructions
-v or --version
  • display the current version of snapsh
--install
  • see "Installation" above
-l or --list
  • List snapshots created by snapsh. The snapshots are always numbered sequentially from 1, starting from the oldest, so when deleting snapshots make sure you delete the newest ones first.
  • The output can be limited to a specific type with the -t or --type flags, see the section about -t below
[user@localhost]$ sudo snapsh -l
Number | Time: | Source | Type | Description
 1 | pe 29.10.2021 01.35.59 +0300 | home | auto | typetest 1
 2 | pe 29.10.2021 01.36.09 +0300 | home | manual | typetest1
 3 | pe 29.10.2021 01.36.19 +0300 | home | auto | typetest 2
 4 | pe 29.10.2021 01.36.29 +0300 | home | manual | typetest2
 5 | pe 29.10.2021 01.36.40 +0300 | home | auto | typetest 3
 6 | pe 29.10.2021 01.36.50 +0300 | home | manual | typetest3
 7 | pe 29.10.2021 01.37.00 +0300 | home | auto | typetest 4
 8 | pe 29.10.2021 01.37.10 +0300 | home | manual | typetest4
 9 | pe 29.10.2021 01.37.20 +0300 | home | auto | typetest 5
 10 | pe 29.10.2021 01.37.30 +0300 | home | manual | typetest5
 11 | pe 29.10.2021 01.37.40 +0300 | home | auto | typetest 6
 12 | pe 29.10.2021 01.37.51 +0300 | home | manual | typetest6
 13 | pe 29.10.2021 01.38.01 +0300 | home | auto | typetest 7
 14 | pe 29.10.2021 01.38.11 +0300 | home | manual | typetest7
 15 | pe 29.10.2021 01.38.21 +0300 | home | auto | typetest 8
 16 | pe 29.10.2021 01.38.31 +0300 | home | manual | typetest8
 17 | pe 29.10.2021 01.38.41 +0300 | home | auto | typetest 9
 18 | pe 29.10.2021 01.38.51 +0300 | home | manual | typetest9
 19 | pe 29.10.2021 01.39.01 +0300 | home | auto | typetest 10
 20 | pe 29.10.2021 01.39.12 +0300 | home | manual | typetest10
[user@localhost]$ sudo snapsh -l -t auto
Number | Time: | Source | Type | Description
 1 | pe 29.10.2021 01.54.42 +0300 | home | auto | typetest 1
 3 | pe 29.10.2021 01.54.44 +0300 | home | auto | typetest 2
 5 | pe 29.10.2021 01.54.46 +0300 | home | auto | typetest 3
 7 | pe 29.10.2021 01.54.48 +0300 | home | auto | typetest 4
 9 | pe 29.10.2021 01.54.51 +0300 | home | auto | typetest 5
 11 | pe 29.10.2021 01.54.53 +0300 | home | auto | typetest 6
 13 | pe 29.10.2021 01.54.55 +0300 | home | auto | typetest 7
 15 | pe 29.10.2021 01.54.57 +0300 | home | auto | typetest 8
 17 | pe 29.10.2021 01.54.59 +0300 | home | auto | typetest 9
 19 | pe 29.10.2021 01.55.02 +0300 | home | auto | typetest 10
 23 | pe 29.10.2021 01.55.25 +0300 | home | auto | This is a description for the snapshot
[user@localhost]$ sudo snapsh -l -t manual
Number | Time: | Source | Type | Description
 2 | pe 29.10.2021 01.54.43 +0300 | home | manual | typetest1
 4 | pe 29.10.2021 01.54.45 +0300 | home | manual | typetest2
 6 | pe 29.10.2021 01.54.47 +0300 | home | manual | typetest3
 8 | pe 29.10.2021 01.54.49 +0300 | home | manual | typetest4
 10 | pe 29.10.2021 01.54.52 +0300 | home | manual | typetest5
 12 | pe 29.10.2021 01.54.54 +0300 | home | manual | typetest6
 14 | pe 29.10.2021 01.54.56 +0300 | home | manual | typetest7
 16 | pe 29.10.2021 01.54.58 +0300 | home | manual | typetest8
 18 | pe 29.10.2021 01.55.01 +0300 | home | manual | typetest9
 20 | pe 29.10.2021 01.55.03 +0300 | home | manual | typetest10
 21 | pe 29.10.2021 01.55.16 +0300 | home | manual | 
 22 | pe 29.10.2021 01.55.21 +0300 | home | manual | This is a description for the snapshot
[user@localhost]$
--mount and --umount
  • If you wish to do something manually that requires accessing the toplevel subvolume, these are convenience options for quickly mounting/unmounting it to the location specified by TOPLEVEL variable in the config file (default /root/btrfs-toplevel)
-s SUBVOLUME or --snapshot SUBVOLUME
  • Take a readonly snapshot of subvolume named SUBVOLUME.
    • example: sudo snapsh -s root will take a snapshot of subvolume named root
  • The snapshots are stored in a separate subvolume (named according to the SNAPSHOTS_LOCATION config variable, default snapshots) under the toplevel id=5 subvolume.
[user@localhost]$ sudo snapsh -s home
Creating snapshot of subvolume home as home_snapshot_2021年10月29日-01.43.24
Create a readonly snapshot of '/root/btrfs-toplevel/home' in '/root/btrfs-toplevel/snapshots/home_snapshot_2021年10月29日-01.43.24'
Snapshot created!
 home_snapshot_2021年10月29日-01.43.24
 DATE=pe 29.10.2021 01.43.25 +0300
 SOURCE_SUBVOLUME=home
 DESCRIPTION=
 TYPE="manual"
[user@localhost]$
-d STR or --description STR
  • Add a description when taking a snapshot.
    • example: sudo snapsh -s root -d "Installing XFCE" will take snapshot of subvolume named root and add a description "Installing XFCE"
[user@localhost]$ sudo snapsh -s home -d "This is a description for the snapshot"
Creating snapshot of subvolume home as home_snapshot_2021年10月29日-01.44.20
Create a readonly snapshot of '/root/btrfs-toplevel/home' in '/root/btrfs-toplevel/snapshots/home_snapshot_2021年10月29日-01.44.20'
Snapshot created!
 home_snapshot_2021年10月29日-01.44.20
 DATE=pe 29.10.2021 01.44.20 +0300
 SOURCE_SUBVOLUME=home
 DESCRIPTION=This is a description for the snapshot
 TYPE="manual"
[user@localhost]$
-t TYPE or --type TYPE
  • TYPE can be one of manual, auto, boot, backup. Default is manual.
    • auto is intended to be used with automatic scheduled backups e.g. via cron
    • backup is used when generating a backup snapshot before rollbacks
    • boot is intended to be used with automatic backups taken on every boot
    • All options can be set manually
  • If used when taking snapshot, mark that snapshot as the given type
    • example: sudo snapsh -s root -d "Installing XFCE" -t auto will take a snapshot of subvolume named root, add a description "Installing XFCE" and mark that snapshot as type auto
  • If used when listing snapshots, list only snapshots of that specific type
    • example: sudo snapsh -l -t backup will list only the snapshots taken before rollbacks (if you have not marked others with that type)
[user@localhost]$ sudo snapsh -s home -d "This is a description for the snapshot" -t auto
Creating snapshot of subvolume home as home_snapshot_2021年10月29日-01.44.57
Create a readonly snapshot of '/root/btrfs-toplevel/home' in '/root/btrfs-toplevel/snapshots/home_snapshot_2021年10月29日-01.44.57'
Snapshot created!
 home_snapshot_2021年10月29日-01.44.57
 DATE=pe 29.10.2021 01.44.57 +0300
 SOURCE_SUBVOLUME=home
 DESCRIPTION=This is a description for the snapshot
 TYPE="auto"
[user@localhost]$
-r N or --remove N
  • If N is a single number
    • Delete snapshot number N (use -l, --list to get the correct number)
  • If N is a comma-separated list of numbers N1,N2,N3
    • Delete snapshots with numbers N1 N2 N3
  • If N is a range separated with a hyphen N1-N2
    • Delete snapshots starting from number N1 to number N2 (e.g. 12-16 will delete snapshots 12,13,14,15 and 16)
  • Please be careful with snapshot numbers, as they will change after every deletion
    If you are deleting multiple snapshots one by one, start from the newest one to delete, that way the indexes of older ones will stay the same.
--rollback NUMBER
  • Rollback to the snapshot number NUMBER
    • The correct subvolume is detected automatically
  • The process is the following:
    • Take a snapshot of type backup of the active target subvolume
    • Rename the currently used subvolume to SUBVOLUME.previous (e.g. home.previous)
    • Take a read/write snapshot of the target snapshot, name that as SUBVOLUME (e.g. home)
    • If the system is using SELinux, ask to enable automatic relabeling for the next boot. See below about SELinux.
    • Ask to reboot the system immediately
    • After the reboot, the included systemd service deletes the SUBVOLUME.previous subvolume.

Notes:

Nestes subvolumes:
  • Nested subvolumes will probably cause issues with rollbacks.
  • Like generally with btrfs, it's far easier to use a flat layout and use /etc/fstab to mount them into correct places
SELinux:
  • After a rollback, SELinux might cause issues like not being able to log in, because SELinux prevents access to the home folder (Might happen for the root user as well). Snapsh asks to enable a relabeling on the next boot if it detects that SELinux is enforcing. This is recommended, but the relabeling might take time on a large filesystem. If you want to skip the long relabeling and face issues, SELinux can be set to permissive mode before booting by:
    • Adding the parameter enforcing=0 to the kernel command line (e.g. press e on GRUB menu to edit the command line for the current boot)
    • Booting to a live USB, mounting the root subvolume and changing SELINUX=enforcing to SELINUX=permissive in /etc/selinux/config

Planned features:

  • systemd timer for automating snapshots
  • --auto option (quiet) for automated snapshots
  • Option to snapshot multiple/all subvolumes
  • Handle nested subvolumes correctly

Root access is required for btrfs-progs.

License:

GPL v3.0