Пример #1
0
        def _precache_catalog(self, pub, hsh):
                """Extract the parts from the catalog_dir to the given path."""

                htdocs_path = os.path.join(self.runtime_dir, "htdocs")
                cat_dir = "{htdocs_path}/{pub}/{hsh}/catalog/1".format(
                    **locals())

                if os.path.exists(cat_dir):
                        shutil.rmtree(cat_dir)

                os.makedirs(cat_dir)
                try:
                        self.p5p.extract_catalog1("catalog.attrs", cat_dir,
                            pub=pub)
                        with open(os.path.join(cat_dir, "catalog.attrs"),
                            "rb") as catalog_attrs:
                                ret_json = json.load(catalog_attrs)
                                for part in ret_json["parts"]:
                                        self.p5p.extract_catalog1(part, cat_dir,
                                            pub=pub)

                except pkg.p5p.UnknownArchiveFiles as e:
                        # if the catalog part is unavailable,
                        # we ignore this for now.  It will be
                        # reported later anyway.
                        pass
Пример #2
0
    def _load(self, fobj):
        """Load a json encoded representation of a plan description
                from the specified file object."""

        assert self.state == UNEVALUATED

        try:
            fobj.seek(0)
            state = json.load(fobj, object_hook=pkg.misc.json_hook)
        except OSError as e:
            # Access to protected member; pylint: disable=W0212
            raise apx._convert_error(e)

        PlanDescription.setstate(self, state)
        del state
Пример #3
0
    def __get_avoid_set(self):
        """Returns a tuple of (avoid, implicit_avoid, obsolete)
                representing packages being avoided by image configuration or
                due to package constraints (respectively)."""

        fpath = self.get_img_file_path("var/pkg/state/avoid_set")
        with open(fpath) as f:
            version, d = json.load(f)

        avoid = set()
        implicit_avoid = set()
        obsolete = set()
        for stem in d:
            if d[stem] == "avoid":
                avoid.add(stem)
            elif d[stem] == "implicit-avoid":
                implicit_avoid.add(stem)
            elif d[stem] == "obsolete":
                obsolete.add(stem)
        return avoid, implicit_avoid, obsolete
Пример #4
0
    def test_unprived_operation(self):
        """Test that pkg freeze and unfreeze display the frozen packages
                without needing privs, and that they don't stack trace when run
                without privs."""

        self.api_obj = self.image_create(self.rurl)
        self.pkg("freeze", su_wrap=True)
        self.pkg("freeze [email protected]", su_wrap=True, exit=1)
        self.pkg("unfreeze foo", su_wrap=True, exit=1)
        self.pkg("freeze [email protected]")
        self.pkg("freeze -H", su_wrap=True)
        tmp = self.output.split()
        self.assertEqualDiff("foo", tmp[0])
        self.assertEqualDiff("1.0", tmp[1])
        self.assertTrue("None" in self.output)
        self.pkg("unfreeze -H", su_wrap=True)
        tmp = self.output.split()
        self.assertEqualDiff("foo", tmp[0])
        self.assertEqualDiff("1.0", tmp[1])
        self.assertTrue("None" in self.output)

        # Test that if the freeze file can't be read, we handle the
        # exception appropriately.
        pth = os.path.join(self.img_path(), "var", "pkg", "state",
                           "frozen_dict")
        mod = stat.S_IMODE(os.stat(pth)[stat.ST_MODE])
        new_mod = mod & ~stat.S_IROTH
        os.chmod(pth, new_mod)
        self.pkg("freeze", exit=1, su_wrap=True)
        self.pkg("unfreeze", exit=1, su_wrap=True)
        os.chmod(pth, mod)

        # Make sure that we can read the file again.
        self.pkg("freeze", su_wrap=True)

        # Test that we don't stack trace if the version is unexpected.
        version, d = json.load(open(pth))
        with open(pth, "w") as fh:
            json.dump((-1, d), fh)
        self.pkg("freeze", exit=1)
        self.pkg("unfreeze", exit=1)
