Beispiel #1
0
    def run(self):
        """
        Synchronize the repository with the remote repository.

        This walks through the standard workflow that most sync operations want to follow. This
        pattern is a recommended starting point for other plugins.

        - Determine what is available remotely.
        - Determine what is already in the local repository.
        - Compare those two, and based on any importer settings or content-type-specific logic,
          figure out what you want to add and remove from the local repository.
        - Use a ChangeSet to make those changes happen.
        """
        # Determine what is available remotely
        self._fetch_manifest()
        # Determine what is already in the repo
        self._fetch_inventory()

        # Based on the above two, figure out what we want to add and remove
        self._find_delta()
        additions = SizedIterable(self._build_additions(),
                                  len(self._keys_to_add))
        removals = SizedIterable(self._build_removals(),
                                 len(self._keys_to_remove))

        # Hand that to a ChangeSet, and we're done!
        changeset = ChangeSet(self._importer,
                              additions=additions,
                              removals=removals)
        changeset.apply_and_drain()
Beispiel #2
0
def sync(remote_pk, repository_pk):
    """
    Sync content from the remote repository.

    Create a new version of the repository that is synchronized with the remote.

    Args:
        remote_pk (str): The remote PK.
        repository_pk (str): The repository PK.

    Raises:
        serializers: ValidationError

    """
    remote = python_models.PythonRemote.objects.get(pk=remote_pk)
    repository = models.Repository.objects.get(pk=repository_pk)

    if not remote.url:
        raise serializers.ValidationError(
            detail=_("A remote must have a url attribute to sync."))

    base_version = models.RepositoryVersion.latest(repository)

    with models.RepositoryVersion.create(repository) as new_version:
        with WorkingDirectory():
            log.info(
                _('Creating RepositoryVersion: repository={repository} remote={remote}'
                  ).format(repository=repository.name, remote=remote.name))

            project_specifiers = python_models.ProjectSpecifier.objects.filter(
                remote=remote).all()

            inventory_keys = _fetch_inventory(base_version)
            remote_metadata = _fetch_specified_metadata(
                remote, project_specifiers)
            remote_keys = set(
                [content['filename'] for content in remote_metadata])

            delta = _find_delta(inventory=inventory_keys, remote=remote_keys)

            additions = _build_additions(delta, remote_metadata)
            removals = _build_removals(delta, base_version)
            changeset = ChangeSet(remote,
                                  new_version,
                                  additions=additions,
                                  removals=removals)
            changeset.apply_and_drain()
Beispiel #3
0
def synchronize(remote_pk, repository_pk):
    """
    Sync content from the remote repository.

    Create a new version of the repository that is synchronized with the remote.

    Args:
        remote_pk (str): The remote PK.
        repository_pk (str): The repository PK.

    Raises:
        ValueError: When remote has no url specified.

    """
    remote = AnsibleRemote.objects.get(pk=remote_pk)
    repository = Repository.objects.get(pk=repository_pk)
    base_version = RepositoryVersion.latest(repository)

    if not remote.url:
        raise ValueError(
            _('A remote must have a url specified to synchronize.'))

    with WorkingDirectory():
        with RepositoryVersion.create(repository) as new_version:
            log.info(_('Synchronizing: repository=%(r)s remote=%(p)s'), {
                'r': repository.name,
                'p': remote.name
            })
            roles = fetch_roles(remote)
            content = fetch_content(base_version)
            delta = find_delta(roles, content)
            additions = build_additions(remote, roles, delta)
            removals = build_removals(base_version, delta)
            changeset = ChangeSet(remote=remote,
                                  repository_version=new_version,
                                  additions=additions,
                                  removals=removals)
            for report in changeset.apply():
                if not log.isEnabledFor(logging.DEBUG):
                    continue
                log.debug(
                    _('Applied: repository=%(r)s remote=%(p)s change:%(c)s'), {
                        'r': repository.name,
                        'p': remote.name,
                        'c': report,
                    })
Beispiel #4
0
def synchronize(importer_pk, repository_pk):
    """
    Create a new version of the repository that is synchronized with the remote
    as specified by the importer.

    Args:
        importer_pk (str): The importer PK.
        repository_pk (str): The repository PK.

    Raises:
        ValueError: When feed_url is empty.
    """
    importer = FileImporter.objects.get(pk=importer_pk)
    repository = Repository.objects.get(pk=repository_pk)
    base_version = RepositoryVersion.latest(repository)

    if not importer.feed_url:
        raise ValueError(
            _('An importer must have a feed_url specified to synchronize.'))

    with WorkingDirectory():
        with RepositoryVersion.create(repository) as new_version:
            log.info(_('Synchronizing: repository=%(r)s importer=%(p)s'), {
                'r': repository.name,
                'p': importer.name
            })
            manifest = fetch_manifest(importer)
            content = fetch_content(base_version)
            delta = find_delta(manifest, content)
            additions = build_additions(importer, manifest, delta)
            removals = build_removals(base_version, delta)
            changeset = ChangeSet(importer=importer,
                                  repository_version=new_version,
                                  additions=additions,
                                  removals=removals)
            for report in changeset.apply():
                if not log.isEnabledFor(logging.DEBUG):
                    continue
                log.debug(
                    _('Applied: repository=%(r)s importer=%(p)s change:%(c)s'),
                    {
                        'r': repository.name,
                        'p': importer.name,
                        'c': report,
                    })