Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ You can selectively include items for backup from the ***Settings*** window. Sel
- **@** and **@home** subvolumes may be on same or different BTRFS volumes
- **@** may be on BTRFS volume and **/home** may be mounted on non-BTRFS partition
- If swap files are used they should not be located in **@** or **@home** and could instead be stored in their own subvolume, eg **@swap**
- Separate partitions (e.g. `/boot`) can be handled via custom created hooks (placed in `/etc/timeshift/backup-hooks.d/` and `/etc/timeshift/restore-hooks.d/`). Script naming must match `run-parts` [requirements](https://manpages.ubuntu.com/manpages/noble/man8/run-parts.8.html). Current snapshot path is exported as `TS_SNAPSHOT_PATH`.
- Separate partitions (e.g. `/boot`) can be handled via custom created hooks (placed in `/etc/timeshift/backup-hooks.d/` and `/etc/timeshift/restore-hooks.d/`). Script naming must match `run-parts` [requirements](https://manpages.ubuntu.com/manpages/noble/man8/run-parts.8.html). Available variables in hooks:
- `TS_SNAPSHOT_PATH` - Path of the current snapshot
- `TS_MODE` - "BTRFS" or "RSYNC"
- Other layouts are not supported
- Make sure, that you have selected subvolume *@* or */@* for root. You can check that executing script below, and if output is *OK*, then everything is alright.

Expand Down
36 changes: 24 additions & 12 deletions src/Core/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@
return;
}

// copy all required enviroment vars from the user to this process

Check failure on line 385 in src/Core/Main.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22.3-amd64, Mint 22, true) / Mint 22

enviroment ==> environment
string[] targets = {"GTK_THEME", "DISPLAY", "XAUTHORITY", "DBUS_SESSION_BUS_ADDRESS"};
foreach (string target in targets) {
string user_var = TeeJee.ProcessHelper.get_env(user_env, target);
Expand Down Expand Up @@ -1597,6 +1597,8 @@

Snapshot snapshot_to_link = null;

this.run_pre_backup_hooks(snapshot_path);

// check if a snapshot was restored recently and use it for linking ---------

try{
Expand Down Expand Up @@ -1742,7 +1744,7 @@
string time_stamp = dt_created.format("%Y-%m-%d_%H-%M-%S");
string snapshot_name = time_stamp;
string sys_uuid = (sys_root == null) ? "" : sys_root.uuid;
string snapshot_path = "";
string snapshot_base_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s/".printf(snapshot_name));

// create subvolume snapshots

Expand All @@ -1752,10 +1754,12 @@

subvol_names = new string[] { "@","@home" };
}

this.run_pre_backup_hooks(snapshot_base_path);

foreach(var subvol_name in subvol_names){

snapshot_path = path_combine(repo.mount_paths[subvol_name], "timeshift-btrfs/snapshots/%s".printf(snapshot_name));
string snapshot_path = path_combine(repo.mount_paths[subvol_name], "timeshift-btrfs/snapshots/%s".printf(snapshot_name));

dir_create(snapshot_path, true);

Expand Down Expand Up @@ -1793,13 +1797,13 @@

//log_msg(_("Writing control file..."));

snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name));
string control_path = snapshot_base_path + snapshot_name;

string initial_tags = (tag == "ondemand") ? "" : tag;

// write control file
var snapshot = Snapshot.write_control_file(
snapshot_path, dt_created, sys_uuid, current_distro.full_name(),
control_path, dt_created, sys_uuid, current_distro.full_name(),
initial_tags, cmd_comments, 0, true, false, repo);

// write subvolume info
Expand All @@ -1811,24 +1815,32 @@
set_tags(snapshot); // set_tags() will update the control file

// Perform any post-backup actions
this.run_post_backup_hooks(snapshot_path);
this.run_post_backup_hooks(snapshot_base_path);

return snapshot;
}

private void run_pre_backup_hooks(string snapshot_path) {
this.run_hooks("/etc/timeshift/pre-backup-hooks.d", snapshot_path);
}

private void run_post_backup_hooks(string snapshot_path) {
const string backuphooksdir = "/etc/timeshift/backup-hooks.d";
FileType fileType = File.new_for_path(backuphooksdir).query_file_type(FileQueryInfoFlags.NONE);
this.run_hooks("/etc/timeshift/backup-hooks.d", snapshot_path);
}

private void run_hooks(string path, string snapshot_path) {
FileType fileType = File.new_for_path(path).query_file_type(FileQueryInfoFlags.NONE);
if(fileType == FileType.DIRECTORY) {
log_debug("Running post-backup tasks...");
log_debug("Running tasks...");

string mode_text = (this.btrfs_mode ? "BTRFS" : "RSYNC");

string sh = "export TS_SNAPSHOT_PATH=\"" + snapshot_path + "\" &&" +
" run-parts --verbose \"%s\"".printf(backuphooksdir);
string sh = "export TS_SNAPSHOT_PATH=\"%s\" TS_MODE=\"%s\" && run-parts --verbose \"%s\"".printf(snapshot_path, mode_text, path);
exec_script_sync(sh, null, null, false, false, false, true);

log_debug("Finished running post-backup tasks...");
log_debug("Finished running tasks...");
} else {
log_debug("Backup hooks skipped, because %s does not exist".printf(backuphooksdir));
log_debug("Hooks skipped, because %s does not exist".printf(path));
}
}

Expand Down
Loading