| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import logging | 5 import logging |
| 6 import os | 6 import os |
| 7 import sys | 7 import sys |
| 8 import tempfile | 8 import tempfile |
| 9 | 9 |
| 10 # Install Infra build environment. | 10 # Install Infra build environment. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 Args: | 36 Args: |
| 37 prefix (str): prefix to use for the temporary directories | 37 prefix (str): prefix to use for the temporary directories |
| 38 leak (bool): if True, do not remove temporary directories | 38 leak (bool): if True, do not remove temporary directories |
| 39 on exit | 39 on exit |
| 40 """ | 40 """ |
| 41 | 41 |
| 42 self._tempdirs = [] | 42 self._tempdirs = [] |
| 43 self._prefix = prefix | 43 self._prefix = prefix |
| 44 self._leak = leak | 44 self._leak = leak |
| 45 | 45 |
| 46 def cleanup(self, path): | 46 def cleanup(self, base=None): |
| 47 self._tempdirs.append(path) | 47 """Explicitly remove ALL temporary directories under "<base>/<prefix>". |
| 48 |
| 49 This can be used e.g. to reduce chances of running out of disk space |
| 50 when temporary directories are leaked. |
| 51 """ |
| 52 base = base or tempfile.gettempdir() |
| 53 path = os.path.join(base, self._prefix) |
| 54 try: |
| 55 if os.path.isdir(path): |
| 56 LOGGER.info('Cleaning up temporary directory [%s].', path) |
| 57 chromium_utils.RemoveDirectory(path) |
| 58 except BaseException: |
| 59 LOGGER.exception('Failed to clean up temporary directory [%s].', path) |
| 48 | 60 |
| 49 def tempdir(self, base=None): | 61 def tempdir(self, base=None): |
| 50 """Creates a temporary working directory and yields it. | 62 """Creates a temporary working directory and yields it. |
| 51 | 63 |
| 52 This creates two levels of directory: | 64 This creates two levels of directory: |
| 53 <base>/<prefix> | 65 <base>/<prefix> |
| 54 <base>/<prefix>/tmpFOO | 66 <base>/<prefix>/tmpFOO |
| 55 | 67 |
| 56 On termination, the entire "<base>/<prefix>" directory is deleted, | 68 On termination, the entire "<base>/<prefix>" directory is deleted, |
| 57 removing the subdirectory created by this instance as well as cleaning up | 69 removing the subdirectory created by this instance as well as cleaning up |
| 58 any other temporary subdirectories leaked by previous executions. | 70 any other temporary subdirectories leaked by previous executions. |
| 59 | 71 |
| 60 Args: | 72 Args: |
| 61 base (str/None): The directory under which the tempdir should be created. | 73 base (str/None): The directory under which the tempdir should be created. |
| 62 If None, the default temporary directory root will be used. | 74 If None, the default temporary directory root will be used. |
| 63 """ | 75 """ |
| 64 base = base or tempfile.gettempdir() | 76 base = base or tempfile.gettempdir() |
| 65 # TODO(phajdan.jr): Clean up leaked directories at the beginning. | |
| 66 # Doing so should automatically prevent more out-of-disk-space scenarios. | |
| 67 basedir = _ensure_directory(base, self._prefix) | 77 basedir = _ensure_directory(base, self._prefix) |
| 68 self.cleanup(basedir) | 78 self._tempdirs.append(basedir) |
| 69 tdir = tempfile.mkdtemp(dir=basedir) | 79 tdir = tempfile.mkdtemp(dir=basedir) |
| 70 return tdir | 80 return tdir |
| 71 | 81 |
| 72 def __enter__(self): | 82 def __enter__(self): |
| 73 return self | 83 return self |
| 74 | 84 |
| 75 def __exit__(self, _et, _ev, _tb): | 85 def __exit__(self, _et, _ev, _tb): |
| 76 self.close() | 86 self.close() |
| 77 | 87 |
| 78 def close(self): | 88 def close(self): |
| 79 if self._leak: | 89 if self._leak: |
| 80 LOGGER.warning('Leaking temporary paths: %s', self._tempdirs) | 90 LOGGER.warning('Leaking temporary paths: %s', self._tempdirs) |
| 81 else: | 91 else: |
| 82 for path in reversed(self._tempdirs): | 92 for path in reversed(self._tempdirs): |
| 83 try: | 93 try: |
| 84 if os.path.isdir(path): | 94 if os.path.isdir(path): |
| 85 LOGGER.debug('Cleaning up temporary directory [%s].', path) | 95 LOGGER.debug('Cleaning up temporary directory [%s].', path) |
| 86 chromium_utils.RemoveDirectory(path) | 96 chromium_utils.RemoveDirectory(path) |
| 87 except BaseException: | 97 except BaseException: |
| 88 LOGGER.exception('Failed to clean up temporary directory [%s].', | 98 LOGGER.exception('Failed to clean up temporary directory [%s].', |
| 89 path) | 99 path) |
| 90 del(self._tempdirs[:]) | 100 del(self._tempdirs[:]) |
| OLD | NEW |