What is Schnapps?⚓︎
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.
Schnapps is not available on Turris Shield.
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 Btrfs 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:
schnapps [-d root] command [options]
The currently available snapshots can be listed simply by running:
# | 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:
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:
schnapps create -t time "Midnight snapshot"
schnapps modify 4 -t time -d "My morning snapshot"
schnapps delete 6 schnapps delete 1 2 3
If you want to delete snapshot a “smarter” way you can use the
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.
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:
schnapps cmp schnapps cmp 8 schnapps cmp 1 2
~ /etc/fstab + /etc/lxc-net - /root/README
If you need more detailed comparison you can use another command:
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.
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.
Preparing for risky configuration⚓︎
From time to time you may want to try some potentially risky reconfiguration that could cut you out of the router. And sometimes, you need to do it even remotely. For this use-case, we have a special workflow in Schnapps that will help you to recover if things go sideways.
Before starting the risky operation, call
schnapps savepoint 15
This will commit the current state of the router as a snapshot and it will start a fifteen minutes timer (changing the number will change the number of minutes, if you leave it out, the default is ten minutes). If everything goes well and the new configuration works, you can subsequently call
This will cancel the timer and remove the original snapshot. If you don’t manage to
commit in time, the state of your router will be rolled back to the snapshot created at the start of your endeavour and the rebooted. You will have a rollback snapshot to inspect, but your router should be back in the state that you can connect to it and give it another try.
Updating factory image⚓︎
As we constantly release new versions, it makes sense to update even the factory image from time to time. That way, if you need to rollback all the way to the factory image, you don’t have to start with something really old. Schnapps can help you keep your factory image up to date. All you need to do is to run the following command and it will download and update your factory image.
It is a good idea to update your factory snapshot after each major update. The configuration might change quite a lot between major versions and while we try to migrate everything, it is better to avoid the need to migrate anything altogether.
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).
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:
schnapps export /mnt/usb
The resulting tarball will have a name such as
omnia-medkit-9.tar.gz.gpg. To be able to import an encrypted tarball, it is necessary to decrypt it first using GPG:
gpg1 --decrypt omnia-medkit-9.tar.gz.gpg > omnia-medkit-9.tar.gz
If you want to import a previously exported snapshot you can simply run something like:
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)
- Local or File – for locally mounted external drive,
uploadis the same as
Look at some examples:
schnapps upload 8 webdav://user:firstname.lastname@example.org/ /snapshots schnapps upload nextcloud:/user:email@example.com/snapshots/ schnapps upload 8 ssh://my.webdav.server/ /snapshots schnapps upload 8 local://mnt/ext/ schnapps upload 8 file://mnt/ext/
~/.ssh/configor added to the running
SSH URLs can be specified with relative or absolute paths (e.g.
ssh://my.webdav.server:/upload is absolute and
ssh://my.webdav.server:upload is relative; absolute paths always start with a slash). For absolute paths, the remote root directory is mounted while for relative paths, the remote login-default directory (usually the user’s home) is mounted. The separating colon (
:) may be omitted for absolute paths. If no path is specified (with or without the colon), the login-default directory is mounted. The path specified as a separate command line argument or a configuration value is always used relatively to the mount point (it does not matter whether it is defined as absolute or relative).
Synchronization of snapshots is an even higher level of operation. You can synchronize your local snapshots to a remote server using these commands:
schnapps sync schnapps sync -t pre,post
Synchronizing snapshots requires explicitly calling one of these commands. In other words, snapshots are not automatically synchronized when being created, modified or deleted.
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:
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 “time” type to be kept after cleaning
keep.max_updater– maximum number of snapshots of the “pre” and “post” types to be kept after cleaning
keep.max_rollback– maximum number of snapshots of the “rollback” 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 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 password.
Another filesystem root⚓︎
All the above paragraph assumed that schnapps work on the root file system (mounted to the VFS root or
/). But 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:
schnapps -d /mnt/disk create