1 |
# Copyright 2002, 2003, 2004 Ben Escoto |
# Copyright 2002, 2003, 2004, 2005 Ben Escoto |
2 |
# |
# |
3 |
# This file is part of rdiff-backup. |
# This file is part of rdiff-backup. |
4 |
# |
# |
24 |
from log import Log, LoggerError, ErrorLog |
from log import Log, LoggerError, ErrorLog |
25 |
import Globals, Time, SetConnections, selection, robust, rpath, \ |
import Globals, Time, SetConnections, selection, robust, rpath, \ |
26 |
manage, backup, connection, restore, FilenameMapping, \ |
manage, backup, connection, restore, FilenameMapping, \ |
27 |
Security, Hardlink, regress, C, fs_abilities, statistics |
Security, Hardlink, regress, C, fs_abilities, statistics, compare |
28 |
|
|
29 |
|
|
30 |
action = None |
action = None |
59 |
|
|
60 |
try: optlist, args = getopt.getopt(arglist, "blr:sv:V", |
try: optlist, args = getopt.getopt(arglist, "blr:sv:V", |
61 |
["backup-mode", "calculate-average", "check-destination-dir", |
["backup-mode", "calculate-average", "check-destination-dir", |
62 |
"compare", "compare-at-time=", "create-full-path", |
"compare", "compare-at-time=", "compare-hash", |
63 |
"current-time=", "exclude=", "exclude-device-files", |
"compare-hash-at-time=", "compare-full", "compare-full-at-time=", |
64 |
"exclude-fifos", "exclude-filelist=", |
"create-full-path", "current-time=", "exclude=", |
65 |
|
"exclude-device-files", "exclude-fifos", "exclude-filelist=", |
66 |
"exclude-symbolic-links", "exclude-sockets", |
"exclude-symbolic-links", "exclude-sockets", |
67 |
"exclude-filelist-stdin", "exclude-globbing-filelist=", |
"exclude-filelist-stdin", "exclude-globbing-filelist=", |
68 |
"exclude-globbing-filelist-stdin", "exclude-mirror=", |
"exclude-globbing-filelist-stdin", "exclude-mirror=", |
92 |
elif opt == "--calculate-average": action = "calculate-average" |
elif opt == "--calculate-average": action = "calculate-average" |
93 |
elif opt == "--carbonfile": Globals.set("carbonfile_active", 1) |
elif opt == "--carbonfile": Globals.set("carbonfile_active", 1) |
94 |
elif opt == "--check-destination-dir": action = "check-destination-dir" |
elif opt == "--check-destination-dir": action = "check-destination-dir" |
95 |
elif opt == "--compare" or opt == "--compare-at-time": |
elif opt in ("--compare", "--compare-at-time", |
96 |
action = "compare" |
"--compare-hash", "--compare-hash-at-time", |
97 |
if opt == "--compare": restore_timestr = "now" |
"--compare-full", "--compare-full-at-time"): |
98 |
else: restore_timestr = arg |
if opt[-8:] == "-at-time": restore_timestr, opt = arg, opt[:-8] |
99 |
|
else: restore_timestr = "now" |
100 |
|
action = opt[2:] |
101 |
elif opt == "--create-full-path": create_full_path = 1 |
elif opt == "--create-full-path": create_full_path = 1 |
102 |
elif opt == "--current-time": |
elif opt == "--current-time": |
103 |
Globals.set_integer('current_time', arg) |
Globals.set_integer('current_time', arg) |
203 |
1: ['list-increments', 'list-increment-sizes', |
1: ['list-increments', 'list-increment-sizes', |
204 |
'remove-older-than', 'list-at-time', |
'remove-older-than', 'list-at-time', |
205 |
'list-changed-since', 'check-destination-dir'], |
'list-changed-since', 'check-destination-dir'], |
206 |
2: ['backup', 'restore', 'restore-as-of', 'compare']} |
2: ['backup', 'restore', 'restore-as-of', |
207 |
|
'compare', 'compare-hash', 'compare-full']} |
208 |
l = len(args) |
l = len(args) |
209 |
if l == 0 and action not in arg_action_dict[l]: |
if l == 0 and action not in arg_action_dict[l]: |
210 |
commandline_error("No arguments given") |
commandline_error("No arguments given") |
267 |
elif action == "backup": Backup(rps[0], rps[1]) |
elif action == "backup": Backup(rps[0], rps[1]) |
268 |
elif action == "calculate-average": CalculateAverage(rps) |
elif action == "calculate-average": CalculateAverage(rps) |
269 |
elif action == "check-destination-dir": CheckDest(rps[0]) |
elif action == "check-destination-dir": CheckDest(rps[0]) |
270 |
elif action == "compare": Compare(*rps) |
elif action.startswith("compare"): Compare(action, rps[0], rps[1]) |
271 |
elif action == "list-at-time": ListAtTime(rps[0]) |
elif action == "list-at-time": ListAtTime(rps[0]) |
272 |
elif action == "list-changed-since": ListChangedSince(rps[0]) |
elif action == "list-changed-since": ListChangedSince(rps[0]) |
273 |
elif action == "list-increments": ListIncrements(rps[0]) |
elif action == "list-increments": ListIncrements(rps[0]) |
596 |
|
|
597 |
def ListIncrements(rp): |
def ListIncrements(rp): |
598 |
"""Print out a summary of the increments and their times""" |
"""Print out a summary of the increments and their times""" |
599 |
rp = require_root_set(rp) |
rp = require_root_set(rp, 1) |
600 |
restore_check_backup_dir(restore_root) |
restore_check_backup_dir(restore_root) |
601 |
mirror_rp = restore_root.new_index(restore_index) |
mirror_rp = restore_root.new_index(restore_index) |
602 |
inc_rpath = Globals.rbdir.append_path('increments', restore_index) |
inc_rpath = Globals.rbdir.append_path('increments', restore_index) |
606 |
print manage.describe_incs_parsable(incs, mirror_time, mirror_rp) |
print manage.describe_incs_parsable(incs, mirror_time, mirror_rp) |
607 |
else: print manage.describe_incs_human(incs, mirror_time, mirror_rp) |
else: print manage.describe_incs_human(incs, mirror_time, mirror_rp) |
608 |
|
|
609 |
def require_root_set(rp): |
def require_root_set(rp, read_only): |
610 |
"""Make sure rp is or is in a valid rdiff-backup dest directory. |
"""Make sure rp is or is in a valid rdiff-backup dest directory. |
611 |
|
|
612 |
Also initializes fs_abilities and quoting and return quoted rp if |
Also initializes fs_abilities (read or read/write) and quoting and |
613 |
necessary. |
return quoted rp if necessary. |
614 |
|
|
615 |
""" |
""" |
616 |
if not restore_set_root(rp): |
if not restore_set_root(rp): |
617 |
Log.FatalError(("Bad directory %s.\n" % (rp.path,)) + |
Log.FatalError(("Bad directory %s.\n" % (rp.path,)) + |
618 |
"It doesn't appear to be an rdiff-backup destination dir") |
"It doesn't appear to be an rdiff-backup destination dir") |
619 |
Globals.rbdir.conn.fs_abilities.single_set_globals(Globals.rbdir) |
Globals.rbdir.conn.fs_abilities.single_set_globals(Globals.rbdir, |
620 |
|
read_only) |
621 |
if Globals.chars_to_quote: return restore_init_quoting(rp) |
if Globals.chars_to_quote: return restore_init_quoting(rp) |
622 |
else: return rp |
else: return rp |
623 |
|
|
624 |
|
|
625 |
def ListIncrementSizes(rp): |
def ListIncrementSizes(rp): |
626 |
"""Print out a summary of the increments """ |
"""Print out a summary of the increments """ |
627 |
rp = require_root_set(rp) |
rp = require_root_set(rp, 1) |
628 |
print manage.ListIncrementSizes(restore_root, restore_index) |
print manage.ListIncrementSizes(restore_root, restore_index) |
629 |
|
|
630 |
|
|
639 |
|
|
640 |
def RemoveOlderThan(rootrp): |
def RemoveOlderThan(rootrp): |
641 |
"""Remove all increment files older than a certain time""" |
"""Remove all increment files older than a certain time""" |
642 |
rootrp = require_root_set(rootrp) |
rootrp = require_root_set(rootrp, 0) |
643 |
rot_require_rbdir_base(rootrp) |
rot_require_rbdir_base(rootrp) |
644 |
try: time = Time.genstrtotime(remove_older_than_string) |
try: time = Time.genstrtotime(remove_older_than_string) |
645 |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
675 |
|
|
676 |
def ListChangedSince(rp): |
def ListChangedSince(rp): |
677 |
"""List all the files under rp that have changed since restoretime""" |
"""List all the files under rp that have changed since restoretime""" |
678 |
rp = require_root_set(rp) |
rp = require_root_set(rp, 1) |
679 |
try: rest_time = Time.genstrtotime(restore_timestr) |
try: rest_time = Time.genstrtotime(restore_timestr) |
680 |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
681 |
mirror_rp = restore_root.new_index(restore_index) |
mirror_rp = restore_root.new_index(restore_index) |
687 |
|
|
688 |
def ListAtTime(rp): |
def ListAtTime(rp): |
689 |
"""List files in archive under rp that are present at restoretime""" |
"""List files in archive under rp that are present at restoretime""" |
690 |
rp = require_root_set(rp) |
rp = require_root_set(rp, 1) |
691 |
try: rest_time = Time.genstrtotime(restore_timestr) |
try: rest_time = Time.genstrtotime(restore_timestr) |
692 |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
693 |
mirror_rp = restore_root.new_index(restore_index) |
mirror_rp = restore_root.new_index(restore_index) |
696 |
print rorp.get_indexpath() |
print rorp.get_indexpath() |
697 |
|
|
698 |
|
|
699 |
def Compare(src_rp, dest_rp, compare_time = None): |
def Compare(compare_type, src_rp, dest_rp, compare_time = None): |
700 |
"""Compare metadata in src_rp with metadata of backup session |
"""Compare metadata in src_rp with metadata of backup session |
701 |
|
|
702 |
Prints to stdout whenever a file in the src_rp directory has |
Prints to stdout whenever a file in the src_rp directory has |
707 |
|
|
708 |
""" |
""" |
709 |
global return_val |
global return_val |
710 |
dest_rp = require_root_set(dest_rp) |
dest_rp = require_root_set(dest_rp, 1) |
711 |
if not compare_time: |
if not compare_time: |
712 |
try: compare_time = Time.genstrtotime(restore_timestr) |
try: compare_time = Time.genstrtotime(restore_timestr) |
713 |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
except Time.TimeException, exc: Log.FatalError(str(exc)) |
714 |
|
|
715 |
mirror_rp = restore_root.new_index(restore_index) |
mirror_rp = restore_root.new_index(restore_index) |
716 |
inc_rp = mirror_rp.append_path("increments", restore_index) |
inc_rp = Globals.rbdir.append_path("increments", restore_index) |
717 |
backup_set_select(src_rp) # Sets source rorp iterator |
backup_set_select(src_rp) # Sets source rorp iterator |
718 |
src_iter = src_rp.conn.backup.SourceStruct.get_source_select() |
if compare_type == "compare": compare_func = compare.Compare |
719 |
return_val = restore.Compare(src_iter, mirror_rp, inc_rp, compare_time) |
elif compare_type == "compare-hash": compare_func = compare.Compare_hash |
720 |
|
else: |
721 |
|
assert compare_type == "compare-full", compare_type |
722 |
|
compare_func = compare.Compare_full |
723 |
|
return_val = compare_func(src_rp, mirror_rp, inc_rp, compare_time) |
724 |
|
|
725 |
|
|
726 |
def CheckDest(dest_rp): |
def CheckDest(dest_rp): |