Exemple #1
0
def __run_search(paths, api_inst):
    """Function which interfaces with the search engine and extracts the
        fmri and variants from the actions which deliver the paths being
        searched for.

        'paths' is the paths to search for.

        'api_inst' is an ImageInterface which references the current image."""

    qs = [
        api.Query(p, case_sensitive=False, return_actions=True) for p in paths
    ]
    search_res = api_inst.local_search(qs)
    res = []
    try:
        for num, pub, (version, return_type, (pfmri, match, a_str)) \
            in search_res:
            pfmri = fmri.PkgFmri(pfmri)
            m = api_inst.img.get_manifest(pfmri)
            vars = variants.VariantSets(
                actions.fromstr(a_str.rstrip()).get_variants())
            vars.merge_unknown(m.get_all_variants())
            res.append((pfmri, vars))
    except api_errors.SlowSearchUsed:
        pass
    return res
Exemple #2
0
    def __init__(self, action, pkg_vars, proto_dir, attrs):
        """Each dependency needs to know the action that generated it
                and the variants for the package containing that action.

                'action' is the action which produced this dependency.

                'pkg_vars' is the list of variants against which the package
                delivering the action was published.

                'proto_dir' is the proto area where the file the action delivers
                lives.

                'attrs' is a dictionary to containing the relevant action tags
                for the dependency.
                """
        self.action = action
        self.pkg_vars = pkg_vars
        self.proto_dir = proto_dir
        self.dep_vars = variant.VariantSets(action.get_variants())

        attrs.update([("fmri", self.DUMMY_FMRI), ("type", self.DEPEND_TYPE),
                      ("%s.reason" % self.DEPEND_DEBUG_PREFIX,
                       self.action_path())])

        if self.dep_vars is not None:
            attrs.update(self.dep_vars)

        depend.DependencyAction.__init__(self, **attrs)
Exemple #3
0
    def get_var_diff(self, ext_vars):
        """Find the difference of the set of variants declared for the
                action that produced this dependency, and another set of
                variants."""

        vars = variant.VariantSets(self.action.get_variants())
        for k in self.pkg_vars:
            if k not in vars:
                vars[k] = self.pkg_vars[k]
        return vars.difference(ext_vars)
def resolve_internal_deps(deps, mfst, proto_dirs, pkg_vars):
        """Given a list of dependencies, remove those which are satisfied by
        others delivered by the same package.

        'deps' is a list of Dependency objects.

        'mfst' is the Manifest of the package that delivered the dependencies
        found in deps.

        'proto_dir' is the path to the proto area which holds the files that
        will be delivered by the package.

        'pkg_vars' are the variants that this package was published against."""

        res = []
        delivered = {}
        delivered_bn = {}
        for a in mfst.gen_actions_by_type("file"):
                pvars = variants.VariantSets(a.get_variants())
                if not pvars:
                        pvars = pkg_vars
                else:
                        pvars.merge_unknown(pkg_vars)
                p = a.attrs["path"]
                delivered.setdefault(p, variants.VariantSets()).merge(pvars)
                p = os.path.join(a.attrs[portable.PD_PROTO_DIR], p)
                np = os.path.normpath(p)
                rp = os.path.realpath(p)
                # adding the normalized path
                delivered.setdefault(np, variants.VariantSets()).merge(pvars)
                # adding the real path
                delivered.setdefault(rp, variants.VariantSets()).merge(pvars)
                bn = os.path.basename(p)
                delivered_bn.setdefault(bn, variants.VariantSets()).merge(pvars)

        for d in deps:
                etype, pvars = d.resolve_internal(delivered_files=delivered,
                    delivered_base_names=delivered_bn)
                if etype is None:
                        continue
                d.dep_vars = pvars
                res.append(d)
        return res
def split_off_variants(dep, pkg_vars):
        """Take a dependency which may be tagged with variants and move those
        tags into a VariantSet."""

        dep_vars = variants.VariantSets(dep.get_variants())
        dep_vars.merge_unknown(pkg_vars)
        # Since all variant information is being kept in the above VariantSets,
        # remove the variant information from the action.  This prevents
        # confusion about which is the authoritative source of information.
        dep.strip_variants()
        return dep, dep_vars
