Example #1
0
    def fetch(self, target):
        """Fetch a file.

        :type target: :obj:`pkgcore.fetch.fetchable` instance
        :return: None if fetching failed,
            else on disk location of the copied file
        """
        if not isinstance(target, fetchable):
            raise TypeError(
                f"target must be fetchable instance/derivative: {target}")

        path = pjoin(self.distdir, target.filename)
        uris = iter(target.uri)
        last_exc = RuntimeError("fetching failed for an unknown reason")
        spawn_opts = {'umask': 0o002, 'env': self.extra_env}
        if self.userpriv and is_userpriv_capable():
            spawn_opts.update({"uid": portage_uid, "gid": portage_gid})

        for _attempt in range(self.attempts):
            try:
                self._verify(path, target)
                return path
            except errors.MissingDistfile as e:
                command = self.command
                last_exc = e
            except errors.ChksumFailure:
                raise
            except errors.FetchFailed as e:
                last_exc = e
                if not e.resumable:
                    try:
                        os.unlink(path)
                        command = self.command
                    except OSError as e:
                        raise errors.UnmodifiableFile(path, e) from e
                else:
                    command = self.resume_command
            # Note we're not even checking the results, the verify portion of
            # the loop handles this. In other words, don't trust the external
            # fetcher's exit code, trust our chksums instead.
            try:
                spawn_bash(
                    command % {"URI": next(uris), "FILE": target.filename},
                    **spawn_opts)
            except StopIteration:
                raise errors.FetchFailed(
                    target.filename, "ran out of urls to fetch from")
        else:
            raise last_exc
Example #2
0
    def fetch(self, target):
        """
        fetch a file

        :type target: :obj:`pkgcore.fetch.fetchable` instance
        :return: None if fetching failed,
            else on disk location of the copied file
        """

        if not isinstance(target, fetchable):
            raise TypeError(
                "target must be fetchable instance/derivative: %s" % target)

        kw = {"mode": 0775}
        if self.readonly:
            kw["mode"] = 0555
        if self.userpriv:
            kw["gid"] = portage_gid
        kw["minimal"] = True
        if not ensure_dirs(self.distdir, **kw):
            raise errors.distdirPerms(
                self.distdir, "if userpriv, uid must be %i, gid must be %i. "
                "if not readonly, directory must be 0775, else 0555" %
                (portage_uid, portage_gid))

        fp = pjoin(self.distdir, target.filename)
        filename = os.path.basename(fp)

        uri = iter(target.uri)
        if self.userpriv and is_userpriv_capable():
            extra = {"uid": portage_uid, "gid": portage_gid}
        else:
            extra = {}
        extra["umask"] = 0002
        extra["env"] = self.extra_env
        attempts = self.attempts
        last_exc = None
        try:
            while attempts >= 0:
                try:
                    c = self._verify(fp, target)
                    return fp
                except errors.MissingDistfile:
                    command = self.command
                    last_exc = sys.exc_info()
                except errors.FetchFailed as e:
                    last_exc = sys.exc_info()
                    if not e.resumable:
                        try:
                            os.unlink(fp)
                            command = self.command
                        except OSError as oe:
                            raise_from(errors.UnmodifiableFile(fp, oe))
                    else:
                        command = self.resume_command

                # yeah, it's funky, but it works.
                if attempts > 0:
                    u = uri.next()
                    # note we're not even checking the results. the
                    # verify portion of the loop handles this. iow,
                    # don't trust their exit code. trust our chksums
                    # instead.
                    spawn_bash(command % {"URI": u, "FILE": filename}, **extra)
                attempts -= 1
            assert last_exc is not None
            raise last_exc[0], last_exc[1], last_exc[2]

        except StopIteration:
            # ran out of uris
            raise errors.FetchFailed(fp, "Ran out of urls to fetch from")
