diff options
| author | Mariano Lopez <mariano.lopez@linux.intel.com> | 2016-01-18 14:33:04 +0000 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-20 17:07:15 +0000 |
| commit | c708411f20f8944eaabce40121b61e17d26e8a15 (patch) | |
| tree | f5fed6f77be0c8c0aaae69149cc396f48676425e | |
| parent | 113e1365a88c5bcdaa8f6b06146de6ff2454a385 (diff) | |
| download | poky-c708411f20f8944eaabce40121b61e17d26e8a15.tar.gz | |
lib/oe/package_manager: Add list_pkgs() to PkgsList class
Currently the class PkgList returns a formated string of the
installed packages. It would be more clean to pass a standard
data structure to the callers instead to format the output
inside PkgsList class.
This patch adds list_pkgs() method to PkgsList class to get the
all the information for installed packages and return a dictionary
with the info.
[YOCTO #7427]
(From OE-Core rev: 6cbb144a86a8188fad102bb281fd9e8d0a4b9142)
Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/lib/oe/package_manager.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/meta/lib/oe/package_manager.py b/meta/lib/oe/package_manager.py index bc397213ae..79cadda682 100644 --- a/meta/lib/oe/package_manager.py +++ b/meta/lib/oe/package_manager.py | |||
| @@ -296,6 +296,60 @@ class PkgsList(object): | |||
| 296 | def list(self, format=None): | 296 | def list(self, format=None): |
| 297 | pass | 297 | pass |
| 298 | 298 | ||
| 299 | @abstractmethod | ||
| 300 | def list_pkgs(self): | ||
| 301 | pass | ||
| 302 | |||
| 303 | |||
| 304 | """ | ||
| 305 | This method parse the output from the package manager | ||
| 306 | and return a dictionary with the information of the | ||
| 307 | installed packages. This is used whne the packages are | ||
| 308 | in deb or ipk format | ||
| 309 | """ | ||
| 310 | def opkg_query(self, cmd_output): | ||
| 311 | verregex = re.compile(' \([=<>]* [^ )]*\)') | ||
| 312 | output = dict() | ||
| 313 | filename = "" | ||
| 314 | dep = [] | ||
| 315 | for line in cmd_output.splitlines(): | ||
| 316 | line = line.rstrip() | ||
| 317 | if ':' in line: | ||
| 318 | if line.startswith("Package: "): | ||
| 319 | pkg = line.split(": ")[1] | ||
| 320 | elif line.startswith("Architecture: "): | ||
| 321 | arch = line.split(": ")[1] | ||
| 322 | elif line.startswith("Version: "): | ||
| 323 | ver = line.split(": ")[1] | ||
| 324 | elif line.startswith("File: "): | ||
| 325 | filename = line.split(": ")[1] | ||
| 326 | elif line.startswith("Depends: "): | ||
| 327 | depends = verregex.sub('', line.split(": ")[1]) | ||
| 328 | for depend in depends.split(", "): | ||
| 329 | dep.append(depend) | ||
| 330 | elif line.startswith("Recommends: "): | ||
| 331 | recommends = verregex.sub('', line.split(": ")[1]) | ||
| 332 | for recommend in recommends.split(", "): | ||
| 333 | dep.append("%s [REC]" % recommend) | ||
| 334 | else: | ||
| 335 | # IPK doesn't include the filename | ||
| 336 | if not filename: | ||
| 337 | filename = "%s_%s_%s.ipk" % (pkg, ver, arch) | ||
| 338 | if pkg: | ||
| 339 | output[pkg] = {"arch":arch, "ver":ver, | ||
| 340 | "filename":filename, "deps": dep } | ||
| 341 | pkg = "" | ||
| 342 | filename = "" | ||
| 343 | dep = [] | ||
| 344 | |||
| 345 | if pkg: | ||
| 346 | if not filename: | ||
| 347 | filename = "%s_%s_%s.ipk" % (pkg, ver, arch) | ||
| 348 | output[pkg] = {"arch":arch, "ver":ver, | ||
| 349 | "filename":filename, "deps": dep } | ||
| 350 | |||
| 351 | return output | ||
| 352 | |||
| 299 | 353 | ||
| 300 | class RpmPkgsList(PkgsList): | 354 | class RpmPkgsList(PkgsList): |
| 301 | def __init__(self, d, rootfs_dir, arch_var=None, os_var=None): | 355 | def __init__(self, d, rootfs_dir, arch_var=None, os_var=None): |
| @@ -412,6 +466,59 @@ class RpmPkgsList(PkgsList): | |||
| 412 | 466 | ||
| 413 | return '\n'.join(output) | 467 | return '\n'.join(output) |
| 414 | 468 | ||
| 469 | def list_pkgs(self): | ||
| 470 | cmd = self.rpm_cmd + ' --root ' + self.rootfs_dir | ||
| 471 | cmd += ' -D "_dbpath /var/lib/rpm" -qa' | ||
| 472 | if self.rpm_version == 4: | ||
| 473 | cmd += " --qf '[%{NAME} %{ARCH} %{VERSION}\n]'" | ||
| 474 | else: | ||
| 475 | cmd += " --qf '[%{NAME} %{ARCH} %{VERSION} %{PACKAGEORIGIN}\n]'" | ||
| 476 | |||
| 477 | try: | ||
| 478 | # bb.note(cmd) | ||
| 479 | tmp_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).strip() | ||
| 480 | except subprocess.CalledProcessError as e: | ||
| 481 | bb.fatal("Cannot get the installed packages list. Command '%s' " | ||
| 482 | "returned %d:\n%s" % (cmd, e.returncode, e.output)) | ||
| 483 | |||
| 484 | output = dict() | ||
| 485 | deps = dict() | ||
| 486 | if self.rpm_version == 4: | ||
| 487 | bb.warn("Dependency listings are not supported with rpm 4 since rpmresolve does not work") | ||
| 488 | dependencies = "" | ||
| 489 | else: | ||
| 490 | dependencies = self._list_pkg_deps() | ||
| 491 | |||
| 492 | # Populate deps dictionary for better manipulation | ||
| 493 | for line in dependencies.splitlines(): | ||
| 494 | pkg, dep = line.split("|") | ||
| 495 | if not pkg in deps: | ||
| 496 | deps[pkg] = list() | ||
| 497 | if not dep in deps[pkg]: | ||
| 498 | deps[pkg].append(dep) | ||
| 499 | |||
| 500 | for line in tmp_output.split('\n'): | ||
| 501 | if len(line.strip()) == 0: | ||
| 502 | continue | ||
| 503 | pkg = line.split()[0] | ||
| 504 | arch = line.split()[1] | ||
| 505 | ver = line.split()[2] | ||
| 506 | dep = deps.get(pkg, []) | ||
| 507 | |||
| 508 | # Skip GPG keys | ||
| 509 | if pkg == 'gpg-pubkey': | ||
| 510 | continue | ||
| 511 | if self.rpm_version == 4: | ||
| 512 | pkgorigin = "unknown" | ||
| 513 | else: | ||
| 514 | pkgorigin = line.split()[3] | ||
| 515 | new_pkg, new_arch = self._pkg_translate_smart_to_oe(pkg, arch) | ||
| 516 | |||
| 517 | output[new_pkg] = {"arch":new_arch, "ver":ver, | ||
| 518 | "filename":pkgorigin, "deps":dep} | ||
| 519 | |||
| 520 | return output | ||
| 521 | |||
| 415 | 522 | ||
| 416 | class OpkgPkgsList(PkgsList): | 523 | class OpkgPkgsList(PkgsList): |
| 417 | def __init__(self, d, rootfs_dir, config_file): | 524 | def __init__(self, d, rootfs_dir, config_file): |
| @@ -466,6 +573,19 @@ class OpkgPkgsList(PkgsList): | |||
| 466 | 573 | ||
| 467 | return '\n'.join(output) | 574 | return '\n'.join(output) |
| 468 | 575 | ||
| 576 | def list_pkgs(self, format=None): | ||
| 577 | cmd = "%s %s status" % (self.opkg_cmd, self.opkg_args) | ||
| 578 | |||
| 579 | try: | ||
| 580 | # bb.note(cmd) | ||
| 581 | cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).strip() | ||
| 582 | |||
| 583 | except subprocess.CalledProcessError as e: | ||
| 584 | bb.fatal("Cannot get the installed packages list. Command '%s' " | ||
| 585 | "returned %d:\n%s" % (cmd, e.returncode, e.output)) | ||
| 586 | |||
| 587 | return self.opkg_query(cmd_output) | ||
| 588 | |||
| 469 | 589 | ||
| 470 | class DpkgPkgsList(PkgsList): | 590 | class DpkgPkgsList(PkgsList): |
| 471 | def list(self, format=None): | 591 | def list(self, format=None): |
| @@ -523,6 +643,21 @@ class DpkgPkgsList(PkgsList): | |||
| 523 | 643 | ||
| 524 | return output | 644 | return output |
| 525 | 645 | ||
| 646 | def list_pkgs(self): | ||
| 647 | cmd = [bb.utils.which(os.getenv('PATH'), "dpkg-query"), | ||
| 648 | "--admindir=%s/var/lib/dpkg" % self.rootfs_dir, | ||
| 649 | "-W"] | ||
| 650 | |||
| 651 | cmd.append("-f=Package: ${Package}\nArchitecture: ${PackageArch}\nVersion: ${Version}\nFile: ${Package}_${Version}_${Architecture}.deb\nDepends: ${Depends}\nRecommends: ${Recommends}\n\n") | ||
| 652 | |||
| 653 | try: | ||
| 654 | cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip() | ||
| 655 | except subprocess.CalledProcessError as e: | ||
| 656 | bb.fatal("Cannot get the installed packages list. Command '%s' " | ||
| 657 | "returned %d:\n%s" % (' '.join(cmd), e.returncode, e.output)) | ||
| 658 | |||
| 659 | return self.opkg_query(cmd_output) | ||
| 660 | |||
| 526 | 661 | ||
| 527 | class PackageManager(object): | 662 | class PackageManager(object): |
| 528 | """ | 663 | """ |
