Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: git_cache.py

Issue 2497503002: Add retries to file operations for Windows. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """A git command for managing a local cache of git repositories.""" 6 """A git command for managing a local cache of git repositories."""
7 7
8 from __future__ import print_function 8 from __future__ import print_function
9 import errno 9 import errno
10 import logging 10 import logging
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 self.url = url 174 self.url = url
175 self.fetch_specs = set([self.parse_fetch_spec(ref) for ref in (refs or [])]) 175 self.fetch_specs = set([self.parse_fetch_spec(ref) for ref in (refs or [])])
176 self.basedir = self.UrlToCacheDir(url) 176 self.basedir = self.UrlToCacheDir(url)
177 self.mirror_path = os.path.join(self.GetCachePath(), self.basedir) 177 self.mirror_path = os.path.join(self.GetCachePath(), self.basedir)
178 if print_func: 178 if print_func:
179 self.print = self.print_without_file 179 self.print = self.print_without_file
180 self.print_func = print_func 180 self.print_func = print_func
181 else: 181 else:
182 self.print = print 182 self.print = print
183 183
184 def print_without_file(self, message, **kwargs): 184 def print_without_file(self, message, **_kwargs):
185 self.print_func(message) 185 self.print_func(message)
186 186
187 @property 187 @property
188 def bootstrap_bucket(self): 188 def bootstrap_bucket(self):
189 if 'chrome-internal' in self.url: 189 if 'chrome-internal' in self.url:
190 return 'chrome-git-cache' 190 return 'chrome-git-cache'
191 else: 191 else:
192 return 'chromium-git-cache' 192 return 'chromium-git-cache'
193 193
194 @classmethod 194 @classmethod
(...skipping 28 matching lines...) Expand all
223 cachepath = subprocess.check_output( 223 cachepath = subprocess.check_output(
224 [cls.git_exe, 'config', '--global', 'cache.cachepath']).strip() 224 [cls.git_exe, 'config', '--global', 'cache.cachepath']).strip()
225 except subprocess.CalledProcessError: 225 except subprocess.CalledProcessError:
226 cachepath = None 226 cachepath = None
227 if not cachepath: 227 if not cachepath:
228 raise RuntimeError( 228 raise RuntimeError(
229 'No global cache.cachepath git configuration found.') 229 'No global cache.cachepath git configuration found.')
230 setattr(cls, 'cachepath', cachepath) 230 setattr(cls, 'cachepath', cachepath)
231 return getattr(cls, 'cachepath') 231 return getattr(cls, 'cachepath')
232 232
233 def Rename(self, src, dst, count=3):
234 i = 0
235 while True:
236 i += 1
237
238 try:
239 os.rename(src, dst)
240 return
241 except OSError as e:
242 # This is somehow racy on Windows.
243 # Catching OSError because WindowsError isn't portable and
244 # pylint complains.
245 if i >= count:
246 raise
247 self.print('Error moving [%s] to [%s] (%d / %d): %s' % (
nodir 2016/11/11 01:34:30 attempt %d / %d so make it obviously clear
248 src, dst, i+1, count, str(e)))
nodir 2016/11/11 01:34:30 sleep?
nodir 2016/11/11 01:34:30 str unnecessary?
249
233 def RunGit(self, cmd, **kwargs): 250 def RunGit(self, cmd, **kwargs):
234 """Run git in a subprocess.""" 251 """Run git in a subprocess."""
235 cwd = kwargs.setdefault('cwd', self.mirror_path) 252 cwd = kwargs.setdefault('cwd', self.mirror_path)
236 kwargs.setdefault('print_stdout', False) 253 kwargs.setdefault('print_stdout', False)
237 kwargs.setdefault('filter_fn', self.print) 254 kwargs.setdefault('filter_fn', self.print)
238 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy()) 255 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy())
239 env.setdefault('GIT_ASKPASS', 'true') 256 env.setdefault('GIT_ASKPASS', 'true')
240 env.setdefault('SSH_ASKPASS', 'true') 257 env.setdefault('SSH_ASKPASS', 'true')
241 self.print('running "git %s" in "%s"' % (' '.join(cmd), cwd)) 258 self.print('running "git %s" in "%s"' % (' '.join(cmd), cwd))
242 gclient_utils.CheckCallAndFilter([self.git_exe] + cmd, **kwargs) 259 gclient_utils.CheckCallAndFilter([self.git_exe] + cmd, **kwargs)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 with zipfile.ZipFile(filename, 'r') as f: 334 with zipfile.ZipFile(filename, 'r') as f:
318 f.printdir() 335 f.printdir()
319 f.extractall(directory) 336 f.extractall(directory)
320 except Exception as e: 337 except Exception as e:
321 self.print('Encountered error: %s' % str(e), file=sys.stderr) 338 self.print('Encountered error: %s' % str(e), file=sys.stderr)
322 retcode = 1 339 retcode = 1
323 else: 340 else:
324 retcode = 0 341 retcode = 0
325 finally: 342 finally:
326 # Clean up the downloaded zipfile. 343 # Clean up the downloaded zipfile.
327 gclient_utils.rm_file_or_tree(tempdir) 344 gclient_utils.rm_file_or_tree(tempdir)
nodir 2016/11/11 01:34:30 can you please add a retry here too?
328 345
329 if retcode: 346 if retcode:
330 self.print( 347 self.print(
331 'Extracting bootstrap zipfile %s failed.\n' 348 'Extracting bootstrap zipfile %s failed.\n'
332 'Resuming normal operations.' % filename) 349 'Resuming normal operations.' % filename)
333 return False 350 return False
334 return True 351 return True
335 352
336 def exists(self): 353 def exists(self):
337 return os.path.isfile(os.path.join(self.mirror_path, 'config')) 354 return os.path.isfile(os.path.join(self.mirror_path, 'config'))
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 # This is a major failure, we need to clean and force a bootstrap. 451 # This is a major failure, we need to clean and force a bootstrap.
435 gclient_utils.rmtree(rundir) 452 gclient_utils.rmtree(rundir)
436 self.print(GIT_CACHE_CORRUPT_MESSAGE) 453 self.print(GIT_CACHE_CORRUPT_MESSAGE)
437 tempdir = self._ensure_bootstrapped(depth, bootstrap, force=True) 454 tempdir = self._ensure_bootstrapped(depth, bootstrap, force=True)
438 assert tempdir 455 assert tempdir
439 self._fetch(tempdir or self.mirror_path, verbose, depth) 456 self._fetch(tempdir or self.mirror_path, verbose, depth)
440 finally: 457 finally:
441 if tempdir: 458 if tempdir:
442 if os.path.exists(self.mirror_path): 459 if os.path.exists(self.mirror_path):
443 gclient_utils.rmtree(self.mirror_path) 460 gclient_utils.rmtree(self.mirror_path)
444 os.rename(tempdir, self.mirror_path) 461 self.Rename(tempdir, self.mirror_path)
445 if not ignore_lock: 462 if not ignore_lock:
446 lockfile.unlock() 463 lockfile.unlock()
447 464
448 def update_bootstrap(self, prune=False): 465 def update_bootstrap(self, prune=False):
449 # The files are named <git number>.zip 466 # The files are named <git number>.zip
450 gen_number = subprocess.check_output( 467 gen_number = subprocess.check_output(
451 [self.git_exe, 'number', 'master'], cwd=self.mirror_path).strip() 468 [self.git_exe, 'number', 'master'], cwd=self.mirror_path).strip()
452 # Run Garbage Collect to compress packfile. 469 # Run Garbage Collect to compress packfile.
453 self.RunGit(['gc', '--prune=all']) 470 self.RunGit(['gc', '--prune=all'])
454 # Creating a temp file and then deleting it ensures we can use this name. 471 # Creating a temp file and then deleting it ensures we can use this name.
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 dispatcher = subcommand.CommandDispatcher(__name__) 739 dispatcher = subcommand.CommandDispatcher(__name__)
723 return dispatcher.execute(OptionParser(), argv) 740 return dispatcher.execute(OptionParser(), argv)
724 741
725 742
726 if __name__ == '__main__': 743 if __name__ == '__main__':
727 try: 744 try:
728 sys.exit(main(sys.argv[1:])) 745 sys.exit(main(sys.argv[1:]))
729 except KeyboardInterrupt: 746 except KeyboardInterrupt:
730 sys.stderr.write('interrupted\n') 747 sys.stderr.write('interrupted\n')
731 sys.exit(1) 748 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698