From: Denys Dmytriyenko <denis@denix.org>
To: Richard Purdie <richard.purdie@linuxfoundation.org>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: [PATCH 1/2] package_manager: Filter to only rpms we depend upon
Date: Tue, 27 Feb 2018 16:36:38 -0500 [thread overview]
Message-ID: <20180227213638.GN2786@denix.org> (raw)
In-Reply-To: <1519761405-20421-1-git-send-email-richard.purdie@linuxfoundation.org>
Is it specific and/or limited to RPMs? How about other package managers?
On Tue, Feb 27, 2018 at 07:56:44PM +0000, Richard Purdie wrote:
> Currently do_rootfs gets to see all rpms in the deploy directory. This filters
> that view to only rpms which the image recipe has actual depends upon which
> potentially removes some sources of confusion in the image construction.
>
> This makes builds more reproducibile and also fixes contamination issues
> where dnf picks up packages it shouldn't be able to 'see'.
>
> [YOCTO #12039]
>
> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
> meta/lib/oe/package_manager.py | 114 ++++++++++++++++++++++++++++++++-
> meta/lib/oeqa/utils/package_manager.py | 3 +-
> 2 files changed, 113 insertions(+), 4 deletions(-)
>
> diff --git a/meta/lib/oe/package_manager.py b/meta/lib/oe/package_manager.py
> index f7e0134..f59eaf7 100644
> --- a/meta/lib/oe/package_manager.py
> +++ b/meta/lib/oe/package_manager.py
> @@ -454,6 +454,114 @@ class PackageManager(object, metaclass=ABCMeta):
> return res
> return _append(uris, base_paths)
>
> +def create_packages_dir(d, rpm_repo_dir, deploydir, taskname, filterbydependencies):
> + """
> + Go through our do_package_write_X dependencies and hardlink the packages we depend
> + upon into the repo directory. This prevents us seeing other packages that may
> + have been built that we don't depend upon and also packages for architectures we don't
> + support.
> + """
> + import errno
> +
> + taskdepdata = d.getVar("BB_TASKDEPDATA", False)
> + mytaskname = d.getVar("BB_RUNTASK")
> + pn = d.getVar("PN")
> + seendirs = set()
> + multilibs = {}
> +
> + rpm_subrepo_dir = oe.path.join(rpm_repo_dir, "rpm")
> +
> + bb.utils.remove(rpm_subrepo_dir, recurse=True)
> + bb.utils.mkdirhier(rpm_subrepo_dir)
> +
> + # Detect bitbake -b usage
> + nodeps = d.getVar("BB_LIMITEDDEPS") or False
> + if nodeps or not filterbydependencies:
> + oe.path.symlink(deploydir, rpm_subrepo_dir, True)
> + return
> +
> + start = None
> + for dep in taskdepdata:
> + data = taskdepdata[dep]
> + if data[1] == mytaskname and data[0] == pn:
> + start = dep
> + break
> + if start is None:
> + bb.fatal("Couldn't find ourself in BB_TASKDEPDATA?")
> + rpmdeps = set()
> + start = [start]
> + seen = set(start)
> + # Support direct dependencies (do_rootfs -> rpms)
> + # or indirect dependencies within PN (do_populate_sdk_ext -> do_rootfs -> rpms)
> + while start:
> + next = []
> + for dep2 in start:
> + for dep in taskdepdata[dep2][3]:
> + if taskdepdata[dep][0] != pn:
> + if "do_" + taskname in dep:
> + rpmdeps.add(dep)
> + elif dep not in seen:
> + next.append(dep)
> + seen.add(dep)
> + start = next
> +
> + for dep in rpmdeps:
> + c = taskdepdata[dep][0]
> +
> + d2 = d
> + variant = ''
> + if taskdepdata[dep][2].startswith("virtual:multilib"):
> + variant = taskdepdata[dep][2].split(":")[2]
> + if variant not in multilibs:
> + multilibs[variant] = oe.utils.get_multilib_datastore(variant, d)
> + d2 = multilibs[variant]
> +
> + if c.endswith("-native"):
> + pkgarchs = ["${BUILD_ARCH}"]
> + elif c.startswith("nativesdk-"):
> + pkgarchs = ["${SDK_ARCH}_${SDK_OS}", "allarch"]
> + elif "-cross-canadian" in c:
> + pkgarchs = ["${SDK_ARCH}_${SDK_ARCH}-${SDKPKGSUFFIX}"]
> + elif "-cross-" in c:
> + pkgarchs = ["${BUILD_ARCH}_${TARGET_ARCH}"]
> + elif "-crosssdk" in c:
> + pkgarchs = ["${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"]
> + else:
> + pkgarchs = ['${MACHINE_ARCH}']
> + pkgarchs = pkgarchs + list(reversed(d2.getVar("PACKAGE_EXTRA_ARCHS").split()))
> + pkgarchs.append('allarch')
> + pkgarchs.append('${SDK_ARCH}_${SDK_ARCH}-${SDKPKGSUFFIX}')
> +
> + for pkgarch in pkgarchs:
> + manifest = d2.expand("${SSTATE_MANIFESTS}/manifest-%s-%s.%s" % (pkgarch, c, taskname))
> + if os.path.exists(manifest):
> + break
> + if not os.path.exists(manifest):
> + bb.warn("Manifest %s not found in %s (variant '%s')?" % (manifest, d2.expand(" ".join(pkgarchs)), variant))
> + continue
> + with open(manifest, "r") as f:
> + for l in f:
> + l = l.strip()
> + dest = l.replace(deploydir, "")
> + dest = rpm_subrepo_dir + dest
> + if l.endswith("/"):
> + if dest not in seendirs:
> + bb.utils.mkdirhier(dest)
> + seendirs.add(dest)
> + continue
> + # Try to hardlink the file, copy if that fails
> + destdir = os.path.dirname(dest)
> + if destdir not in seendirs:
> + bb.utils.mkdirhier(destdir)
> + seendirs.add(destdir)
> + try:
> + os.link(l, dest)
> + except OSError as err:
> + if err.errno == errno.EXDEV:
> + bb.utils.copyfile(l, dest)
> + else:
> + raise
> +
> class RpmPM(PackageManager):
> def __init__(self,
> d,
> @@ -462,7 +570,8 @@ class RpmPM(PackageManager):
> task_name='target',
> arch_var=None,
> os_var=None,
> - rpm_repo_workdir="oe-rootfs-repo"):
> + rpm_repo_workdir="oe-rootfs-repo",
> + filterbydependencies=True):
> super(RpmPM, self).__init__(d)
> self.target_rootfs = target_rootfs
> self.target_vendor = target_vendor
> @@ -477,8 +586,7 @@ class RpmPM(PackageManager):
> self.primary_arch = self.d.getVar('MACHINE_ARCH')
>
> self.rpm_repo_dir = oe.path.join(self.d.getVar('WORKDIR'), rpm_repo_workdir)
> - bb.utils.mkdirhier(self.rpm_repo_dir)
> - oe.path.symlink(self.d.getVar('DEPLOY_DIR_RPM'), oe.path.join(self.rpm_repo_dir, "rpm"), True)
> + create_packages_dir(self.d, self.rpm_repo_dir, d.getVar("DEPLOY_DIR_RPM"), "package_write_rpm", filterbydependencies)
>
> self.saved_packaging_data = self.d.expand('${T}/saved_packaging_data/%s' % self.task_name)
> if not os.path.exists(self.d.expand('${T}/saved_packaging_data')):
> diff --git a/meta/lib/oeqa/utils/package_manager.py b/meta/lib/oeqa/utils/package_manager.py
> index 724afb2..afd5b8e 100644
> --- a/meta/lib/oeqa/utils/package_manager.py
> +++ b/meta/lib/oeqa/utils/package_manager.py
> @@ -14,7 +14,8 @@ def get_package_manager(d, root_path):
> if pkg_class == "rpm":
> pm = RpmPM(d,
> root_path,
> - d.getVar('TARGET_VENDOR'))
> + d.getVar('TARGET_VENDOR'),
> + filterbydependencies=False)
> pm.create_configs()
>
> elif pkg_class == "ipk":
> --
> 2.7.4
>
> --
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core
next prev parent reply other threads:[~2018-02-27 21:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-27 19:56 [PATCH 1/2] package_manager: Filter to only rpms we depend upon Richard Purdie
2018-02-27 19:56 ` [PATCH 2/2] sstatesig/staging/package_manager: Create common sstate manifest code Richard Purdie
2018-02-27 21:36 ` Denys Dmytriyenko [this message]
2018-02-27 21:53 ` [PATCH 1/2] package_manager: Filter to only rpms we depend upon Richard Purdie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180227213638.GN2786@denix.org \
--to=denis@denix.org \
--cc=openembedded-core@lists.openembedded.org \
--cc=richard.purdie@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox