Merge lp:~dernils/duplicity/robust-dropbox-backend into lp:~duplicity-team/duplicity/0.8-series

Proposed by nils
Status: Merged
Approved by: Kenneth Loafman
Approved revision: 1158
Merge reported by: Kenneth Loafman
Merged at revision: not available
Proposed branch: lp:~dernils/duplicity/robust-dropbox-backend
Merge into: lp:~duplicity-team/duplicity/0.8-series
Diff against target: 162 lines (+47/-3)
5 files modified
bin/duplicity.1 (+6/-0)
duplicity/backend.py (+2/-2)
duplicity/backends/dpbxbackend.py (+31/-1)
duplicity/commandline.py (+5/-0)
duplicity/globals.py (+3/-0)
To merge this branch: bzr merge lp:~dernils/duplicity/robust-dropbox-backend
Reviewer Review Type Date Requested Status
edso Approve
Review via email: mp+311073@code.launchpad.net

Description of the change

Added new command line option --backend-retry-delay that allows to determine the time that duplicity sleeps before retrying after an error has occured.

Added some robustness to dpbxbackend.py that ensures re-authentication happens in case that a socket is changed (e.g. due to a forced reconnect of a dynamic internet connection).

To post a comment you must log in.
Revision history for this message
edso (ed.so) wrote :

hey Nils,

looks good, but please add the new parameter to the man page /bin/duplicity.1 as well. no use to have a parameter that is not properly documented.

thanks.. ede

review: Needs Fixing
1157. By nils

Added --backend-retry-delay to the manpage

Revision history for this message
nils (dernils) wrote :

Good point!
[x] done

Revision history for this message
edso (ed.so) wrote :

close, but your missing the parameter eg.

.BI "--backend-retry-delay " number

..ede

review: Needs Fixing
1158. By nils

minor fix in manpage

Revision history for this message
nils (dernils) wrote :

:-)
fixed

Revision history for this message
edso (ed.so) :
review: Approve
Revision history for this message
Kenneth Loafman (kenneth-loafman) wrote :

This had already been merged. LP did not mark it.

Revision history for this message
nils (dernils) wrote :

Thanks for letting me know. I was already a little bit surprised ;-)

Kenneth Loafman <email address hidden> schrieb am Sa., 29. Apr. 2017 um
14:50 Uhr:

> This had already been merged. LP did not mark it.
>
> --
>
> https://code.launchpad.net/~dernils/duplicity/robust-dropbox-backend/+merge/311073
> You are the owner of lp:~dernils/duplicity/robust-dropbox-backend.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/duplicity.1'
2--- bin/duplicity.1 2016-11-01 19:26:03 +0000
3+++ bin/duplicity.1 2016-11-17 11:36:06 +0000
4@@ -313,6 +313,12 @@
5 enough storage space is required to store two volumes.
6
7 .TP
8+.BI "--backend-retry-delay " number
9+Specifies the number of seconds that duplicity waits after an error has
10+occured before attempting to repeat the operation.
11+
12+
13+.TP
14 .BI "--cf-backend " backend
15 Allows the explicit selection of a cloudfiles backend. Defaults to
16 .BR pyrax .
17
18=== modified file 'duplicity/backend.py'
19--- duplicity/backend.py 2016-06-28 21:03:46 +0000
20+++ duplicity/backend.py 2016-11-17 11:36:06 +0000
21@@ -395,9 +395,9 @@
22 % (n, e.__class__.__name__, util.uexc(e)))
23 if not at_end:
24 if isinstance(e, TemporaryLoadException):
25- time.sleep(90) # wait longer before trying again
26+ time.sleep(3*globals.backend_retry_delay) # wait longer before trying again
27 else:
28- time.sleep(30) # wait a bit before trying again
29+ time.sleep(globals.backend_retry_delay) # wait a bit before trying again
30 if hasattr(self.backend, '_retry_cleanup'):
31 self.backend._retry_cleanup()
32
33
34=== modified file 'duplicity/backends/dpbxbackend.py'
35--- duplicity/backends/dpbxbackend.py 2016-06-28 21:03:46 +0000
36+++ duplicity/backends/dpbxbackend.py 2016-11-17 11:36:06 +0000
37@@ -98,7 +98,14 @@
38 self.auth_flow = None
39
40 self.login()
41-
42+ def user_authenticated(self):
43+ try:
44+ account = self.api_client.users_get_current_account()
45+ log.Debug("User authenticated as ,%s" % account)
46+ return True
47+ except:
48+ log.Debug('User not authenticated')
49+ return False
50 def load_access_token(self):
51 return os.environ.get('DPBX_ACCESS_TOKEN', None)
52
53@@ -196,10 +203,14 @@
54 (res_metadata.size, file_size))
55
56 def put_file_small(self, source_path, remote_path):
57+ if not self.user_authenticated():
58+ self.login()
59+
60 file_size = os.path.getsize(source_path.name)
61 f = source_path.open('rb')
62 try:
63 log.Debug('dpbx,files_upload(%s, [%d bytes])' % (remote_path, file_size))
64+
65 res_metadata = self.api_client.files_upload(f, remote_path,
66 mode=WriteMode.overwrite,
67 autorename=False,
68@@ -212,6 +223,9 @@
69 f.close()
70
71 def put_file_chunked(self, source_path, remote_path):
72+ if not self.user_authenticated():
73+ self.login()
74+
75 file_size = os.path.getsize(source_path.name)
76 f = source_path.open('rb')
77 try:
78@@ -295,6 +309,10 @@
79 log.Debug('dpbx,files_upload_session_append: %s' % e)
80
81 retry_number -= 1
82+
83+ if not self.user_authenticated():
84+ self.login()
85+
86 if retry_number == 0:
87 raise
88
89@@ -320,6 +338,9 @@
90
91 @command()
92 def _get(self, remote_filename, local_path):
93+ if not self.user_authenticated():
94+ self.login()
95+
96 remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/'))
97 remote_path = '/' + os.path.join(remote_dir, remote_filename).rstrip()
98
99@@ -353,6 +374,8 @@
100 @command()
101 def _list(self):
102 # Do a long listing to avoid connection reset
103+ if not self.user_authenticated():
104+ self.login()
105 remote_dir = '/' + urllib.unquote(self.parsed_url.path.lstrip('/')).rstrip()
106
107 log.Debug('dpbx.files_list_folder(%s)' % remote_dir)
108@@ -373,6 +396,9 @@
109
110 @command()
111 def _delete(self, filename):
112+ if not self.user_authenticated():
113+ self.login()
114+
115 remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/'))
116 remote_path = '/' + os.path.join(remote_dir, filename).rstrip()
117
118@@ -390,6 +416,8 @@
119
120 @command()
121 def _query(self, filename):
122+ if not self.user_authenticated():
123+ self.login()
124 remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/'))
125 remote_path = '/' + os.path.join(remote_dir, filename).rstrip()
126
127@@ -399,6 +427,8 @@
128 return {'size': info.size}
129
130 def check_renamed_files(self, file_list):
131+ if not self.user_authenticated():
132+ self.login()
133 bad_list = [x for x in file_list if DPBX_AUTORENAMED_FILE_RE.search(x) is not None]
134 if len(bad_list) == 0:
135 return
136
137=== modified file 'duplicity/commandline.py'
138--- duplicity/commandline.py 2016-03-01 15:38:58 +0000
139+++ duplicity/commandline.py 2016-11-17 11:36:06 +0000
140@@ -624,6 +624,11 @@
141 metavar=_("path"), dest="file_changed",
142 callback=lambda o, s, v, p: setattr(p.values, "file_changed", v.rstrip('/')))
143
144+ # delay time before next try after a failure of a backend operation
145+ # TRANSL: Used in usage help. Example:
146+ # --backend-retry-delay <seconds>
147+ parser.add_option("--backend-retry-delay", type="int", metavar=_("seconds"))
148+
149 # parse the options
150 (options, args) = parser.parse_args()
151
152
153=== modified file 'duplicity/globals.py'
154--- duplicity/globals.py 2016-06-12 13:13:57 +0000
155+++ duplicity/globals.py 2016-11-17 11:36:06 +0000
156@@ -293,3 +293,6 @@
157
158 # If set, collect only the file status, not the whole root.
159 file_changed = None
160+
161+# delay (in seconds) before next operation after failure
162+backend_retry_delay = 30

Subscribers

People subscribed via source and target branches