Example #1
0
    def __unit_ids_to_plugin_unit_keys(self, unit_ids_by_type, repo_ids):
        """
        Parse a dictionary of unit ids keyed by content type id and return a dictionary of 
        corresponding plugin unit keys keyed by content type id.

        :param unit_ids_by_type: dictionary of <content type id> : <list of unit ids>
        :type unit_ids_by_type: dict

        :return: if units are specified, return the corresponding plugin unit_keys. If unit_ids_by_type dict
                 is empty, return plugin unit keys corresponging to all units in given repo ids.
                 If unit ids list for a particular unit type is empty, return all plugin unit_keys
                 in given repo ids with that unit type.
        :rtype: dict
        """
        repo_unit_association_query_manager = managers.repo_unit_association_query_manager()
        content_query_manager = managers.content_query_manager()

        result_unit_keys = {}

        if unit_ids_by_type is not None:
            for unit_type_id, unit_ids in unit_ids_by_type.items():
                # Get unit type specific collection
                collection = content_query_manager.get_content_unit_collection(type_id=unit_type_id)
                type_def = content_types_db.type_definition(unit_type_id)
                if not unit_ids:
                    # If unit_list is empty for a unit_type, consider all units of specific type
                    criteria = UnitAssociationCriteria(unit_fields = ['unit_id'])
                    for repo_id in repo_ids:
                        repo_units = repo_unit_association_query_manager.get_units_by_type(repo_id, unit_type_id, criteria)
                        # Get metadata for each unit from type specific collection
                        pulp_units = [collection.find_one({'_id': u['unit_id']}) for u in repo_units]
                        # Convert pulp units to plugin unit keys
                        plugin_unit_keys = [common_utils.to_plugin_unit(u, type_def).unit_key for u in pulp_units]
                        result_unit_keys.setdefault(unit_type_id, []).extend(plugin_unit_keys)
                else:
                    # Get metadata for each unit from type specific collection
                    pulp_units = [collection.find_one({'_id': unit_id}) for unit_id in unit_ids]
                    # Convert pulp units to plugin unit keys
                    plugin_unit_keys = [common_utils.to_plugin_unit(u, type_def).unit_key for u in pulp_units]
                    result_unit_keys.setdefault(unit_type_id, []).extend(plugin_unit_keys)
        else:
            # If units are not specified, consider all units in given repos.
            for repo_id in repo_ids:
                all_unit_type_ids = content_types_db.all_type_ids()
                for unit_type_id in all_unit_type_ids:
                    criteria = UnitAssociationCriteria(type_ids=[unit_type_id], unit_fields = ['unit_id', 'unit_type_id'])
                    repo_units = repo_unit_association_query_manager.get_units(repo_id, criteria)

                    # Get unit metadata for each unit from type specific collection
                    collection = content_query_manager.get_content_unit_collection(type_id=unit_type_id)
                    pulp_units = [collection.find_one({'_id': u['unit_id']}) for u in repo_units]
  
                    # Convert pulp units to plugin unit keys
                    type_def = content_types_db.type_definition(unit_type_id)
                    plugin_unit_keys = [common_utils.to_plugin_unit(u, type_def).unit_key for u in pulp_units]
                    result_unit_keys.setdefault(unit_type_id, []).extend(plugin_unit_keys)

        return result_unit_keys
