Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split Distribution into two objects #124

Merged
merged 1 commit into from
May 10, 2019

Conversation

bmbouter
Copy link
Member

@bmbouter bmbouter commented May 9, 2019

The Distribution contained options which should not be mixed.
Specifically the repository and repository_version options go together
and the publication goes by itself.

This PR splits that object into two new objects
RepositoryVersionDistribution and PublicationDistribution. The two
models are not detail objects, and require the plugin writer to declare
a Distribution detail object. It was already this way before this PR.

Required PR: pulp/pulpcore-plugin#97
Required PR: pulp/pulp_file#219

https://pulp.plan.io/issues/4785
closes #4785

bmbouter pushed a commit to bmbouter/pulpcore-plugin that referenced this pull request May 9, 2019
The Distribution object was split into two objects for concrete use by
users. The models are available for plugin writers to reference, but the
serializers and viewsets are designed to always be provided by core so
they are not available through the plugin API.

Required PR: pulp/pulpcore#124

https://pulp.plan.io/issues/4785
closes #4785
@bmbouter bmbouter force-pushed the split-distribution branch 3 times, most recently from 5506711 to 2f1878c Compare May 9, 2019 17:11
bmbouter pushed a commit to bmbouter/pulpcore-plugin that referenced this pull request May 9, 2019
Model Changes

The Distribution model was replaced with the
RepositoryVersionDistribution and PublicationDistribution models. These
are both abstract models and are meant to be subclassed further.

Serializer Changes

The DistributionSerializer is removed and now
BaseDistributionSerializer, PublicationDistributionSerializer, and
RepositoryVersionDistributionSerializer are here. These can also be
further subclassed by plugin writers.

ViewSet Changes

DistributionViewset is now called BaseDistributionViewSet. No other
viewsets are provided.

Required PR: pulp/pulpcore#124
Required PR: pulp/pulp_file#219

https://pulp.plan.io/issues/4785
closes #4785

Raises:
PathNotResolved: when not matched.
"""
base_paths = Handler._base_paths(path)
try:
return Distribution.objects.get(base_path__in=base_paths)
return BaseDistribution.objects.get(base_path__in=base_paths)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems problematic to me. This would include custom distributions that are also subclasses of BaseDistribution. Isn't that an issue?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think BaseDistribution should provide a property called 'served_by_pulpcore' and default it to True.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok so we know we don't love this, but I think I'm going to file it as a follow story since that's an additive change and bugfix. Sound ok?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed the issue here, and I also commented on why maybe it won't happen? https://pulp.plan.io/issues/4809#note-1


Raises:
PathNotResolved: when not matched.
"""
base_paths = Handler._base_paths(path)
try:
return Distribution.objects.get(base_path__in=base_paths)
return BaseDistribution.objects.get(base_path__in=base_paths)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This make @dkliban's commtent (#117 (comment)) apply again. However, I think we need a better mechanism than subclassing to control which distributions are served by content apps. Should we leave it as it is for the time being and explore possible refinements later?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed some refinements to the handler code (needed updates) but I also filed this for us to maybe do better in the future in this area: https://pulp.plan.io/issues/4809


if len(in_use_keys) > 1:
msg = _("The attributes {keys} must be used exclusively.".format(keys=in_use_keys))
if 'repository' in data and 'repository_version' in data:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what happens if those parameters are set to null? I don't know if they disappear or result in None. If the latter, it is better to use data.get('repository') and data.get('repository_version') here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They disappear when I was testing it I was testing with one or the other. I'm also going to write some test issues which will add a functional test for this aspect to give us confidence over time.

@@ -95,12 +99,12 @@ def async_reserved_resources(self, instance):
@classmethod
def is_master_viewset(cls):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this method is not needed anymore. This Viewset now has an associated Model that actually is a master model.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree let me remove it now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup it works the same without this.


class Meta:
abstract = True
default_related_name = '_distributions'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think L#247 and L#255 can be the same? It's working for me, but that's because there is exactly 1 concrete class definition with that default_related_name. I think additional classes with default_related_name = '_distributions' would cause an ambiguation error. Note that it needs to match the _distributions of PublicationSerializer here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I wondered how this works as well. Your assumption why this works makes sense. Do we need the default_related_name in RepositoryVersionDistribution at all? And if so, do we need to set it to _distributions as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do need it because we need to represent the backref in other objects like the PublicationSerializer. I don't think these backrefs will make themselves and if we don't specify them they'll just end up with stranger names.

