diff --git a/pulpcore/app/migrations/0126_remoteartifact_failed_at.py b/pulpcore/app/migrations/0126_remoteartifact_failed_at.py deleted file mode 100644 index d5b9e2309a..0000000000 --- a/pulpcore/app/migrations/0126_remoteartifact_failed_at.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.16 on 2024-11-27 15:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0125_openpgpdistribution_openpgpkeyring_openpgppublickey_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='remoteartifact', - name='failed_at', - field=models.DateTimeField(null=True), - ), - ] diff --git a/pulpcore/app/models/content.py b/pulpcore/app/models/content.py index dafd158f5d..8310c310b2 100644 --- a/pulpcore/app/models/content.py +++ b/pulpcore/app/models/content.py @@ -703,7 +703,9 @@ class RemoteArtifact(BaseModel, QueryMixin): sha256 (models.CharField): The expected SHA-256 checksum of the file. sha384 (models.CharField): The expected SHA-384 checksum of the file. sha512 (models.CharField): The expected SHA-512 checksum of the file. - failed_at (models.DateTimeField): The datetime of last download attempt failure. + pulp_last_updated (models.DateTimeField): + Re-purposed this field to enable a backport that contained a migration. + See https://github.com/pulp/pulpcore/pull/6196 Relations: @@ -722,7 +724,6 @@ class RemoteArtifact(BaseModel, QueryMixin): sha256 = models.CharField(max_length=64, null=True, db_index=True) sha384 = models.CharField(max_length=96, null=True, db_index=True) sha512 = models.CharField(max_length=128, null=True, db_index=True) - failed_at = models.DateTimeField(null=True) content_artifact = models.ForeignKey(ContentArtifact, on_delete=models.CASCADE) remote = models.ForeignKey("Remote", on_delete=models.CASCADE) diff --git a/pulpcore/content/handler.py b/pulpcore/content/handler.py index 390122da50..73bea9e2c2 100644 --- a/pulpcore/content/handler.py +++ b/pulpcore/content/handler.py @@ -823,11 +823,10 @@ async def _stream_content_artifact(self, request, response, content_artifact): ClientConnectionError, ) - protection_time = settings.REMOTE_CONTENT_FETCH_FAILURE_COOLDOWN remote_artifacts = ( content_artifact.remoteartifact_set.select_related("remote") .order_by_acs() - .exclude(failed_at__gte=timezone.now() - timedelta(seconds=protection_time)) + .exclude(pulp_last_updated__gte=timezone.now()) ) async for remote_artifact in remote_artifacts: try: @@ -1126,8 +1125,12 @@ async def finalize(): try: download_result = await downloader.run() except DigestValidationError: - remote_artifact.failed_at = timezone.now() - await remote_artifact.asave() + # Using this otherwise unused dbfield is a workaround to allow this fix to be + # backported. Read "failed_at" instead. + await RemoteArtifact.objects.filter(pulp_id=remote_artifact.pulp_id).aupdate( + pulp_last_updated=timezone.now() + + timedelta(settings.REMOTE_CONTENT_FETCH_FAILURE_COOLDOWN) + ) await downloader.session.close() close_tcp_connection(request.transport._sock) REMOTE_CONTENT_FETCH_FAILURE_COOLDOWN = settings.REMOTE_CONTENT_FETCH_FAILURE_COOLDOWN