aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMariano Lopez <mariano.lopez@linux.intel.com>2016-01-18 14:33:04 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-20 09:20:05 +0000
commit6cbb144a86a8188fad102bb281fd9e8d0a4b9142 (patch)
treee95e94b1e3bcc64c2aa7bdb4674e8549984bd3f3
parentf1d9f7b2ea930fec3198264a2d1d04088efc8f3c (diff)
downloadopenembedded-core-contrib-6cbb144a86a8188fad102bb281fd9e8d0a4b9142.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] Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com>
-rw-r--r--meta/lib/oe/package_manager.py135
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):
def list(self, format=None):
pass
+ @abstractmethod
+ def list_pkgs(self):
+ pass
+
+
+ """
+ This method parse the output from the package manager
+ and return a dictionary with the information of the
+ installed packages. This is used whne the packages are
+ in deb or ipk format
+ """
+ def opkg_query(self, cmd_output):
+ verregex = re.compile(' \([=<>]* [^ )]*\)')
+ output = dict()
+ filename = ""
+ dep = []
+ for line in cmd_output.splitlines():
+ line = line.rstrip()
+ if ':' in line:
+ if line.startswith("Package: "):
+ pkg = line.split(": ")[1]
+ elif line.startswith("Architecture: "):
+ arch = line.split(": ")[1]
+ elif line.startswith("Version: "):
+ ver = line.split(": ")[1]
+ elif line.startswith("File: "):
+ filename = line.split(": ")[1]
+ elif line.startswith("Depends: "):
+ depends = verregex.sub('', line.split(": ")[1])
+ for depend in depends.split(", "):
+ dep.append(depend)
+ elif line.startswith("Recommends: "):
+ recommends = verregex.sub('', line.split(": ")[1])
+ for recommend in recommends.split(", "):
+ dep.append("%s [REC]" % recommend)
+ else:
+ # IPK doesn't include the filename
+ if not filename:
+ filename = "%s_%s_%s.ipk" % (pkg, ver, arch)
+ if pkg:
+ output[pkg] = {"arch":arch, "ver":ver,
+ "filename":filename, "deps": dep }
+ pkg = ""
+ filename = ""
+ dep = []
+
+ if pkg:
+ if not filename:
+ filename = "%s_%s_%s.ipk" % (pkg, ver, arch)
+ output[pkg] = {"arch":arch, "ver":ver,
+ "filename":filename, "deps": dep }
+
+ return output
+
class RpmPkgsList(PkgsList):
def __init__(self, d, rootfs_dir, arch_var=None, os_var=None):
@@ -412,6 +466,59 @@ class RpmPkgsList(PkgsList):
return '\n'.join(output)
+ def list_pkgs(self):
+ cmd = self.rpm_cmd + ' --root ' + self.rootfs_dir
+ cmd += ' -D "_dbpath /var/lib/rpm" -qa'
+ if self.rpm_version == 4:
+ cmd += " --qf '[%{NAME} %{ARCH} %{VERSION}\n]'"
+ else:
+ cmd += " --qf '[%{NAME} %{ARCH} %{VERSION} %{PACKAGEORIGIN}\n]'"
+
+ try:
+ # bb.note(cmd)
+ tmp_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).strip()
+ except subprocess.CalledProcessError as e:
+ bb.fatal("Cannot get the installed packages list. Command '%s' "
+ "returned %d:\n%s" % (cmd, e.returncode, e.output))
+
+ output = dict()
+ deps = dict()
+ if self.rpm_version == 4:
+ bb.warn("Dependency listings are not supported with rpm 4 since rpmresolve does not work")
+ dependencies = ""
+ else:
+ dependencies = self._list_pkg_deps()
+
+ # Populate deps dictionary for better manipulation
+ for line in dependencies.splitlines():
+ pkg, dep = line.split("|")
+ if not pkg in deps:
+ deps[pkg] = list()
+ if not dep in deps[pkg]:
+ deps[pkg].append(dep)
+
+ for line in tmp_output.split('\n'):
+ if len(line.strip()) == 0:
+ continue
+ pkg = line.split()[0]
+ arch = line.split()[1]
+ ver = line.split()[2]
+ dep = deps.get(pkg, [])
+
+ # Skip GPG keys
+ if pkg == 'gpg-pubkey':
+ continue
+ if self.rpm_version == 4:
+ pkgorigin = "unknown"
+ else:
+ pkgorigin = line.split()[3]
+ new_pkg, new_arch = self._pkg_translate_smart_to_oe(pkg, arch)
+
+ output[new_pkg] = {"arch":new_arch, "ver":ver,
+ "filename":pkgorigin, "deps":dep}
+
+ return output
+
class OpkgPkgsList(PkgsList):
def __init__(self, d, rootfs_dir, config_file):
@@ -466,6 +573,19 @@ class OpkgPkgsList(PkgsList):
return '\n'.join(output)
+ def list_pkgs(self, format=None):
+ cmd = "%s %s status" % (self.opkg_cmd, self.opkg_args)
+
+ try:
+ # bb.note(cmd)
+ cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).strip()
+
+ except subprocess.CalledProcessError as e:
+ bb.fatal("Cannot get the installed packages list. Command '%s' "
+ "returned %d:\n%s" % (cmd, e.returncode, e.output))
+
+ return self.opkg_query(cmd_output)
+
class DpkgPkgsList(PkgsList):
def list(self, format=None):
@@ -523,6 +643,21 @@ class DpkgPkgsList(PkgsList):
return output
+ def list_pkgs(self):
+ cmd = [bb.utils.which(os.getenv('PATH'), "dpkg-query"),
+ "--admindir=%s/var/lib/dpkg" % self.rootfs_dir,
+ "-W"]
+
+ cmd.append("-f=Package: ${Package}\nArchitecture: ${PackageArch}\nVersion: ${Version}\nFile: ${Package}_${Version}_${Architecture}.deb\nDepends: ${Depends}\nRecommends: ${Recommends}\n\n")
+
+ try:
+ cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
+ except subprocess.CalledProcessError as e:
+ bb.fatal("Cannot get the installed packages list. Command '%s' "
+ "returned %d:\n%s" % (' '.join(cmd), e.returncode, e.output))
+
+ return self.opkg_query(cmd_output)
+
class PackageManager(object):
"""