44 public Gee.ArrayList<
string>
tags;
57 public Gee.HashMap<string,
string>
paths;
66 var f = File.new_for_path(dir_path);
67 var info = f.query_info(
"*", FileQueryInfoFlags.NONE);
70 name = info.get_name();
75 date =
new DateTime.from_unix_utc(0);
76 tags =
new Gee.ArrayList<
string>();
81 paths =
new Gee.HashMap<string,
string>();
142 foreach(
string tag
in tags){
149 foreach(
string tag
in value.split(
" ")){
150 if (!
tags.contains(tag.strip())){
151 tags.add(tag.strip());
160 foreach(
string tag
in tags){
161 str +=
" " + tag.replace(
"ondemand",
"O").replace(
"boot",
"B").replace(
"hourly",
"H").replace(
"daily",
"D").replace(
"weekly",
"W").replace(
"monthly",
"M");
169 if (!
tags.contains(tag.strip())){
170 tags.add(tag.strip());
177 if (
tags.contains(tag.strip())){
178 tags.remove(tag.strip());
185 return tags.contains(tag.strip());
194 string ctl_file =
path +
"/info.json";
196 var f = File.new_for_path(ctl_file);
198 if (f.query_exists()) {
200 var parser =
new Json.Parser();
203 parser.load_from_file(ctl_file);
208 var node = parser.get_root();
209 var config = node.get_object();
211 if ((node ==
null)||(config ==
null)){
217 if (val.length > 0) {
218 DateTime date_utc =
new DateTime.from_unix_utc(int64.parse(val));
219 date = date_utc.to_local();
229 string type = config.get_string_member_with_default(
"type",
"rsync");
231 string extension = (type ==
"btrfs") ?
"@" :
"localhost";
236 if (config.has_member(
"subvolumes")){
238 var subvols = (Json.Object) config.get_object_member(
"subvolumes");
240 foreach(
string subvol_name
in subvols.get_members()){
242 if ((subvol_name !=
"@")&&(subvol_name !=
"@home")){
continue; }
252 var subvolume =
new Subvolume(subvol_name, subvol_path,
"",
repo);
257 foreach(Json.Node jnode in subvols.get_array_member(subvol_name).get_elements()) {
259 string item = jnode.get_string();
262 subvolume.name = item;
265 subvolume.id =
long.parse(item);
268 subvolume.total_bytes = int64.parse(item);
271 subvolume.unshared_bytes = int64.parse(item);
274 subvolume.device_uuid = item.strip();
281 string delete_trigger_file =
path +
"/delete";
295 string list_file =
path +
"/exclude.list";
299 var f = File.new_for_path(list_file);
301 if (f.query_exists()) {
345 string ctl_file =
path +
"/info.json";
346 var f = File.new_for_path(ctl_file);
348 if (f.query_exists()) {
350 var parser =
new Json.Parser();
352 parser.load_from_file(ctl_file);
356 var node = parser.get_root();
357 var config = node.get_object();
359 config.set_string_member(
"tags",
taglist);
361 config.set_string_member(
"live",
live.to_string());
364 var subvols =
new Json.Object();
365 config.set_object_member(
"subvolumes",subvols);
367 Json.Array arr =
new Json.Array();
368 arr.add_string_element(subvol.name);
369 arr.add_string_element(subvol.id.to_string());
370 arr.add_string_element(subvol.total_bytes.to_string());
371 arr.add_string_element(subvol.unshared_bytes.to_string());
372 arr.add_string_element(subvol.device_uuid);
373 subvols.set_array_member(subvol.name,arr);
377 var
json =
new Json.Generator();
380 node.set_object(config);
383 json.to_file(ctl_file);
392 string ctl_file =
path +
"/info.json";
397 string snapshot_path, DateTime dt_created,
string root_uuid,
string distro_full_name,
398 string tag,
string comments, int64 item_count,
bool is_btrfs,
bool is_live,
SnapshotRepo repo,
bool silent =
false){
400 var ctl_path = snapshot_path +
"/info.json";
401 var config =
new Json.Object();
403 config.set_string_member(
"created", dt_created.to_utc().to_unix().to_string());
404 config.set_string_member(
"sys-uuid", root_uuid);
405 config.set_string_member(
"sys-distro", distro_full_name);
406 config.set_string_member(
"app-version", AppVersion);
407 config.set_string_member(
"file_count", item_count.to_string());
408 config.set_string_member(
"tags", tag);
409 config.set_string_member(
"comments", comments);
410 config.set_string_member(
"live", is_live.to_string());
411 config.set_string_member(
"type", (is_btrfs ?
"btrfs" :
"rsync"));
413 var
json =
new Json.Generator();
416 var node =
new Json.Node(NodeType.OBJECT);
417 node.set_object(config);
421 var f = File.new_for_path(ctl_path);
422 if (f.query_exists()){
426 json.to_file(ctl_path);
432 log_msg(
_(
"Created control file") +
": %s".printf(ctl_path));
442 if (en.
options.contains(
"subvol=@")){
451 var list =
new Gee.ArrayList<
Subvolume>();
456 return strcmp(a.name, b.name);
464 public bool remove(
bool wait){
484 log_msg(
string.nfill(78,
'-'));
486 var message =
_(
"Removing") +
" '%s'...".printf(
name);
489 delete_file_task.dest_path =
"%s/".printf(
path);
490 delete_file_task.status_message = message;
501 stdout.printf(
"%6.2f%% %s (%s %s)\r".printf(
508 stdout.printf(
string.nfill(80,
' ') +
"\r");
511 message =
"%s '%s'".printf(
_(
"Removed"),
name);
513 log_msg(
string.nfill(78,
'-'));
521 log_msg(
string.nfill(78,
'-'));
523 var message =
_(
"Removing snapshot") +
": %s".printf(
name);
530 bool ok = subvol.remove();
533 log_msg(
string.nfill(78,
'-'));
542 bool ok = dir_delete(
paths[subvol.name],
true);
545 log_msg(
string.nfill(78,
'-'));
550 if (!dir_delete(
path,
true)){
553 log_msg(
string.nfill(78,
'-'));
558 log_msg(
string.nfill(78,
'-'));
565 string delete_trigger_file =
path +
"/delete";
string??? stat_time_remaining
static LinuxDistro get_dist_info(string root_path)
static int64 first_snapshot_count
Gee.HashMap< string, string > mount_paths
DeleteFileTask delete_file_task
Gee.ArrayList< CryptTabEntry > cryttab_list
static Snapshot write_control_file(string snapshot_path, DateTime dt_created, string root_uuid, string distro_full_name, string tag, string comments, int64 item_count, bool is_btrfs, bool is_live, SnapshotRepo repo, bool silent=false)
void remove_control_file()
string rsync_restore_changes_log_file
string exclude_file_for_restore
Gee.HashMap< string, Subvolume > subvolumes
string exclude_file_for_backup
string rsync_restore_log_file
void remove_tag(string tag)
void update_control_file()
void read_crypttab_file()
string rsync_changes_log_file
Gee.ArrayList< string > exclude_list
Gee.ArrayList< Subvolume > subvolumes_sorted
Gee.ArrayList< string > tags
bool remove_rsync(bool wait)
Gee.HashMap< string, string > paths
Gee.ArrayList< FsTabEntry > fstab_list
Snapshot(string dir_path, bool btrfs_snapshot, SnapshotRepo _repo)
Subvolume(string name, string path, string parent_dev_uuid, SnapshotRepo? parent_repo)
bool file_exists(string file_path)
string? file_read(string file_path)
bool file_write(string file_path, string contents)
string path_combine(string path1, string path2)
bool file_delete(string file_path)
bool dir_exists(string dir_path)
uint64 json_get_uint64(Json.Object jobj, string member, uint64 def_value)
string json_get_string(Json.Object jobj, string member, string def_value)
bool json_get_bool(Json.Object jobj, string member, bool def_value)
void log_error(string message, bool highlight=false, bool is_warning=false)
void log_msg(string message, bool highlight=false)
void sleep(int milliseconds)