From: "Zac Medico" <zmedico@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/package/ebuild/, pym/_emerge/
Date: Tue, 4 Apr 2017 03:20:30 +0000 (UTC) [thread overview]
Message-ID: <1491275969.285d5d038d8bb8a17d853816e156147c8c59f248.zmedico@gentoo> (raw)
commit: 285d5d038d8bb8a17d853816e156147c8c59f248
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 3 00:40:55 2017 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue Apr 4 03:19:29 2017 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=285d5d03
EbuildBuild: async spawn_nofetch in _fetchonly_exit (bug 614116)
Replace a synchronous spawn_nofetch call with an asynchronous one,
in order to avoid event loop recursion which is not compatible with
asyncio. This involves refactoring of spawn_nofetch to provide an
asynchronous interface.
X-Gentoo-bug: 614116
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=614116
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>
pym/_emerge/EbuildBuild.py | 18 ++++-
pym/portage/package/ebuild/_spawn_nofetch.py | 106 +++++++++++++++++----------
2 files changed, 85 insertions(+), 39 deletions(-)
diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
index 11eb1c93e..48f470483 100644
--- a/pym/_emerge/EbuildBuild.py
+++ b/pym/_emerge/EbuildBuild.py
@@ -22,7 +22,7 @@ import portage
from portage import _encodings, _unicode_decode, _unicode_encode, os
from portage.package.ebuild.digestcheck import digestcheck
from portage.package.ebuild.doebuild import _check_temp_dir
-from portage.package.ebuild._spawn_nofetch import spawn_nofetch
+from portage.package.ebuild._spawn_nofetch import SpawnNofetchWithoutBuilddir
class EbuildBuild(CompositeTask):
@@ -165,8 +165,22 @@ class EbuildBuild(CompositeTask):
def _fetchonly_exit(self, fetcher):
self._final_exit(fetcher)
if self.returncode != os.EX_OK:
+ self.returncode = None
portdb = self.pkg.root_config.trees[self._tree].dbapi
- spawn_nofetch(portdb, self._ebuild_path, settings=self.settings)
+ self._start_task(SpawnNofetchWithoutBuilddir(
+ background=self.background,
+ portdb=portdb,
+ ebuild_path=self._ebuild_path,
+ scheduler=self.scheduler,
+ settings=self.settings),
+ self._nofetch_without_builddir_exit)
+ return
+
+ self.wait()
+
+ def _nofetch_without_builddir_exit(self, nofetch):
+ self._final_exit(nofetch)
+ self.returncode = 1
self.wait()
def _pre_clean_exit(self, pre_clean_phase):
diff --git a/pym/portage/package/ebuild/_spawn_nofetch.py b/pym/portage/package/ebuild/_spawn_nofetch.py
index 0fc53c8ca..bbfd5b72b 100644
--- a/pym/portage/package/ebuild/_spawn_nofetch.py
+++ b/pym/portage/package/ebuild/_spawn_nofetch.py
@@ -14,11 +14,14 @@ from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
from portage.util._async.SchedulerInterface import SchedulerInterface
from portage.util._eventloop.EventLoop import EventLoop
from portage.util._eventloop.global_event_loop import global_event_loop
+from _emerge.CompositeTask import CompositeTask
from _emerge.EbuildPhase import EbuildPhase
-def spawn_nofetch(portdb, ebuild_path, settings=None, fd_pipes=None):
+
+class SpawnNofetchWithoutBuilddir(CompositeTask):
"""
- This spawns pkg_nofetch if appropriate. The settings parameter
+ This spawns pkg_nofetch if appropriate, while avoiding the
+ need to lock a global build directory. The settings parameter
is useful only if setcpv has already been called in order
to cache metadata. It will be cloned internally, in order to
prevent any changes from interfering with the calling code.
@@ -40,33 +43,42 @@ def spawn_nofetch(portdb, ebuild_path, settings=None, fd_pipes=None):
to be displayed for problematic packages even though they do
not set RESTRICT=fetch (bug #336499).
- This function does nothing if the PORTAGE_PARALLEL_FETCHONLY
+ This class does nothing if the PORTAGE_PARALLEL_FETCHONLY
variable is set in the config instance.
"""
+ __slots__ = ('ebuild_path', 'fd_pipes', 'portdb', 'settings',
+ '_private_tmpdir')
+
+ def _start(self):
+ settings = self.settings
+ if settings is None:
+ settings = self.portdb.settings
+
+ if 'PORTAGE_PARALLEL_FETCHONLY' in settings:
+ # parallel-fetch mode
+ self.returncode = os.EX_OK
+ self._async_wait()
+ return
- if settings is None:
- settings = config(clone=portdb.settings)
- else:
- settings = config(clone=settings)
-
- if 'PORTAGE_PARALLEL_FETCHONLY' in settings:
- return os.EX_OK
-
- # We must create our private PORTAGE_TMPDIR before calling
- # doebuild_environment(), since lots of variables such
- # as PORTAGE_BUILDDIR refer to paths inside PORTAGE_TMPDIR.
- portage_tmpdir = settings.get('PORTAGE_TMPDIR')
- if not portage_tmpdir or not os.access(portage_tmpdir, os.W_OK):
- portage_tmpdir = None
- private_tmpdir = tempfile.mkdtemp(dir=portage_tmpdir)
- settings['PORTAGE_TMPDIR'] = private_tmpdir
- settings.backup_changes('PORTAGE_TMPDIR')
- # private temp dir was just created, so it's not locked yet
- settings.pop('PORTAGE_BUILDDIR_LOCKED', None)
-
- try:
- doebuild_environment(ebuild_path, 'nofetch',
- settings=settings, db=portdb)
+ # Prevent temporary config changes from interfering
+ # with config instances that are reused.
+ settings = self.settings = config(clone=settings)
+
+ # We must create our private PORTAGE_TMPDIR before calling
+ # doebuild_environment(), since lots of variables such
+ # as PORTAGE_BUILDDIR refer to paths inside PORTAGE_TMPDIR.
+ portage_tmpdir = settings.get('PORTAGE_TMPDIR')
+ if not portage_tmpdir or not os.access(portage_tmpdir, os.W_OK):
+ portage_tmpdir = None
+ private_tmpdir = self._private_tmpdir = tempfile.mkdtemp(
+ dir=portage_tmpdir)
+ settings['PORTAGE_TMPDIR'] = private_tmpdir
+ settings.backup_changes('PORTAGE_TMPDIR')
+ # private temp dir was just created, so it's not locked yet
+ settings.pop('PORTAGE_BUILDDIR_LOCKED', None)
+
+ doebuild_environment(self.ebuild_path, 'nofetch',
+ settings=settings, db=self.portdb)
restrict = settings['PORTAGE_RESTRICT'].split()
defined_phases = settings['DEFINED_PHASES'].split()
if not defined_phases:
@@ -76,18 +88,38 @@ def spawn_nofetch(portdb, ebuild_path, settings=None, fd_pipes=None):
if 'fetch' not in restrict and \
'nofetch' not in defined_phases:
- return os.EX_OK
+ self.returncode = os.EX_OK
+ self._async_wait()
+ return
prepare_build_dirs(settings=settings)
- ebuild_phase = EbuildPhase(background=False,
+
+ ebuild_phase = EbuildPhase(background=self.background,
phase='nofetch',
- scheduler=SchedulerInterface(portage._internal_caller and
+ scheduler=self.scheduler,
+ fd_pipes=self.fd_pipes, settings=settings)
+
+ self._start_task(ebuild_phase, self._nofetch_exit)
+
+ def _nofetch_exit(self, ebuild_phase):
+ self._final_exit(ebuild_phase)
+ elog_process(self.settings.mycpv, self.settings)
+ shutil.rmtree(self._private_tmpdir)
+ self._async_wait()
+
+
+def spawn_nofetch(portdb, ebuild_path, settings=None, fd_pipes=None):
+ """
+ Create a NofetchPrivateTmpdir instance, and execute it synchronously.
+ This function must not be called from asynchronous code, since it will
+ trigger event loop recursion which is incompatible with asyncio.
+ """
+ nofetch = SpawnNofetchWithoutBuilddir(background=False,
+ portdb=portdb,
+ ebuild_path=ebuild_path,
+ scheduler=SchedulerInterface(portage._internal_caller and
global_event_loop() or EventLoop(main=False)),
- fd_pipes=fd_pipes, settings=settings)
- ebuild_phase.start()
- ebuild_phase.wait()
- elog_process(settings.mycpv, settings)
- finally:
- shutil.rmtree(private_tmpdir)
-
- return ebuild_phase.returncode
+ fd_pipes=fd_pipes, settings=settings)
+
+ nofetch.start()
+ return nofetch.wait()
next reply other threads:[~2017-04-04 3:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-04 3:20 Zac Medico [this message]
-- strict thread matches above, loose matches on Subject: below --
2018-06-04 23:46 [gentoo-commits] proj/portage:master commit in: pym/portage/package/ebuild/, pym/_emerge/ Zac Medico
2018-04-23 0:08 Zac Medico
2012-12-19 3:58 Arfrever Frehtes Taifersar Arahesis
2012-09-01 22:43 Zac Medico
2012-05-09 20:16 Zac Medico
2012-05-09 20:00 Zac Medico
2011-11-17 23:25 Zac Medico
2011-06-29 9:27 Zac Medico
2011-06-06 16:00 Arfrever Frehtes Taifersar Arahesis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1491275969.285d5d038d8bb8a17d853816e156147c8c59f248.zmedico@gentoo \
--to=zmedico@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox