Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/sync/modules/rsync/
Date: Mon, 05 Feb 2018 18:44:51
Message-Id: 1517856098.56affbecaa1e5faecdf5176a574aa97d098d486b.mgorny@gentoo
1 commit: 56affbecaa1e5faecdf5176a574aa97d098d486b
2 Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
3 AuthorDate: Fri Feb 2 19:32:24 2018 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Mon Feb 5 18:41:38 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=56affbec
7
8 rsync: Pre-indent the try-finally block for gemato key scope
9
10 Reviewed-by: Zac Medico <zmedico <AT> gentoo.org>
11
12 pym/portage/sync/modules/rsync/rsync.py | 467 ++++++++++++++++----------------
13 1 file changed, 235 insertions(+), 232 deletions(-)
14
15 diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py
16 index e6e218868..5c0b53f9e 100644
17 --- a/pym/portage/sync/modules/rsync/rsync.py
18 +++ b/pym/portage/sync/modules/rsync/rsync.py
19 @@ -110,247 +110,250 @@ class RsyncSync(NewBase):
20 level=logging.WARNING, noiselevel=-1)
21 self.verify_jobs = None
22
23 - # Real local timestamp file.
24 - self.servertimestampfile = os.path.join(
25 - self.repo.location, "metadata", "timestamp.chk")
26 -
27 - content = portage.util.grabfile(self.servertimestampfile)
28 - timestamp = 0
29 - if content:
30 - try:
31 - timestamp = time.mktime(time.strptime(content[0],
32 - TIMESTAMP_FORMAT))
33 - except (OverflowError, ValueError):
34 - pass
35 - del content
36 -
37 - try:
38 - self.rsync_initial_timeout = \
39 - int(self.settings.get("PORTAGE_RSYNC_INITIAL_TIMEOUT", "15"))
40 - except ValueError:
41 - self.rsync_initial_timeout = 15
42 -
43 - try:
44 - maxretries=int(self.settings["PORTAGE_RSYNC_RETRIES"])
45 - except SystemExit as e:
46 - raise # Needed else can't exit
47 - except:
48 - maxretries = -1 #default number of retries
49 -
50 - if syncuri.startswith("file://"):
51 - self.proto = "file"
52 - dosyncuri = syncuri[7:]
53 - unchanged, is_synced, exitcode, updatecache_flg = self._do_rsync(
54 - dosyncuri, timestamp, opts)
55 - self._process_exitcode(exitcode, dosyncuri, out, 1)
56 - return (exitcode, updatecache_flg)
57 -
58 - retries=0
59 try:
60 - self.proto, user_name, hostname, port = re.split(
61 - r"(rsync|ssh)://([^:/]+@)?(\[[:\da-fA-F]*\]|[^:/]*)(:[0-9]+)?",
62 - syncuri, maxsplit=4)[1:5]
63 - except ValueError:
64 - writemsg_level("!!! sync-uri is invalid: %s\n" % syncuri,
65 - noiselevel=-1, level=logging.ERROR)
66 - return (1, False)
67 + # Real local timestamp file.
68 + self.servertimestampfile = os.path.join(
69 + self.repo.location, "metadata", "timestamp.chk")
70
71 - self.ssh_opts = self.settings.get("PORTAGE_SSH_OPTS")
72 + content = portage.util.grabfile(self.servertimestampfile)
73 + timestamp = 0
74 + if content:
75 + try:
76 + timestamp = time.mktime(time.strptime(content[0],
77 + TIMESTAMP_FORMAT))
78 + except (OverflowError, ValueError):
79 + pass
80 + del content
81
82 - if port is None:
83 - port=""
84 - if user_name is None:
85 - user_name=""
86 - if re.match(r"^\[[:\da-fA-F]*\]$", hostname) is None:
87 - getaddrinfo_host = hostname
88 - else:
89 - # getaddrinfo needs the brackets stripped
90 - getaddrinfo_host = hostname[1:-1]
91 - updatecache_flg = False
92 - all_rsync_opts = set(self.rsync_opts)
93 - all_rsync_opts.update(self.extra_rsync_opts)
94 + try:
95 + self.rsync_initial_timeout = \
96 + int(self.settings.get("PORTAGE_RSYNC_INITIAL_TIMEOUT", "15"))
97 + except ValueError:
98 + self.rsync_initial_timeout = 15
99
100 - family = socket.AF_UNSPEC
101 - if "-4" in all_rsync_opts or "--ipv4" in all_rsync_opts:
102 - family = socket.AF_INET
103 - elif socket.has_ipv6 and \
104 - ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
105 - family = socket.AF_INET6
106 + try:
107 + maxretries=int(self.settings["PORTAGE_RSYNC_RETRIES"])
108 + except SystemExit as e:
109 + raise # Needed else can't exit
110 + except:
111 + maxretries = -1 #default number of retries
112 +
113 + if syncuri.startswith("file://"):
114 + self.proto = "file"
115 + dosyncuri = syncuri[7:]
116 + unchanged, is_synced, exitcode, updatecache_flg = self._do_rsync(
117 + dosyncuri, timestamp, opts)
118 + self._process_exitcode(exitcode, dosyncuri, out, 1)
119 + return (exitcode, updatecache_flg)
120 +
121 + retries=0
122 + try:
123 + self.proto, user_name, hostname, port = re.split(
124 + r"(rsync|ssh)://([^:/]+@)?(\[[:\da-fA-F]*\]|[^:/]*)(:[0-9]+)?",
125 + syncuri, maxsplit=4)[1:5]
126 + except ValueError:
127 + writemsg_level("!!! sync-uri is invalid: %s\n" % syncuri,
128 + noiselevel=-1, level=logging.ERROR)
129 + return (1, False)
130
131 - addrinfos = None
132 - uris = []
133 + self.ssh_opts = self.settings.get("PORTAGE_SSH_OPTS")
134
135 - try:
136 - addrinfos = getaddrinfo_validate(
137 - socket.getaddrinfo(getaddrinfo_host, None,
138 - family, socket.SOCK_STREAM))
139 - except socket.error as e:
140 - writemsg_level(
141 - "!!! getaddrinfo failed for '%s': %s\n"
142 - % (_unicode_decode(hostname), _unicode(e)),
143 - noiselevel=-1, level=logging.ERROR)
144 -
145 - if addrinfos:
146 -
147 - AF_INET = socket.AF_INET
148 - AF_INET6 = None
149 - if socket.has_ipv6:
150 - AF_INET6 = socket.AF_INET6
151 -
152 - ips_v4 = []
153 - ips_v6 = []
154 -
155 - for addrinfo in addrinfos:
156 - if addrinfo[0] == AF_INET:
157 - ips_v4.append("%s" % addrinfo[4][0])
158 - elif AF_INET6 is not None and addrinfo[0] == AF_INET6:
159 - # IPv6 addresses need to be enclosed in square brackets
160 - ips_v6.append("[%s]" % addrinfo[4][0])
161 -
162 - random.shuffle(ips_v4)
163 - random.shuffle(ips_v6)
164 -
165 - # Give priority to the address family that
166 - # getaddrinfo() returned first.
167 - if AF_INET6 is not None and addrinfos and \
168 - addrinfos[0][0] == AF_INET6:
169 - ips = ips_v6 + ips_v4
170 - else:
171 - ips = ips_v4 + ips_v6
172 -
173 - for ip in ips:
174 - uris.append(syncuri.replace(
175 - "//" + user_name + hostname + port + "/",
176 - "//" + user_name + ip + port + "/", 1))
177 -
178 - if not uris:
179 - # With some configurations we need to use the plain hostname
180 - # rather than try to resolve the ip addresses (bug #340817).
181 - uris.append(syncuri)
182 -
183 - # reverse, for use with pop()
184 - uris.reverse()
185 - uris_orig = uris[:]
186 -
187 - effective_maxretries = maxretries
188 - if effective_maxretries < 0:
189 - effective_maxretries = len(uris) - 1
190 -
191 - local_state_unchanged = True
192 - while (1):
193 - if uris:
194 - dosyncuri = uris.pop()
195 - elif maxretries < 0 or retries > maxretries:
196 - writemsg("!!! Exhausted addresses for %s\n"
197 - % _unicode_decode(hostname), noiselevel=-1)
198 - return (1, False)
199 - else:
200 - uris.extend(uris_orig)
201 - dosyncuri = uris.pop()
202 -
203 - if (retries==0):
204 - if "--ask" in opts:
205 - uq = UserQuery(opts)
206 - if uq.query("Do you want to sync your Portage tree " + \
207 - "with the mirror at\n" + blue(dosyncuri) + bold("?"),
208 - enter_invalid) == "No":
209 - print()
210 - print("Quitting.")
211 - print()
212 - sys.exit(128 + signal.SIGINT)
213 - self.logger(self.xterm_titles,
214 - ">>> Starting rsync with " + dosyncuri)
215 - if "--quiet" not in opts:
216 - print(">>> Starting rsync with "+dosyncuri+"...")
217 - else:
218 - self.logger(self.xterm_titles,
219 - ">>> Starting retry %d of %d with %s" % \
220 - (retries, effective_maxretries, dosyncuri))
221 - writemsg_stdout(
222 - "\n\n>>> Starting retry %d of %d with %s\n" % \
223 - (retries, effective_maxretries, dosyncuri), noiselevel=-1)
224 -
225 - if dosyncuri.startswith('ssh://'):
226 - dosyncuri = dosyncuri[6:].replace('/', ':/', 1)
227 -
228 - unchanged, is_synced, exitcode, updatecache_flg = self._do_rsync(
229 - dosyncuri, timestamp, opts)
230 - if not unchanged:
231 - local_state_unchanged = False
232 - if is_synced:
233 - break
234 -
235 - retries=retries+1
236 -
237 - if maxretries < 0 or retries <= maxretries:
238 - print(">>> Retrying...")
239 - else:
240 - # over retries
241 - # exit loop
242 - exitcode = EXCEEDED_MAX_RETRIES
243 - break
244 - self._process_exitcode(exitcode, dosyncuri, out, maxretries)
245 -
246 - # if synced successfully, verify now
247 - if exitcode == 0 and self.verify_metamanifest:
248 - if gemato is None:
249 - writemsg_level("!!! Unable to verify: gemato-11.0+ is required\n",
250 - level=logging.ERROR, noiselevel=-1)
251 - exitcode = 127
252 + if port is None:
253 + port=""
254 + if user_name is None:
255 + user_name=""
256 + if re.match(r"^\[[:\da-fA-F]*\]$", hostname) is None:
257 + getaddrinfo_host = hostname
258 else:
259 - # Use isolated environment if key is specified,
260 - # system environment otherwise
261 - if self.repo.sync_openpgp_key_path is not None:
262 - openpgp_env_cls = gemato.openpgp.OpenPGPEnvironment
263 + # getaddrinfo needs the brackets stripped
264 + getaddrinfo_host = hostname[1:-1]
265 + updatecache_flg = False
266 + all_rsync_opts = set(self.rsync_opts)
267 + all_rsync_opts.update(self.extra_rsync_opts)
268 +
269 + family = socket.AF_UNSPEC
270 + if "-4" in all_rsync_opts or "--ipv4" in all_rsync_opts:
271 + family = socket.AF_INET
272 + elif socket.has_ipv6 and \
273 + ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
274 + family = socket.AF_INET6
275 +
276 + addrinfos = None
277 + uris = []
278 +
279 + try:
280 + addrinfos = getaddrinfo_validate(
281 + socket.getaddrinfo(getaddrinfo_host, None,
282 + family, socket.SOCK_STREAM))
283 + except socket.error as e:
284 + writemsg_level(
285 + "!!! getaddrinfo failed for '%s': %s\n"
286 + % (_unicode_decode(hostname), _unicode(e)),
287 + noiselevel=-1, level=logging.ERROR)
288 +
289 + if addrinfos:
290 +
291 + AF_INET = socket.AF_INET
292 + AF_INET6 = None
293 + if socket.has_ipv6:
294 + AF_INET6 = socket.AF_INET6
295 +
296 + ips_v4 = []
297 + ips_v6 = []
298 +
299 + for addrinfo in addrinfos:
300 + if addrinfo[0] == AF_INET:
301 + ips_v4.append("%s" % addrinfo[4][0])
302 + elif AF_INET6 is not None and addrinfo[0] == AF_INET6:
303 + # IPv6 addresses need to be enclosed in square brackets
304 + ips_v6.append("[%s]" % addrinfo[4][0])
305 +
306 + random.shuffle(ips_v4)
307 + random.shuffle(ips_v6)
308 +
309 + # Give priority to the address family that
310 + # getaddrinfo() returned first.
311 + if AF_INET6 is not None and addrinfos and \
312 + addrinfos[0][0] == AF_INET6:
313 + ips = ips_v6 + ips_v4
314 + else:
315 + ips = ips_v4 + ips_v6
316 +
317 + for ip in ips:
318 + uris.append(syncuri.replace(
319 + "//" + user_name + hostname + port + "/",
320 + "//" + user_name + ip + port + "/", 1))
321 +
322 + if not uris:
323 + # With some configurations we need to use the plain hostname
324 + # rather than try to resolve the ip addresses (bug #340817).
325 + uris.append(syncuri)
326 +
327 + # reverse, for use with pop()
328 + uris.reverse()
329 + uris_orig = uris[:]
330 +
331 + effective_maxretries = maxretries
332 + if effective_maxretries < 0:
333 + effective_maxretries = len(uris) - 1
334 +
335 + local_state_unchanged = True
336 + while (1):
337 + if uris:
338 + dosyncuri = uris.pop()
339 + elif maxretries < 0 or retries > maxretries:
340 + writemsg("!!! Exhausted addresses for %s\n"
341 + % _unicode_decode(hostname), noiselevel=-1)
342 + return (1, False)
343 + else:
344 + uris.extend(uris_orig)
345 + dosyncuri = uris.pop()
346 +
347 + if (retries==0):
348 + if "--ask" in opts:
349 + uq = UserQuery(opts)
350 + if uq.query("Do you want to sync your Portage tree " + \
351 + "with the mirror at\n" + blue(dosyncuri) + bold("?"),
352 + enter_invalid) == "No":
353 + print()
354 + print("Quitting.")
355 + print()
356 + sys.exit(128 + signal.SIGINT)
357 + self.logger(self.xterm_titles,
358 + ">>> Starting rsync with " + dosyncuri)
359 + if "--quiet" not in opts:
360 + print(">>> Starting rsync with "+dosyncuri+"...")
361 + else:
362 + self.logger(self.xterm_titles,
363 + ">>> Starting retry %d of %d with %s" % \
364 + (retries, effective_maxretries, dosyncuri))
365 + writemsg_stdout(
366 + "\n\n>>> Starting retry %d of %d with %s\n" % \
367 + (retries, effective_maxretries, dosyncuri), noiselevel=-1)
368 +
369 + if dosyncuri.startswith('ssh://'):
370 + dosyncuri = dosyncuri[6:].replace('/', ':/', 1)
371 +
372 + unchanged, is_synced, exitcode, updatecache_flg = self._do_rsync(
373 + dosyncuri, timestamp, opts)
374 + if not unchanged:
375 + local_state_unchanged = False
376 + if is_synced:
377 + break
378 +
379 + retries=retries+1
380 +
381 + if maxretries < 0 or retries <= maxretries:
382 + print(">>> Retrying...")
383 else:
384 - openpgp_env_cls = gemato.openpgp.OpenPGPSystemEnvironment
385 + # over retries
386 + # exit loop
387 + exitcode = EXCEEDED_MAX_RETRIES
388 + break
389 + self._process_exitcode(exitcode, dosyncuri, out, maxretries)
390 +
391 + # if synced successfully, verify now
392 + if exitcode == 0 and self.verify_metamanifest:
393 + if gemato is None:
394 + writemsg_level("!!! Unable to verify: gemato-11.0+ is required\n",
395 + level=logging.ERROR, noiselevel=-1)
396 + exitcode = 127
397 + else:
398 + # Use isolated environment if key is specified,
399 + # system environment otherwise
400 + if self.repo.sync_openpgp_key_path is not None:
401 + openpgp_env_cls = gemato.openpgp.OpenPGPEnvironment
402 + else:
403 + openpgp_env_cls = gemato.openpgp.OpenPGPSystemEnvironment
404 +
405 + try:
406 + with openpgp_env_cls() as openpgp_env:
407 + if self.repo.sync_openpgp_key_path is not None:
408 + out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,))
409 + with io.open(self.repo.sync_openpgp_key_path, 'rb') as f:
410 + openpgp_env.import_key(f)
411 + out.ebegin('Refreshing keys from keyserver')
412 + openpgp_env.refresh_keys()
413 + out.eend(0)
414 +
415 + # we always verify the Manifest signature, in case
416 + # we had to deal with key revocation case
417 + m = gemato.recursiveloader.ManifestRecursiveLoader(
418 + os.path.join(self.repo.location, 'Manifest'),
419 + verify_openpgp=True,
420 + openpgp_env=openpgp_env,
421 + max_jobs=self.verify_jobs)
422 + if not m.openpgp_signed:
423 + raise RuntimeError('OpenPGP signature not found on Manifest')
424 +
425 + ts = m.find_timestamp()
426 + if ts is None:
427 + raise RuntimeError('Timestamp not found in Manifest')
428 +
429 + out.einfo('Manifest timestamp: %s UTC' % (ts.ts,))
430 + out.einfo('Valid OpenPGP signature found:')
431 + out.einfo('- primary key: %s' % (
432 + m.openpgp_signature.primary_key_fingerprint))
433 + out.einfo('- subkey: %s' % (
434 + m.openpgp_signature.fingerprint))
435 + out.einfo('- timestamp: %s UTC' % (
436 + m.openpgp_signature.timestamp))
437 +
438 + # if nothing has changed, skip the actual Manifest
439 + # verification
440 + if not local_state_unchanged:
441 + out.ebegin('Verifying %s' % (self.repo.location,))
442 + m.assert_directory_verifies()
443 + out.eend(0)
444 + except GematoException as e:
445 + writemsg_level("!!! Manifest verification failed:\n%s\n"
446 + % (e,),
447 + level=logging.ERROR, noiselevel=-1)
448 + exitcode = 1
449
450 - try:
451 - with openpgp_env_cls() as openpgp_env:
452 - if self.repo.sync_openpgp_key_path is not None:
453 - out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,))
454 - with io.open(self.repo.sync_openpgp_key_path, 'rb') as f:
455 - openpgp_env.import_key(f)
456 - out.ebegin('Refreshing keys from keyserver')
457 - openpgp_env.refresh_keys()
458 - out.eend(0)
459 -
460 - # we always verify the Manifest signature, in case
461 - # we had to deal with key revocation case
462 - m = gemato.recursiveloader.ManifestRecursiveLoader(
463 - os.path.join(self.repo.location, 'Manifest'),
464 - verify_openpgp=True,
465 - openpgp_env=openpgp_env,
466 - max_jobs=self.verify_jobs)
467 - if not m.openpgp_signed:
468 - raise RuntimeError('OpenPGP signature not found on Manifest')
469 -
470 - ts = m.find_timestamp()
471 - if ts is None:
472 - raise RuntimeError('Timestamp not found in Manifest')
473 -
474 - out.einfo('Manifest timestamp: %s UTC' % (ts.ts,))
475 - out.einfo('Valid OpenPGP signature found:')
476 - out.einfo('- primary key: %s' % (
477 - m.openpgp_signature.primary_key_fingerprint))
478 - out.einfo('- subkey: %s' % (
479 - m.openpgp_signature.fingerprint))
480 - out.einfo('- timestamp: %s UTC' % (
481 - m.openpgp_signature.timestamp))
482 -
483 - # if nothing has changed, skip the actual Manifest
484 - # verification
485 - if not local_state_unchanged:
486 - out.ebegin('Verifying %s' % (self.repo.location,))
487 - m.assert_directory_verifies()
488 - out.eend(0)
489 - except GematoException as e:
490 - writemsg_level("!!! Manifest verification failed:\n%s\n"
491 - % (e,),
492 - level=logging.ERROR, noiselevel=-1)
493 - exitcode = 1
494 -
495 - return (exitcode, updatecache_flg)
496 + return (exitcode, updatecache_flg)
497 + finally:
498 + pass
499
500
501 def _process_exitcode(self, exitcode, syncuri, out, maxretries):