commit: 67663e586320347e604727aef006bfe027bcd470 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Mon Feb 12 02:10:52 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Mon Feb 12 13:57:42 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=67663e58
EbuildBuild: Execute EbuildFetchonly in subprocess Execute EbuildFetchonly in a subprocess since it needs to run the event loop itself (even for pretend mode since it may need to fetch mirror layouts as reported in bug 702154). Also remove obsolete loop.is_running() case in doebuild related to bug 601252, since it will fail if a mirror layout file needs to be fetched, so we should just assume that the event loop is not running. Set fetched = 2 for listonly (pretend) mode in the fetch function so that EbuildFetchonly will properly report success for this mode. Pass ebuild_path to EbuildFetchonly, and also remove setcpv call from EbuildFetchonly since it's called earlier in EbuildBuild. Bug: https://bugs.gentoo.org/924287 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/_emerge/EbuildBuild.py | 39 +++++++++++++++++----------------- lib/_emerge/EbuildFetchonly.py | 10 +++------ lib/portage/package/ebuild/doebuild.py | 30 ++++++++------------------ lib/portage/package/ebuild/fetch.py | 1 + 4 files changed, 33 insertions(+), 47 deletions(-) diff --git a/lib/_emerge/EbuildBuild.py b/lib/_emerge/EbuildBuild.py index 81cbfdc085..d4a4c6dacb 100644 --- a/lib/_emerge/EbuildBuild.py +++ b/lib/_emerge/EbuildBuild.py @@ -1,4 +1,4 @@ -# Copyright 1999-2020 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import functools @@ -22,6 +22,7 @@ from portage.package.ebuild.digestcheck import digestcheck from portage.package.ebuild.doebuild import _check_temp_dir from portage.package.ebuild._spawn_nofetch import SpawnNofetchWithoutBuilddir from portage.util._async.AsyncTaskFuture import AsyncTaskFuture +from portage.util.futures.executor.fork import ForkExecutor from portage.util.path import first_existing @@ -152,29 +153,25 @@ class EbuildBuild(CompositeTask): if opts.fetchonly: if opts.pretend: fetcher = EbuildFetchonly( + ebuild_path=self._ebuild_path, fetch_all=opts.fetch_all_uri, pkg=pkg, pretend=opts.pretend, settings=settings, ) - retval = fetcher.execute() - if retval == os.EX_OK: - self._current_task = None - self.returncode = os.EX_OK - self._async_wait() - else: - # For pretend mode, the convention it to execute - # pkg_nofetch and return a successful exitcode. - self._start_task( - SpawnNofetchWithoutBuilddir( - background=self.background, - portdb=self.pkg.root_config.trees[self._tree].dbapi, - ebuild_path=self._ebuild_path, - scheduler=self.scheduler, - settings=self.settings, + # Execute EbuildFetchonly in a subprocess since it needs to + # run the event loop itself (even for pretend mode since it + # may need to fetch mirror layouts as reported in bug 702154). + self._start_task( + AsyncTaskFuture( + background=self.background, + scheduler=self.scheduler, + future=self.scheduler.run_in_executor( + ForkExecutor(loop=self.scheduler), fetcher.execute ), - self._default_final_exit, - ) + ), + self._fetchonly_exit, + ) return quiet_setting = settings.get("PORTAGE_QUIET", False) @@ -241,8 +238,12 @@ class EbuildBuild(CompositeTask): self._start_task(pre_clean_phase, self._pre_clean_exit) def _fetchonly_exit(self, fetcher): + if not fetcher.cancelled and isinstance(fetcher, AsyncTaskFuture): + # Set returncode from EbuildFetchonly.execute() result, since + # it can fail if it can't resolve a mirror for a file. + fetcher.returncode = fetcher.future.result() self._final_exit(fetcher) - if self.returncode != os.EX_OK: + if not self.cancelled and self.returncode != os.EX_OK: self.returncode = None portdb = self.pkg.root_config.trees[self._tree].dbapi self._start_task( diff --git a/lib/_emerge/EbuildFetchonly.py b/lib/_emerge/EbuildFetchonly.py index e887dd858d..c806122bea 100644 --- a/lib/_emerge/EbuildFetchonly.py +++ b/lib/_emerge/EbuildFetchonly.py @@ -1,4 +1,4 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import portage @@ -8,20 +8,16 @@ from portage.util.SlotObject import SlotObject class EbuildFetchonly(SlotObject): - __slots__ = ("fetch_all", "pkg", "pretend", "settings") + __slots__ = ("ebuild_path", "fetch_all", "pkg", "pretend", "settings") def execute(self): settings = self.settings pkg = self.pkg portdb = pkg.root_config.trees["porttree"].dbapi - ebuild_path = portdb.findname(pkg.cpv, myrepo=pkg.repo) - if ebuild_path is None: - raise AssertionError(f"ebuild not found for '{pkg.cpv}'") - settings.setcpv(pkg) debug = settings.get("PORTAGE_DEBUG") == "1" rval = portage.doebuild( - ebuild_path, + self.ebuild_path, "fetch", settings=settings, debug=debug, diff --git a/lib/portage/package/ebuild/doebuild.py b/lib/portage/package/ebuild/doebuild.py index 1c89af5ac8..4cf155e033 100644 --- a/lib/portage/package/ebuild/doebuild.py +++ b/lib/portage/package/ebuild/doebuild.py @@ -1334,32 +1334,20 @@ def doebuild( dist_digests = mf.getTypeDigests("DIST") loop = asyncio._safe_loop() - if loop.is_running(): - # Called by EbuildFetchonly for emerge --pretend --fetchonly. - success = fetch( + success = loop.run_until_complete( + loop.run_in_executor( + ForkExecutor(loop=loop), + _fetch_subprocess, fetchme, mysettings, - listonly=listonly, - fetchonly=fetchonly, - allow_missing_digests=False, - digests=dist_digests, - ) - else: - success = loop.run_until_complete( - loop.run_in_executor( - ForkExecutor(loop=loop), - _fetch_subprocess, - fetchme, - mysettings, - listonly, - dist_digests, - fetchonly, - ) + listonly, + dist_digests, + fetchonly, ) + ) if not success: # Since listonly mode is called by emerge --pretend in an - # asynchronous context, spawn_nofetch would trigger event loop - # recursion here, therefore delegate execution of pkg_nofetch + # asynchronous context, execution of pkg_nofetch is delegated # to the caller (bug 657360). if not listonly: spawn_nofetch( diff --git a/lib/portage/package/ebuild/fetch.py b/lib/portage/package/ebuild/fetch.py index 5f970fe62d..bfa0c2b275 100644 --- a/lib/portage/package/ebuild/fetch.py +++ b/lib/portage/package/ebuild/fetch.py @@ -1562,6 +1562,7 @@ def fetch( tried_locations.add(loc) if listonly: writemsg_stdout(loc + " ", noiselevel=-1) + fetched = 2 continue # allow different fetchcommands per protocol protocol = loc[0 : loc.find("://")]