Example #3
0
                    try:
                        cwd = os.getcwd()
                    except OSError:
                        cwd = "/"
                    try:
                        # crap.
                        os.chmod(self.env["CCACHE_DIR"], 02775)
                        os.chown(self.env["CCACHE_DIR"], -1, portage_gid)
                        os.chdir(cwd)
                        if 0 != spawn(
                                ["chgrp", "-R", str(portage_gid), self.env["CCACHE_DIR"]]):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed changing ownership for CCACHE_DIR")
                        if 0 != spawn_bash(
                                "find '%s' -type d -print0 | %s --null chmod 02775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")

                        if 0 != spawn_bash(
                                "find '%s' -type f -print0 | %s --null chmod 0775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")
                    finally:
                        os.chdir(cwd)
            except OSError:
                raise_from(format.FailedDirectory(
Example #4
0
    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=0o2775, gid=portage_gid):
                    raise format.FailedDirectory(
                        pjoin(self.env["DISTCC_DIR"], p),
                        "failed creating needed distcc directory")
        if self.ccache:
            # yuck.
            st = None
            try:
                st = os.stat(self.env["CCACHE_DIR"])
            except OSError as e:
                st = None
                if not ensure_dirs(self.env["CCACHE_DIR"], mode=0o2775,
                                   gid=portage_gid):
                    raise format.FailedDirectory(
                        self.env["CCACHE_DIR"],
                        "failed creation of ccache dir") from e

                # XXX this is more then mildly stupid.
                st = os.stat(self.env["CCACHE_DIR"])
            try:
                if st.st_gid != portage_gid or (st.st_mode & 0o2775) != 0o2775:
                    try:
                        cwd = os.getcwd()
                    except OSError:
                        cwd = "/"
                    with chdir(cwd):
                        # crap.
                        os.chmod(self.env["CCACHE_DIR"], 0o2775)
                        os.chown(self.env["CCACHE_DIR"], -1, portage_gid)
                        if 0 != spawn(
                                ["chgrp", "-R", str(portage_gid), self.env["CCACHE_DIR"]]):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed changing ownership for CCACHE_DIR")
                        if 0 != spawn_bash(
                                "find '%s' -type d -print0 | %s --null chmod 02775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")

                        if 0 != spawn_bash(
                                "find '%s' -type f -print0 | %s --null chmod 0775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")
            except OSError as e:
                raise format.FailedDirectory(
                    self.env["CCACHE_DIR"],
                    "failed ensuring perms/group owner for CCACHE_DIR") from e

        return setup_mixin.setup(self)
Example #5
0
 def test_spawn_bash(self, capfd):
     # bash builtin for true without exec'ing true (eg, no path lookup)
     assert 0 == spawn.spawn_bash('echo bash')
     out, err = capfd.readouterr()
     assert out.strip() == 'bash'
Example #6
0
 def test_bash(self):
     # bash builtin for true without exec'ing true (eg, no path lookup)
     assert 0 == spawn.spawn_bash(":")
Example #7
0
    def fetch(self, target):
        """Fetch a file.

        :type target: :obj:`pkgcore.fetch.fetchable` instance
        :return: None if fetching failed,
            else on disk location of the copied file
        """
        if not isinstance(target, fetchable):
            raise TypeError(
                f"target must be fetchable instance/derivative: {target}")

        kw = {"mode": 0o775}
        if self.readonly:
            kw["mode"] = 0o555
        if self.userpriv:
            kw["gid"] = portage_gid
        kw["minimal"] = True
        if not ensure_dirs(self.distdir, **kw):
            raise errors.DistdirPerms(
                self.distdir, "if userpriv, uid must be %i, gid must be %i. "
                "if not readonly, directory must be 0775, else 0555" % (
                    portage_uid, portage_gid))

        path = pjoin(self.distdir, target.filename)
        uris = iter(target.uri)
        last_exc = RuntimeError("fetching failed for an unknown reason")
        spawn_opts = {'umask': 0o002, 'env': self.extra_env}
        if self.userpriv and is_userpriv_capable():
            spawn_opts.update({"uid": portage_uid, "gid": portage_gid})

        for _attempt in range(self.attempts):
            try:
                self._verify(path, target)
                return path
            except errors.MissingDistfile as e:
                command = self.command
                last_exc = e
            except errors.ChksumFailure:
                raise
            except errors.FetchFailed as e:
                last_exc = e
                if not e.resumable:
                    try:
                        os.unlink(path)
                        command = self.command
                    except OSError as e:
                        raise errors.UnmodifiableFile(path, e) from e
                else:
                    command = self.resume_command
            # Note we're not even checking the results, the verify portion of
            # the loop handles this. In other words, don't trust the external
            # fetcher's exit code, trust our chksums instead.
            try:
                spawn_bash(
                    command % {"URI": next(uris), "FILE": target.filename},
                    **spawn_opts)
            except StopIteration:
                raise errors.FetchFailed(
                    target.filename, "ran out of urls to fetch from")
        else:
            raise last_exc
Example #8
0
 def test_bash(self):
     # bash builtin for true without exec'ing true (eg, no path lookup)
     assert 0 == spawn.spawn_bash(":")
Example #9
0
    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=0o2775, gid=portage_gid):
                    raise format.FailedDirectory(
                        pjoin(self.env["DISTCC_DIR"], p),
                        "failed creating needed distcc directory")
        if self.ccache:
            # yuck.
            st = None
            try:
                st = os.stat(self.env["CCACHE_DIR"])
            except OSError as e:
                st = None
                if not ensure_dirs(self.env["CCACHE_DIR"], mode=0o2775,
                                   gid=portage_gid):
                    raise format.FailedDirectory(
                        self.env["CCACHE_DIR"],
                        "failed creation of ccache dir") from e

                # XXX this is more then mildly stupid.
                st = os.stat(self.env["CCACHE_DIR"])
            try:
                if st.st_gid != portage_gid or (st.st_mode & 0o2775) != 0o2775:
                    try:
                        cwd = os.getcwd()
                    except OSError:
                        cwd = "/"
                    with chdir(cwd):
                        # crap.
                        os.chmod(self.env["CCACHE_DIR"], 0o2775)
                        os.chown(self.env["CCACHE_DIR"], -1, portage_gid)
                        if 0 != spawn(
                                ["chgrp", "-R", str(portage_gid), self.env["CCACHE_DIR"]]):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed changing ownership for CCACHE_DIR")
                        if 0 != spawn_bash(
                                "find '%s' -type d -print0 | %s --null chmod 02775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")

                        if 0 != spawn_bash(
                                "find '%s' -type f -print0 | %s --null chmod 0775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")
            except OSError as e:
                raise format.FailedDirectory(
                    self.env["CCACHE_DIR"],
                    "failed ensuring perms/group owner for CCACHE_DIR") from e

        return setup_mixin.setup(self)