Example #2
0
    def __parse_units(self, user_units, repo_ids):
        """
        Parse units specified by user and return a dictionary of all plugin unit_keys 
        to be considered for applicability keyed by unit_type_id.

        :param user_units: dictionary of unit metadata filters keyed by unit-type-id specified by user
        :type user_units: dict

        :return: if specific units are specified, return the corresponding plugin unit_keys. If units dict is empty, 
                 return all plugin unit_keys corresponging to units in given repo ids keyed by unit_type_id. 
                 If units list for a particular unit type in units is empty, return all plugin unit_keys 
                 in given repo ids with that unit type keyed by unit_type_id.
        :rtype: dict
        """
        repo_unit_association_query_manager = managers.repo_unit_association_query_manager()
        content_query_manager = managers.content_query_manager()

        result_unit_keys = {}
        if user_units is not None:
            for unit_type_id, unit_list in user_units.items():
                # Get unit type specific collection
                collection = content_query_manager.get_content_unit_collection(type_id=unit_type_id)
                type_def = content_types_db.type_definition(unit_type_id)
                if not unit_list:
                    # If unit_list is empty for a unit_type, consider all units of specific type
                    criteria = UnitAssociationCriteria(unit_fields = ['unit_id'])
                    for repo_id in repo_ids:
                        repo_units = repo_unit_association_query_manager.get_units_by_type(repo_id, unit_type_id, criteria)
                        # Get unit metadata for each unit from type specific collection
                        pulp_units = [collection.find_one({'_id': u['unit_id']}) for u in repo_units]
                        plugin_units = [common_utils.to_plugin_unit(u, type_def) for u in pulp_units]
                        plugin_unit_keys = [u.unit_key for u in plugin_units]
                        result_unit_keys.setdefault(unit_type_id, []).extend(plugin_unit_keys)
                else:
                    for unit in unit_list:
                        criteria = UnitAssociationCriteria(unit_filters=unit, unit_fields = ['unit_id'])
                        for repo_id in repo_ids:
                            repo_units = repo_unit_association_query_manager.get_units_by_type(repo_id, unit_type_id, criteria)
                            # Get unit metadata for each unit from type specific collection
                            pulp_units = [collection.find_one({'_id': u['unit_id']}) for u in repo_units]
                            plugin_units = [common_utils.to_plugin_unit(u, type_def) for u in pulp_units]
                            plugin_unit_keys = [u.unit_key for u in plugin_units]
                            result_unit_keys.setdefault(unit_type_id, []).extend(plugin_unit_keys)
        else:
            # If units are not specified, consider all units in repo_ids list.
            for repo_id in repo_ids:
                criteria = UnitAssociationCriteria(unit_fields = ['unit_id','unit_type_id'])
                repo_units = repo_unit_association_query_manager.get_units(repo_id, criteria)
                # Get unit metadata for each unit from type specific collection
                for repo_unit in repo_units:
                    collection = content_query_manager.get_content_unit_collection(type_id=repo_unit['unit_type_id'])
                    type_def = content_types_db.type_definition(repo_unit['unit_type_id'])
                    pulp_unit = collection.find_one({'_id': repo_unit['unit_id']})
                    plugin_unit = common_utils.to_plugin_unit(pulp_unit, type_def)
                    result_unit_keys.setdefault(repo_unit['unit_type_id'], []).append(plugin_unit.unit_key)

        return result_unit_keys
Example #3
0
File: mixins.py Project: omps/pulp
    def search_all_units(self, type_id, criteria):
        """
        Searches for units of a given type in the server, regardless of their
        associations to any repositories.

        @param type_id: indicates the type of units being retrieved
        @type  type_id: str
        @param criteria: used to query which units are returned
        @type  criteria: pulp.server.db.model.criteria.Criteria

        @return: list of unit instances
        @rtype:  list of L{Unit}
        """

        try:
            query_manager = manager_factory.content_query_manager()
            units = query_manager.find_by_criteria(type_id, criteria)
            type_def = types_db.type_definition(type_id)

            transfer_units = []
            for pulp_unit in units:
                u = common_utils.to_plugin_unit(pulp_unit, type_def)
                transfer_units.append(u)

            return transfer_units

        except Exception, e:
            logger.exception(
                'Exception from server requesting all units of type [%s]' %
                type_id)
            raise self.exception_class(e), None, sys.exc_info()[2]
