summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/Rdiff.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/rdiff_backup/Rdiff.py')
-rw-r--r--rdiff-backup/rdiff_backup/Rdiff.py99
1 files changed, 32 insertions, 67 deletions
diff --git a/rdiff-backup/rdiff_backup/Rdiff.py b/rdiff-backup/rdiff_backup/Rdiff.py
index 39dcb8a..7821141 100644
--- a/rdiff-backup/rdiff_backup/Rdiff.py
+++ b/rdiff-backup/rdiff_backup/Rdiff.py
@@ -17,75 +17,53 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
-"""Invoke rdiff utility to make signatures, deltas, or patch
-
-All these operations should be done in a relatively safe manner using
-RobustAction and the like.
-
-"""
+"""Invoke rdiff utility to make signatures, deltas, or patch"""
import os, librsync
-from log import Log
-import robust, TempFile, Globals
+import Globals, log, static, TempFile, rpath
def get_signature(rp):
"""Take signature of rpin file and return in file object"""
- Log("Getting signature of %s" % rp.path, 7)
+ log.Log("Getting signature of %s" % rp.path, 7)
return librsync.SigFile(rp.open("rb"))
def get_delta_sigfileobj(sig_fileobj, rp_new):
"""Like get_delta but signature is in a file object"""
- Log("Getting delta of %s with signature stream" % (rp_new.path,), 7)
+ log.Log("Getting delta of %s with signature stream" % (rp_new.path,), 7)
return librsync.DeltaFile(sig_fileobj, rp_new.open("rb"))
def get_delta_sigrp(rp_signature, rp_new):
"""Take signature rp and new rp, return delta file object"""
- Log("Getting delta of %s with signature %s" %
- (rp_new.path, rp_signature.get_indexpath()), 7)
+ log.Log("Getting delta of %s with signature %s" %
+ (rp_new.path, rp_signature.get_indexpath()), 7)
return librsync.DeltaFile(rp_signature.open("rb"), rp_new.open("rb"))
-def write_delta_action(basis, new, delta, compress = None):
- """Return action writing delta which brings basis to new
-
- If compress is true, the output of rdiff will be gzipped
- before written to delta.
-
- """
- delta_tf = TempFile.new(delta)
- def init(): write_delta(basis, new, delta_tf, compress)
- return robust.make_tf_robustaction(init, delta_tf, delta)
-
def write_delta(basis, new, delta, compress = None):
"""Write rdiff delta which brings basis to new"""
- Log("Writing delta %s from %s -> %s" %
- (basis.path, new.path, delta.path), 7)
+ log.Log("Writing delta %s from %s -> %s" %
+ (basis.path, new.path, delta.path), 7)
sigfile = librsync.SigFile(basis.open("rb"))
deltafile = librsync.DeltaFile(sigfile, new.open("rb"))
delta.write_from_fileobj(deltafile, compress)
-def patch_action(rp_basis, rp_delta, rp_out = None, out_tf = None,
- delta_compressed = None):
- """Return RobustAction which patches rp_basis with rp_delta
+def write_patched_fp(basis_fp, delta_fp, out_fp):
+ """Write patched file to out_fp given input fps. Closes input files"""
+ rpath.copyfileobj(librsync.PatchedFile(basis_fp, delta_fp), out_fp)
+ assert not basis_fp.close() and not delta_fp.close()
- If rp_out is None, put output in rp_basis. Will use TempFile
- out_tf it is specified. If delta_compressed is true, the
- delta file will be decompressed before processing with rdiff.
+def write_via_tempfile(fp, rp):
+ """Write fileobj fp to rp by writing to tempfile and renaming"""
+ tf = TempFile.new(rp)
+ tf.write_from_fileobj(fp)
+ tf.rename(rp)
- """
- if not rp_out: rp_out = rp_basis
- if not out_tf: out_tf = TempFile.new(rp_out)
- def init():
- rp_basis.conn.Rdiff.patch_local(rp_basis, rp_delta,
- out_tf, delta_compressed)
- out_tf.setdata()
- return robust.make_tf_robustaction(init, out_tf, rp_out)
-
-def patch_local(rp_basis, rp_delta, outrp, delta_compressed = None):
- """Patch routine that must be run on rp_basis.conn
+def patch_local(rp_basis, rp_delta, outrp = None, delta_compressed = None):
+ """Patch routine that must be run locally, writes to outrp
- This is because librsync may need to seek() around in rp_basis,
- and so needs a real file. Other rpaths can be remote.
+ This should be run local to rp_basis because it needs to be a real
+ file (librsync may need to seek around in it). If outrp is None,
+ patch rp_basis instead.
"""
assert rp_basis.conn is Globals.local_connection
@@ -94,32 +72,19 @@ def patch_local(rp_basis, rp_delta, outrp, delta_compressed = None):
sigfile = librsync.SigFile(rp_basis.open("rb"))
patchfile = librsync.PatchedFile(rp_basis.open("rb"), deltafile)
- outrp.write_from_fileobj(patchfile)
-
-def patch_with_attribs_action(rp_basis, rp_delta, rp_out = None):
- """Like patch_action, but also transfers attributs from rp_delta"""
- if not rp_out: rp_out = rp_basis
- tf = TempFile.new(rp_out)
- return robust.chain_nested(patch_action(rp_basis, rp_delta, rp_out, tf),
- robust.copy_attribs_action(rp_delta, tf))
-
-def copy_action(rpin, rpout):
- """Use rdiff to copy rpin to rpout, conserving bandwidth"""
- if not rpin.isreg() or not rpout.isreg() or rpin.conn is rpout.conn:
- # rdiff not applicable, fallback to regular copying
- return robust.copy_action(rpin, rpout)
-
- Log("Rdiff copying %s to %s" % (rpin.path, rpout.path), 6)
- out_tf = TempFile.new(rpout)
- def init(): rpout.conn.Rdiff.copy_local(rpin, rpout, out_tf)
- return robust.make_tf_robustaction(init, out_tf, rpout)
-
-def copy_local(rpin, rpout, rpnew):
+
+ if outrp: outrp.write_from_fileobj(patchfile)
+ else: write_via_tempfile(patchfile, rp_basis)
+
+def copy_local(rpin, rpout, rpnew = None):
"""Write rpnew == rpin using rpout as basis. rpout and rpnew local"""
- assert rpnew.conn is rpout.conn is Globals.local_connection
+ assert rpout.conn is Globals.local_connection
sigfile = librsync.SigFile(rpout.open("rb"))
deltafile = rpin.conn.librsync.DeltaFile(sigfile, rpin.open("rb"))
- rpnew.write_from_fileobj(librsync.PatchedFile(rpout.open("rb"), deltafile))
+ patched_file = librsync.PatchedFile(rpout.open("rb"), deltafile)
+
+ if rpnew: rpnew.write_from_fileobj(patched_file)
+ else: write_via_tempfile(patched_file, rpout)