← All Modules

assay.fs_snapshot

Lua stdlib for taking read-only filesystem snapshots before a backup read. Auto-selects a backend by inspecting the source's mount point:

BackendDetected whenSnapshot mechanism
btrfsfindmnt reports btrfsbtrfs subvolume snapshot -r <subvol> <snap_path>
zfsfindmnt reports zfszfs snapshot <pool>/<dataset>@<id>
noneany other fsno snapshot — caller reads live
local snap = require("assay.fs_snapshot")

-- Bracket pattern (preferred) — releases on error.
snap.with_snapshot("manual", "/var/lib/machines", function(handle)
  -- handle.path points at the read-only snapshot view (or the live path
  -- on the `none` backend). Pass it to your read flow.
  do_backup(handle.path)
end)

Functions

Handle shape

{
  backend     = "btrfs" | "zfs" | "none",
  path        = "/var/lib/machines/.assay-snap-manual-1730500800",
  source_path = "/var/lib/machines",
  -- zfs only:
  snap_ref    = "tank/data@manual-1730500800",
}

The path field is what callers read from — the read-only snapshot view on btrfs/zfs, or the original path on the none backend.

Privilege model

btrfs / zfs commands typically need root. The stdlib detects whether the running uid is 0 and prepends sudo -n when not, so a host with a sudoers rule for btrfs subvolume snapshot/delete and zfs snapshot/destroy works out of the box.

Integration with assay.rustic

The canonical use is bracketing a assay.rustic backup call so the capture is crash-consistent:

snap.with_snapshot("daily", "/var/lib/machines", function(h)
  rustic.backup(repo_opts, {
    sources = { h.path .. "/agentx", h.path .. "/web" },
    tags    = { "host", "daily" },
    json    = true,
  })
end)