From 4d96023f503a707931d351062421bc4309cc5891 Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Mon, 7 Sep 2026 15:52:59 +0200 Subject: [PATCH] Add a datarepair for 8067 Distribution base_path in order to allow safely to upgrade to 3.117. Fixes #8067 --- CHANGES/8067.bugfix | 1 + .../app/management/commands/datarepair.py | 41 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 CHANGES/8067.bugfix diff --git a/CHANGES/8067.bugfix b/CHANGES/8067.bugfix new file mode 100644 index 00000000000..aa40b657736 --- /dev/null +++ b/CHANGES/8067.bugfix @@ -0,0 +1 @@ +Add a management command to help remove distributions with a dysfunctional base_path that prevents upgrading to 3.117. diff --git a/pulpcore/app/management/commands/datarepair.py b/pulpcore/app/management/commands/datarepair.py index ab998f45752..8b8bd6f69ea 100644 --- a/pulpcore/app/management/commands/datarepair.py +++ b/pulpcore/app/management/commands/datarepair.py @@ -4,7 +4,8 @@ from django.conf import settings from django.core.management import BaseCommand, CommandError from django.db import connection -from django.db.models import Q +from django.db.models import CharField, Q, Value +from django.db.models.functions import Concat from django.utils.encoding import force_bytes, force_str from pulpcore.app import models @@ -19,7 +20,12 @@ class Command(BaseCommand): def add_arguments(self, parser): """Set up arguments.""" - parser.add_argument("issue", help=_("The github issue # of the issue to be fixed.")) + parser.add_argument( + "issue", + help=_("The github issue # of the issue to be fixed.") + + " " + + _("One of: [{}]").format(", ".join(["2327", "7272", "7465", "8067"])), + ) parser.add_argument( "--dry-run", action="store_true", @@ -39,6 +45,8 @@ def handle(self, *args, **options): self.repair_7272(options) elif issue == "7465": self.repair_7465(options) + elif issue == "8067": + self.repair_8067(options) else: raise CommandError(_("Unknown issue: '{}'").format(issue)) @@ -236,3 +244,32 @@ def repair_7465(self, options): ) else: self.stdout.write(f"Finished. ({number_missing} repository versions fixed)") + + def repair_8067(self, options): + POSTGRES_INVALID_PATH_REGEX = "[\n\r\s\t\?#]|(/\.{0,2}/)" + dry_run = options["dry_run"] + + qs = ( + models.Distribution.objects.only("base_path") + .annotate( + slashed_base_path=Concat( + Value("/"), "base_path", Value("/"), output_field=CharField() + ) + ) + .filter(slashed_base_path__regex=POSTGRES_INVALID_PATH_REGEX) + ) + if qs.exists(): + self.stdout.write( + _("""There are distribution in this installation with improper base-paths. +Maybe their paths are not normalized. Maybe they contain invalid characters. +In any case they are dysfunctional and preven a clean upgrade to Pulpcore 3.117.""") + ) + self.stdout.write(_("Distributions with offending base_path:")) + for distribution in qs: + self.stdout.write(f"{distribution.pk} : '{distribution.base_path}'") + if dry_run: + self.stdout.write(_("These base_paths must be repaired before upgrading to 3.117.")) + else: + answer = input(_("Delete ALL these entries? [y/N] ")) + if answer.lower() == "y": + qs.delete()