Since we want them all to have unique names we need to remove these and have the actual detail methods name them. If we allow these to be inherited we'll end up with duplicates for sure. I'm removing these and adding it to FileDistribution now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They'll also have to make their serializer, e.g. FilePublicationSerializer include the backref name to match default_related_name but that's just the way it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds right to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm about to push a version that also updates the handler some. Let's see what you think of it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

django wouldn't start complaining about the ambiguity of _distributions between these two models specifically.

Why do you expect Django to complain in this case? My understanding is that Django 'injects' a kind of a pseudo field into the model/serializer of the model the foreign key is from. Thus, Publication, Repository, and RepositoryVersion each have a '_distributions' field that one can use in the respective serializer.

Copy link
Contributor

@gmbnomis gmbnomis May 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just cobbled together something: pulp_cookbook has two distributor types (one for 'cookbook', one for 'cookbook2', RepositorySerializer has a _distributions field showing related RepositoryVersionDistribution models (obviously, this does not make any sense). And:

$ http :24817$PUBLICATION_HREF
{
    "_created": "2019-05-09T22:30:06.686178Z",
    "_distributions": [
        "/pulp/api/v3/distributions/cookbook/cookbook/95f06efb-5331-441d-bd08-459bc806ff30/"
    ],
    "_href": "/pulp/api/v3/publications/cookbook/cookbook/e003db72-78b9-4ce1-8fb2-066d92608170/",
    "_type": "cookbook.cookbook",
    "publisher": "/pulp/api/v3/publishers/cookbook/cookbook/e0ceb4a7-2dba-4267-8454-44b7dee8f073/",
    "repository": "http://localhost:24817/pulp/api/v3/repositories/%3CRepository:%20foo%3E/",
    "repository_version": "/pulp/api/v3/repositories/8f5b97e4-5485-4b4c-9ae4-f91a14c1a0a2/versions/1/"
}

$ http :24817$REPO_HREF
{
    "_created": "2019-05-09T22:27:28.355982Z",
    "_distributions": [
        "/pulp/api/v3/distributions/cookbook/cookbook2/f38d83a7-282d-457f-ab77-9f1c79d2df54/"
    ],
    "_href": "/pulp/api/v3/repositories/8f5b97e4-5485-4b4c-9ae4-f91a14c1a0a2/",
    "_latest_version_href": "/pulp/api/v3/repositories/8f5b97e4-5485-4b4c-9ae4-f91a14c1a0a2/versions/1/",
    "_versions_href": "/pulp/api/v3/repositories/8f5b97e4-5485-4b4c-9ae4-f91a14c1a0a2/versions/",
    "description": "",
    "name": "foo"
}

Commit is here: gmbnomis@d80e3f3

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to wait to merge this until I can do some testing also tomorrow morning.

@gmbnomis is the idea just to bring back PublicationSerializer._distributions to replace FilePublicationSerializer._file_distributions ?

I don't think we want to make models.PublicationDistribution and RepositoryVersionDistribution models non-abstract because then the inheritance tree becomes 3 large and with concrete tables that is too much for the ORM I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is is the idea. You are right, we should avoid deep inheritance levels if possible. I think we should keep it as you implemented it and make the REST API nicer by a small adaptation on the plugin side: https://github.com/pulp/pulp_file/pull/219/files#r282762667

bmbouter pushed a commit to bmbouter/pulpcore-plugin that referenced this pull request May 9, 2019
Model Changes

The Distribution model was replaced with the
RepositoryVersionDistribution and PublicationDistribution models. These
are both abstract models and are meant to be subclassed further.

Serializer Changes

The DistributionSerializer is removed and now
BaseDistributionSerializer, PublicationDistributionSerializer, and
RepositoryVersionDistributionSerializer are here. These can also be
further subclassed by plugin writers.

ViewSet Changes

DistributionViewset is now called BaseDistributionViewSet. No other
viewsets are provided.

Docs Changes

The release notes are updated to indicate the breaking changes.

Required PR: pulp/pulpcore#124
Required PR: pulp/pulp_file#219

https://pulp.plan.io/issues/4785
closes #4785
@bmbouter bmbouter force-pushed the split-distribution branch 3 times, most recently from 76b3035 to d8122b8 Compare May 9, 2019 21:10
@bmbouter bmbouter requested a review from a team May 9, 2019 21:10
@bmbouter bmbouter force-pushed the split-distribution branch 2 times, most recently from 5190c62 to 77b0872 Compare May 9, 2019 22:07
@codecov
Copy link

codecov bot commented May 9, 2019

Codecov Report

Merging #124 into master will decrease coverage by 0.14%.
The diff coverage is 84.61%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #124      +/-   ##
==========================================
- Coverage   67.26%   67.11%   -0.15%     
==========================================
  Files          64       64              
  Lines        3030     3029       -1     
==========================================
- Hits         2038     2033       -5     
- Misses        992      996       +4
Impacted Files Coverage Δ
pulpcore/app/serializers/__init__.py 100% <ø> (ø) ⬆️
pulpcore/app/models/__init__.py 100% <ø> (ø) ⬆️
pulpcore/app/viewsets/__init__.py 100% <ø> (ø) ⬆️
pulpcore/app/viewsets/publication.py 100% <100%> (ø) ⬆️
pulpcore/app/models/publication.py 79.41% <100%> (+0.95%) ⬆️
pulpcore/content/handler.py 61.49% <61.53%> (ø) ⬆️
pulpcore/app/serializers/publication.py 91.66% <89.65%> (-3.58%) ⬇️
pulpcore/app/serializers/task.py 98.07% <0%> (-1.93%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f0bd807...ee41552. Read the comment docs.

bmbouter pushed a commit to bmbouter/pulpcore-plugin that referenced this pull request May 9, 2019
Model Changes

The Distribution model was replaced with the
RepositoryVersionDistribution and PublicationDistribution models. These
are both abstract models and are meant to be subclassed further.

Serializer Changes

The DistributionSerializer is removed and now
BaseDistributionSerializer, PublicationDistributionSerializer, and
RepositoryVersionDistributionSerializer are here. These can also be
further subclassed by plugin writers.

ViewSet Changes

DistributionViewset is now called BaseDistributionViewSet. No other
viewsets are provided.

Docs Changes

The release notes are updated to indicate the breaking changes.

Required PR: pulp/pulpcore#124
Required PR: pulp/pulp_file#219

https://pulp.plan.io/issues/4785
closes #4785
@gmbnomis
Copy link
Contributor

LGTM. This improves the plugin API and REST API for Distribution a lot! And having the plugin writer implement a distributions field in the publication serializer is a minor nuisance compared to excessive joining in the content app's hot path.

@@ -80,7 +80,7 @@ def test_02_read_publication_with_specific_fields(self):

Permutate field list to ensure different combinations on result.
"""
fields = ('_href', '_created', '_distributions', 'publisher')
fields = ('_href', '_created', '_file_distributions', 'publisher')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every plugin will have now a different field for this? like..._rpm_distributions and so on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to switch this to distributions see here for more commentary: pulp/pulp_file#219 (comment)

The Distribution contained options which should not be mixed.
Specifically the repository and repository_version options go together
and the publication goes by itself.

This PR splits that object into two new objects
RepositoryVersionDistribution and PublicationDistribution. The two
models are not detail objects, and require the plugin writer to declare
a Distribution detail object. It was already this way before this PR.

This also adds a release note about the breaking changes that come with
the switch to Master/Detail.

Required PR: pulp/pulpcore-plugin#97
Required PR: pulp/pulp_file#219

https://pulp.plan.io/issues/4785
closes pulp#4785
@bmbouter bmbouter merged commit 6cf33cf into pulp:master May 10, 2019
@bmbouter bmbouter deleted the split-distribution branch May 10, 2019 16:50
daviddavis pushed a commit to daviddavis/pulp_file that referenced this pull request May 14, 2019
The plugin API now uses PublicationDistribution which causes pulp_file
users to only receive the fields they can actually use.

Required PR: pulp/pulpcore#124
Required PR: pulp/pulpcore-plugin#97

https://pulp.plan.io/issues/4785
closes #4785
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants