From 187df8a3beaffb09948799f5630f5cceeaeb95c5 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 18 Aug 2010 17:08:59 -0700 Subject: Move the code from _prepare_env_file() to a new BinpkgEnvExtractor class. --- pym/_emerge/Binpkg.py | 18 +++++----- pym/_emerge/BinpkgEnvExtractor.py | 66 ++++++++++++++++++++++++++++++++++ pym/_emerge/EbuildPhase.py | 24 ++++++++++++- pym/portage/dbapi/vartree.py | 8 ++--- pym/portage/package/ebuild/doebuild.py | 66 +++++++++++++--------------------- 5 files changed, 126 insertions(+), 56 deletions(-) create mode 100644 pym/_emerge/BinpkgEnvExtractor.py diff --git a/pym/_emerge/Binpkg.py b/pym/_emerge/Binpkg.py index 4dee0925f..66b7bd424 100644 --- a/pym/_emerge/Binpkg.py +++ b/pym/_emerge/Binpkg.py @@ -3,6 +3,7 @@ from _emerge.EbuildPhase import EbuildPhase from _emerge.BinpkgFetcher import BinpkgFetcher +from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor from _emerge.BinpkgExtractorAsync import BinpkgExtractorAsync from _emerge.CompositeTask import CompositeTask from _emerge.BinpkgVerifier import BinpkgVerifier @@ -16,7 +17,6 @@ from portage import _unicode_encode import codecs import logging from portage.output import colorize -from portage.package.ebuild.doebuild import _prepare_env_file class Binpkg(CompositeTask): @@ -255,10 +255,13 @@ class Binpkg(CompositeTask): finally: f.close() - rval = _prepare_env_file(self.settings) - if rval != os.EX_OK: - self._current_phase = None - self.returncode = rval + env_extractor = BinpkgEnvExtractor(background=self.background, + scheduler=self.scheduler, settings=self.settings) + + self._start_task(env_extractor, self._env_extractor_exit) + + def _env_extractor_exit(self, env_extractor): + if self._default_exit(env_extractor) != os.EX_OK: self._unlock_builddir() self.wait() return @@ -267,12 +270,11 @@ class Binpkg(CompositeTask): # such as remove binary packages after they're installed. settings = self.settings settings.setcpv(self.pkg) - settings["PORTAGE_BINPKG_FILE"] = pkg_path + settings["PORTAGE_BINPKG_FILE"] = self._pkg_path settings.backup_changes("PORTAGE_BINPKG_FILE") - phase = "setup" setup_phase = EbuildPhase(background=self.background, - phase=phase, scheduler=self.scheduler, + phase="setup", scheduler=self.scheduler, settings=settings) setup_phase.addExitListener(self._setup_exit) diff --git a/pym/_emerge/BinpkgEnvExtractor.py b/pym/_emerge/BinpkgEnvExtractor.py new file mode 100644 index 000000000..77060589a --- /dev/null +++ b/pym/_emerge/BinpkgEnvExtractor.py @@ -0,0 +1,66 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import errno + +from _emerge.CompositeTask import CompositeTask +from _emerge.SpawnProcess import SpawnProcess +from portage import os, _shell_quote, _unicode_encode +from portage.const import BASH_BINARY + +class BinpkgEnvExtractor(CompositeTask): + """ + Extract environment.bz2 for a binary or installed package. + """ + __slots__ = ('settings',) + + def saved_env_exists(self): + return os.path.exists(self._get_saved_env_path()) + + def dest_env_exists(self): + return os.path.exists(self._get_dest_env_path()) + + def _get_saved_env_path(self): + return os.path.join(os.path.dirname(self.settings['EBUILD']), + "environment.bz2") + + def _get_dest_env_path(self): + return os.path.join(self.settings["T"], "environment") + + def _start(self): + saved_env_path = self._get_saved_env_path() + dest_env_path = self._get_dest_env_path() + shell_cmd = "bzip2 -dc %s > %s" % \ + (_shell_quote(saved_env_path), + _shell_quote(dest_env_path)) + extractor_proc = SpawnProcess( + args=[BASH_BINARY, "-c", shell_cmd], + background=self.background, + env=self.settings.environ(), + scheduler=self.scheduler, + logfile=self.settings.get('PORTAGE_LOGFILE')) + + self._start_task(extractor_proc, self._extractor_exit) + + def _remove_dest_env(self): + try: + os.unlink(self._get_dest_env_path()) + except OSError as e: + if e.errno != errno.ENOENT: + raise + + def _extractor_exit(self, extractor_proc): + + if self._default_exit(extractor_proc) != os.EX_OK: + self._remove_dest_env() + self.wait() + return + + # This is a signal to ebuild.sh, so that it knows to filter + # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that + # would be preserved between normal phases. + open(_unicode_encode(self._get_dest_env_path() + '.raw'), 'w') + + self._current_task = None + self.returncode = os.EX_OK + self.wait() diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py index 5680925e4..5f52b4292 100644 --- a/pym/_emerge/EbuildPhase.py +++ b/pym/_emerge/EbuildPhase.py @@ -1,6 +1,7 @@ -# Copyright 1999-2009 Gentoo Foundation +# Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor from _emerge.MiscFunctionsProcess import MiscFunctionsProcess from _emerge.EbuildProcess import EbuildProcess from _emerge.CompositeTask import CompositeTask @@ -24,6 +25,27 @@ class EbuildPhase(CompositeTask): def _start(self): + if self.phase == 'prerm': + env_extractor = BinpkgEnvExtractor(background=self.background, + scheduler=self.scheduler, settings=self.settings) + if env_extractor.saved_env_exists(): + self._start_task(env_extractor, self._env_extractor_exit) + return + # If the environment.bz2 doesn't exist, then ebuild.sh will + # source the ebuild as a fallback. + + self._start_ebuild() + + def _env_extractor_exit(self, env_extractor): + if self._default_exit(env_extractor) != os.EX_OK: + self._unlock_builddir() + self.wait() + return + + self._start_ebuild() + + def _start_ebuild(self): + ebuild_process = EbuildProcess(actionmap=self.actionmap, background=self.background, phase=self.phase, scheduler=self.scheduler, diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index d9115318f..6146da3a6 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -16,7 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(), 'portage.locks:lockdir,unlockdir', 'portage.output:bold,colorize', 'portage.package.ebuild.doebuild:doebuild,doebuild_environment,' + \ - '_prepare_env_file', + '_spawn_phase', 'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs', 'portage.update:fixdbentries', 'portage.util:apply_secpass_permissions,ConfigProtect,ensure_dirs,' + \ @@ -2194,14 +2194,10 @@ class dblink(object): catdir_lock = None prepare_build_dirs(self.myroot, self.settings, 1) - _prepare_env_file(self.settings) log_path = self.settings.get("PORTAGE_LOG_FILE") if scheduler is None: - retval = doebuild(myebuildpath, ebuild_phase, self.myroot, - self.settings, cleanup=cleanup, use_cache=0, - mydbapi=self.vartree.dbapi, tree=self.treetype, - vartree=self.vartree) + retval = _spawn_phase('prerm', self.settings) else: retval = scheduler.dblinkEbuildPhase( self, self.vartree.dbapi, myebuildpath, ebuild_phase) diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py index 10c8e0684..e606ac302 100644 --- a/pym/portage/package/ebuild/doebuild.py +++ b/pym/portage/package/ebuild/doebuild.py @@ -52,6 +52,7 @@ from portage.util import apply_recursive_permissions, \ writemsg, writemsg_stdout, write_atomic from portage.util.lafilefixer import rewrite_lafile from portage.versions import _pkgsplit +from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor from _emerge.EbuildPhase import EbuildPhase from _emerge.EbuildSpawnProcess import EbuildSpawnProcess from _emerge.TaskScheduler import TaskScheduler @@ -839,48 +840,31 @@ def _check_temp_dir(settings): return os.EX_OK def _prepare_env_file(settings): - env_file = os.path.join(settings["T"], "environment") - env_stat = None - saved_env = None - try: - env_stat = os.stat(env_file) - except OSError as e: - if e.errno != errno.ENOENT: - raise - if not env_stat: - saved_env = os.path.join( - os.path.dirname(settings['EBUILD']), "environment.bz2") - if not os.path.isfile(saved_env): - saved_env = None - if saved_env: - retval = os.system( - "bzip2 -dc %s > %s" % \ - (_shell_quote(saved_env), - _shell_quote(env_file))) - try: - env_stat = os.stat(env_file) - except OSError as e: - if e.errno != errno.ENOENT: - raise - if os.WIFEXITED(retval) and \ - os.WEXITSTATUS(retval) == os.EX_OK and \ - env_stat and env_stat.st_size > 0: - # This is a signal to ebuild.sh, so that it knows to filter - # out things like SANDBOX_{DENY,PREDICT,READ,WRITE} that - # would be preserved between normal phases. - open(_unicode_encode(env_file + '.raw'), 'w') - else: - writemsg(_("!!! Error extracting saved " - "environment: '%s'\n") % \ - saved_env, noiselevel=-1) - try: - os.unlink(env_file) - except OSError as e: - if e.errno != errno.ENOENT: - raise - env_stat = None + """ + Extract environment.bz2 if it exists, but only if the destination + environment file doesn't already exist. There are lots of possible + states when doebuild() calls this function, and we want to avoid + clobbering an existing environment file. + """ - return os.EX_OK + task_scheduler = TaskScheduler() + env_extractor = BinpkgEnvExtractor(background=False, + scheduler=task_scheduler.sched_iface, settings=settings) + + if env_extractor.dest_env_exists(): + # There are lots of possible states when doebuild() + # calls this function, and we want to avoid + # clobbering an existing environment file. + return os.EX_OK + + if not env_extractor.saved_env_exists(): + # If the environment.bz2 doesn't exist, then ebuild.sh will + # source the ebuild as a fallback. + return os.EX_OK + + task_scheduler.add(env_extractor) + task_scheduler.run() + return env_extractor.returncode def _prepare_fake_distdir(settings, alist): orig_distdir = settings["DISTDIR"] -- cgit v1.2.3-1-g7c22