Skip to content

Add Read-Only Btrfs Snapshots Option (issue #332) #373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions files/timeshift.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"parent_device_uuid" : "",
"do_first_run" : "true",
"btrfs_mode" : "false",
"btrfs_readonly" : "true",
"include_btrfs_home" : "false",
"stop_cron_emails" : "true",
"schedule_monthly" : "false",
Expand Down
5 changes: 5 additions & 0 deletions src/AppConsole.vala
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ public class AppConsole : GLib.Object {
App.app_mode = "ondemand";
break;

case "--readonly":
App.btrfs_readonly = bool.parse(args[++k]);
break;

case "--comment":
case "--comments":
App.cmd_comments = args[++k];
Expand Down Expand Up @@ -368,6 +372,7 @@ public class AppConsole : GLib.Object {
msg += " --check " + _("Create snapshot if scheduled") + "\n";
msg += " --create " + _("Create snapshot (even if not scheduled)") + "\n";
msg += " --comments <string> " + _("Set snapshot description") + "\n";
msg += " --readonly <bool> " + _("Create read-only snapshots (BTRFS only) (default: config)") + "\n";
msg += " --tags {O,B,H,D,W,M} " + _("Add tags to snapshot (default: O)") + "\n";;
msg += "\n";
msg += _("Restore") + ":\n";
Expand Down
8 changes: 6 additions & 2 deletions src/Core/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class Main : GLib.Object{
public string backup_parent_uuid = "";

public bool btrfs_mode = true;
public bool btrfs_readonly = true;
public bool include_btrfs_home_for_backup = false;
public bool include_btrfs_home_for_restore = false;

Expand Down Expand Up @@ -1654,7 +1655,7 @@ public class Main : GLib.Object{
dst_path = dst_path.replace("/@home/@home", "/@home");
}

string cmd = "btrfs subvolume snapshot '%s' '%s' \n".printf(src_path, dst_path);
string cmd = "btrfs subvolume snapshot %s '%s' '%s' \n".printf(btrfs_readonly ? "-r" : "", src_path, dst_path);

if (LOG_COMMANDS) { log_debug(cmd); }

Expand Down Expand Up @@ -1683,7 +1684,7 @@ public class Main : GLib.Object{
// write control file
var snapshot = Snapshot.write_control_file(
snapshot_path, dt_created, sys_uuid, current_distro.full_name(),
initial_tags, cmd_comments, 0, true, false, repo);
initial_tags, btrfs_readonly ? "ReadOnly" : cmd_comments, 0, true, false, repo);

// write subvolume info
foreach(var subvol in sys_subvolumes.values){
Expand Down Expand Up @@ -3207,6 +3208,7 @@ public class Main : GLib.Object{

config.set_string_member("do_first_run", false.to_string());
config.set_string_member("btrfs_mode", btrfs_mode.to_string());
config.set_string_member("btrfs_readonly", btrfs_readonly.to_string());
config.set_string_member("include_btrfs_home_for_backup", include_btrfs_home_for_backup.to_string());
config.set_string_member("include_btrfs_home_for_restore", include_btrfs_home_for_restore.to_string());
config.set_string_member("stop_cron_emails", stop_cron_emails.to_string());
Expand Down Expand Up @@ -3304,6 +3306,8 @@ public class Main : GLib.Object{
bool do_first_run = json_get_bool(config, "do_first_run", false); // false as default

btrfs_mode = json_get_bool(config, "btrfs_mode", false); // false as default

btrfs_readonly = json_get_bool(config, "btrfs_readonly", true); // true as default

if (do_first_run){
set_first_run_flag();
Expand Down
21 changes: 21 additions & 0 deletions src/Gtk/SnapshotBackendBox.vala
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class SnapshotBackendBox : Gtk.Box{

private Gtk.RadioButton opt_rsync;
private Gtk.RadioButton opt_btrfs;
private Gtk.CheckButton opt_btrfs_readonly;
private Gtk.Label lbl_description;
private Gtk.Window parent_window;

Expand Down Expand Up @@ -103,15 +104,34 @@ class SnapshotBackendBox : Gtk.Box{
}

opt_btrfs.toggled.connect(()=>{
add_opt_btrfs_ro(hbox);
if (opt_btrfs.active){
App.btrfs_mode = true;
init_backend();
type_changed();
update_description();
}
this.show_all();
});
}

private void add_opt_btrfs_ro(Gtk.Box hbox){
if (opt_btrfs.active){
var opt = new Gtk.CheckButton.with_label(_("Create Read-only snapshots by default"));
hbox.add(opt);
opt_btrfs_readonly = opt;

opt_btrfs_readonly.toggled.connect(()=>{
App.btrfs_readonly = opt_btrfs_readonly.active;
});
} else {
if (opt_btrfs_readonly != null){
hbox.remove(opt_btrfs_readonly);
opt_btrfs_readonly = null;
}
}
}

private bool check_for_btrfs_tools() {
try {
const string args[] = {"lsblk", "-o", "FSTYPE", null};
Expand Down Expand Up @@ -212,6 +232,7 @@ class SnapshotBackendBox : Gtk.Box{
public void refresh(){

opt_btrfs.active = App.btrfs_mode;
opt_btrfs_readonly.active = App.btrfs_readonly;
type_changed();
update_description();
}
Expand Down