Hello, As a user of btrfs, I've been using the fs-snapshot plugin for a while. I discovered snapper (http://snapper.io/) a while ago now and started looking at how it could be used with the fs-snapshot plugin. FYI snapper is already available as a package in Fedora.
Reading the source, I see there are references to it, namely while creating LVM snapshots (but it doesn't go further than that so it's pretty much useless as it is). To people who have never used snapper, the website lists the following features: - Manually create snapshots - Automatically create snapshots, e.g. with YaST and zypp - Automatically create timeline of snapshots - Show and revert changes between snapshots - Works with btrfs, ext4 and thin-provisioned LVM volumes - Supports Access Control Lists and Extended Attributes - Automatic cleanup of old snapshots - Command line interface - D-Bus interface - PAM module to create snapshots during login and logout An example of how it can be used: http://lizards.opensuse.org/2011/04/01/introducing-snapper/ To me the killer features are really regular snapshots and the fact you can diff them... I've created a quick and dirty patch for fs-snapshot which adds a use_snapper option to the plugin. When enabled (it's disabled by default), instead of using the native btrfs tool to create snaps, it uses snapper (in pre and post). Is this something people could be interested in? Could it be merged as such (after some polishing) or should I rather target dnf? Thanks for your feedback. diff --git a/plugins/fs-snapshot/fs-snapshot.conf b/plugins/fs-snapshot/fs-snapshot.conf index 9ada717..b253b17 100644 --- a/plugins/fs-snapshot/fs-snapshot.conf +++ b/plugins/fs-snapshot/fs-snapshot.conf @@ -1,6 +1,7 @@ [main] enabled = 1 create_snapshots_in_post = 0 +use_snapper = 0 [lvm] enabled = 0 diff --git a/plugins/fs-snapshot/fs-snapshot.py b/plugins/fs-snapshot/fs-snapshot.py index 786b0c1..95134d9 100644 --- a/plugins/fs-snapshot/fs-snapshot.py +++ b/plugins/fs-snapshot/fs-snapshot.py @@ -209,16 +209,31 @@ def _create_btrfs_snapshot(conduit, snapshot_tag, volume): if not mntpnt.endswith("/"): mntpnt = mntpnt + "/" - snapname = mntpnt + snapshot_tag - conduit.info(1, "fs-snapshot: snapshotting " + mntpnt + ": " + snapname) - p = Popen(["/sbin/btrfs", "filesystem", "sync", mntpnt], stdout=PIPE, stderr=PIPE) - err = p.wait() - if err: - return 1 - p = Popen(["/sbin/btrfs", "subvolume", "snapshot", mntpnt, snapname], stdout=PIPE, stderr=PIPE) - err = p.wait() - if err: - return 1 + if conduit._base.__plugin_fs_snapshot_use_snapper: + if not conduit._base.__plugin_fs_snapshot_pre_snapshot_tag: + conduit.info(1, "fs-snapshot: pre-snapshotting " + mntpnt) + p = Popen(["/usr/bin/snapper", "create", "--type=pre", "--cleanup-algorithm=number", "--print-number", "--description=yum"], stdout=PIPE, stderr=PIPE) + err = p.wait() + if err: + return 1 + conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = p.communicate()[0].rstrip() + else: + conduit.info(1, "fs-snapshot: post-snapshotting " + mntpnt) + p = Popen(["/usr/bin/snapper", "create", "--type=post", "--cleanup-algorithm=number", "--pre-number=" + conduit._base.__plugin_fs_snapshot_pre_snapshot_tag], stdout=PIPE, stderr=PIPE) + err = p.wait() + if err: + return 1 + else: + snapname = mntpnt + snapshot_tag + conduit.info(1, "fs-snapshot: snapshotting " + mntpnt + ": " + snapname) + p = Popen(["/sbin/btrfs", "filesystem", "sync", mntpnt], stdout=PIPE, stderr=PIPE) + err = p.wait() + if err: + return 1 + p = Popen(["/sbin/btrfs", "subvolume", "snapshot", mntpnt, snapname], stdout=PIPE, stderr=PIPE) + err = p.wait() + if err: + return 1 return 2 def add_lvm_tag_to_snapshot(conduit, tag, snap_volume): @@ -303,12 +318,15 @@ def create_snapshots(conduit): everything that is snapshottable, since we do not know what an RPM will modify (thank you scriptlets). """ - # common snapshot tag format: yum_${year}${month}${day}${hour}${minute}${sec} - snapshot_tag = "yum_" + time.strftime("%Y%m%d%H%M%S") - if not conduit._base.__plugin_fs_snapshot_pre_snapshot_tag: - conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = snapshot_tag - else: - conduit._base.__plugin_fs_snapshot_post_snapshot_tag = snapshot_tag + if conduit._base.__plugin_fs_snapshot_use_snapper: + snapshot_tag = None + else: + # common snapshot tag format: yum_${year}${month}${day}${hour}${minute}${sec} + snapshot_tag = "yum_" + time.strftime("%Y%m%d%H%M%S") + if not conduit._base.__plugin_fs_snapshot_pre_snapshot_tag: + conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = snapshot_tag + else: + conduit._base.__plugin_fs_snapshot_post_snapshot_tag = snapshot_tag volumes = get_volumes(conduit) for volume in volumes: @@ -320,11 +336,12 @@ def create_snapshots(conduit): conduit.registerPackageName("yum-plugin-fs-snapshot") def pretrans_hook(conduit): + conduit._base.__plugin_fs_snapshot_use_snapper = conduit.confBool('main', 'use_snapper', default=0) conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = None conduit._base.__plugin_fs_snapshot_post_snapshot_tag = None create_snapshots(conduit) def posttrans_hook(conduit): create_snapshots_in_post = conduit.confBool('main', 'create_snapshots_in_post', default=0) - if create_snapshots_in_post: + if create_snapshots_in_post or conduit._base.__plugin_fs_snapshot_use_snapper: create_snapshots(conduit) -- Mathieu Chouquet-Stringer m+...@thi.eu.com The sun itself sees not till heaven clears. -- William Shakespeare -- _______________________________________________ Yum-devel mailing list Yum-devel@lists.baseurl.org http://lists.baseurl.org/mailman/listinfo/yum-devel