diff options
Diffstat (limited to 'rdiff-backup/rdiff_backup/Main.py')
-rw-r--r-- | rdiff-backup/rdiff_backup/Main.py | 75 |
1 files changed, 47 insertions, 28 deletions
diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py index 35624c2..06a1285 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -44,16 +44,17 @@ def parse_cmdlineoptions(arglist): "checkpoint-interval=", "current-time=", "exclude=", "exclude-device-files", "exclude-filelist=", "exclude-filelist-stdin", "exclude-mirror=", - "exclude-regexp=", "force", "include=", - "include-filelist=", "include-filelist-stdin", + "exclude-other-filesystems", "exclude-regexp=", "force", + "include=", "include-filelist=", "include-filelist-stdin", "include-regexp=", "list-increments", "mirror-only", - "no-compression", "no-compression-regexp=", - "no-hard-links", "no-resume", "null-separator", - "parsable-output", "print-statistics", "quoting-char=", - "remote-cmd=", "remote-schema=", "remove-older-than=", - "restore-as-of=", "resume", "resume-window=", "server", - "ssh-no-compression", "terminal-verbosity=", - "test-server", "verbosity", "version", "windows-mode", + "no-compression", "no-compression-regexp=", "no-hard-links", + "no-resume", "null-separator", "parsable-output", + "print-statistics", "quoting-char=", "remote-cmd=", + "remote-schema=", "remove-older-than=", "restore-as-of=", + "restrict=", "restrict-read-only=", "restrict-update-only=", + "resume", "resume-window=", "server", "sleep-ratio=", + "ssh-no-compression", "terminal-verbosity=", "test-server", + "verbosity", "version", "windows-mode", "windows-time-format"]) except getopt.error, e: commandline_error("Bad commandline options: %s" % str(e)) @@ -80,6 +81,8 @@ def parse_cmdlineoptions(arglist): select_files.append(sys.stdin) elif opt == "--exclude-mirror": select_mirror_opts.append(("--exclude", arg)) + elif opt == "--exclude-other-filesystems": + select_opts.append((opt, arg)) elif opt == "--exclude-regexp": select_opts.append((opt, arg)) elif opt == "--force": force = 1 elif opt == "--include": select_opts.append((opt, arg)) @@ -99,23 +102,34 @@ def parse_cmdlineoptions(arglist): elif opt == "--no-hard-links": Globals.set('preserve_hardlinks', 0) elif opt == '--no-resume': Globals.resume = 0 elif opt == "--null-separator": Globals.set("null_separator", 1) - elif opt == "-r" or opt == "--restore-as-of": - restore_timestr, action = arg, "restore-as-of" elif opt == "--parsable-output": Globals.set('parsable_output', 1) elif opt == "--print-statistics": Globals.set('print_statistics', 1) elif opt == "--quoting-char": Globals.set('quoting_char', arg) Globals.set('quoting_enabled', 1) + elif opt == "-r" or opt == "--restore-as-of": + restore_timestr, action = arg, "restore-as-of" elif opt == "--remote-cmd": remote_cmd = arg elif opt == "--remote-schema": remote_schema = arg elif opt == "--remove-older-than": remove_older_than_string = arg action = "remove-older-than" + elif opt == "--restrict": Globals.restrict_path = arg + elif opt == "--restrict-read-only": + Globals.security_level = "read-only" + Globals.restrict_path = arg + elif opt == "--restrict-update-only": + Globals.security_level = "update-only" + Globals.restrict_path = arg elif opt == '--resume': Globals.resume = 1 elif opt == '--resume-window': Globals.set_integer('resume_window', arg) - elif opt == "-s" or opt == "--server": action = "server" + elif opt == "-s" or opt == "--server": + action = "server" + Globals.server = 1 + elif opt == "--sleep-ratio": + Globals.set_float("sleep_ratio", arg, 0, 1, inclusive=0) elif opt == "--ssh-no-compression": Globals.set('ssh_compression', None) elif opt == "--terminal-verbosity": Log.setterm_verbosity(arg) @@ -176,7 +190,6 @@ def misc_setup(rps): os.umask(077) Time.setcurtime(Globals.current_time) FilenameMapping.set_init_quote_vals() - Globals.set("isclient", 1) SetConnections.UpdateGlobal("client_conn", Globals.local_connection) # This is because I originally didn't think compiled regexps @@ -209,7 +222,9 @@ def Main(arglist): """Start everything up!""" parse_cmdlineoptions(arglist) set_action() - rps = SetConnections.InitRPs(args, remote_schema, remote_cmd) + cmdpairs = SetConnections.get_cmd_pairs(args, remote_schema, remote_cmd) + Security.initialize(action, cmdpairs) + rps = map(SetConnections.cmdpair2rp, cmdpairs) misc_setup(rps) take_action(rps) cleanup() @@ -222,6 +237,7 @@ def Mirror(src_rp, dest_rp): # Since no "rdiff-backup-data" dir, use root of destination. SetConnections.UpdateGlobal('rbdir', dest_rp) SetConnections.BackupInitConnections(src_rp.conn, dest_rp.conn) + backup_init_select(src_rp, dest_rp) HighLevel.Mirror(src_rp, dest_rp) def mirror_check_paths(rpin, rpout): @@ -245,7 +261,7 @@ def Backup(rpin, rpout): Time.setprevtime(prevtime) HighLevel.Mirror_and_increment(rpin, rpout, incdir, RSI) else: HighLevel.Mirror(rpin, rpout, incdir, RSI) - backup_touch_curmirror(rpin, rpout) + rpout.conn.Main.backup_touch_curmirror_local(rpin, rpout) def backup_init_select(rpin, rpout): """Create Select objects on source and dest connections""" @@ -307,6 +323,7 @@ may need to use the --exclude option.""" % (rpout.path, rpin.path), 2) def backup_get_mirrorrps(): """Return list of current_mirror rps""" + datadir = Globals.rbdir if not datadir.isdir(): return [] mirrorrps = [datadir.append(fn) for fn in datadir.listdir() if fn.startswith("current_mirror.")] @@ -324,12 +341,14 @@ went wrong during your last backup? Using """ + mirrorrps[-1].path, 2) timestr = mirrorrps[-1].getinctime() return Time.stringtotime(timestr) -def backup_touch_curmirror(rpin, rpout): +def backup_touch_curmirror_local(rpin, rpout): """Make a file like current_mirror.time.data to record time - Also updates rpout so mod times don't get messed up. + Also updates rpout so mod times don't get messed up. This should + be run on the destination connection. """ + datadir = Globals.rbdir map(RPath.delete, backup_get_mirrorrps()) mirrorrp = datadir.append("current_mirror.%s.%s" % (Time.curtimestr, "data")) @@ -337,7 +356,6 @@ def backup_touch_curmirror(rpin, rpout): mirrorrp.touch() RPath.copy_attribs(rpin, rpout) - def restore(src_rp, dest_rp = None): """Main restoring function @@ -474,23 +492,24 @@ def RemoveOlderThan(rootrp): (datadir.path,)) try: time = Time.genstrtotime(remove_older_than_string) - except TimeError, exc: Log.FatalError(str(exc)) + except Time.TimeException, exc: Log.FatalError(str(exc)) timep = Time.timetopretty(time) Log("Deleting increment(s) before %s" % timep, 4) - itimes = [Time.stringtopretty(inc.getinctime()) - for inc in Restore.get_inclist(datadir.append("increments")) - if Time.stringtotime(inc.getinctime()) < time] - - if not itimes: + times_in_secs = map(lambda inc: Time.stringtotime(inc.getinctime()), + Restore.get_inclist(datadir.append("increments"))) + times_in_secs = filter(lambda t: t < time, times_in_secs) + if not times_in_secs: Log.FatalError("No increments older than %s found" % timep) - inc_pretty_time = "\n".join(itimes) - if len(itimes) > 1 and not force: + + times_in_secs.sort() + inc_pretty_time = "\n".join(map(Time.timetopretty, times_in_secs)) + if len(times_in_secs) > 1 and not force: Log.FatalError("Found %d relevant increments, dated:\n%s" "\nIf you want to delete multiple increments in this way, " - "use the --force." % (len(itimes), inc_pretty_time)) + "use the --force." % (len(times_in_secs), inc_pretty_time)) Log("Deleting increment%sat times:\n%s" % - (len(itimes) == 1 and " " or "s ", inc_pretty_time), 3) + (len(times_in_secs) == 1 and " " or "s ", inc_pretty_time), 3) Manage.delete_earlier_than(datadir, time) |