示例#1
0
    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
示例#2
0
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
示例#3
0
    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(
示例#4
0
 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("/") + "/"
示例#5
0
 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)
示例#6
0
 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
示例#7
0
 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
示例#8
0
    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
示例#9
0
 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
示例#10
0
            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):
示例#11
0
                    % 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(
示例#12
0
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