From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 3D48D158095 for ; Wed, 28 Sep 2022 23:56:21 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 53F07E0943; Wed, 28 Sep 2022 23:56:20 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1288FE0973 for ; Wed, 28 Sep 2022 23:56:20 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 16D9E340D33 for ; Wed, 28 Sep 2022 23:56:19 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id E2DD075 for ; Wed, 28 Sep 2022 23:56:16 +0000 (UTC) From: "Sam James" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" Message-ID: <1664409368.b8c3f38ec5eec077e69451f1f3126999065ea132.sam@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: bin/, lib/_emerge/, lib/portage/ X-VCS-Repository: proj/portage X-VCS-Files: bin/gpkg-helper.py bin/quickpkg lib/_emerge/Binpkg.py lib/portage/gpkg.py X-VCS-Directories: lib/portage/ lib/_emerge/ bin/ X-VCS-Committer: sam X-VCS-Committer-Name: Sam James X-VCS-Revision: b8c3f38ec5eec077e69451f1f3126999065ea132 X-VCS-Branch: master Date: Wed, 28 Sep 2022 23:56:16 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: fbea7aa5-cfab-497f-83b3-e429a454ee0c X-Archives-Hash: 078de94a41b22466f792a4004d045a17 commit: b8c3f38ec5eec077e69451f1f3126999065ea132 Author: Sheng Yu protonmail com> AuthorDate: Sun Sep 25 04:29:55 2022 +0000 Commit: Sam James gentoo org> CommitDate: Wed Sep 28 23:56:08 2022 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=b8c3f38e Add more error handling for binpkgs And catch process Exception spawned by portage itself. e.g. bad decompress command. Bug: https://bugs.gentoo.org/871570 Signed-off-by: Sheng Yu protonmail.com> Closes: https://github.com/gentoo/portage/pull/910 Signed-off-by: Sam James gentoo.org> bin/gpkg-helper.py | 12 +++++++++--- bin/quickpkg | 30 ++++++++++++++++++------------ lib/_emerge/Binpkg.py | 34 ++++++++++++++++++++-------------- lib/portage/gpkg.py | 9 +++++++-- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/bin/gpkg-helper.py b/bin/gpkg-helper.py index 4752c84ee..4481f4b93 100755 --- a/bin/gpkg-helper.py +++ b/bin/gpkg-helper.py @@ -8,9 +8,11 @@ import portage portage._internal_caller = True from portage import os +from portage.output import EOutput def command_compose(args): + eout = EOutput() usage = "usage: compose \n" @@ -31,9 +33,13 @@ def command_compose(args): sys.stderr.write("Argument 4 is not a directory: '%s'\n" % image_dir) return 1 - gpkg_file = portage.gpkg.gpkg(portage.settings, basename, binpkg_path) - metadata = gpkg_file._generate_metadata_from_dir(metadata_dir) - gpkg_file.compress(image_dir, metadata) + try: + gpkg_file = portage.gpkg.gpkg(portage.settings, basename, binpkg_path) + metadata = gpkg_file._generate_metadata_from_dir(metadata_dir) + gpkg_file.compress(image_dir, metadata) + except portage.exception.CompressorOperationFailed: + eout.eerror("Compressor Operation Failed") + exit(1) return os.EX_OK diff --git a/bin/quickpkg b/bin/quickpkg index eef5f912f..67eee697a 100755 --- a/bin/quickpkg +++ b/bin/quickpkg @@ -27,6 +27,7 @@ from portage.dbapi.dep_expand import dep_expand from portage.dep import Atom, use_reduce from portage.exception import ( AmbiguousPackageName, + CompressorOperationFailed, InvalidAtom, InvalidData, InvalidBinaryPackageFormat, @@ -203,24 +204,29 @@ def quickpkg_atom(options, infos, arg, eout): ) else: raise InvalidBinaryPackageFormat(binpkg_format) + except CompressorOperationFailed as e: + eout.eerror(f"Compressor operation failed") + os.remove(binpkg_tmpfile) + binpkg_tmpfile = None finally: if have_lock: dblnk.unlockdb() - pkg_info = bintree.inject(cpv, current_pkg_path=binpkg_tmpfile) - # The pkg_info value ensures that the following getname call - # returns the correct path when FEATURES=binpkg-multi-instance - # is enabled, but fallback to cpv in case the inject call - # returned None due to some kind of failure. - binpkg_path = bintree.getname(pkg_info or cpv) - try: - s = os.stat(binpkg_path) - except OSError: - s = None + if binpkg_tmpfile is not None: + pkg_info = bintree.inject(cpv, current_pkg_path=binpkg_tmpfile) + # The pkg_info value ensures that the following getname call + # returns the correct path when FEATURES=binpkg-multi-instance + # is enabled, but fallback to cpv in case the inject call + # returned None due to some kind of failure. + binpkg_path = bintree.getname(pkg_info or cpv) + try: + s = os.stat(binpkg_path) + except OSError: + s = None - if s is None or pkg_info is None: + if binpkg_tmpfile is None or s is None or pkg_info is None: # Sanity check, shouldn't happen normally. eout.eend(1) - eout.eerror("Failed to create package: '%s'" % binpkg_path) + eout.eerror(f"Failed to create package: '{cpv}'") retval |= 1 else: eout.eend(0) diff --git a/lib/_emerge/Binpkg.py b/lib/_emerge/Binpkg.py index 7ce0da15f..6c1c0666a 100644 --- a/lib/_emerge/Binpkg.py +++ b/lib/_emerge/Binpkg.py @@ -12,7 +12,6 @@ from _emerge.EbuildMerge import EbuildMerge from _emerge.EbuildBuildDir import EbuildBuildDir from _emerge.SpawnProcess import SpawnProcess from portage.eapi import eapi_exports_replace_vars -from portage.exception import PortageException from portage.output import colorize from portage.util import ensure_dirs from portage.util._async.AsyncTaskFuture import AsyncTaskFuture @@ -393,7 +392,17 @@ class Binpkg(CompositeTask): def _unpack_metadata_exit(self, unpack_metadata): if self._default_exit(unpack_metadata) != os.EX_OK: - unpack_metadata.future.result() + try: + unpack_metadata.future.result() + except Exception as e: + self._writemsg_level( + colorize( + "BAD", + f"!!! Error Extracting '{self._pkg_path}', {e}\n", + ), + noiselevel=-1, + level=logging.ERROR, + ) self._async_unlock_builddir(returncode=self.returncode) return @@ -427,18 +436,15 @@ class Binpkg(CompositeTask): if self._default_exit(unpack_contents) != os.EX_OK: try: unpack_contents.future.result() - err = "" - except PortageException as e: - err = e - - self._writemsg_level( - colorize( - "BAD", - f"!!! Error Extracting '{self._pkg_path}', {err}\n", - ), - noiselevel=-1, - level=logging.ERROR, - ) + except Exception as e: + self._writemsg_level( + colorize( + "BAD", + f"!!! Error Extracting '{self._pkg_path}', {e}\n", + ), + noiselevel=-1, + level=logging.ERROR, + ) self._async_unlock_builddir(returncode=self.returncode) return diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py index c0a80208f..ff2195854 100644 --- a/lib/portage/gpkg.py +++ b/lib/portage/gpkg.py @@ -214,7 +214,11 @@ class tar_stream_writer: if self.proc: # Write to external program - self.proc.stdin.write(data) + try: + self.proc.stdin.write(data) + except BrokenPipeError: + self.error = True + raise CompressorOperationFailed("PIPE broken") else: # Write to container self.container.fileobj.write(data) @@ -232,7 +236,8 @@ class tar_stream_writer: if self.proc is not None: self.proc.stdin.close() if self.proc.wait() != os.EX_OK: - raise CompressorOperationFailed("compression failed") + if not self.error: + raise CompressorOperationFailed("compression failed") if self.read_thread.is_alive(): self.read_thread.join()