Example #4
0
    def search_all_units(self, type_id, criteria):
        """
        Searches for units of a given type in the server, regardless of their
        associations to any repositories.

        @param type_id: indicates the type of units being retrieved
        @type  type_id: str
        @param criteria: used to query which units are returned
        @type  criteria: pulp.server.db.model.criteria.Criteria

        @return: list of unit instances
        @rtype:  list of L{Unit}
        """

        try:
            query_manager = manager_factory.content_query_manager()
            units = query_manager.find_by_criteria(type_id, criteria)
            type_def = types_db.type_definition(type_id)

            transfer_units = []
            for pulp_unit in units:
                u = common_utils.to_plugin_unit(pulp_unit, type_def)
                transfer_units.append(u)

            return transfer_units

        except Exception, e:
            _LOG.exception('Exception from server requesting all units of type [%s]' % type_id)
            raise self.exception_class(e), None, sys.exc_info()[2]
Example #5
0
def do_get_repo_units(repo_id, criteria, exception_class):
    """
    Performs a repo unit association query. This is split apart so we can have
    custom mixins with different signatures.
    """
    try:
        association_query_manager = manager_factory.repo_unit_association_query_manager()
        units = association_query_manager.get_units(repo_id, criteria=criteria)

        all_units = []

        # Load all type definitions in use so we don't hammer the database
        unique_type_defs = set([u['unit_type_id'] for u in units])
        type_defs = {}
        for def_id in unique_type_defs:
            type_def = types_db.type_definition(def_id)
            type_defs[def_id] = type_def

        # Convert to transfer object
        for unit in units:
            type_id = unit['unit_type_id']
            u = common_utils.to_plugin_unit(unit, type_defs[type_id])
            all_units.append(u)

        return all_units

    except Exception, e:
        _LOG.exception('Exception from server requesting all content units for repository [%s]' % repo_id)
        raise exception_class(e), None, sys.exc_info()[2]
Example #6
0
    def find_unit_by_unit_key(self, type_id, unit_key):
        """
        Finds a unit based on its unit key. If more than one unit comes back,
        an exception will be raised.

        @param type_id: indicates the type of units being retrieved
        @type  type_id: str
        @param unit_key: the unit key for the unit
        @type  unit_key: dict

        @return: a single unit
        @rtype:  L{Unit}
        """
        content_query_manager = manager_factory.content_query_manager()
        try:
            # this call returns a unit or raises MissingResource
            existing_unit = content_query_manager.get_content_unit_by_keys_dict(
                type_id, unit_key)
            unit_key_fields = units_controller.get_unit_key_fields_for_type(
                type_id)
            plugin_unit = common_utils.to_plugin_unit(existing_unit, type_id,
                                                      unit_key_fields)
            return plugin_unit
        except pulp_exceptions.MissingResource:
            return None
Example #7
0
def create_transfer_units(associate_units, associated_unit_type_ids):
    type_defs = {}
    for def_id in associated_unit_type_ids:
        type_def = types_db.type_definition(def_id)
        type_defs[def_id] = type_def

    transfer_units = []
    for unit in associate_units:
        type_id = unit['unit_type_id']
        u = conduit_common_utils.to_plugin_unit(unit, type_defs[type_id])
        transfer_units.append(u)

    return transfer_units
Example #8
0
    def get_source_units(self, criteria=None):
        """
        Returns the collection of content units associated with the source
        repository for a unit import.

        Units returned from this call will have the id field populated and are
        useable in any calls in this conduit that require the id field.

        @param criteria: used to scope the returned results or the data within;
               the Criteria class can be imported from this module
        @type  criteria: L{Criteria}

        @return: list of unit instances
        @rtype:  list of L{AssociatedUnit}
        """

        try:
            units = self.__association_query_manager.get_units_across_types(self.source_repo_id, criteria=criteria)

            all_units = []

            # Load all type definitions in use so we don't hammer the database
            unique_type_defs = set([u['unit_type_id'] for u in units])
            type_defs = {}
            for def_id in unique_type_defs:
                type_def = types_db.type_definition(def_id)
                type_defs[def_id] = type_def

            # Convert to transfer object
            for unit in units:
                type_id = unit['unit_type_id']
                u = common_utils.to_plugin_unit(unit, type_defs[type_id])
                all_units.append(u)

            return all_units

        except Exception, e:
            _LOG.exception('Exception from server requesting all content units for repository [%s]' % self.repo_id)
            raise UnitImportConduitException(e), None, sys.exc_info()[2]
