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
Repository.latest_version() considering deleted versions #555
Conversation
pulpcore/app/models/repository.py
Outdated
| @@ -740,6 +740,9 @@ def delete(self, **kwargs): | |||
| # and delete the version | |||
| repo_relations.filter(version_added=self).delete() | |||
| repo_relations.filter(version_removed=self).update(version_removed=None) | |||
| if self.number == self.repository.last_version: | |||
| self.repository.last_version = self.number - 1 | |||
| self.repository.save() | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested this out, but could you check this scenario? What happens if you create 3 new repository versions, so you have:
0, 1, 2, 3
repository.last_version = 3
If you delete 3 and then 2 you would probably get the correct result:
0, 1,
repository.last_version = 1
But if you delete 2 and then 3, then I think with this algorithm you would get:
0, 1
repository.last_version = 2
I could be wrong, it's just an edge case we should check :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will write a test for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just 2 versions is enough to test this, version 1 isn't really doing much as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this also brings a question to mind -- do we want repository version numbers to be re-usable? Because if we reset last_version appropriately, and we also set number of the next version as last_version + 1 , then that means that it will be possible to overwrite the value of ${REPO_HREF}/versions/2/ with a new version 2 that contains different content. The version number won't be monotonically increasing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solution from IRC:
- Rename
Repository.last_versiontoRepository.next_versionand do a data migration to add +1 to its value - When creating a new repository version, use the value of
Repository.next_versionand if it is successfully created increment this value. - To determine the latest repository version, do this (and see if we can get rid of that custom field)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds right to me. Does this change the REST API ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkliban it shouldn't. We don't expose that field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't, no. last_version isn't serialized and next_version doesn't need to be either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! thanks for confirming that.
cfd5e91
to
260ddd4
Compare
| Repository = apps.get_model('core', 'Repository') | ||
| if 'last_version' in dir(Repository): | ||
| for repository in Repository.objects.all().only('last_version'): | ||
| repository.last_version = int(repository.last_version) + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could try something like this, it might be more efficient: https://stackoverflow.com/questions/12661253/how-to-bulk-update-with-django
The main benefit though is that I think .save() would change the last_updated timestamp and while I don't think that's necessarily a problem we should avoid it if we can help it.
| @@ -93,10 +92,8 @@ def new_version(self, base_version=None): | |||
| with transaction.atomic(): | |||
| version = RepositoryVersion( | |||
| repository=self, | |||
| number=int(self.last_version) + 1, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love that this logic was made simpler!
pulpcore/app/models/repository.py
Outdated
| @@ -748,7 +760,7 @@ def delete(self, **kwargs): | |||
| RepositoryContent.objects.filter(version_removed=self) \ | |||
| .update(version_removed=None) | |||
| CreatedResource.objects.filter(object_id=self.pk).delete() | |||
| self.repository.last_version = self.number - 1 | |||
| self.repository.next_version = self.number - 1 | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line should be deleted entirely. We should only increment repository.next_version once the repository version has been successfully created and finalized, so we shouldn't ever need to decrement it. If the repository version wasn't completed then it shouldn't have been incremented so we shouldn't need to decrement it here.
pulpcore/app/models/repository.py
Outdated
| adding = self._state.adding | ||
| super().save(*args, **kwargs) | ||
| if adding: | ||
| self.repository.next_version = self.number + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this actually needs to happen here: https://github.com/pulp/pulpcore/pull/555/files#diff-ae59196c41f139ec2b7e3ae3aa581a45R832
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabricio-aguiar This looks excellent, thank you!
I think this should have a review from at least one other person, David/Brian/Dennis
| # re: https://pulp.plan.io/issues/6147 | ||
| with transaction.atomic(): | ||
| Repository = apps.get_model('core', 'Repository') | ||
| if 'last_version' in dir(Repository): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not totally sure I understand what the conditional does, do some Repository objects not have this field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is for not breaking if for any reason someone re-run the migration, because after migration last_version will no longer exist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's possible to re-run a migration unless you go out of your way to do so, the most recent migration is stored somewhere and it picks up from there afterwards
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible to rerun a migration because we don't provide downgrade migrations. Is this part of the logic still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added it in case someone would rerun, since it is not possible to rerun, it is not needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
CHANGES/6147.removal
Outdated
| @@ -0,0 +1 @@ | |||
| Replacing Repository.last_version with Repository.next_version | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rephrase this some? Can it be Renaming Repository.last_version to Repository.next_version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @fabricio-aguiar this looks great!
[noissue] Notice this with pulp/pulpcore#555 Renaming last_version was breaking pulp_rpm
https://pulp.plan.io/issues/6147 Required PR: pulp/pulpcore#555 ref #6147
https://pulp.plan.io/issues/6147 Required PR: pulp/pulpcore#555 ref #6147
https://pulp.plan.io/issues/6147 Required PR: pulp/pulpcore#555 ref #6147
https://pulp.plan.io/issues/6147 Required PR: pulp/pulpcore#555 ref #6147
https://pulp.plan.io/issues/6147
closes #6147
Please be sure you have read our documentation on creating PRs:
https://docs.pulpproject.org/contributing/pull-request-walkthrough.html