Project

Profile

Help

Story #3285

closed

Story #3209: As a user, I have Repository Versions

As a plugin writer, I have a tool that helps me write tasks that create RepositoryVersions

Added by amacdona@redhat.com almost 7 years ago. Updated over 4 years ago.

Status:
CLOSED - CURRENTRELEASE
Priority:
Normal
Assignee:
Category:
-
Sprint/Milestone:
Start date:
Due date:
% Done:

0%

Estimated time:
Platform Release:
Groomed:
Yes
Sprint Candidate:
Yes
Tags:
Sprint:
Sprint 31
Quarter:

Description

Tasks that create new RepositoryVersions have to write to pulpcore tables in transactions, set up a working directory, finalize the new version and clean up the database if the task fails. All of this should be handled by a context manager that is a part of the plugin API.

Proposal: Wrapper for the RepositoryVersion object in the plugin API

The object can be used as a context manager that creates RepositoryVersions. The pulpcore model for RepositoryVersion will be removed from the plugin API, so the wrapper will be the only supported way for plugin writers to create new RepositoryVersions, and must be performed only in celery tasks. It will contain all business logic for creation, as well as adding and removing content. The wrapper will be passed to the changeset.

example usage

Create a new RepositoryVersion. Plugin writers can use this object to add/remove content. Or they can pass it to the ChangeSet.


with RepositoryVersion.create(repository) as created_version:
    created_version.add_content(some_content)
    changeset = ChangeSet(created_version, ...)

The wrapper object can also be used to access the RepositoryVersion model layer, which replaces the use of plugin.models.RepositoryVersion.objects.get() with:


latest_version = RepositoryVersion.latest(repository)
for content in latest_version.content():

The wrapper will provide any functions that plugin writers need to act safely upon the RepositoryVersion and related tables. It will enforce correct usage (and therefore RepositoryVersion immutability) by:

  1. ensuring it is only run in tasks
  2. exclusive control of the RepositoryVersion.complete flag
  3. only allowing repository versions to add and remove content if RepositoryVersion.complete = True
  4. using transactions to create a new version and update related tables
  5. handle failure scenarios by cleaning up incomplete work

The business logic that will live in this class is psuedo-implemented in this comment: https://pulp.plan.io/issues/3285#note-6

Working code that will be moved to this class currently lives in:

  1. the File plugin's sync https://github.com/asmacdo/pulp_file/blob/a8997383e2a64f915769db629435ae4abecf576c/pulp_file/app/tasks.py#L52-L79
  2. RepositoryVersion django model in models.repository.RepositoryVersion

Review of plugin API changes

The RepositoryVersion django model (models.repository.RepositoryVersion) will be removed from the plugin API. Plugin writers should use the RepositoryVersion wrapper/facade instead of the model directly. New/incomplete repository versions will be used exclusively within the context_manager. The ChangeSet will no longer accept a models.repository.RepositoryVersion object, and will instead accept an instance of the class created by this story.

The changes above allow us to make the following promise to users: "Once a RepositoryVersion is marked complete, it cannot be altered by any plugin."

They also limit the access to the pulpcore data model, which reduces the likelihood of plugin writer errors. We can promise the plugin writer:

  1. When dealing with new RepositoryVersions, your code will either run successfully or the pulpcore data layer will be cleaned up.
  2. All pulpcore actions that must take place together in transactions is handled for you under the hood.
  3. The object you have access to is guarded against unsafe use.

Related issues

Copied to Pulp - Story #3295: As a plugin writer, I have a tool that helps me write tasks that create PublicationsCLOSED - CURRENTRELEASEjortel@redhat.com

Actions

Also available in: Atom PDF