Example #9
0
    def find_unit_by_unit_key(self, type_id, unit_key):
        """
        Finds a unit based on its unit key. If more than one unit comes back,
        an exception will be raised.

        @param type_id: indicates the type of units being retrieved
        @type  type_id: str
        @param unit_key: the unit key for the unit
        @type  unit_key: dict

        @return: a single unit
        @rtype:  L{Unit}
        """
        content_query_manager = manager_factory.content_query_manager()
        try:
            # this call returns a unit or raises MissingResource
            existing_unit = content_query_manager.get_content_unit_by_keys_dict(type_id, unit_key)
            unit_key_fields = units_controller.get_unit_key_fields_for_type(type_id)
            plugin_unit = common_utils.to_plugin_unit(existing_unit, type_id, unit_key_fields)
            return plugin_unit
        except pulp_exceptions.MissingResource:
            return None
Example #10
0
    def resolve_dependencies_by_units(self, repo_id, units, options):
        """
        Calculates dependencies for the given set of units in the given
        repository.

        @param repo_id: identifies the repository
        @type  repo_id: str

        @param units: list of database representations of units to resolve
               dependencies for
        @type  units: list

        @param options: dict of options to pass the importer to drive the resolution
        @type  options: dict or None

        @return: report from the plugin
        @rtype:  object

        @raise MissingResource: if the repo does not exist or does not have
               an importer
        """

        # Validation
        repo_query_manager = manager_factory.repo_query_manager()
        importer_manager = manager_factory.repo_importer_manager()

        # The following will raise MissingResource as appropriate
        repo = repo_query_manager.get_repository(repo_id)
        repo_importer = importer_manager.get_importer(repo_id)

        try:
            importer_instance, plugin_config = plugin_api.get_importer_by_id(repo_importer['importer_type_id'])
        except plugin_exceptions.PluginNotFound:
            raise MissingResource(repo_id), None, sys.exc_info()[2]

        # Package for the importer call
        call_config = PluginCallConfiguration(plugin_config, repo_importer['config'], options)
        transfer_repo = common_utils.to_transfer_repo(repo)
        transfer_repo.working_dir = common_utils.importer_working_dir(repo_importer['importer_type_id'], repo_id, mkdir=True)

        conduit = DependencyResolutionConduit(repo_id, repo_importer['id'])

        # Convert all of the units into the plugin standard representation
        transfer_units = []

        # Preload all the type defs so we don't hammer the database unnecessarily
        type_defs = {}
        all_type_def_ids = set([u['unit_type_id'] for u in units])
        for def_id in all_type_def_ids:
            type_def = types_db.type_definition(def_id)
            type_defs[def_id] = type_def

        for unit in units:
            type_id = unit['unit_type_id']
            u = conduit_common_utils.to_plugin_unit(unit, type_defs[type_id])
            transfer_units.append(u)

        # Invoke the importer
        try:
            dep_report = importer_instance.resolve_dependencies(transfer_repo, transfer_units, conduit, call_config)
        except Exception, e:
            raise PulpExecutionException(), None, sys.exc_info()[2]
