Project

Profile

Help

Issue #3541

Updated by bmbouter over 4 years ago

h3. General Problem: 

 Some plugins have validation requirements for the membership of content units in a repository. The validation required depends on the plugin and the content type. Currently add/remove is done with a POST to v3/repositories/1234/versions/. This does not involve the plugins at all, so there is no opportunity for plugins to create these validations. 

 h3. Example Problem with Docker: 

 ManifestLists cannot be added unless the Manifests they refer to are also in the repository.  
 L1 is ManifestList, and it refers to (contains) 2 Manifests, M1, M2. The repository is considered corrupt if it contains L1, but not M1 and M2. M1 and M2 could be in the repository without L1. 

 h2. Solutions: 

 h3. Add a plugin opportunity to Validate 

 Allow a plugin to define a <code>validate_repo_version</code> 

 <pre> 
 class DockerManifestList(Content): 

     ... 

     @staticmethod 
     def validate_repo_version(qs_content, repo_version): 
         """  
         Validates a repository version's DockerManifestList units. 

         This method specifically ensures that the repo has all the right DockerManifests that correspond 
         with this DockerManifestList 

         Args: 
             qs_content (django.Queryset): A Queryset of the detail instances for this content type 
             repo_version (RepositoryVersion): The Repository version to validate 

         Raises: 
             django.core.exceptions.ValidationError: if the repository is invalid 
         """  
         # check all of the validation related DockerManifestList content 
         if has_a_validation_problem: 
             raise ValidationException('Repo foo has ManifestList Y but is missing Manifest Z') 
 </pre> 


 h3. Add a plugin add_content and remove_content 

 <pre> 
 class ModuleMD(Content): 

     ... 

     @staticmethod 
     def add_content(qa_add_content, repo_version): 
         """  
         Handles any extra work needed for ModuleMD content being added to a RepositoryVersion. 

         Args: 
             qs_content (django.Queryset): A Queryset of the detail instances for this content type 
             repo_version (RepositoryVersion): The Repository version the content is being added to 

         """  
         # check on if I need to also add some other content also 

     @staticmethod 
     def remove_content(qa_add_content, repo_version): 
         """  
         Handles any extra work needed for ModuleMD content being removed from a RepositoryVersion. 

         Args: 
             qs_content (django.Queryset): A Queryset of the detail instances for this content type 
             repo_version (RepositoryVersion): The Repository version the content is being removed from 

         """  
         # check if I should also remove corresponding RPMs 
         #    qa_rpms_to_remove = ... 
         if qa_rpms_to _remove 
             repo_version.remove_content(qa_rpms_to_remove, call_plugin_hook=False) 
 </pre> 

 It's possible we'll have a recursive call 

 RepositoryVersion.remove_content -> ModuleMD.remove_content -> RepositoryVersion.remove_content so the 'if' statement will prevent it by not causing an additional call to ModuleMD.remove_content if there are 0 items to remove. 

 The "existing add_content and remove_content": calls will receive an additional parameter <code>call_plugin_hook</code> <code>call_plugin_hook</code which defaults to True. If True, the plugin callback will occur, otherwise it won't.

Back