diff options
author | Zac Medico <zmedico@gentoo.org> | 2024-02-11 18:10:52 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2024-02-12 05:57:42 -0800 |
commit | 67663e586320347e604727aef006bfe027bcd470 (patch) | |
tree | 8e7afade046e3519d89c044f9872b6c7b367d94c | |
parent | process._exec: Use _start_fork for os.fork() error handling (diff) | |
download | portage-67663e586320347e604727aef006bfe027bcd470.tar.gz portage-67663e586320347e604727aef006bfe027bcd470.tar.bz2 portage-67663e586320347e604727aef006bfe027bcd470.zip |
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@gentoo.org>
-rw-r--r-- | lib/_emerge/EbuildBuild.py | 39 | ||||
-rw-r--r-- | lib/_emerge/EbuildFetchonly.py | 10 | ||||
-rw-r--r-- | lib/portage/package/ebuild/doebuild.py | 30 | ||||
-rw-r--r-- | 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 81cbfdc08..d4a4c6dac 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 e887dd858..c806122be 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 1c89af5ac..4cf155e03 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 5f970fe62..bfa0c2b27 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("://")] |