summaryrefslogtreecommitdiffstats
path: root/pym/_emerge/Binpkg.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-06-22 16:43:52 +0000
committerZac Medico <zmedico@gentoo.org>2009-06-22 16:43:52 +0000
commitd057d91f391981fb0564873c471d550f2f62edf5 (patch)
treed6cd416fc5e9389806ec98a02ae236c99e876e4b /pym/_emerge/Binpkg.py
parent28184c982a0688ed9bc4d82df407d4e400f6318c (diff)
downloadportage-d057d91f391981fb0564873c471d550f2f62edf5.tar.gz
portage-d057d91f391981fb0564873c471d550f2f62edf5.tar.bz2
portage-d057d91f391981fb0564873c471d550f2f62edf5.zip
Bug #275047 - Split _emerge/__init__.py into smaller pieces. Thanks to
Sebastian Mingramm (few) <s.mingramm@gmx.de> for this patch. svn path=/main/trunk/; revision=13663
Diffstat (limited to 'pym/_emerge/Binpkg.py')
-rw-r--r--pym/_emerge/Binpkg.py301
1 files changed, 301 insertions, 0 deletions
diff --git a/pym/_emerge/Binpkg.py b/pym/_emerge/Binpkg.py
new file mode 100644
index 000000000..084ecd47d
--- /dev/null
+++ b/pym/_emerge/Binpkg.py
@@ -0,0 +1,301 @@
+from _emerge.EbuildPhase import EbuildPhase
+from _emerge.BinpkgFetcher import BinpkgFetcher
+from _emerge.BinpkgExtractorAsync import BinpkgExtractorAsync
+from _emerge.CompositeTask import CompositeTask
+from _emerge.BinpkgVerifier import BinpkgVerifier
+from _emerge.EbuildMerge import EbuildMerge
+from _emerge.EbuildBuildDir import EbuildBuildDir
+from portage.util import writemsg
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ import sys
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+import os
+from portage.output import colorize
+class Binpkg(CompositeTask):
+
+ __slots__ = ("find_blockers",
+ "ldpath_mtimes", "logger", "opts",
+ "pkg", "pkg_count", "prefetcher", "settings", "world_atom") + \
+ ("_bintree", "_build_dir", "_ebuild_path", "_fetched_pkg",
+ "_image_dir", "_infloc", "_pkg_path", "_tree", "_verify")
+
+ def _writemsg_level(self, msg, level=0, noiselevel=0):
+
+ if not self.background:
+ portage.util.writemsg_level(msg,
+ level=level, noiselevel=noiselevel)
+
+ log_path = self.settings.get("PORTAGE_LOG_FILE")
+ if log_path is not None:
+ f = open(log_path, 'a')
+ try:
+ f.write(msg)
+ finally:
+ f.close()
+
+ def _start(self):
+
+ pkg = self.pkg
+ settings = self.settings
+ settings.setcpv(pkg)
+ self._tree = "bintree"
+ self._bintree = self.pkg.root_config.trees[self._tree]
+ self._verify = not self.opts.pretend
+
+ dir_path = os.path.join(settings["PORTAGE_TMPDIR"],
+ "portage", pkg.category, pkg.pf)
+ self._build_dir = EbuildBuildDir(dir_path=dir_path,
+ pkg=pkg, settings=settings)
+ self._image_dir = os.path.join(dir_path, "image")
+ self._infloc = os.path.join(dir_path, "build-info")
+ self._ebuild_path = os.path.join(self._infloc, pkg.pf + ".ebuild")
+ settings["EBUILD"] = self._ebuild_path
+ debug = settings.get("PORTAGE_DEBUG") == "1"
+ portage.doebuild_environment(self._ebuild_path, "setup",
+ settings["ROOT"], settings, debug, 1, self._bintree.dbapi)
+ settings.configdict["pkg"]["EMERGE_FROM"] = pkg.type_name
+
+ # The prefetcher has already completed or it
+ # could be running now. If it's running now,
+ # wait for it to complete since it holds
+ # a lock on the file being fetched. The
+ # portage.locks functions are only designed
+ # to work between separate processes. Since
+ # the lock is held by the current process,
+ # use the scheduler and fetcher methods to
+ # synchronize with the fetcher.
+ prefetcher = self.prefetcher
+ if prefetcher is None:
+ pass
+ elif not prefetcher.isAlive():
+ prefetcher.cancel()
+ elif prefetcher.poll() is None:
+
+ waiting_msg = ("Fetching '%s' " + \
+ "in the background. " + \
+ "To view fetch progress, run `tail -f " + \
+ "/var/log/emerge-fetch.log` in another " + \
+ "terminal.") % prefetcher.pkg_path
+ msg_prefix = colorize("GOOD", " * ")
+ from textwrap import wrap
+ waiting_msg = "".join("%s%s\n" % (msg_prefix, line) \
+ for line in wrap(waiting_msg, 65))
+ if not self.background:
+ writemsg(waiting_msg, noiselevel=-1)
+
+ self._current_task = prefetcher
+ prefetcher.addExitListener(self._prefetch_exit)
+ return
+
+ self._prefetch_exit(prefetcher)
+
+ def _prefetch_exit(self, prefetcher):
+
+ pkg = self.pkg
+ pkg_count = self.pkg_count
+ if not (self.opts.pretend or self.opts.fetchonly):
+ self._build_dir.lock()
+ # If necessary, discard old log so that we don't
+ # append to it.
+ self._build_dir.clean_log()
+ # Initialze PORTAGE_LOG_FILE.
+ portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1)
+ fetcher = BinpkgFetcher(background=self.background,
+ logfile=self.settings.get("PORTAGE_LOG_FILE"), pkg=self.pkg,
+ pretend=self.opts.pretend, scheduler=self.scheduler)
+ pkg_path = fetcher.pkg_path
+ self._pkg_path = pkg_path
+
+ if self.opts.getbinpkg and self._bintree.isremote(pkg.cpv):
+
+ msg = " --- (%s of %s) Fetching Binary (%s::%s)" %\
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path)
+ short_msg = "emerge: (%s of %s) %s Fetch" % \
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv)
+ self.logger.log(msg, short_msg=short_msg)
+ self._start_task(fetcher, self._fetcher_exit)
+ return
+
+ self._fetcher_exit(fetcher)
+
+ def _fetcher_exit(self, fetcher):
+
+ # The fetcher only has a returncode when
+ # --getbinpkg is enabled.
+ if fetcher.returncode is not None:
+ self._fetched_pkg = True
+ if self._default_exit(fetcher) != os.EX_OK:
+ self._unlock_builddir()
+ self.wait()
+ return
+
+ if self.opts.pretend:
+ self._current_task = None
+ self.returncode = os.EX_OK
+ self.wait()
+ return
+
+ verifier = None
+ if self._verify:
+ logfile = None
+ if self.background:
+ logfile = self.settings.get("PORTAGE_LOG_FILE")
+ verifier = BinpkgVerifier(background=self.background,
+ logfile=logfile, pkg=self.pkg)
+ self._start_task(verifier, self._verifier_exit)
+ return
+
+ self._verifier_exit(verifier)
+
+ def _verifier_exit(self, verifier):
+ if verifier is not None and \
+ self._default_exit(verifier) != os.EX_OK:
+ self._unlock_builddir()
+ self.wait()
+ return
+
+ logger = self.logger
+ pkg = self.pkg
+ pkg_count = self.pkg_count
+ pkg_path = self._pkg_path
+
+ if self._fetched_pkg:
+ self._bintree.inject(pkg.cpv, filename=pkg_path)
+
+ if self.opts.fetchonly:
+ self._current_task = None
+ self.returncode = os.EX_OK
+ self.wait()
+ return
+
+ msg = " === (%s of %s) Merging Binary (%s::%s)" % \
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path)
+ short_msg = "emerge: (%s of %s) %s Merge Binary" % \
+ (pkg_count.curval, pkg_count.maxval, pkg.cpv)
+ logger.log(msg, short_msg=short_msg)
+
+ phase = "clean"
+ settings = self.settings
+ ebuild_phase = EbuildPhase(background=self.background,
+ pkg=pkg, phase=phase, scheduler=self.scheduler,
+ settings=settings, tree=self._tree)
+
+ self._start_task(ebuild_phase, self._clean_exit)
+
+ def _clean_exit(self, clean_phase):
+ if self._default_exit(clean_phase) != os.EX_OK:
+ self._unlock_builddir()
+ self.wait()
+ return
+
+ dir_path = self._build_dir.dir_path
+
+ infloc = self._infloc
+ pkg = self.pkg
+ pkg_path = self._pkg_path
+
+ dir_mode = 0755
+ for mydir in (dir_path, self._image_dir, infloc):
+ portage.util.ensure_dirs(mydir, uid=portage.data.portage_uid,
+ gid=portage.data.portage_gid, mode=dir_mode)
+
+ # This initializes PORTAGE_LOG_FILE.
+ portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1)
+ self._writemsg_level(">>> Extracting info\n")
+
+ pkg_xpak = portage.xpak.tbz2(self._pkg_path)
+ check_missing_metadata = ("CATEGORY", "PF")
+ missing_metadata = set()
+ for k in check_missing_metadata:
+ v = pkg_xpak.getfile(k)
+ if not v:
+ missing_metadata.add(k)
+
+ pkg_xpak.unpackinfo(infloc)
+ for k in missing_metadata:
+ if k == "CATEGORY":
+ v = pkg.category
+ elif k == "PF":
+ v = pkg.pf
+ else:
+ continue
+
+ f = open(os.path.join(infloc, k), 'wb')
+ try:
+ f.write(v + "\n")
+ finally:
+ f.close()
+
+ # Store the md5sum in the vdb.
+ f = open(os.path.join(infloc, "BINPKGMD5"), "w")
+ try:
+ f.write(str(portage.checksum.perform_md5(pkg_path)) + "\n")
+ finally:
+ f.close()
+
+ # This gives bashrc users an opportunity to do various things
+ # such as remove binary packages after they're installed.
+ settings = self.settings
+ settings.setcpv(self.pkg)
+ settings["PORTAGE_BINPKG_FILE"] = pkg_path
+ settings.backup_changes("PORTAGE_BINPKG_FILE")
+
+ phase = "setup"
+ setup_phase = EbuildPhase(background=self.background,
+ pkg=self.pkg, phase=phase, scheduler=self.scheduler,
+ settings=settings, tree=self._tree)
+
+ setup_phase.addExitListener(self._setup_exit)
+ self._current_task = setup_phase
+ self.scheduler.scheduleSetup(setup_phase)
+
+ def _setup_exit(self, setup_phase):
+ if self._default_exit(setup_phase) != os.EX_OK:
+ self._unlock_builddir()
+ self.wait()
+ return
+
+ extractor = BinpkgExtractorAsync(background=self.background,
+ image_dir=self._image_dir,
+ pkg=self.pkg, pkg_path=self._pkg_path, scheduler=self.scheduler)
+ self._writemsg_level(">>> Extracting %s\n" % self.pkg.cpv)
+ self._start_task(extractor, self._extractor_exit)
+
+ def _extractor_exit(self, extractor):
+ if self._final_exit(extractor) != os.EX_OK:
+ self._unlock_builddir()
+ writemsg("!!! Error Extracting '%s'\n" % self._pkg_path,
+ noiselevel=-1)
+ self.wait()
+
+ def _unlock_builddir(self):
+ if self.opts.pretend or self.opts.fetchonly:
+ return
+ portage.elog.elog_process(self.pkg.cpv, self.settings)
+ self._build_dir.unlock()
+
+ def install(self):
+
+ # This gives bashrc users an opportunity to do various things
+ # such as remove binary packages after they're installed.
+ settings = self.settings
+ settings["PORTAGE_BINPKG_FILE"] = self._pkg_path
+ settings.backup_changes("PORTAGE_BINPKG_FILE")
+
+ merge = EbuildMerge(find_blockers=self.find_blockers,
+ ldpath_mtimes=self.ldpath_mtimes, logger=self.logger,
+ pkg=self.pkg, pkg_count=self.pkg_count,
+ pkg_path=self._pkg_path, scheduler=self.scheduler,
+ settings=settings, tree=self._tree, world_atom=self.world_atom)
+
+ try:
+ retval = merge.execute()
+ finally:
+ settings.pop("PORTAGE_BINPKG_FILE", None)
+ self._unlock_builddir()
+ return retval
+