pungi/pungi/phases/gather/link.py
Jan Kaluza 4562fba459 Optimize link_files by creating temporary dict mapping path to pkg_obj.
Previously, the pkg_object has been found by iterating over pkg_sets
for each package. This was quite slow given the number of RPMs in the
compose.

In this commit, the temporary dict is created which stores mapping
between path and pkg_obj and is used instead.

In this commit, the get_package_path is called just once instead of
twice in the loop which might also save some time.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-11 12:20:01 +00:00

168 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import kobo.rpmlib
from pungi.linker import LinkerPool
# TODO: global Linker instance - to keep hardlinks on dest?
# DONE: show overall progress, not each file
# TODO: (these should be logged separately)
def _get_src_nevra(compose, pkg_obj, srpm_map):
"""Return source N-E:V-R.A.rpm; guess if necessary."""
result = srpm_map.get(pkg_obj.sourcerpm, None)
if not result:
nvra = kobo.rpmlib.parse_nvra(pkg_obj.sourcerpm)
nvra["epoch"] = pkg_obj.epoch
result = kobo.rpmlib.make_nvra(nvra, add_rpm=True, force_epoch=True)
compose.log_warning(
"Package %s has no SRPM available, guessing epoch: %s"
% (pkg_obj.nevra, result)
)
return result
def get_package_path(filename, hashed_directory=False):
"""Get path for filename. If ``hashed_directory`` is ``True``, the path
will include a prefix based on the initial letter.
>>> get_package_path('my-package.rpm')
'my-package.rpm'
>>> get_package_path('my-package.rpm', True)
'm/my-package.rpm'
>>> get_package_path('My-Package.rpm', True)
'm/My-Package.rpm'
"""
if hashed_directory:
prefix = filename[0].lower()
return os.path.join(prefix, filename)
return filename
def link_files(compose, arch, variant, pkg_map, pkg_sets, manifest, srpm_map={}):
# srpm_map instance is shared between link_files() runs
msg = "Linking packages (arch: %s, variant: %s)" % (arch, variant)
compose.log_info("[BEGIN] %s" % msg)
link_type = compose.conf["link_type"]
pool = LinkerPool.with_workers(10, link_type, logger=compose._logger)
hashed_directories = compose.conf["hashed_directories"]
# Create temporary dict mapping package path to package object from pkgset
# so we do not have to search all pkg_sets for every package in pkg_map.
pkg_by_path = {}
for pkg_set in pkg_sets:
for path in pkg_set[arch]:
pkg_by_path[path] = pkg_set[arch][path]
packages_dir = compose.paths.compose.packages("src", variant)
packages_dir_relpath = compose.paths.compose.packages("src", variant, relative=True)
for pkg in pkg_map["srpm"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="source",
)
# update srpm_map
srpm_map.setdefault(pkg_obj.file_name, nevra)
packages_dir = compose.paths.compose.packages(arch, variant)
packages_dir_relpath = compose.paths.compose.packages(arch, variant, relative=True)
for pkg in pkg_map["rpm"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
src_nevra = _get_src_nevra(compose, pkg_obj, srpm_map)
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="binary",
srpm_nevra=src_nevra,
)
packages_dir = compose.paths.compose.debug_packages(arch, variant)
packages_dir_relpath = compose.paths.compose.debug_packages(
arch, variant, relative=True
)
for pkg in pkg_map["debuginfo"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
src_nevra = _get_src_nevra(compose, pkg_obj, srpm_map)
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="debug",
srpm_nevra=src_nevra,
)
pool.start()
pool.stop()
compose.log_info("[DONE ] %s" % msg)