Project

Profile

Help

Story #4716

Updated by dalley over 5 years ago

Simple content copy means that a list of content units can be copied from one repository into another repository without    considering content-type-specific invariants, such as making sure dependencies are satisfied. 

 The most straightforwards current design is to model this after one-shot upload.    A new URL endpoint will be defined at /api/v3/rpm/copy/.    POSTing to that endpoint with valid parameters will yield an asynchronous task, which will result in a new repository version in the target repository. 

 The user workflow should look like this: 

 <pre> 
 http --form POST http://localhost:24817/pulp/api/v3/rpm/copy/ source_repository=${S_REPO_HREF} destination_repository=${D_REPO_HREF}    content_set:="[\"$CONTENT_1_HREF\", \"$CONTENT_2_HREF\"]" 
 </pre> 

 Both the repository parameters are required.    The content_set parameter is not required; if excluded, all content will be copied.   

 The additions to Django boilerplate will look something like this (see also: copy.py for an example of the function that does the work) (but see also, OneShotUploadSerializer in serializers.py and copy.py). 

 urls.py 
 <pre><code class="python"> 
 urlpatterns = [ 
     url(r'rpm/upload/$', OneShotUploadView.as_view()), 
     url(r'rpm/copy/$', CopyView.as_view()) 
 ] 
 </code></pre> 

 viewsets.py 
 <pre><code class="python"> 
 class CopyView(views.APIView): 
     def post(self, request): 

         serializer = CopySerializer(data=request.data, context={'request': request}) 
         serializer.is_valid(raise_exception=True) 

         # ..... 
         async_result = enqueue_with_reservation( 
             copy_content, [...],       # function to perform the copying, and arguments to provide it 
             kwargs={ 
                 'source_repo': ..., 
                 'dest_repo': ...., 
                 'content_set':    ..., 
                 # .... 
             } 
         ) 
         return OperationPostponedResponse(async_result, request) 
 </code></pre> 

 serializers.py 

 <pre><code class="python"> 
 class CopySerializer(serializers.Serializer): 

     source_repository = serializers.HyperlinkedRelatedField( 
         help_text=_('A URI of the repository.'), 
         required=True, 
         queryset=Repository.objects.all(), 
         view_name='repositories-detail', 
     ) 
     destination_repository = serializers.HyperlinkedRelatedField( 
         help_text=_('A URI of the repository.'), 
         required=True, 
         queryset=Repository.objects.all(), 
         view_name='repositories-detail', 
     ) 
     content_set = serializers.ListField( 
         help_text=_('A list of content units to copy to a new repository version'), 
         write_only=True, 
         required=True, 
     ) 

 </code></pre> 


 Outstanding questions: 

 # The exact names of the parameters, e.g. destination_repository vs target_repository, *repository vs. *repo, "content_set" 
 # Whether those is sufficient for the most basic implementation 
 # Whether doing a full copy when content_set is unspecified is appropriate 

Back