duplicity-team team mailing list archive
-
duplicity-team team
-
Mailing list archive
-
Message #03980
[Merge] lp:~horgh/duplicity/copy-symlink-targets-721599 into lp:duplicity
Will Storey has proposed merging lp:~horgh/duplicity/copy-symlink-targets-721599 into lp:duplicity.
Requested reviews:
duplicity-team (duplicity-team)
For more details, see:
https://code.launchpad.net/~horgh/duplicity/copy-symlink-targets-721599/+merge/312438
Hello,
I recently started using duplicity. I have a directory with many symlinks in it. I was hoping to be able to back the data up while dereferencing the symlinks as that is easier for my use case.
I see there is a bug report requesting such behaviour: https://bugs.launchpad.net/duplicity/+bug/721599
I understand why by design it would be acceptable to not dereference symlinks, but I think it can be useful to provide a flag to do it.
My solution is to add a flag called --copy-links. rsync has a flag with this name so that is why I picked the naem. This is rsync's brief description for it: "--copy-links transform symlink into referent file/dir".
I found that it was sufficient to change the os.lstat() call in path.py to os.stat() when this flag is enabled so that duplicity no longer actually sees symlinks. I did wonder if this is an acceptable place for it though, as path.py seems fairly low level to be worried about globals. But I saw elsewhere in this file and class that we access globals.
I've found that backup and restore behaviour works fine in manually tests with this update. If I run a second backup without the flag given, then the backed up version updates to hold the symlink, and vice versa.
I've not updated any documentation or anything yet as I thought I should get feedback whether this will be acceptable, and whether this approach is okay.
Please let me know if you have any thoughts on this or improvements I can make.
Thank you for your time!
--
Your team duplicity-team is requested to review the proposed merge of lp:~horgh/duplicity/copy-symlink-targets-721599 into lp:duplicity.
=== modified file 'duplicity/commandline.py'
--- duplicity/commandline.py 2016-11-21 17:06:39 +0000
+++ duplicity/commandline.py 2016-12-05 05:25:53 +0000
@@ -290,6 +290,10 @@
parser.add_option("--config-dir", type="file", metavar=_("path"),
help=optparse.SUPPRESS_HELP)
+ # When symlinks are encountered, the item they point to is copied rather than
+ # the symlink.
+ parser.add_option("--copy-links", action="store_true")
+
# for testing -- set current time
parser.add_option("--current-time", type="int",
dest="current_time", help=optparse.SUPPRESS_HELP)
=== modified file 'duplicity/globals.py'
--- duplicity/globals.py 2016-11-21 17:06:39 +0000
+++ duplicity/globals.py 2016-12-05 05:25:53 +0000
@@ -274,6 +274,10 @@
# enable data comparison on verify runs
compare_data = False
+# When symlinks are encountered, the item they point to is copied rather than
+# the symlink.
+copy_links = False
+
# When selected, triggers a dry-run before a full or incremental to compute
# changes, then runs the real operation and keeps track of the real progress
progress = False
=== modified file 'duplicity/path.py'
--- duplicity/path.py 2016-07-24 12:30:45 +0000
+++ duplicity/path.py 2016-12-05 05:25:53 +0000
@@ -517,7 +517,12 @@
def setdata(self):
"""Refresh stat cache"""
try:
- self.stat = os.lstat(self.name)
+ # We may be asked to look at the target of symlinks rather than
+ # the link itself.
+ if globals.copy_links:
+ self.stat = os.stat(self.name)
+ else:
+ self.stat = os.lstat(self.name)
except OSError as e:
err_string = errno.errorcode[e[0]]
if err_string in ["ENOENT", "ENOTDIR", "ELOOP", "ENOTCONN"]:
Follow ups