diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-10-25 22:15:48 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-10-25 20:54:25 +0100 |
commit | f5fd1c2fd3d50adcc0039b30694dd8e7e4070bd4 (patch) | |
tree | 1c590c7368965ccc3935d8283edc346e5b628cfa /bitbake/lib | |
parent | ac66132f92bf7badc4180a8d5b6de47b32861dde (diff) | |
download | poky-f5fd1c2fd3d50adcc0039b30694dd8e7e4070bd4.tar.gz |
bitbake: fetch2/git: Avoid races over mirror tarball creation
There is a potential race over the mirror tarballs where a partial git repo
could be extracted causing fetcher failures if the tarball is being rewritten
whilst another build accesses it.
Create the mirror tarball atomically to avoid this.
[YOCTO #14441]
(Bitbake rev: 7c8f344b81b8f8936214f87f695e24dc4e546659)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 3250bc950c56bd7dd2114df26e5a8e13b04ceac8)
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/bb/fetch2/git.py | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py index cf7424ebf4..95cd971d56 100644 --- a/bitbake/lib/bb/fetch2/git.py +++ b/bitbake/lib/bb/fetch2/git.py | |||
@@ -68,6 +68,7 @@ import subprocess | |||
68 | import tempfile | 68 | import tempfile |
69 | import bb | 69 | import bb |
70 | import bb.progress | 70 | import bb.progress |
71 | from contextlib import contextmanager | ||
71 | from bb.fetch2 import FetchMethod | 72 | from bb.fetch2 import FetchMethod |
72 | from bb.fetch2 import runfetchcmd | 73 | from bb.fetch2 import runfetchcmd |
73 | from bb.fetch2 import logger | 74 | from bb.fetch2 import logger |
@@ -414,6 +415,20 @@ class Git(FetchMethod): | |||
414 | bb.utils.remove(tmpdir, recurse=True) | 415 | bb.utils.remove(tmpdir, recurse=True) |
415 | 416 | ||
416 | def build_mirror_data(self, ud, d): | 417 | def build_mirror_data(self, ud, d): |
418 | |||
419 | # Create as a temp file and move atomically into position to avoid races | ||
420 | @contextmanager | ||
421 | def create_atomic(filename, d): | ||
422 | fd, tfile = tempfile.mkstemp(dir=os.path.dirname(filename)) | ||
423 | try: | ||
424 | yield tfile | ||
425 | umask = os.umask(0o666) | ||
426 | os.umask(umask) | ||
427 | os.chmod(tfile, (0o666 & ~umask)) | ||
428 | runfetchcmd("mv %s %s" % (tfile, filename), d) | ||
429 | finally: | ||
430 | os.close(fd) | ||
431 | |||
417 | if ud.shallow and ud.write_shallow_tarballs: | 432 | if ud.shallow and ud.write_shallow_tarballs: |
418 | if not os.path.exists(ud.fullshallow): | 433 | if not os.path.exists(ud.fullshallow): |
419 | if os.path.islink(ud.fullshallow): | 434 | if os.path.islink(ud.fullshallow): |
@@ -424,7 +439,8 @@ class Git(FetchMethod): | |||
424 | self.clone_shallow_local(ud, shallowclone, d) | 439 | self.clone_shallow_local(ud, shallowclone, d) |
425 | 440 | ||
426 | logger.info("Creating tarball of git repository") | 441 | logger.info("Creating tarball of git repository") |
427 | runfetchcmd("tar -czf %s ." % ud.fullshallow, d, workdir=shallowclone) | 442 | with create_atomic(ud.fullshallow, d) as tfile: |
443 | runfetchcmd("tar -czf %s ." % tfile, d, workdir=shallowclone) | ||
428 | runfetchcmd("touch %s.done" % ud.fullshallow, d) | 444 | runfetchcmd("touch %s.done" % ud.fullshallow, d) |
429 | finally: | 445 | finally: |
430 | bb.utils.remove(tempdir, recurse=True) | 446 | bb.utils.remove(tempdir, recurse=True) |
@@ -433,7 +449,8 @@ class Git(FetchMethod): | |||
433 | os.unlink(ud.fullmirror) | 449 | os.unlink(ud.fullmirror) |
434 | 450 | ||
435 | logger.info("Creating tarball of git repository") | 451 | logger.info("Creating tarball of git repository") |
436 | runfetchcmd("tar -czf %s ." % ud.fullmirror, d, workdir=ud.clonedir) | 452 | with create_atomic(ud.fullmirror, d) as tfile: |
453 | runfetchcmd("tar -czf %s ." % tfile, d, workdir=ud.clonedir) | ||
437 | runfetchcmd("touch %s.done" % ud.fullmirror, d) | 454 | runfetchcmd("touch %s.done" % ud.fullmirror, d) |
438 | 455 | ||
439 | def clone_shallow_local(self, ud, dest, d): | 456 | def clone_shallow_local(self, ud, dest, d): |