package_manager: don't race on a file when installing complementary packages

PackageManager.install_complementary() uses WORKDIR/installed_pkgs.txt as a
temporary file but if two tasks are executing for the same recipe which uses
this file (e.g. bitbake my-image my-image:do_populate_sdk) then it's possible
for the file to be overwritten or deleted.

Instead of using a static filename, use tempfile to generate a unique name and
ensure it is cleaned up when finished.

Also move the glob generation/expansion earlier in the function as if there are
no globs to install, we don't need to generate a package list.

(From OE-Core rev: f5a1013ffa9815f22e13989e2bcb83f966e7ce2c)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Ross Burton 2017-04-18 16:19:12 +01:00 committed by Richard Purdie
parent 4c6d7a20bc
commit ae5d643114
1 changed files with 22 additions and 25 deletions

View File

@ -377,15 +377,6 @@ class PackageManager(object, metaclass=ABCMeta):
installation
"""
def install_complementary(self, globs=None):
# we need to write the list of installed packages to a file because the
# oe-pkgdata-util reads it from a file
installed_pkgs_file = os.path.join(self.d.getVar('WORKDIR'),
"installed_pkgs.txt")
with open(installed_pkgs_file, "w+") as installed_pkgs:
pkgs = self.list_installed()
output = oe.utils.format_pkg_list(pkgs, "arch")
installed_pkgs.write(output)
if globs is None:
globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY')
split_linguas = set()
@ -402,22 +393,28 @@ class PackageManager(object, metaclass=ABCMeta):
if globs is None:
return
cmd = [bb.utils.which(os.getenv('PATH'), "oe-pkgdata-util"),
"-p", self.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs_file,
globs]
exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY')
if exclude:
cmd.extend(['--exclude=' + '|'.join(exclude.split())])
try:
bb.note("Installing complementary packages ...")
bb.note('Running %s' % cmd)
complementary_pkgs = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode("utf-8")
except subprocess.CalledProcessError as e:
bb.fatal("Could not compute complementary packages list. Command "
"'%s' returned %d:\n%s" %
(' '.join(cmd), e.returncode, e.output.decode("utf-8")))
self.install(complementary_pkgs.split(), attempt_only=True)
os.remove(installed_pkgs_file)
# we need to write the list of installed packages to a file because the
# oe-pkgdata-util reads it from a file
with tempfile.NamedTemporaryFile(mode="w+", prefix="installed-pkgs") as installed_pkgs:
pkgs = self.list_installed()
output = oe.utils.format_pkg_list(pkgs, "arch")
installed_pkgs.write(output)
cmd = [bb.utils.which(os.getenv('PATH'), "oe-pkgdata-util"),
"-p", self.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs.name,
globs]
exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY')
if exclude:
cmd.extend(['--exclude=' + '|'.join(exclude.split())])
try:
bb.note("Installing complementary packages ...")
bb.note('Running %s' % cmd)
complementary_pkgs = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode("utf-8")
except subprocess.CalledProcessError as e:
bb.fatal("Could not compute complementary packages list. Command "
"'%s' returned %d:\n%s" %
(' '.join(cmd), e.returncode, e.output.decode("utf-8")))
self.install(complementary_pkgs.split(), attempt_only=True)
def deploy_dir_lock(self):
if self.deploy_dir is None: