<citerefentry><refentrytitle>snapper-configs</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
+ <refsect1 id='plugins'>
+ <title>PLUGINS</title>
+ <para>snapper can execute external scripts after certain actions. Scripts
+ have to be placed in <filename>/usr/lib/snapper/plugins</filename>.
+ The name has to start with a digit, execution order is alphabetical.</para>
+ <para>The first argument of a script is the action snapper executed. The
+ following actions are defined:</para>
+ <variablelist>
+ <varlistentry>
+ <term><option>create-snapshot <replaceable>subvolume</replaceable> <replaceable>snapshot-number</replaceable></option></term>
+ <listitem>
+ <para>Executed when a new snapshot gets created</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>delete-snapshot <replaceable>subvolume</replaceable> <replaceable>snapshot-number</replaceable></option></term>
+ <listitem>
+ <para>Executed when a snapshot is removed</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>modify-snapshot <replaceable>subvolume</replaceable> <replaceable>snapshot-number</replaceable></option></term>
+ <listitem>
+ <para>Executed when a snapshot gets modified</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>set-default-snapshot <replaceable>subvolume</replaceable> <replaceable>snapshot-number</replaceable></option></term>
+ <listitem>
+ <para>Executed when the default snapshot gets changed</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
<refsect1 id='files'>
<title>FILES</title>
<variablelist>
#include "snapper/Btrfs.h"
#include "snapper/BtrfsUtils.h"
#include "snapper/File.h"
+#include "snapper/Hooks.h"
#include "snapper/Snapper.h"
#include "snapper/SnapperTmpl.h"
#include "snapper/SnapperDefines.h"
SDir snapshot_dir = openSnapshotDir(num);
subvolid_t id = get_id(snapshot_dir.fd());
set_default_id(general_dir.fd(), id);
+
+ Hooks::set_default_snapshot(subvolume, this, num);
}
}
catch (const runtime_error& e)
#include "config.h"
+#include <string.h>
+
+#include <boost/algorithm/string/join.hpp>
+
+#include "snapper/FileUtils.h"
#include "snapper/Hooks.h"
#include "snapper/SystemCmd.h"
+#include "snapper/Log.h"
namespace snapper
{
using namespace std;
+ static bool
+ _plugins_filter_entries(unsigned char type, const char* name)
+ {
+ // must start with digit
+ if (*name >= '0' && *name <= '9')
+ return true;
+ return false;
+ }
+
+ void
+ Hooks::run_scripts(const list<string>& args)
+ {
+ SDir dir("/usr/lib/snapper/plugins");
+
+ vector<string> scripts = dir.entries(_plugins_filter_entries);
+ std::sort(scripts.begin(), scripts.end());
+ for (const string& script : scripts)
+ {
+ string cmdln = dir.fullname(script);
+ for (const string& arg : args) {
+ cmdln += " " + quote(arg);
+ }
+ SystemCmd cmd(cmdln);
+ }
+ }
void
Hooks::create_config(const string& subvolume, const Filesystem* filesystem)
void
- Hooks::create_snapshot(const string& subvolume, const Filesystem* filesystem)
+ Hooks::create_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot)
{
grub(subvolume, filesystem, "--refresh");
+ run_scripts(std::list<string>({"create-snapshot", subvolume, std::to_string(snapshot.getNum())}));
}
void
- Hooks::modify_snapshot(const string& subvolume, const Filesystem* filesystem)
+ Hooks::modify_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot)
{
grub(subvolume, filesystem, "--refresh");
+ run_scripts(std::list<string>({"modify-snapshot", subvolume, std::to_string(snapshot.getNum())}));
}
void
- Hooks::delete_snapshot(const string& subvolume, const Filesystem* filesystem)
+ Hooks::delete_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot)
{
grub(subvolume, filesystem, "--refresh");
+ run_scripts(std::list<string>({"delete-snapshot", subvolume, std::to_string(snapshot.getNum())}));
}
+ void
+ Hooks::set_default_snapshot(const string& subvolume, const Filesystem* filesystem, unsigned int num)
+ {
+ run_scripts(std::list<string>({"set-default-snapshot", subvolume, std::to_string(num)}));
+ }
void
Hooks::grub(const string& subvolume, const Filesystem* filesystem, const char* option)
{
public:
+ static void run_scripts(const list<string>& args);
static void create_config(const string& subvolume, const Filesystem* filesystem);
static void delete_config(const string& subvolume, const Filesystem* filesystem);
- static void create_snapshot(const string& subvolume, const Filesystem* filesystem);
- static void modify_snapshot(const string& subvolume, const Filesystem* filesystem);
- static void delete_snapshot(const string& subvolume, const Filesystem* filesystem);
+ static void create_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot);
+ static void modify_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot);
+ static void delete_snapshot(const string& subvolume, const Filesystem* filesystem, const Snapshot& snapshot);
+ static void set_default_snapshot(const string& subvolume, const Filesystem* filesystem, unsigned int num);
static void rollback(const string& old_root, const string& new_root);
SN_RETHROW(e);
}
- Hooks::create_snapshot(snapper->subvolumeDir(), snapper->getFilesystem());
+ Hooks::create_snapshot(snapper->subvolumeDir(), snapper->getFilesystem(), snapshot);
return entries.insert(entries.end(), snapshot);
}
snapshot->writeInfo();
- Hooks::modify_snapshot(snapper->subvolumeDir(), snapper->getFilesystem());
+ Hooks::modify_snapshot(snapper->subvolumeDir(), snapper->getFilesystem(), *snapshot);
}
entries.erase(snapshot);
- Hooks::delete_snapshot(snapper->subvolumeDir(), snapper->getFilesystem());
+ Hooks::delete_snapshot(snapper->subvolumeDir(), snapper->getFilesystem(), *snapshot);
}