Example #11
0
    def associate_from_repo(self, source_repo_id, dest_repo_id, criteria=None):
        """
        Creates associations in a repository based on the contents of a source
        repository. Units from the source repository can be filtered by
        specifying a criteria object.

        The destination repository must have an importer that can support
        the types of units being associated. This is done by analyzing the
        unit list and the importer metadata and takes place before the
        destination repository is called.

        Pulp does not actually perform the associations as part of this call.
        The unit list is determined and passed to the destination repository's
        importer. It is the job of the importer to make the associate calls
        back into Pulp where applicable.

        If criteria is None, the effect of this call is to copy the source
        repository's associations into the destination repository.

        @param source_repo_id: identifies the source repository
        @type  source_repo_id: str

        @param dest_repo_id: identifies the destination repository
        @type  dest_repo_id: str

        @param criteria: optional; if specified, will filter the units retrieved
                         from the source repository
        @type  criteria: L{Criteria}

        @raise MissingResource: if either of the specified repositories don't exist
        """

        # Validation
        repo_query_manager = manager_factory.repo_query_manager()
        importer_manager = manager_factory.repo_importer_manager()
        dependency_manager = manager_factory.dependency_manager()
        association_query_manager = manager_factory.repo_unit_association_query_manager()

        source_repo = repo_query_manager.get_repository(source_repo_id)
        dest_repo = repo_query_manager.get_repository(dest_repo_id)

        # This will raise MissingResource if there isn't one, which is the
        # behavior we want this method to exhibit, so just let it bubble up.
        dest_repo_importer = importer_manager.get_importer(dest_repo_id)
        source_repo_importer = importer_manager.get_importer(source_repo_id)

        # The docs are incorrect on the list_importer_types call; it actually
        # returns a dict with the types under key "types" for some reason.
        supported_type_ids = plugin_api.list_importer_types(dest_repo_importer['importer_type_id'])['types']

        # If criteria is specified, retrieve the list of units now
        associate_us = None
        if criteria is not None:
            criteria.association_fields = None
            criteria.unit_fields = None

            # Retrieve the units to be associated
            associate_us = association_query_manager.get_units(source_repo_id, criteria=criteria)

            # If units were supposed to be filtered but none matched, we're done
            if len(associate_us) is 0:
                return

        # Now we can make sure the destination repository's importer is capable
        # of importing either the selected units or all of the units
        if associate_us is not None:
            associated_unit_type_ids = set([u['unit_type_id'] for u in associate_us])
        else:
            association_query_manager = manager_factory.repo_unit_association_query_manager()

            # We may want to make a call here that only retrieves the unique
            # type IDs instead of all of the units, but for now it doesn't exist
            # and I'm not entirely sure this will be a huge problem.
            all_units = association_query_manager.get_units(source_repo_id)
            associated_unit_type_ids = set(u['unit_type_id'] for u in all_units)

        unsupported_types = [t for t in associated_unit_type_ids if t not in supported_type_ids]

        if len(unsupported_types) > 0:
            raise exceptions.InvalidValue(['types'])

        # Convert all of the units into the plugin standard representation if
        # a filter was specified
        transfer_units = None
        if associate_us is not None:
            type_defs = {}
            for def_id in associated_unit_type_ids:
                type_def = types_db.type_definition(def_id)
                type_defs[def_id] = type_def

            transfer_units = []
            for unit in associate_us:
                type_id = unit['unit_type_id']
                u = conduit_common_utils.to_plugin_unit(unit, type_defs[type_id])
                transfer_units.append(u)

        # Convert the two repos into the plugin API model
        transfer_dest_repo = common_utils.to_transfer_repo(dest_repo)
        transfer_dest_repo.working_dir = common_utils.importer_working_dir(dest_repo_importer['importer_type_id'], dest_repo['id'], mkdir=True)

        transfer_source_repo = common_utils.to_transfer_repo(source_repo)
        transfer_source_repo.working_dir = common_utils.importer_working_dir(source_repo_importer['importer_type_id'], source_repo['id'], mkdir=True)

        # Invoke the importer
        importer_instance, plugin_config = plugin_api.get_importer_by_id(dest_repo_importer['importer_type_id'])

        call_config = PluginCallConfiguration(plugin_config, dest_repo_importer['config'])
        conduit = ImportUnitConduit(source_repo_id, dest_repo_id, source_repo_importer['id'], dest_repo_importer['id'])

        try:
            importer_instance.import_units(transfer_source_repo, transfer_dest_repo, conduit, call_config, units=transfer_units)
        except Exception:
            _LOG.exception('Exception from importer [%s] while importing units into repository [%s]' % (dest_repo_importer['importer_type_id'], dest_repo_id))
            raise exceptions.PulpExecutionException(), None, sys.exc_info()[2]