Automatic snapshots with btrfs and ruby

I’ve been using this script for a while to automatically create snapshots of my system and rotate old snapshots. It has saved me a few times when an upgrade has gone wrong, or a setting crashed my whole desktop:

https://github.com/markmcb/btrfs_snapshot_rotate

It’s easy to set up, just install the packages below (on Arch Linux):
pacman -S ruby

the Ruby gem ‘colorize’ is also required (run as root or with sudo):
gem install colorize

After installing the packages you will need to add the btrfs-root to a mountpoint, I’m using /mnt/snapshots for this. Add this to your /etc/fstab if you’ve followed my earlier guide on how to set up Arch Linux:
/dev/mapper/lvmvg-rootvol /mnt/snapshots btrfs rw,relatime,noauto 0 0

Then you need to edit the script downloaded from markmcb’s github. Below is what I use on one of my machines:

SnapshotConfigurations = [
{
# array of mount points. Path must be in /etc/fstab with mount options.
# All mounts listed will be unmounted when the script completes.
# If everything is already mounted, leave an empty array, i.e, []
full_paths_to_mount: ['/mnt/snapshots'],
full_path_of_source_subvolume: '/mnt/snapshots/root',
full_path_of_snapshot_directory: '/mnt/snapshots',
snapshot_filename_prefix: 'root_snapshot',
# Define how many snapshots to keep in different time aggregations
keep: { days: 7, weeks: 4, day_of_week: "Monday", months: 2, years: 0 }
},
{
# array of mount points. Path must be in /etc/fstab with mount options.
# All mounts listed will be unmounted when the script completes.
# If everything is already mounted, leave an empty array, i.e, []
full_paths_to_mount: ['/mnt/snapshots'],
full_path_of_source_subvolume: '/mnt/snapshots/home',
full_path_of_snapshot_directory: '/mnt/snapshots',
snapshot_filename_prefix: 'home_snapshot',
# Define how many snapshots to keep in different time aggregations
keep: { days: 7, weeks: 4, day_of_week: "Monday", months: 2, years: 0 }
}
]

Before you can add cronjobs you must install a cron handler, I recommend cronie, install and activate it with:
pacman -S cronie
systemctl enable cronie

Lastly just add the script to your root’s crontab (with crontab -e):
0 23 * * * ruby /home/username/bin/btrfs_snapshot_rotate.rb -y

I would recommend running the command manually once to see that it works as well.

If disaster strikes and you need to restore a snapshot, you can use this cheatsheet to get started:
* Start Arch Linux boot USB/CD
* Mount your disk
loadkeys sv-latin1
cryptsetup luksOpen /dev/sda3 lvm
mount /dev/mapper/lvmvg-rootvol /mnt

* Go to /mnt and see which snapshots are available

If you want to, for example, restore your root to an earlier snapshot, you can do like this:
mv root root_
btrfs subvolume snapshot root_snapshot-2016-09-26 root

If you changed the kernel version between that snapshot and the live image (so that your /boot and /boot/efi was modified), you also need to mount those partitions and re-run the kernel-installation.
umount /mnt
mount -o subvol=root,ssd /dev/mapper/lvmvg-rootvol /mnt
mount -o subvol=home,ssd /dev/mapper/lvmvg-rootvol /mnt/home
swapon /dev/mapper/lvmvg-swapvol
mount /dev/sda2 /mnt/boot
mount /dev/sda1 /mnt/boot/efi
arch-chroot /mnt /bin/zsh
pacman -S linux

This should make your OS bootable again with the kernel found in the snapshot you restored!
If everything work, you can remove your broken root by mounting /mnt/snapshot, go into that folder, and run btrfs subvolume delete root_