Exemple #6
0
def resolve_deps(manifest_paths, api_inst):
    """For each manifest given, resolve the file dependencies to package
        dependencies. It returns a mapping from manifest_path to a list of
        dependencies and a list of unresolved dependencies.

        'manifest_paths' is a list of paths to the manifests being resolved.

        'api_inst' is an ImageInterface which references the current image."""

    manifests = [(mp, choose_name(mp, mfst), mfst, mfst.get_all_variants())
                 for mp, mfst in ((mp, make_manifest(mp))
                                  for mp in manifest_paths)]
    delivered_files = {}
    # Build a list of all files delivered in the manifests being resolved.
    for n, f_list, pkg_vars in ((name,
                                 itertools.chain(
                                     mfst.gen_actions_by_type("file"),
                                     mfst.gen_actions_by_type("hardlink"),
                                     mfst.gen_actions_by_type("link")), pv)
                                for mp, name, mfst, pv in manifests):
        for f in f_list:
            dep_vars = variants.VariantSets(f.get_variants())
            dep_vars.merge_unknown(pkg_vars)
            delivered_files.setdefault(f.attrs["path"], []).append(
                (n, dep_vars))
    pkg_deps = {}
    errs = []
    for mp, name, mfst, pkg_vars in manifests:
        if mfst is None:
            pkg_deps[mp] = None
            continue
        pkg_res = [(d, find_package(api_inst, delivered_files, d, pkg_vars))
                   for d in mfst.gen_actions_by_type("depend")
                   if is_file_dependency(d)]
        deps = []
        for file_dep, (res, dep_vars) in pkg_res:
            if not res:
                dep_vars.merge_unknown(pkg_vars)
                errs.append((mp, file_dep, dep_vars))
            else:
                deps.extend(res)
                if not dep_vars.is_satisfied():
                    errs.append((mp, file_dep, dep_vars))
        pkg_deps[mp] = deps

    return pkg_deps, errs
        def add_fmri_path_mapping(pathdict, pfmri, mfst):
                """Add mappings from path names to FMRIs and variants.

                'pathdict' is a dict path -> (fmri, variants) to which
                entries are added.

                'pfmri' is the FMRI of the current manifest

                'mfst' is the manifest to process."""

                pvariants = mfst.get_all_variants()

                for f in itertools.chain(mfst.gen_actions_by_type("file"),
                     mfst.gen_actions_by_type("hardlink"),
                     mfst.gen_actions_by_type("link")):
                        dep_vars = variants.VariantSets(f.get_variants())
                        dep_vars.merge_unknown(pvariants)
                        pathdict.setdefault(f.attrs["path"], []).append(
                            (pfmri, dep_vars))
Exemple #8
0
def find_package(api_inst, delivered, file_dep, pkg_vars):
    """Find the packages which resolve the dependency. It returns a list of
        dependency actions with the fmri tag resolved.

        'api_inst' is an ImageInterface which references the current image.

        'delivered' is a dictionary mapping paths to a list of fmri, variants
        pairs.

        'file_dep' is the dependency being resolved.

        "pkg_vars' is the variants against which the package was published."""

    dep_vars = variants.VariantSets(file_dep.get_variants())
    dep_vars.merge_unknown(pkg_vars)
    res, dep_vars = \
        find_package_using_delivered_files(delivered, file_dep,
            dep_vars, pkg_vars)
    if res and dep_vars.is_satisfied():
        return res, dep_vars
    search_res, dep_vars = \
        find_package_using_search(api_inst, file_dep, dep_vars, pkg_vars)
    res.extend(search_res)
    return res, dep_vars
Exemple #9
0
 def get_var_set(self):
     vars = variant.VariantSets(self.action.get_variants())
     for k in self.pkg_vars:
         if k not in vars:
             vars[k] = self.pkg_vars[k]
     return vars
Exemple #10
0
 def get_all_variants(self):
     """Return a dictionary mapping variant tags to their values."""
     return variant.VariantSets(
         dict(((name, self.attributes[name]) for name in self.attributes
               if name.startswith("variant."))))
Exemple #11
0
 def get_variants(self):
     return variant.VariantSets(
         dict(((v, self.attrs[v]) for v in self.get_varcet_keys()[0])))