summaryrefslogtreecommitdiff
path: root/buildstream/plugins/sources
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2018-11-07 13:07:09 +0000
committerrichardmaw-codethink <richard.maw@codethink.co.uk>2018-11-19 11:39:51 +0000
commita6defc0b47423180c3f17a723692019458603bb6 (patch)
treeaf58414e2b742b0c98f11a718472f2c1ac6bef6f /buildstream/plugins/sources
parentf23b6031b1b6bd27858f44d3deb63282483e6197 (diff)
downloadbuildstream-a6defc0b47423180c3f17a723692019458603bb6.tar.gz
Fix os.rename in git source element to correctly handle error codes
According to the documentation (https://www.unix.com/man-page/POSIX/3posix/rename/), when the directory already is there, either EEXIST or ENOTEMPTY could be thrown. Previously only ENOTEMPTY was checked. Done: - Separated the move into its own function - Check for both errors - Create unit tests for it, covering most test cases
Diffstat (limited to 'buildstream/plugins/sources')
-rw-r--r--buildstream/plugins/sources/git.py33
1 files changed, 18 insertions, 15 deletions
diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py
index 23e3369b1..b51ed79d9 100644
--- a/buildstream/plugins/sources/git.py
+++ b/buildstream/plugins/sources/git.py
@@ -141,21 +141,24 @@ class GitMirror(SourceFetcher):
fail="Failed to clone git repository {}".format(url),
fail_temporarily=True)
- # Attempt atomic rename into destination, this will fail if
- # another process beat us to the punch
- try:
- os.rename(tmpdir, self.mirror)
- except OSError as e:
-
- # When renaming and the destination repo already exists, os.rename()
- # will fail with ENOTEMPTY, since an empty directory will be silently
- # replaced
- if e.errno == errno.ENOTEMPTY:
- self.source.status("{}: Discarding duplicate clone of {}"
- .format(self.source, url))
- else:
- raise SourceError("{}: Failed to move cloned git repository {} from '{}' to '{}': {}"
- .format(self.source, url, tmpdir, self.mirror, e)) from e
+ self._atomic_move_mirror(tmpdir, url)
+
+ def _atomic_move_mirror(self, tmpdir, url):
+ # Attempt atomic rename into destination, this will fail if
+ # another process beat us to the punch
+ try:
+ os.rename(tmpdir, self.mirror)
+ except OSError as e:
+ # When renaming and the destination repo already exists, os.rename()
+ # will fail with either ENOTEMPTY or EEXIST, depending on the underlying
+ # implementation.
+ # An empty directory would always be replaced.
+ if e.errno in (errno.EEXIST, errno.ENOTEMPTY):
+ self.source.status("{}: Discarding duplicate clone of {}"
+ .format(self.source, url))
+ else:
+ raise SourceError("{}: Failed to move cloned git repository {} from '{}' to '{}': {}"
+ .format(self.source, url, tmpdir, self.mirror, e)) from e
def _fetch(self, alias_override=None):
url = self.source.translate_url(self.url,