summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2019-01-17 14:46:18 -0500
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2019-01-18 10:59:28 -0500
commitf874295f0bba8004a565afff4fa3024f2db0a5f5 (patch)
tree8208dd173ebd877f43d53b2ff25f22cb3cd3afc1
parentad2df651bc3fd0d3bfe915ed81a0b5df6a0e2ca2 (diff)
downloadbuildstream-f874295f0bba8004a565afff4fa3024f2db0a5f5.tar.gz
bzr source plugin: Use lock files to avoid corrupting the source cache
This patch by itself fixes #868
-rw-r--r--buildstream/plugins/sources/bzr.py35
1 files changed, 29 insertions, 6 deletions
diff --git a/buildstream/plugins/sources/bzr.py b/buildstream/plugins/sources/bzr.py
index f52472918..39cee2bf9 100644
--- a/buildstream/plugins/sources/bzr.py
+++ b/buildstream/plugins/sources/bzr.py
@@ -56,6 +56,7 @@ details on common configuration options for sources.
import os
import shutil
+import fcntl
from contextlib import contextmanager
from buildstream import Source, SourceError, Consistency
@@ -84,10 +85,12 @@ class BzrSource(Source):
if self.ref is None or self.tracking is None:
return Consistency.INCONSISTENT
- if self._check_ref():
- return Consistency.CACHED
- else:
- return Consistency.RESOLVED
+ # Lock for the _check_ref()
+ with self._locked():
+ if self._check_ref():
+ return Consistency.CACHED
+ else:
+ return Consistency.RESOLVED
def load_ref(self, node):
self.ref = self.node_get_member(node, str, 'ref', None)
@@ -100,7 +103,7 @@ class BzrSource(Source):
def track(self):
with self.timed_activity("Tracking {}".format(self.url),
- silent_nested=True):
+ silent_nested=True), self._locked():
self._ensure_mirror(skip_ref_check=True)
ret, out = self.check_output([self.host_bzr, "version-info",
"--custom", "--template={revno}",
@@ -114,7 +117,7 @@ class BzrSource(Source):
def fetch(self):
with self.timed_activity("Fetching {}".format(self.url),
- silent_nested=True):
+ silent_nested=True), self._locked():
self._ensure_mirror()
def stage(self, directory):
@@ -141,6 +144,26 @@ class BzrSource(Source):
"--directory={}".format(directory), url],
fail="Failed to switch workspace's parent branch to {}".format(url))
+ # _locked()
+ #
+ # This context manager ensures exclusive access to the
+ # bzr repository.
+ #
+ @contextmanager
+ def _locked(self):
+ lockdir = os.path.join(self.get_mirror_directory(), 'locks')
+ lockfile = os.path.join(
+ lockdir,
+ utils.url_directory_name(self.original_url) + '.lock'
+ )
+ os.makedirs(lockdir, exist_ok=True)
+ with open(lockfile, 'w') as lock:
+ fcntl.flock(lock, fcntl.LOCK_EX)
+ try:
+ yield
+ finally:
+ fcntl.flock(lock, fcntl.LOCK_UN)
+
def _check_ref(self):
# If the mirror doesnt exist yet, then we dont have the ref
if not os.path.exists(self._get_branch_dir()):