Skip to content
API Documentation
BastionGuard™
SnapshotBackendBox.vala
Go to the documentation of this file.
1/*
2 * SnapshotBackendBox.vala
3 *
4 * Copyright 2012-2018 Tony George <teejeetech@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 *
22 */
23
24using Gtk;
25using Gee;
26
27using TeeJee.Logging;
32using TeeJee.System;
33using TeeJee.Misc;
34
35class SnapshotBackendBox : Gtk.Box{
36
37 private Gtk.CheckButton opt_rsync;
38 private Gtk.CheckButton opt_btrfs;
39 private Gtk.Label lbl_description;
40 private Gtk.Window parent_window;
41
42 public signal void type_changed();
43
44 public SnapshotBackendBox (Gtk.Window _parent_window) {
45
46 log_debug("SnapshotBackendBox: SnapshotBackendBox()");
47
48 //base(Gtk.Orientation.VERTICAL, 6); // issue with vala
49 GLib.Object(orientation: Gtk.Orientation.VERTICAL, spacing: 6); // work-around
50 parent_window = _parent_window;
51 margin_top = 12;
52 margin_bottom = 12;
53 margin_start = 12;
54 margin_end = 12;
55
56 build_ui();
57
58 refresh();
59
60 log_debug("SnapshotBackendBox: SnapshotBackendBox(): exit");
61 }
62
63 private void build_ui(){
64
65 add_label_header(this, _("Select Snapshot Type"), true);
66
67 var vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
68 //hbox.homogeneous = true;
69 append(vbox);
70
71 add_opt_rsync(vbox);
72
73 add_opt_btrfs(vbox);
74
76 }
77
78 private void add_opt_rsync(Gtk.Box hbox){
79
80 var opt = new Gtk.CheckButton.with_label(_("RSYNC"));
81 opt.set_tooltip_markup(_("Create snapshots using RSYNC tool and hard-links"));
82 hbox.append(opt);
83 opt_rsync = opt;
84
85 opt_rsync.toggled.connect(()=>{
86 if (opt_rsync.active){
87 App.btrfs_mode = false;
92 }
93 });
94 }
95
96 private void add_opt_btrfs(Gtk.Box hbox){
97
98 var opt = new Gtk.CheckButton.with_label(_("BTRFS"));
99 opt.set_group(opt_rsync);
100 opt.set_tooltip_markup(_("Create snapshots using BTRFS"));
101 hbox.append(opt);
102 opt_btrfs = opt;
103
104 if (!check_for_btrfs_tools()) {
105 opt.sensitive = false;
106 opt_rsync.active = true;
107 }
108
109 opt_btrfs.toggled.connect(()=>{
110 if (opt_btrfs.active){
111 App.btrfs_mode = true;
112 init_backend();
113 type_changed();
115 }
116 });
117 }
118
119 private bool check_for_btrfs_tools() {
120 try {
121 const string args[] = {"lsblk", "-o", "FSTYPE", null};
122 var proc = new Subprocess.newv(
123 args,
124 SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_SILENCE
125 );
126
127 Bytes stdout;
128 if (proc.communicate(null, null, out stdout, null)) {
129 string output = (string) Bytes.unref_to_data(stdout);
130
131 if (output.contains("btrfs")) {
132 return true;
133 }
134 }
135 }
136 catch (Error e) {
137 log_error (e.message);
138 }
139
140 return false;
141 }
142
143 private void add_description(){
144
145 Gtk.Expander expander = new Gtk.Expander(_("Help"));
146 expander.use_markup = true;
147 expander.margin_top = 12;
148 this.append(expander);
149
150 // scrolled
151 var scrolled = new Gtk.ScrolledWindow();
152 scrolled.margin_top = 6;
153 //scrolled.expand = true;
154 scrolled.set_size_request(-1,200);
155 scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
156 scrolled.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
157 expander.set_child(scrolled);
158
159 var lbl = new Gtk.Label("");
160 lbl.set_use_markup(true);
161 lbl.xalign = (float) 0.0;
162 lbl.yalign = (float) 0.0;
163 lbl.wrap = true;
164 lbl.wrap_mode = Pango.WrapMode.WORD;
165 lbl.margin_start = 12;
166 lbl.margin_end = 12;
167 lbl.margin_top = 12;
168 lbl.margin_bottom = 12;
169 lbl.vexpand = true;
170 scrolled.set_child(lbl);
171
172 lbl_description = lbl;
173 }
174
175 private void update_description(){
176
177 string bullet = "• ";
178
179 if (opt_btrfs.active){
180 string txt = "<b>" + _("BTRFS Snapshots") + "</b>\n\n";
181
182 txt += bullet + _("Snapshots are created using the built-in features of the BTRFS file system.") + "\n\n";
183
184 txt += bullet + _("Snapshots are created and restored instantly. Snapshot creation is an atomic transaction at the file system level.") + "\n\n";
185
186 txt += bullet + _("Snapshots are restored by replacing system subvolumes. Since files are never copied, deleted or overwritten, there is no risk of data loss. The existing system is preserved as a new snapshot after restore.") + "\n\n";
187
188 txt += bullet + _("Snapshots are perfect, byte-for-byte copies of the system. Nothing is excluded.") + "\n\n";
189
190 txt += bullet + _("Snapshots are saved on the same disk from which they are created (system disk). Storage on other disks is not supported. If system disk fails then snapshots stored on it will be lost along with the system.") + "\n\n";
191
192 txt += bullet + _("Size of BTRFS snapshots are initially zero. As system files gradually change with time, data gets written to new data blocks which take up disk space (copy-on-write). Files in the snapshot continue to point to original data blocks.") + "\n\n";
193
194 txt += bullet + _("OS must be installed on a BTRFS partition with Ubuntu-type subvolume layout (@ and @home subvolumes). Other layouts are not supported.") + "\n\n";
195
196 lbl_description.label = txt;
197 }
198 else{
199 string txt = "<b>" + _("RSYNC Snapshots") + "</b>\n\n";
200
201 txt += bullet + _("Snapshots are created by creating copies of system files using rsync, and hard-linking unchanged files from previous snapshot.") + "\n\n";
202
203 txt += bullet + _("All files are copied when first snapshot is created. Subsequent snapshots are incremental. Unchanged files will be hard-linked from the previous snapshot if available.") + "\n\n";
204
205 txt += bullet + _("Snapshots can be saved to any disk formatted with a Linux file system. Saving snapshots to non-system or external disk allows the system to be restored even if system disk is damaged or re-formatted.") + "\n\n";
206
207 txt += bullet + _("Files and directories can be excluded to save disk space.") + "\n\n";
208
209 lbl_description.label = txt;
210 }
211 }
212
217
218 public void refresh(){
219
220 opt_btrfs.active = App.btrfs_mode;
221 type_changed();
223 }
224}
Main App
#define _(s)
static uint64 first_snapshot_size
Definition Main.vala:123
bool btrfs_mode
Definition Main.vala:52
void try_select_default_device_for_backup(Gtk.Window? parent_win)
Definition Main.vala:4110
void add_opt_btrfs(Gtk.Box hbox)
Gtk.CheckButton opt_rsync
Gtk.CheckButton opt_btrfs
SnapshotBackendBox(Gtk.Window _parent_window)
void add_opt_rsync(Gtk.Box hbox)
signal void type_changed()
void log_debug(string message)
void log_error(string message, bool highlight=false, bool is_warning=false)