Schnapps is a command-line tool for manipulation with Btrfs snapshots. It is useful especially when you want to make some experiments with your Turris.
What is Btrfs
Btrfs is a modern file system based on the copy-on-write principle. It has many important features such as snapshots, subvolumes, self-healing, file cloning, block discard, pooling, checksums, transparent compression, and many others. Btrfs is used as the main file system in Turris (on the internal eMMC device) although it also supports more file systems supported by the Linux kernel (e.g. ext3, ext4, squashfs, NFS…).
The most important feature of Btrfs is to work with snapshots. These snapshots can be created, deleted, compared, rolled back to, backed up and so on. Thanks to the nature of Btrfs all of these operations are fast and effective.
What you can do with schnapps
Although you can use standard Bfrfs tools to deal with snapshots schnapps is a high-level tool and provides more features. Filesystem snapshots can be not only manipulated locally but easily exported/imported and even uploaded to a server as well.
Some uses of schnapps on Turris are automatic. For example, before and after each software update a snapshot is created. So if anything was wrong (and Turris could boot at least) after an update or subsequent modifications there has been a possibility to roll back to the last working snapshot. Furthermore, one snapshot per week is created by the cron daemon.
The general format for running schnapps is the following:
The list of all supported commands with their options and short descriptions can be obtained by this command:
schnapps [-d root] command [options]
You also get the same if you run schnapps without any arguments.
The currently available snapshots can be listed simply by running:
You get something like this:
There are four snapshots. The first one was created automatically before updating system packages, the second one after the packages were updated. The third snapshot was created by the cron and the last one by a user manually. For each the snapshot you can see its number, type (see below), timestamp of creation and description.
# | Type | Size | Date | Description ------+-----------+-------------+-----------------------------+------------------------------------ 1 | pre | 36.82MiB | 2019-07-10 16:37:56 +0200 | Automatic pre-update snapshot 2 | post | 820.00KiB | 2019-07-10 16:40:23 +0200 | Automatic post-update snapshot 3 | time | 1.32KiB | 2019-07-15 01:05:06 +0200 | Snapshot created by cron 4 | single | 8.00KiB | 2019-07-17 09:02:42 +0200 | User created snapshot
The list above is suitable for a human user. If you want to use a snapshot list as an input for any other tools you can use JSON export:
schnapps list -j
Creating, modifying and deleting snapshots
The simplest command for creating snapshots is the following:
It creates a snapshot of the “single” type and described as “User created snapshot”. If you want to annotate your snapshot (and it is recommended to do so) simply add your description:
Enclose the description into the quotation marks to prevent potential unwanted effects. You can also specify the type of the snapshot to distinguish between more types especially for later automatic processing. There are five types:
schnapps create "Before breaking it down"
single- standard manually created snapshots
time- snapshots created on time base (by cron)
pre- snapshots created before updates
post- snapshots created after updates
rollback- snapshots created when rolling back (can’t be created manually)
The full form of the command will be like:
Both the type and description can be modified later. This command changes the parameters of one of the previously created snapshots:
schnapps create -t time "Midnight snapshot"
You can delete the created snapshot by running:
schnapps modify 4 -t time -d "My morning snapshot"
The first command deletes only one snapshot (numbered 6). The second one deletes three snapshots. You can specify as many snapshots as you want. The remaining snapshots retain their original numbers so if you delete some snapshots there will be “holes” in the order.
schnapps delete 6 schnapps delete 1 2 3
If you want to delete snapshot a “smarter” way you can use the
The first command deletes all snapshots which are older than the numbers specified in
schnapps cleanup schnapps cleanup --compare
/etc/config/schnapps(see below). The second one also deletes the snapshots which contain no changes to the previous ones.
This is the most important feature of snapshots. You can roll back to a snapshot at any time. The current file system state is not lost. It creates a “rollback” type snapshot automatically and you will be able to roll back to this snapshot later.
The first command rolls back to the last snapshot. The second one rolls back to the specified snapshot (if it exists).
schnapps rollback schnapps rollback 3
Always reboot your Turris after rolling back. Many files are processed only at boot thus unbooted Turris is in inconsistent state and some things may not work as you expected.
You can compare one snapshot to another one. There are two commands to do it. The first is
cmp and displays only
what files are different:
The first command compares the current state of the file system to the last snapshot. The second one compares the current state of the file system to the specified snapshot (8) and the last one compares two specified snapshots. The comparison can take some time, especially it the compared snapshots are far between. The result contains a list of files marked by a character that tells what type of difference it is (the legend is also included in the result).
schnapps cmp schnapps cmp 8 schnapps cmp 1 2
This listing means that the first file has changed its content, the second one has been added and the third one has been deleted in the newer snapshot (or in the current state if no later snapshot was specified).
~ /etc/fstab + /etc/lxc-net - /root/README
If you need more detailed comparison you can use another command:
It does the same as the
schnapps diff 1 2
cmpcommand above but furthermore, it displays diffs for individual files.
Working with data in snapshots
Each Btrfs snapshot appears as a complete file system and as such can be mounted and worked with its files.
The first command mounts one snapshot to
schnapps mount 2 schnapps mount 2 3
/mnt/snapshot-@N, where “N” is the number of the snapshot. The second one mounts two snapshots (you can mount as many snapshots as you want). The mounted snapshot may be modified and such changes don’t apply to any other snapshots. You can, for example, mount a snapshot, modify its files and then roll back to that snapshot to apply your changes.
Export and import
You can export your snapshot to create a media kit (medkit) which can be simply backed up or copied to another Turris of the same type (e.g. from your Omnia to another Omnia).
This set of commands does the following:
mkdir /mnt/usb mount /dev/sda1 /mnt/usb schnapps export 9 /mnt/usb umount /mnt/usb rmdir /mnt/usb
1. Creates a directory to be the mount point for the USB drive. 2. Mounts the /dev/sda1 device (the first partition on the USB drive) to the mount point. 3. Exports the given snapshot to the mounted file system. 4. Unmounts the target file system. 5. Removes the mount point.
The export command itself creates two files. One of them (
*.tar.gz) contains the exported snapshot as a
tarred and gzipped
directory tree. The other one (
*.info) contains information about the snapshot.
The names of these files are created this way:
The “turris-series” value is “omnia” or “mox” for these devices or “schnapps” otherwise. You can export the current file system state as well (but it is not recommended because it may be inconsistent):
While exporting snapshots you can symmetrically encrypt the resulting tarball. It works only if you have your GPG key properly prepared and the password is set in the configuration file (see below).
schnapps export /mnt/usb
The resulting tarball will have a name such as
If you want to import a previously exported snapshot you can simply run something like:
Most of the commands are described above. Only the third one is different. It’s the import itself. Notice that it takes the path to the information file (and not to the tarball). After importing, a rollback snapshot is automatically created.
mkdir /mnt/usb mount /dev/sda1 /mnt/usb schnapps import /mnt/usb/omnia-medkit-9.info umount /mnt/usb rmdir /mnt/usb
For an imported snapshot, no data deduplication is done and therefore it takes a lot of space.
Remote manipulation with snapshots
One of the high-level features of schnapps is remote manipulation with snapshots. You can not only work with local snapshots but also upload them to a server and even keep in sync.
The simplest operation is the upload of one snapshot. Currently, these remote resources are supported:
- WebDAV - use if you have a WebDAV server
- Nextcloud - basically the same as WebDAV but with simpler specification for Nextcloud servers; use if you have a Nextcloud server
- SSHFS - use for any SSH-capable server (e.g. almost any Linux machine)
Look at some examples:
The first command uploads the snapshot numbered 8 to the specified WebDAV server to the specified directory. The user credentials are incorporated into the URL. The second example is similar but it uploads the current file system state and the target directory is a part of the URL. The third command uses SSHFS and the user credentials are omitted (it logs in as the current user and authenticates he/she by the key which must be preconfigured in
schnapps 8 webdav://user:email@example.com/ /snapshots schnapps nextcloud:/user:firstname.lastname@example.org/snapshots/ schnapps 8 ssh://my.webdav.server/ /snapshots
~/.ssh/configor added to the running
Synchronization of snapshots is an even higher level of operation. You can synchronize your local snapshots to a remote server using these commands:
The first command synchronizes all local snapshots to the remote server. The other command synchronizes only the snapshots having the given types (here pre and post).
schnapps sync schnapps sync -t pre,post
The remote server must be properly configured in
/etc/config/schnapps before running synchronization commands.
The last schnapps command is
rlist which displays remotely saved (uploaded or synchronized) snapshots:
The second command outputs the list as JSON for use in automation tools.
schnapps rlist schnapps rlist -j
As meant in the above paragraphs, schnapps is configurable and some commands require the configuration to be prepared before using them. There are those parameters:
keep.max_single- maximum number of snapshots of the “single” type to be kept after cleaning
keep.max_time- maximum number of snapshots of the “single” type to be kept after cleaning
keep.max_updater- maximum number of snapshots of the “single” type to be kept after cleaning
keep.max_rollback- maximum number of snapshots of the “single” type to be kept after cleaning
remote.url- URL for accessing the remote server
remote.path- the directory path to be used for uploading and synchronizing snapshots
remote.user- the user name to log in to the remote server
remote.password- the password to log in to the remote server
encrypt.pass- the GPG key password to be used for encryption
A real configuration file would look like this:
config keep 'keep' option max_single '-1' option max_time '5' option max_updater '5' option max_rollback '3' config remote 'remote' option url 'nextcloud://my.nextcloud.server' option path '/turris/backups' option user 'myuser' option password 'mypassword' option sync_types 'single,time' config encrypt 'encrypt' option pass 'mypassword'
This configuration means that “single” type snapshots are retained infinitely, last five “time” type snapshots are kept, last five updater snapshots (“pre” and “post”) and last three “rollback” snapshots. Remote synchronization uses the given Nextcloud URL, path, user name and password; “single” and “time” snapshots are included in the synchronization. Encrypted snapshots are encrypted using the given key password.
Another filesystem root
All the above paragraph assumed that schnapps work on the root file system (mounted to the VFS root or
schnapps can work on other Btrfs file systems too. For example, you can connect your portable USB disk with Btrfs
to your Turris and use schnapps to work with snapshots on it the same way you managed the root file system ones.
If your file system is mounted on
/mnt/disk you can create a snapshot by this command:
Other commands can be used similarly.
schnapps -d /mnt/disk create