diff options
-rw-r--r-- | meta/lib/oe/package_manager/__init__.py | 78 | ||||
-rw-r--r-- | meta/lib/oe/package_manager/deb/__init__.py | 26 | ||||
-rw-r--r-- | meta/lib/oe/package_manager/ipk/__init__.py | 20 | ||||
-rw-r--r-- | meta/lib/oe/package_manager/rpm/__init__.py | 8 | ||||
-rwxr-xr-x | scripts/oe-pkgdata-util | 14 |
5 files changed, 111 insertions, 35 deletions
diff --git a/meta/lib/oe/package_manager/__init__.py b/meta/lib/oe/package_manager/__init__.py index 88bc5ab195..b9a4218939 100644 --- a/meta/lib/oe/package_manager/__init__.py +++ b/meta/lib/oe/package_manager/__init__.py | |||
@@ -32,7 +32,7 @@ def create_index(arg): | |||
32 | 32 | ||
33 | def opkg_query(cmd_output): | 33 | def opkg_query(cmd_output): |
34 | """ | 34 | """ |
35 | This method parse the output from the package managerand return | 35 | This method parse the output from the package manager and return |
36 | a dictionary with the information of the packages. This is used | 36 | a dictionary with the information of the packages. This is used |
37 | when the packages are in deb or ipk format. | 37 | when the packages are in deb or ipk format. |
38 | """ | 38 | """ |
@@ -369,40 +369,48 @@ class PackageManager(object, metaclass=ABCMeta): | |||
369 | if globs: | 369 | if globs: |
370 | # we need to write the list of installed packages to a file because the | 370 | # we need to write the list of installed packages to a file because the |
371 | # oe-pkgdata-util reads it from a file | 371 | # oe-pkgdata-util reads it from a file |
372 | with tempfile.NamedTemporaryFile(mode="w+", prefix="installed-pkgs") as installed_pkgs: | 372 | with tempfile.NamedTemporaryFile(mode="w+", prefix="all-pkgs") as all_pkgs: |
373 | pkgs = self.list_installed() | 373 | with tempfile.NamedTemporaryFile(mode="w+", prefix="installed-pkgs") as installed_pkgs: |
374 | 374 | pkgs = self.list_installed() | |
375 | provided_pkgs = set() | 375 | |
376 | for pkg in pkgs.values(): | 376 | provided_pkgs = set() |
377 | provided_pkgs |= set(pkg.get('provs', [])) | 377 | for pkg in pkgs.values(): |
378 | 378 | provided_pkgs |= set(pkg.get('provs', [])) | |
379 | output = oe.utils.format_pkg_list(pkgs, "arch") | 379 | |
380 | installed_pkgs.write(output) | 380 | output = oe.utils.format_pkg_list(pkgs, "arch") |
381 | installed_pkgs.flush() | 381 | installed_pkgs.write(output) |
382 | 382 | installed_pkgs.flush() | |
383 | cmd = ["oe-pkgdata-util", | 383 | |
384 | "-p", self.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs.name, | 384 | cmd = ["oe-pkgdata-util", |
385 | globs] | 385 | "-p", self.d.getVar('PKGDATA_DIR'), "glob", |
386 | exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY') | 386 | installed_pkgs.name, globs] |
387 | if exclude: | 387 | |
388 | cmd.extend(['--exclude=' + '|'.join(exclude.split())]) | 388 | if hasattr(self, "list_all"): |
389 | try: | 389 | output_allpkg = self.list_all() |
390 | bb.note('Running %s' % cmd) | 390 | all_pkgs.write(output_allpkg) |
391 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 391 | all_pkgs.flush() |
392 | stdout, stderr = proc.communicate() | 392 | cmd.extend(["--allpkgs=%s" % all_pkgs.name]) |
393 | if stderr: bb.note(stderr.decode("utf-8")) | 393 | |
394 | complementary_pkgs = stdout.decode("utf-8") | 394 | exclude = self.d.getVar('PACKAGE_EXCLUDE_COMPLEMENTARY') |
395 | complementary_pkgs = set(complementary_pkgs.split()) | 395 | if exclude: |
396 | skip_pkgs = sorted(complementary_pkgs & provided_pkgs) | 396 | cmd.extend(['--exclude=' + '|'.join(exclude.split())]) |
397 | install_pkgs = sorted(complementary_pkgs - provided_pkgs) | 397 | try: |
398 | bb.note("Installing complementary packages ... %s (skipped already provided packages %s)" % ( | 398 | bb.note('Running %s' % cmd) |
399 | ' '.join(install_pkgs), | 399 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
400 | ' '.join(skip_pkgs))) | 400 | stdout, stderr = proc.communicate() |
401 | self.install(install_pkgs, hard_depends_only=True) | 401 | if stderr: bb.note(stderr.decode("utf-8")) |
402 | except subprocess.CalledProcessError as e: | 402 | complementary_pkgs = stdout.decode("utf-8") |
403 | bb.fatal("Could not compute complementary packages list. Command " | 403 | complementary_pkgs = set(complementary_pkgs.split()) |
404 | "'%s' returned %d:\n%s" % | 404 | skip_pkgs = sorted(complementary_pkgs & provided_pkgs) |
405 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | 405 | install_pkgs = sorted(complementary_pkgs - provided_pkgs) |
406 | bb.note("Installing complementary packages ... %s (skipped already provided packages %s)" % ( | ||
407 | ' '.join(install_pkgs), | ||
408 | ' '.join(skip_pkgs))) | ||
409 | self.install(install_pkgs, hard_depends_only=True) | ||
410 | except subprocess.CalledProcessError as e: | ||
411 | bb.fatal("Could not compute complementary packages list. Command " | ||
412 | "'%s' returned %d:\n%s" % | ||
413 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | ||
406 | 414 | ||
407 | if self.d.getVar('IMAGE_LOCALES_ARCHIVE') == '1': | 415 | if self.d.getVar('IMAGE_LOCALES_ARCHIVE') == '1': |
408 | target_arch = self.d.getVar('TARGET_ARCH') | 416 | target_arch = self.d.getVar('TARGET_ARCH') |
diff --git a/meta/lib/oe/package_manager/deb/__init__.py b/meta/lib/oe/package_manager/deb/__init__.py index eb48f3f982..0f74e1322f 100644 --- a/meta/lib/oe/package_manager/deb/__init__.py +++ b/meta/lib/oe/package_manager/deb/__init__.py | |||
@@ -112,6 +112,29 @@ class PMPkgsList(PkgsList): | |||
112 | 112 | ||
113 | return opkg_query(cmd_output) | 113 | return opkg_query(cmd_output) |
114 | 114 | ||
115 | def list_all_pkgs(self, apt_conf_file=None): | ||
116 | if not apt_conf_file: | ||
117 | apt_conf_file = self.d.expand("${APTCONF_TARGET}/apt/apt.conf") | ||
118 | os.environ['APT_CONFIG'] = apt_conf_file | ||
119 | |||
120 | cmd = [bb.utils.which(os.getenv('PATH'), "apt"), "list"] | ||
121 | |||
122 | try: | ||
123 | cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip().decode("utf-8") | ||
124 | except subprocess.CalledProcessError as e: | ||
125 | bb.fatal("Cannot get the all packages list. Command '%s' " | ||
126 | "returned %d:\n%s" % (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | ||
127 | |||
128 | all_pkgs_lines = [] | ||
129 | for line in cmd_output.splitlines(): | ||
130 | line_parts = line.split() | ||
131 | # the valid lines takes the format of something like "findutils-locale-ga/unknown 4.10.0-r0 amd64" | ||
132 | if len(line_parts) != 3: | ||
133 | continue | ||
134 | line_parts[0] = line_parts[0].split('/')[0] | ||
135 | new_line = ' '.join(line_parts) | ||
136 | all_pkgs_lines.append(new_line) | ||
137 | return "\n".join(all_pkgs_lines) | ||
115 | 138 | ||
116 | class DpkgPM(OpkgDpkgPM): | 139 | class DpkgPM(OpkgDpkgPM): |
117 | def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True): | 140 | def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True): |
@@ -436,6 +459,9 @@ class DpkgPM(OpkgDpkgPM): | |||
436 | def list_installed(self): | 459 | def list_installed(self): |
437 | return PMPkgsList(self.d, self.target_rootfs).list_pkgs() | 460 | return PMPkgsList(self.d, self.target_rootfs).list_pkgs() |
438 | 461 | ||
462 | def list_all(self): | ||
463 | return PMPkgsList(self.d, self.target_rootfs).list_all_pkgs(apt_conf_file=self.apt_conf_file) | ||
464 | |||
439 | def package_info(self, pkg): | 465 | def package_info(self, pkg): |
440 | """ | 466 | """ |
441 | Returns a dictionary with the package info. | 467 | Returns a dictionary with the package info. |
diff --git a/meta/lib/oe/package_manager/ipk/__init__.py b/meta/lib/oe/package_manager/ipk/__init__.py index 4794f31f88..2f330ec4f0 100644 --- a/meta/lib/oe/package_manager/ipk/__init__.py +++ b/meta/lib/oe/package_manager/ipk/__init__.py | |||
@@ -90,6 +90,23 @@ class PMPkgsList(PkgsList): | |||
90 | 90 | ||
91 | return opkg_query(cmd_output) | 91 | return opkg_query(cmd_output) |
92 | 92 | ||
93 | def list_all_pkgs(self, format=None): | ||
94 | cmd = "%s %s list" % (self.opkg_cmd, self.opkg_args) | ||
95 | |||
96 | # opkg returns success even when it printed some | ||
97 | # "Collected errors:" report to stderr. Mixing stderr into | ||
98 | # stdout then leads to random failures later on when | ||
99 | # parsing the output. To avoid this we need to collect both | ||
100 | # output streams separately and check for empty stderr. | ||
101 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) | ||
102 | cmd_output, cmd_stderr = p.communicate() | ||
103 | cmd_output = cmd_output.decode("utf-8") | ||
104 | cmd_stderr = cmd_stderr.decode("utf-8") | ||
105 | if p.returncode or cmd_stderr: | ||
106 | bb.fatal("Cannot get all packages list. Command '%s' " | ||
107 | "returned %d and stderr:\n%s" % (cmd, p.returncode, cmd_stderr)) | ||
108 | |||
109 | return cmd_output | ||
93 | 110 | ||
94 | class OpkgPM(OpkgDpkgPM): | 111 | class OpkgPM(OpkgDpkgPM): |
95 | def __init__(self, d, target_rootfs, config_file, archs, task_name='target', ipk_repo_workdir="oe-rootfs-repo", filterbydependencies=True, prepare_index=True): | 112 | def __init__(self, d, target_rootfs, config_file, archs, task_name='target', ipk_repo_workdir="oe-rootfs-repo", filterbydependencies=True, prepare_index=True): |
@@ -364,6 +381,9 @@ class OpkgPM(OpkgDpkgPM): | |||
364 | def list_installed(self): | 381 | def list_installed(self): |
365 | return PMPkgsList(self.d, self.target_rootfs).list_pkgs() | 382 | return PMPkgsList(self.d, self.target_rootfs).list_pkgs() |
366 | 383 | ||
384 | def list_all(self): | ||
385 | return PMPkgsList(self.d, self.target_rootfs).list_all_pkgs() | ||
386 | |||
367 | def dummy_install(self, pkgs): | 387 | def dummy_install(self, pkgs): |
368 | """ | 388 | """ |
369 | The following function dummy installs pkgs and returns the log of output. | 389 | The following function dummy installs pkgs and returns the log of output. |
diff --git a/meta/lib/oe/package_manager/rpm/__init__.py b/meta/lib/oe/package_manager/rpm/__init__.py index 20e6cb8744..a51057650a 100644 --- a/meta/lib/oe/package_manager/rpm/__init__.py +++ b/meta/lib/oe/package_manager/rpm/__init__.py | |||
@@ -275,6 +275,14 @@ class RpmPM(PackageManager): | |||
275 | elif os.path.isfile(source_dir): | 275 | elif os.path.isfile(source_dir): |
276 | shutil.copy2(source_dir, target_dir) | 276 | shutil.copy2(source_dir, target_dir) |
277 | 277 | ||
278 | def list_all(self): | ||
279 | output = self._invoke_dnf(["repoquery", "--all", "--queryformat", "Packages: %{name} %{arch} %{version}"], print_output = False) | ||
280 | all_pkgs_lines = [] | ||
281 | for line in output.splitlines(): | ||
282 | if line.startswith("Packages: "): | ||
283 | all_pkgs_lines.append(line.replace("Packages: ", "")) | ||
284 | return "\n".join(all_pkgs_lines) | ||
285 | |||
278 | def list_installed(self): | 286 | def list_installed(self): |
279 | output = self._invoke_dnf(["repoquery", "--installed", "--queryformat", "Package: %{name} %{arch} %{version} %{name}-%{version}-%{release}.%{arch}.rpm\nDependencies:\n%{requires}\nRecommendations:\n%{recommends}\nDependenciesEndHere:\n"], | 287 | output = self._invoke_dnf(["repoquery", "--installed", "--queryformat", "Package: %{name} %{arch} %{version} %{name}-%{version}-%{release}.%{arch}.rpm\nDependencies:\n%{requires}\nRecommendations:\n%{recommends}\nDependenciesEndHere:\n"], |
280 | print_output = False) | 288 | print_output = False) |
diff --git a/scripts/oe-pkgdata-util b/scripts/oe-pkgdata-util index 44ae40549a..5b7cd768a4 100755 --- a/scripts/oe-pkgdata-util +++ b/scripts/oe-pkgdata-util | |||
@@ -51,6 +51,15 @@ def glob(args): | |||
51 | 51 | ||
52 | skippedpkgs = set() | 52 | skippedpkgs = set() |
53 | mappedpkgs = set() | 53 | mappedpkgs = set() |
54 | allpkgs = set() | ||
55 | if args.allpkgs: | ||
56 | with open(args.allpkgs, 'r') as f: | ||
57 | for line in f: | ||
58 | fields = line.rstrip().split() | ||
59 | if not fields: | ||
60 | continue | ||
61 | else: | ||
62 | allpkgs.add(fields[0]) | ||
54 | with open(args.pkglistfile, 'r') as f: | 63 | with open(args.pkglistfile, 'r') as f: |
55 | for line in f: | 64 | for line in f: |
56 | fields = line.rstrip().split() | 65 | fields = line.rstrip().split() |
@@ -136,6 +145,10 @@ def glob(args): | |||
136 | logger.debug("%s is not a valid package!" % (pkg)) | 145 | logger.debug("%s is not a valid package!" % (pkg)) |
137 | break | 146 | break |
138 | 147 | ||
148 | if args.allpkgs: | ||
149 | if mappedpkg not in allpkgs: | ||
150 | continue | ||
151 | |||
139 | if mappedpkg: | 152 | if mappedpkg: |
140 | logger.debug("%s (%s) -> %s" % (pkg, g, mappedpkg)) | 153 | logger.debug("%s (%s) -> %s" % (pkg, g, mappedpkg)) |
141 | mappedpkgs.add(mappedpkg) | 154 | mappedpkgs.add(mappedpkg) |
@@ -592,6 +605,7 @@ def main(): | |||
592 | parser_glob.add_argument('pkglistfile', help='File listing packages (one package name per line)') | 605 | parser_glob.add_argument('pkglistfile', help='File listing packages (one package name per line)') |
593 | parser_glob.add_argument('glob', nargs="+", help='Glob expression for package names, e.g. *-dev') | 606 | parser_glob.add_argument('glob', nargs="+", help='Glob expression for package names, e.g. *-dev') |
594 | parser_glob.add_argument('-x', '--exclude', help='Exclude packages matching specified regex from the glob operation') | 607 | parser_glob.add_argument('-x', '--exclude', help='Exclude packages matching specified regex from the glob operation') |
608 | parser_glob.add_argument('-a', '--allpkgs', help='File listing all available packages (one package name per line)') | ||
595 | parser_glob.set_defaults(func=glob) | 609 | parser_glob.set_defaults(func=glob) |
596 | 610 | ||
597 | 611 | ||