def _setup_distfiles(self): if not self.verified_files and self.allow_fetching: ops = self.domain.pkg_operations(self.pkg, observer=self.observer) if not ops.fetch(): raise format.GenericBuildError("failed fetching required distfiles") self.verified_files = ops._fetch_op.verified_files if self.verified_files: try: if os.path.exists(self.env["DISTDIR"]): if (os.path.isdir(self.env["DISTDIR"]) and not os.path.islink(self.env["DISTDIR"])): shutil.rmtree(self.env["DISTDIR"]) else: os.unlink(self.env["DISTDIR"]) except EnvironmentError as e: raise format.FailedDirectory( self.env["DISTDIR"], f"failed removing existing file/dir/link: {e}") from e if not ensure_dirs(self.env["DISTDIR"], mode=0o770, gid=portage_gid): raise format.FailedDirectory( self.env["DISTDIR"], "failed creating distdir symlink directory") try: for src, dest in [ (k, pjoin(self.env["DISTDIR"], v.filename)) for (k, v) in self.verified_files.items()]: os.symlink(src, dest) except EnvironmentError as e: raise format.GenericBuildError( f"Failed symlinking in distfiles for src {src} -> {dest}: {e}") from e
def run_generic_phase(pkg, phase, env, userpriv, sandbox, fakeroot, extra_handlers=None, failure_allowed=False, logging=None): """ :param phase: phase to execute :param env: environment mapping for the phase :param userpriv: will we drop to :obj:`pkgcore.os_data.portage_uid` and :obj:`pkgcore.os_data.portage_gid` access for this phase? :param sandbox: should this phase be sandboxed? :param fakeroot: should the phase be fakeroot'd? Only really useful for install phase, and is mutually exclusive with sandbox :param extra_handlers: extra command handlers :type extra_handlers: mapping from string to callable :param failure_allowed: allow failure without raising error :type failure_allowed: boolean :param logging: None or a filepath to log output to :return: True when the phase has finished execution """ userpriv = userpriv and is_userpriv_capable() sandbox = sandbox and is_sandbox_capable() fakeroot = fakeroot and is_fakeroot_capable() if env is None: env = expected_ebuild_env(pkg) ebd = request_ebuild_processor(userpriv=userpriv, sandbox=sandbox, fakeroot=fakeroot) # this is a bit of a hack; used until ebd accepts observers that handle # the output redirection on it's own. Primary relevance is when # stdout/stderr are pointed at a file; we leave buffering on, just # force the flush for synchronization. sys.stdout.flush() sys.stderr.flush() try: if not ebd.run_phase(phase, env, env.get('T'), sandbox=sandbox, logging=logging, additional_commands=extra_handlers): if not failure_allowed: raise format.GenericBuildError( phase + ": Failed building (False/0 return from handler)") logger.warning("executing phase %s: execution failed, ignoring" % (phase,)) except Exception as e: ebd.shutdown_processor() release_ebuild_processor(ebd) if isinstance(e, IGNORED_EXCEPTIONS + (format.GenericBuildError,)): raise raise_from( format.GenericBuildError("Executing phase %s: Caught exception: " "%s" % (phase, e))) release_ebuild_processor(ebd) return True
def setup_distfiles(self): if not self.verified_files and self.allow_fetching: ops = self.domain.pkg_operations(self.pkg, observer=self.observer) if not ops.fetch(): raise format.GenericBuildError( "failed fetching required distfiles") self.verified_files = ops._fetch_op.verified_files if self.verified_files: try: if os.path.exists(self.env["DISTDIR"]): if (os.path.isdir(self.env["DISTDIR"]) and not os.path.islink(self.env["DISTDIR"])): shutil.rmtree(self.env["DISTDIR"]) else: os.unlink(self.env["DISTDIR"]) except EnvironmentError as e: raise_from( format.FailedDirectory( self.env["DISTDIR"], "failed removing existing file/dir/link at: exception %s" % e)) if not ensure_dirs(self.env["DISTDIR"], mode=0770, gid=portage_gid): raise format.FailedDirectory(
def init_distfiles_env(self): # cvs/svn ebuilds need to die. distdir_write = self.domain.fetcher.get_storage_path() if distdir_write is None: raise format.GenericBuildError("no usable distdir was found " "for PORTAGE_ACTUAL_DISTDIR from fetcher %s" % self.domain.fetcher) self.env["PORTAGE_ACTUAL_DISTDIR"] = distdir_write self.env["DISTDIR"] = normpath( pjoin(self.builddir, "distdir")) for x in ("PORTAGE_ACTUAL_DISTDIR", "DISTDIR"): self.env[x] = os.path.realpath(self.env[x]).rstrip("/") + "/"
def unpack(self): """execute the unpack phase""" if self.setup_is_for_src: self.setup_distfiles() if self.userpriv: try: os.chown(self.env["WORKDIR"], portage_uid, -1) except OSError as e: raise_from(format.GenericBuildError( "failed forcing %i uid for WORKDIR: %s" % (portage_uid, e))) return self._generic_phase("unpack", True, True)
def _init_distfiles_env(self): # TODO: PORTAGE_ACTUAL_DISTDIR usage by vcs eclasses needs to be killed off distdir_write = self.domain.fetcher.get_storage_path() if distdir_write is None: raise format.GenericBuildError( "no usable distdir was found " f"for PORTAGE_ACTUAL_DISTDIR from fetcher {self.domain.fetcher}") self.env["PORTAGE_ACTUAL_DISTDIR"] = distdir_write self.env["DISTDIR"] = normpath( pjoin(self.builddir, "distdir")) for x in ("PORTAGE_ACTUAL_DISTDIR", "DISTDIR"): self.env[x] = os.path.realpath(self.env[x]).rstrip(os.sep) + os.sep
def do_cleanup(self): try: shutil.rmtree(self.builddir) # try to wipe the cat dir; if not empty, ignore it try: os.rmdir(os.path.dirname(self.builddir)) except EnvironmentError as e: if e.errno != errno.ENOTEMPTY: raise except EnvironmentError as oe: raise_from(format.GenericBuildError( "clean: Caught exception while cleansing: %s" % (oe,))) return True
def prepare(self): """Execute a source preparation phase. does nothing if the pkg's EAPI is less than 2 """ ret = True if "prepare" in self.eapi.phases: ret = self._generic_phase("prepare", True, True) if (self.eapi.options.user_patches and not os.path.exists(pjoin(self.env['T'], '.user_patches_applied'))): self.observer.error( 'eapply_user (or default) must be called in src_prepare()') raise format.GenericBuildError('missing eapply_user call') return ret
def do_cleanup(self): try: shutil.rmtree(self.builddir) # try to wipe the cat dir; if not empty, ignore it try: os.rmdir(os.path.dirname(self.builddir)) except EnvironmentError as e: # POSIX specifies either ENOTEMPTY or EEXIST for non-empty dir # in particular, Solaris uses EEXIST in that case. # https://github.com/pkgcore/pkgcore/pull/181 if e.errno not in (errno.ENOTEMPTY, errno.EEXIST): raise except EnvironmentError as e: raise_from(format.GenericBuildError( "clean: Caught exception while cleansing: %s" % (e,))) return True
if not ensure_dirs(self.env["DISTDIR"], mode=0770, gid=portage_gid): raise format.FailedDirectory( self.env["DISTDIR"], "failed creating distdir symlink directory") try: for src, dest in [(k, pjoin(self.env["DISTDIR"], v.filename)) for (k, v) in self.verified_files.iteritems()]: os.symlink(src, dest) except EnvironmentError as oe: raise_from( format.GenericBuildError( "Failed symlinking in distfiles for src %s -> %s: %s" % (src, dest, str(oe)))) @observer.decorate_build_method("setup") def setup(self): """ execute the setup phase, mapping out to pkg_setup in the ebuild necessarily dirs are created as required, and build env is initialized at this point """ if self.distcc: for p in ("", "/lock", "/state"): if not ensure_dirs(pjoin(self.env["DISTCC_DIR"], p), mode=02775, gid=portage_gid):
% e)) if not ensure_dirs(self.env["DISTDIR"], mode=0770, gid=portage_gid): raise format.FailedDirectory( self.env["DISTDIR"], "failed creating distdir symlink directory") try: for src, dest in [ (k, pjoin(self.env["DISTDIR"], v.filename)) for (k, v) in self.verified_files.iteritems()]: os.symlink(src, dest) except EnvironmentError as e: raise_from(format.GenericBuildError( "Failed symlinking in distfiles for src %s -> %s: %s" % ( src, dest, e))) @observer.decorate_build_method("setup") def setup(self): """ execute the setup phase, mapping out to pkg_setup in the ebuild necessarily dirs are created as required, and build env is initialized at this point """ if self.distcc: for p in ("", "/lock", "/state"): if not ensure_dirs(pjoin(self.env["DISTCC_DIR"], p), mode=02775, gid=portage_gid): raise format.FailedDirectory(
def run_generic_phase(pkg, phase, env, userpriv, sandbox, fd_pipes=None, extra_handlers=None, failure_allowed=False, logging=None, **kwargs): """ :param phase: phase to execute :param env: environment mapping for the phase :param userpriv: will we drop to :obj:`pkgcore.os_data.portage_uid` and :obj:`pkgcore.os_data.portage_gid` access for this phase? :param sandbox: should this phase be sandboxed? :param fd_pipes: use custom file descriptors for ebd instance :type fd_pipes: mapping between file descriptors :param extra_handlers: extra command handlers :type extra_handlers: mapping from string to callable :param failure_allowed: allow failure without raising error :type failure_allowed: boolean :param logging: None or a filepath to log output to :return: True when the phase has finished execution """ userpriv = userpriv and is_userpriv_capable() sandbox = sandbox and is_sandbox_capable() tmpdir = kwargs.get('tmpdir', env.get('T', None)) if env is None: env = expected_ebuild_env(pkg) ebd = request_ebuild_processor(userpriv=userpriv, sandbox=sandbox, fd_pipes=fd_pipes) # this is a bit of a hack; used until ebd accepts observers that handle # the output redirection on its own. Primary relevance is when # stdout/stderr are pointed at a file; we leave buffering on, just # force the flush for synchronization. sys.stdout.flush() sys.stderr.flush() try: if not ebd.run_phase(phase, env, tmpdir=tmpdir, sandbox=sandbox, logging=logging, additional_commands=extra_handlers): if not failure_allowed: raise format.GenericBuildError( phase + ": Failed building (False/0 return from handler)") logger.warning(f"executing phase {phase}: execution failed, ignoring") except Exception as e: if isinstance(e, ebd_ipc.IpcError): # notify bash side of IPC error ebd.write(e.ret) if isinstance(e, ebd_ipc.IpcInternalError): # show main exception cause for internal IPC errors ebd.shutdown_processor(force=True) raise e.__cause__ try: ebd.shutdown_processor() except ProcessorError as pe: # catch die errors during shutdown e = pe release_ebuild_processor(ebd) if isinstance(e, ProcessorError): # force verbose die output e._verbosity = 1 raise e elif isinstance(e, IGNORED_EXCEPTIONS + (format.GenericBuildError,)): raise raise format.GenericBuildError( f"Executing phase {phase}: Caught exception: {e}") from e release_ebuild_processor(ebd) return True