Skip to content

Wisp: Snapper Snapshots in the GNOME Top Bar

On most btrfs installations snapper is already running and nobody notices. openSUSE sets it up out of the box; on Fedora, Arch and Debian it is a package away. It takes a snapshot every hour, and with the distribution’s own plugin installed (snapper-zypp-plugin on openSUSE, snap-pac on Arch, the dnf plugin on Fedora) one on either side of every package transaction as well. By the time something breaks there is almost certainly a good copy of the system sitting on the disk.

Getting to it is the part I did not enjoy. I wanted the snapshot list in the top bar and a restore two clicks away, so I wrote Wisp: snapper snapshots in GNOME Shell, listed in a menu in the top bar, with everything snapper can do from the command line reachable from a settings window. This post covers what it does, what has to be installed first, and two things about snapper that bite whether or not you use a GUI for it.

the menu listing two configs, newest snapshots first

The Problem

Reading snapshots back means the command line. To find out what changed since this morning you list the snapshots, read off two numbers, and diff them:

snapper -c root list
snapper -c root status 118..127
snapper -c root -v undochange 118..127 /etc/fstab

That works, and it is exactly what you do not want to be reciting from memory at the moment you actually need it. The alternative was a separate application to install and open. I wanted it in the shell I am already looking at.

The name is the faint light that hangs over a bog at night. A snapshot is the same sort of thing: the shape the system had, still there after the moment it belonged to.

What I Built: snapper snapshots in GNOME Shell

A menu and a settings window, and behind them the whole of snapper rather than a subset of it. From the menu: take a snapshot with a description no cleanup rule will remove, delete one after a confirmation that says exactly what goes, open one in Files and read it as it was. Per snapshot: rename it, mark it important, change its cleanup rule, and turn read-only off.

The part I use most is the diff. Everything that has changed since a snapshot, searchable, and for a package transaction, exactly what that transaction changed. From there you either put chosen files back or roll the root filesystem back.

changed files since a snapshot, five selected for restoring

The settings side covers timeline limits per config, creating or removing a config, snapper’s own timers, btrfsmaintenance’s jobs, and what btrfs has handed out to chunks. The menu updates live whoever changed the snapshots, so a snapshot taken in a terminal shows up without a refresh. Anything missing is named along with the line that installs it.

Prerequisites

PackageWhy
snapper and one configRequired. Not installed by default on most distributions, and there is nothing to list until a config exists.
polkitThe optional lock in front of the menu, and switching snapper’s timers.
util-linux, btrfs-progsThe Storage page.
btrfsmaintenanceBalance, scrub, defrag and trim on the Schedule page. snapper does not need it.

Check that snapper is actually there and has something to show before installing anything else:

snapper --version
systemctl status snapperd.service
snapper list-configs

An empty list-configs means there is nothing for the extension to do yet. GNOME Shell 46 or newer is the other requirement.

Installation

Step 1: install the extension

Wisp is on extensions.gnome.org: open the page and flip the switch, or install it from the Extension Manager app. That is the whole installation, and Steps 2 and 3 are not needed.

To install by hand instead, every tag builds the same zip that goes to extensions.gnome.org:

gnome-extensions install --force wisp.zip

From the sources, tools/install-local.sh installs into the running session and tools/pack.sh builds the same zip:

git clone https://github.com/epogonii/wisp
cd wisp
tools/install-local.sh

Step 2: restart the shell

Only for the zip or the sources, and before enabling it, not after. A running shell keeps an extension’s JavaScript in memory for the life of the process, so new code needs a new shell. On X11, Alt+F2 then r does it. On Wayland it has to be a new session.

Step 3: enable and verify

gnome-extensions enable wisp@epogonii.github.io
gnome-extensions info wisp@epogonii.github.io | grep State

Expected result: State: ACTIVE, and snapper snapshots in GNOME Shell: an indicator in the top bar listing your configs, newest snapshot first. If the menu is there but empty, read the next section.

Why The Menu Is Empty At First

This is the part that surprises people, and it is snapper’s design rather than the extension’s. snapperd does not use polkit. Each config carries its own ALLOW_USERS and ALLOW_GROUPS in /etc/snapper/configs/<name>, and both are empty until somebody fills them in. A fresh install therefore tells an ordinary account nothing at all, which is what an empty menu means.

Wisp runs nothing as root. For a config the account is not on, the menu shows the command that adds it, with a button that copies it, to run once as root in a terminal:

sudo snapper -c <config> set-config ALLOW_USERS=<you> SYNC_ACL=yes

SYNC_ACL is what puts an ACL on the snapshot directory; without it the snapshots are listed but their files cannot be opened. snapperd reports the change and the menu fills in on its own. Everything after that goes straight to snapperd over D-Bus as the user, with no prompt.

Restoring files, rolling back, the settings in /etc/snapper/configs and btrfsmaintenance’s file belong to root either way, and they work the same way: Wisp shows the command and copies it for you to run, so your password stays with your terminal. snapper’s timers are switched through systemd’s own D-Bus API, which asks polkit itself.

The fstab Trap

Worth knowing whether you use Wisp or the command line. snapper rollback points btrfs at a different default subvolume, so it takes effect at the next boot. It does nothing at all if /etc/fstab names the subvolume it mounts at /:

grep ' / ' /etc/fstab
# UUID=...  /  btrfs  subvol=@,compress=zstd:1  0 0
#                     ^^^^^^^^ this overrules the default subvolume

An explicit subvol= wins every time, so the rollback appears to succeed and the machine comes back exactly as it was. Where that is the case Wisp says so up front, instead of letting the reboot say it.

Preferences

gnome-extensions prefs wisp@epogonii.github.io
PageWhat is on it
AppearanceWhere the indicator sits and whether it is shown, what a middle click does, how many snapshots each config lists, ages or dates, whether a finished action answers with a pill under the panel or a notification, and the lock: never, after a while, or every time.
SnapshotsOne row per config with the subvolume it snapshots, whether it shows in the menu, whether this account may read it, and the timeline and numbered limits snapper cleans up by.
Schedulesnapper’s three timers, and how often btrfsmaintenance balances, scrubs, defragments and trims.
StorageSize, what btrfs has handed out to chunks, what is written, what is free, and the same per chunk type.
the Storage page

Gotchas

  • An empty menu on a working snapper install is almost always ALLOW_USERS, not a bug.
  • A rollback needs a reboot to mean anything, and needs fstab checked first.
  • Every string is translatable and none is translated yet. po/wisp.pot holds them, msginit --locale=<code> --input=po/wisp.pot --output=po/<code>.po starts a language, and pull requests are welcome.

For an issue: extension version, GNOME Shell version and distribution, snapper --version, whether systemctl status snapperd.service answers, and the shell’s log:

journalctl --user -b 0 -o cat /usr/bin/gnome-shell | grep -i wisp

Takeaways

  • If you run btrfs, you probably already have hourly snapshots and snapshots around every package transaction. The snapshots are not the missing piece; reaching them is.
  • snapper’s access control is per config in a text file, not polkit. Nothing works for a normal account until ALLOW_USERS and SYNC_ACL are set.
  • An explicit subvol= in fstab silently defeats snapper rollback. Check it before you need it.
  • Restoring a handful of files is the operation you actually want most of the time, and it is the one snapper snapshots in GNOME Shell make quick. A full rollback is the rare case.

Links

Install: extensions.gnome.org/extension/10755/wisp

Published inGNOME ShellLinux