1
0
mirror of https://git.yoctoproject.org/poky synced 2026-06-02 13:29:49 +00:00

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>
This commit is contained in:
Richard Purdie
2021-10-25 22:15:48 +08:00
parent ac66132f92
commit f5fd1c2fd3
+19 -2
View File
@@ -68,6 +68,7 @@ import subprocess
import tempfile import tempfile
import bb import bb
import bb.progress import bb.progress
from contextlib import contextmanager
from bb.fetch2 import FetchMethod from bb.fetch2 import FetchMethod
from bb.fetch2 import runfetchcmd from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger from bb.fetch2 import logger
@@ -414,6 +415,20 @@ class Git(FetchMethod):
bb.utils.remove(tmpdir, recurse=True) bb.utils.remove(tmpdir, recurse=True)
def build_mirror_data(self, ud, d): def build_mirror_data(self, ud, d):
# Create as a temp file and move atomically into position to avoid races
@contextmanager
def create_atomic(filename, d):
fd, tfile = tempfile.mkstemp(dir=os.path.dirname(filename))
try:
yield tfile
umask = os.umask(0o666)
os.umask(umask)
os.chmod(tfile, (0o666 & ~umask))
runfetchcmd("mv %s %s" % (tfile, filename), d)
finally:
os.close(fd)
if ud.shallow and ud.write_shallow_tarballs: if ud.shallow and ud.write_shallow_tarballs:
if not os.path.exists(ud.fullshallow): if not os.path.exists(ud.fullshallow):
if os.path.islink(ud.fullshallow): if os.path.islink(ud.fullshallow):
@@ -424,7 +439,8 @@ class Git(FetchMethod):
self.clone_shallow_local(ud, shallowclone, d) self.clone_shallow_local(ud, shallowclone, d)
logger.info("Creating tarball of git repository") logger.info("Creating tarball of git repository")
runfetchcmd("tar -czf %s ." % ud.fullshallow, d, workdir=shallowclone) with create_atomic(ud.fullshallow, d) as tfile:
runfetchcmd("tar -czf %s ." % tfile, d, workdir=shallowclone)
runfetchcmd("touch %s.done" % ud.fullshallow, d) runfetchcmd("touch %s.done" % ud.fullshallow, d)
finally: finally:
bb.utils.remove(tempdir, recurse=True) bb.utils.remove(tempdir, recurse=True)
@@ -433,7 +449,8 @@ class Git(FetchMethod):
os.unlink(ud.fullmirror) os.unlink(ud.fullmirror)
logger.info("Creating tarball of git repository") logger.info("Creating tarball of git repository")
runfetchcmd("tar -czf %s ." % ud.fullmirror, d, workdir=ud.clonedir) with create_atomic(ud.fullmirror, d) as tfile:
runfetchcmd("tar -czf %s ." % tfile, d, workdir=ud.clonedir)
runfetchcmd("touch %s.done" % ud.fullmirror, d) runfetchcmd("touch %s.done" % ud.fullmirror, d)
def clone_shallow_local(self, ud, dest, d): def clone_shallow_local(self, ud, dest, d):