From 11ccd25bb332b1aa9be3661c7e99a7c6084aeb4c Mon Sep 17 00:00:00 2001 From: Gerrod Ubben Date: Fri, 20 Oct 2023 12:22:55 -0400 Subject: [PATCH] Fix update_highest_version when versions were uploaded out-of-order fixes: #1623 --- CHANGES/1623.bugfix | 1 + pulp_ansible/app/tasks/collections.py | 25 +++++++++++++++++-------- pulp_ansible/app/tasks/upload.py | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 CHANGES/1623.bugfix diff --git a/CHANGES/1623.bugfix b/CHANGES/1623.bugfix new file mode 100644 index 000000000..6e28a167c --- /dev/null +++ b/CHANGES/1623.bugfix @@ -0,0 +1 @@ +Fixed highest version calculation failing when versions of a collection were created out of order. diff --git a/pulp_ansible/app/tasks/collections.py b/pulp_ansible/app/tasks/collections.py index d869e1085..6d4e82610 100644 --- a/pulp_ansible/app/tasks/collections.py +++ b/pulp_ansible/app/tasks/collections.py @@ -429,14 +429,23 @@ def _update_highest_version(collection_version): qs = collection_version.collection.versions.annotate(prerelease=Q(version_prerelease__ne="")) highest_subq = qs.order_by("prerelease", "-version")[0:1].values("pk") - # Order them in such a way, that only the latest updated record will recieve true. - # This should prevent hitting the uniquenes constraint. - update_qs = qs.annotate(new_is_highest=Q(pk=highest_subq)).order_by("-prerelease", "version") - try: - update_qs.update(is_highest=F("new_is_highest")) - except IntegrityError: - # Try once more - update_qs.update(is_highest=F("new_is_highest")) + update_qs = qs.annotate(new_is_highest=Q(pk=highest_subq)) + # To avoid ordering issues, set everything to False first, then update with proper value + for i in range(2): + try: + with transaction.atomic(): + update_qs.update(is_highest=False) + update_qs.update(is_highest=F("new_is_highest")) + except IntegrityError: + log.debug(f"Retrying update_highest_version {collection_version.relative_path}") + pass + else: + return + log.warning( + _("Failed to update is_highest for {}, potentially out of date").format( + collection_version.relative_path + ) + ) class AnsibleDeclarativeVersion(DeclarativeVersion): diff --git a/pulp_ansible/app/tasks/upload.py b/pulp_ansible/app/tasks/upload.py index 65ccea25e..8c6806a43 100644 --- a/pulp_ansible/app/tasks/upload.py +++ b/pulp_ansible/app/tasks/upload.py @@ -81,7 +81,7 @@ def finish_collection_upload(collection_version, tags, origin_repository): tag, created = Tag.objects.get_or_create(name=name) collection_version.tags.add(tag) - _update_highest_version(collection_version) if origin_repository is not None: collection_version.repository = origin_repository collection_version.save() + _update_highest_version(collection_version)