Пример #5
0
def _load_publisher_info(api_inst, image_dir):
    """Loads information about the publishers configured for the
        given ImageInterface from image_dir in a format identical to that
        returned by _get_publisher_info(..)  that is, a dictionary mapping
        URIs to a list of lists. An example entry might be:
            pub_info[uri] = [[prefix, cert, key, hash of the uri, proxy], ... ]

        and a list of publishers which have no origin or mirror URIs.

        If the cache doesn't exist, or is in a format we don't recognise, or
        we've managed to determine that it's stale, we return None, None
        indicating that the publisher_info must be rebuilt.
        """
    pub_info = None
    no_uri_pubs = None
    cache_path = os.path.join(
        image_dir, pkg.client.global_settings.sysrepo_pub_cache_path)
    try:
        try:
            st_cache = os.lstat(cache_path)
        except OSError as e:
            if e.errno == errno.ENOENT:
                return None, None
            else:
                raise

        # the cache must be a regular file
        if not stat.S_ISREG(st_cache.st_mode):
            raise IOError("not a regular file")

        with open(cache_path, "r") as cache_file:
            try:
                pub_info_tuple = json.load(cache_file)
            except json.JSONDecodeError:
                error(
                    _("Invalid config cache file at {0} "
                      "generating fresh configuration.").format(cache_path))
                return None, None

            if len(pub_info_tuple) != 2:
                error(
                    _("Invalid config cache at {0} "
                      "generating fresh configuration.").format(cache_path))
                return None, None

            pub_info, no_uri_pubs = pub_info_tuple
            # sanity-check the cached configuration
            try:
                __validate_pub_info(pub_info, no_uri_pubs, api_inst)
            except SysrepoException as e:
                error(
                    _("Invalid config cache at {0} "
                      "generating fresh configuration.").format(cache_path))
                return None, None

    # If we have any problems loading the publisher info, we explain why.
    except IOError as e:
        error(
            _("Unable to load config from {cache_path}: {e}").format(
                **locals()))
        return None, None

    return pub_info, no_uri_pubs
Пример #6
0
def parse(data=None, fileobj=None, location=None):
    """Reads the pkg(5) publisher JSON formatted data at 'location'
        or from the provided file-like object 'fileobj' and returns a
        list of tuples of the format (publisher object, pkg_names).
        pkg_names is a list of strings representing package names or
        FMRIs.  If any pkg_names not specific to a publisher were
        provided, the last tuple returned will be of the format (None,
        pkg_names).

        'data' is an optional string containing the p5i data.

        'fileobj' is an optional file-like object that must support a
        'read' method for retrieving data.

        'location' is an optional string value that should either start
        with a leading slash and be pathname of a file or a URI string.
        If it is a URI string, supported protocol schemes are 'file',
        'ftp', 'http', and 'https'.

        'data' or 'fileobj' or 'location' must be provided."""

    if data is None and location is None and fileobj is None:
        raise api_errors.InvalidResourceLocation(location)

    if location is not None:
        if location.find("://") == -1 and \
            not location.startswith("file:/"):
            # Convert the file path to a URI.
            location = os.path.abspath(location)
            location = urlunparse(
                ("file", "", pathname2url(location), "", "", ""))

        try:
            fileobj = urlopen(location)
        except (EnvironmentError, ValueError, HTTPError) as e:
            raise api_errors.RetrievalError(e, location=location)

    try:
        if data is not None:
            dump_struct = json.loads(data)
        else:
            dump_struct = json.load(fileobj)
    except (EnvironmentError, HTTPError) as e:
        raise api_errors.RetrievalError(e)
    except ValueError as e:
        # Not a valid JSON file.
        raise api_errors.InvalidP5IFile(e)

    try:
        ver = int(dump_struct["version"])
    except KeyError:
        raise api_errors.InvalidP5IFile(_("missing version"))
    except ValueError:
        raise api_errors.InvalidP5IFile(_("invalid version"))

    if ver > CURRENT_VERSION:
        raise api_errors.UnsupportedP5IFile()

    result = []
    try:
        plist = dump_struct.get("publishers", [])

        for p in plist:
            alias = p.get("alias", None)
            prefix = p.get("name", None)

            if not prefix:
                prefix = "Unknown"

            pub = publisher.Publisher(prefix, alias=alias)
            pkglist = p.get("packages", [])
            result.append((pub, pkglist))

            for r in p.get("repositories", []):
                rargs = {}
                for prop in ("collection_type", "description", "name",
                             "refresh_seconds", "registration_uri"):
                    val = r.get(prop, None)
                    if val is None or val == "None":
                        continue
                    rargs[prop] = val

                for prop in ("legal_uris", "mirrors", "origins",
                             "related_uris"):
                    val = r.get(prop, [])
                    if not isinstance(val, list):
                        continue
                    rargs[prop] = val

                repo = publisher.Repository(**rargs)
                pub.repository = repo

        pkglist = dump_struct.get("packages", [])
        if pkglist:
            result.append((None, pkglist))
    except (api_errors.PublisherError, TypeError, ValueError) as e:
        raise api_errors.InvalidP5IFile(str(e))
    return result