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

Side by Side Diff: git_cache.py

Issue 2497503002: Add retries to file operations for Windows. (Closed)
Patch Set: Bug 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 sleep_time = 1
nodir 2016/11/11 01:53:59 Strange indentation
235 while True:
236 try:
237 os.rename(src, dst)
238 return
239 except OSError as e:
240 # This is somehow racy on Windows.
241 # Catching OSError because WindowsError isn't portable and
242 # pylint complains.
243 if not count:
244 raise
245
246 self.print('Error moving [%s] to [%s] (%d retries remaining): %s' % (
247 src, dst, count, str(e)))
nodir 2016/11/11 01:53:59 str unnecessary?
248 time.sleep(sleep_time)
249 count -= 1
250 sleep_time *= 2
251
252
233 def RunGit(self, cmd, **kwargs): 253 def RunGit(self, cmd, **kwargs):
234 """Run git in a subprocess.""" 254 """Run git in a subprocess."""
235 cwd = kwargs.setdefault('cwd', self.mirror_path) 255 cwd = kwargs.setdefault('cwd', self.mirror_path)
236 kwargs.setdefault('print_stdout', False) 256 kwargs.setdefault('print_stdout', False)
237 kwargs.setdefault('filter_fn', self.print) 257 kwargs.setdefault('filter_fn', self.print)
238 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy()) 258 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy())
239 env.setdefault('GIT_ASKPASS', 'true') 259 env.setdefault('GIT_ASKPASS', 'true')
240 env.setdefault('SSH_ASKPASS', 'true') 260 env.setdefault('SSH_ASKPASS', 'true')
241 self.print('running "git %s" in "%s"' % (' '.join(cmd), cwd)) 261 self.print('running "git %s" in "%s"' % (' '.join(cmd), cwd))
242 gclient_utils.CheckCallAndFilter([self.git_exe] + cmd, **kwargs) 262 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: 337 with zipfile.ZipFile(filename, 'r') as f:
318 f.printdir() 338 f.printdir()
319 f.extractall(directory) 339 f.extractall(directory)
320 except Exception as e: 340 except Exception as e:
321 self.print('Encountered error: %s' % str(e), file=sys.stderr) 341 self.print('Encountered error: %s' % str(e), file=sys.stderr)
322 retcode = 1 342 retcode = 1
323 else: 343 else:
324 retcode = 0 344 retcode = 0
325 finally: 345 finally:
326 # Clean up the downloaded zipfile. 346 # Clean up the downloaded zipfile.
327 gclient_utils.rm_file_or_tree(tempdir) 347 gclient_utils.rm_file_or_tree(tempdir)
nodir 2016/11/11 01:53:59 Retry here please
328 348
329 if retcode: 349 if retcode:
330 self.print( 350 self.print(
331 'Extracting bootstrap zipfile %s failed.\n' 351 'Extracting bootstrap zipfile %s failed.\n'
332 'Resuming normal operations.' % filename) 352 'Resuming normal operations.' % filename)
333 return False 353 return False
334 return True 354 return True
335 355
336 def exists(self): 356 def exists(self):
337 return os.path.isfile(os.path.join(self.mirror_path, 'config')) 357 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. 454 # This is a major failure, we need to clean and force a bootstrap.
435 gclient_utils.rmtree(rundir) 455 gclient_utils.rmtree(rundir)
436 self.print(GIT_CACHE_CORRUPT_MESSAGE) 456 self.print(GIT_CACHE_CORRUPT_MESSAGE)
437 tempdir = self._ensure_bootstrapped(depth, bootstrap, force=True) 457 tempdir = self._ensure_bootstrapped(depth, bootstrap, force=True)
438 assert tempdir 458 assert tempdir
439 self._fetch(tempdir or self.mirror_path, verbose, depth) 459 self._fetch(tempdir or self.mirror_path, verbose, depth)
440 finally: 460 finally:
441 if tempdir: 461 if tempdir:
442 if os.path.exists(self.mirror_path): 462 if os.path.exists(self.mirror_path):
443 gclient_utils.rmtree(self.mirror_path) 463 gclient_utils.rmtree(self.mirror_path)
444 os.rename(tempdir, self.mirror_path) 464 self.Rename(tempdir, self.mirror_path)
445 if not ignore_lock: 465 if not ignore_lock:
446 lockfile.unlock() 466 lockfile.unlock()
447 467
448 def update_bootstrap(self, prune=False): 468 def update_bootstrap(self, prune=False):
449 # The files are named <git number>.zip 469 # The files are named <git number>.zip
450 gen_number = subprocess.check_output( 470 gen_number = subprocess.check_output(
451 [self.git_exe, 'number', 'master'], cwd=self.mirror_path).strip() 471 [self.git_exe, 'number', 'master'], cwd=self.mirror_path).strip()
452 # Run Garbage Collect to compress packfile. 472 # Run Garbage Collect to compress packfile.
453 self.RunGit(['gc', '--prune=all']) 473 self.RunGit(['gc', '--prune=all'])
454 # Creating a temp file and then deleting it ensures we can use this name. 474 # 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__) 742 dispatcher = subcommand.CommandDispatcher(__name__)
723 return dispatcher.execute(OptionParser(), argv) 743 return dispatcher.execute(OptionParser(), argv)
724 744
725 745
726 if __name__ == '__main__': 746 if __name__ == '__main__':
727 try: 747 try:
728 sys.exit(main(sys.argv[1:])) 748 sys.exit(main(sys.argv[1:]))
729 except KeyboardInterrupt: 749 except KeyboardInterrupt:
730 sys.stderr.write('interrupted\n') 750 sys.stderr.write('interrupted\n')
731 sys.exit(1) 751 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