Skip to content

Commit 8958d97

Browse files
authored
Pause snapshots (#498)
* pause snapshots config * ui for pausing and unpausing snapshots * reorder "Pause Snapshots" menu
1 parent 1c95813 commit 8958d97

3 files changed

Lines changed: 128 additions & 23 deletions

File tree

src/Core/Main.vala

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public class Main : GLib.Object{
9595
public int count_hourly = 6;
9696
public int count_boot = 5;
9797

98+
// pause snapshots - use snapshots_paused to query this
99+
private string pause_snapshots_this_boot = ""; // if the string contains the current /proc/sys/kernel/random/boot_id: enabled; else: disabled
100+
private long pause_snapshots_until = 0; // unix time until snapshots are allowed again [s]
101+
102+
// empty in "gui mode" contains mode in "cli mode"
98103
public string app_mode = "";
99104

100105
public bool dry_run = false;
@@ -1083,7 +1088,13 @@ public class Main : GLib.Object{
10831088
public bool create_snapshot (bool is_ondemand, Gtk.Window? parent_win){
10841089

10851090
log_debug("Main: create_snapshot()");
1086-
1091+
1092+
// in scripted mode and snapshots paused
1093+
if(App.cmd_scripted && this.snapshots_paused) {
1094+
log_msg("Main: snapshots are currently paused");
1095+
return false;
1096+
}
1097+
10871098
bool status = true;
10881099
bool update_symlinks = false;
10891100

@@ -3396,6 +3407,12 @@ public class Main : GLib.Object{
33963407
}
33973408
config.set_array_member("exclude-apps",arr);
33983409

3410+
if(this.pause_snapshots_until > 0) {
3411+
config.set_string_member("pause_snapshots", this.pause_snapshots_until.to_string());
3412+
} else if(this.pause_snapshots_this_boot.length > 0) {
3413+
config.set_string_member("pause_snapshots", this.pause_snapshots_this_boot);
3414+
}
3415+
33993416
var json = new Json.Generator();
34003417
json.pretty = true;
34013418
json.indent = 2;
@@ -3527,11 +3544,63 @@ public class Main : GLib.Object{
35273544
}
35283545
}
35293546

3547+
string pause_snapshots = config.get_string_member_with_default("pause_snapshots", "");
3548+
long pause_snapshots_long = 0;
3549+
if(long.try_parse(pause_snapshots, out pause_snapshots_long)) {
3550+
this.pause_snapshots_until = pause_snapshots_long;
3551+
this.pause_snapshots_this_boot = "";
3552+
} else {
3553+
this.pause_snapshots_until = 0;
3554+
3555+
// read current boot_id
3556+
if(TeeJee.System.get_current_boot_id() == pause_snapshots) {
3557+
this.pause_snapshots_this_boot = pause_snapshots;
3558+
} else {
3559+
this.pause_snapshots_this_boot = "";
3560+
}
3561+
}
3562+
35303563
if ((app_mode == "")||(LOG_DEBUG)){
35313564
log_msg(_("App config loaded") + ": %s".printf(this.app_conf_path));
35323565
}
35333566
}
35343567

3568+
/**
3569+
Are snapshots currently paused?
3570+
*/
3571+
public bool snapshots_paused {
3572+
get {
3573+
// paused until given time
3574+
bool isTimePaused = this.pause_snapshots_until > (GLib.get_real_time() / 1000000);
3575+
if(!isTimePaused) {
3576+
this.pause_snapshots_until = 0;
3577+
}
3578+
3579+
// paused until reboot
3580+
bool bootPaused = this.pause_snapshots_this_boot.length > 0;
3581+
3582+
return isTimePaused || bootPaused;
3583+
}
3584+
}
3585+
3586+
public void pause_snapshots_for(int time_in_s) {
3587+
this.pause_snapshots_until = (long) (GLib.get_real_time() / 1000000) + time_in_s;
3588+
this.pause_snapshots_this_boot = "";
3589+
this.save_app_config();
3590+
}
3591+
3592+
public void pause_snapshots_for_this_boot() {
3593+
this.pause_snapshots_until = 0;
3594+
this.pause_snapshots_this_boot = TeeJee.System.get_current_boot_id();
3595+
this.save_app_config();
3596+
}
3597+
3598+
public void unpause_snapshots() {
3599+
this.pause_snapshots_until = 0;
3600+
this.pause_snapshots_this_boot = "";
3601+
this.save_app_config();
3602+
}
3603+
35353604
public void set_first_run_flag(){
35363605

35373606
first_run = true;

src/Gtk/MainWindow.vala

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class MainWindow : Gtk.Window{
4444
private Gtk.ToolButton btn_browse_snapshot;
4545
private Gtk.ToolButton btn_settings;
4646
private Gtk.ToolButton btn_wizard;
47-
private Gtk.Menu menu_extra;
4847

4948
private SnapshotListBox snapshot_list_box;
5049

@@ -209,9 +208,7 @@ class MainWindow : Gtk.Window{
209208
toolbar.add(button);
210209

211210
// click event
212-
button.clicked.connect(()=>{
213-
menu_extra_popup(null);
214-
});
211+
button.clicked.connect(() => menu_extra_popup());
215212
}
216213

217214
private void init_ui_snapshot_list(){
@@ -357,47 +354,72 @@ class MainWindow : Gtk.Window{
357354
// TODO: low: refresh device list automatically when a device is plugged in
358355
}
359356

360-
private bool menu_extra_popup(Gdk.EventButton? event){
357+
private bool menu_extra_popup(){
361358

362-
menu_extra = new Gtk.Menu();
359+
Gtk.Menu? menu_extra = new Gtk.Menu();
363360
menu_extra.reserve_toggle_size = false;
364361

365362
Gtk.MenuItem menu_item = null;
366363

367364
if (!App.live_system()){
368365
// app logs
369-
menu_item = create_menu_item(_("View TimeShift Logs"), "", "", 16);
366+
menu_item = create_menu_item(_("View TimeShift Logs"));
370367
menu_extra.append(menu_item);
371368
menu_item.activate.connect(btn_view_app_logs_clicked);
369+
370+
// pause snapshots
371+
menu_item = create_menu_item(_("Pause Snapshots"));
372+
menu_extra.append(menu_item);
373+
374+
Gtk.Menu? menu_pause = new Gtk.Menu();
375+
Gtk.MenuItem? menu_pause_item = create_menu_item(_("Unpause"));
376+
menu_pause_item.activate.connect(() => App.unpause_snapshots());
377+
menu_pause_item.sensitive = App.snapshots_paused;
378+
menu_pause.append(menu_pause_item);
379+
380+
menu_pause_item = create_menu_item(_("Pause until shutdown"));
381+
menu_pause_item.activate.connect(() => App.pause_snapshots_for_this_boot());
382+
menu_pause.append(menu_pause_item);
383+
384+
menu_pause_item = create_menu_item(_("Pause for 30min"));
385+
menu_pause_item.activate.connect(() => App.pause_snapshots_for(1800));
386+
menu_pause.append(menu_pause_item);
387+
388+
menu_pause_item = create_menu_item(_("Pause for 4h"));
389+
menu_pause_item.activate.connect(() => App.pause_snapshots_for(3600*4));
390+
menu_pause.append(menu_pause_item);
391+
392+
menu_pause_item = create_menu_item(_("Pause for 8h"));
393+
menu_pause_item.activate.connect(() => App.pause_snapshots_for(3600*8));
394+
menu_pause.append(menu_pause_item);
395+
396+
menu_pause_item = create_menu_item(_("Pause for 12h"));
397+
menu_pause_item.activate.connect(() => App.pause_snapshots_for(3600*12));
398+
menu_pause.append(menu_pause_item);
399+
400+
menu_item.submenu = menu_pause;
372401
}
373402

374403
// about
375-
menu_item = create_menu_item(_("About"), "", "", 16);
404+
menu_item = create_menu_item(_("About"));
376405
menu_extra.append(menu_item);
377406
menu_item.activate.connect(btn_about_clicked);
378407

379408
menu_extra.show_all();
380-
381-
if (event != null) {
382-
menu_extra.popup (null, null, null, event.button, event.time);
383-
}
384-
else {
385-
menu_extra.popup (null, null, null, 0, Gtk.get_current_event_time());
386-
}
409+
410+
menu_extra.popup (null, null, null, 0, Gtk.get_current_event_time());
387411

388412
return true;
389413
}
390414

391-
private Gtk.MenuItem create_menu_item(
392-
string label_text, string icon_name_stock, string icon_name_custom,
393-
int icon_size, string tooltip_text = ""){
394-
395-
var menu_item = new Gtk.MenuItem();
415+
private Gtk.MenuItem create_menu_item(string label_text, string tooltip_text = ""){
416+
417+
Gtk.MenuItem menu_item = new Gtk.MenuItem();
396418

397-
var box = new Gtk.Box(Orientation.HORIZONTAL, 3);
419+
Gtk.Box box = new Gtk.Box(Orientation.HORIZONTAL, 3);
398420
menu_item.add(box);
399421

400-
var label = new Gtk.Label(label_text);
422+
Gtk.Label label = new Gtk.Label(label_text);
401423
label.xalign = (float) 0.0;
402424
label.margin_end = 6;
403425
label.set_tooltip_text((tooltip_text.length > 0) ? tooltip_text : label_text);

src/Utility/TeeJee.System.vala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ namespace TeeJee.System{
151151
return dir_exists("/sys/firmware/efi");
152152
}
153153

154+
private static string? current_boot_id = null;
155+
public static string? get_current_boot_id() {
156+
if(current_boot_id != null) {
157+
return current_boot_id;
158+
}
159+
160+
current_boot_id = file_read("/proc/sys/kernel/random/boot_id");
161+
if(null != current_boot_id) {
162+
current_boot_id._strip();
163+
}
164+
165+
return current_boot_id;
166+
}
167+
154168
// timers --------------------------------------------------
155169

156170
public GLib.Timer timer_start(){

0 commit comments

Comments
 (0)