From 20f77e42231e2a02d9b4d83d7f1a21f4f495da26 Mon Sep 17 00:00:00 2001 From: Ina Panova Date: Mon, 4 Sep 2023 16:45:07 +0200 Subject: [PATCH] Allow two modules with same NSVCA but different snippet content. closes #3241 It no longer holds true to rely on NSVCA module's uniqueness, add the hash of the document snippet to it. --- CHANGES/3241.bugfix | 1 + .../app/migrations/0052_modulemd_digest.py | 51 +++++++++++++++++++ pulp_rpm/app/models/modulemd.py | 13 +++-- pulp_rpm/app/modulemd.py | 1 + 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 CHANGES/3241.bugfix create mode 100644 pulp_rpm/app/migrations/0052_modulemd_digest.py diff --git a/CHANGES/3241.bugfix b/CHANGES/3241.bugfix new file mode 100644 index 0000000000..01e9c77493 --- /dev/null +++ b/CHANGES/3241.bugfix @@ -0,0 +1 @@ +Adjust modules uniqueness to allow two modules with same NSVCA but different snippet content. diff --git a/pulp_rpm/app/migrations/0052_modulemd_digest.py b/pulp_rpm/app/migrations/0052_modulemd_digest.py new file mode 100644 index 0000000000..84655949fb --- /dev/null +++ b/pulp_rpm/app/migrations/0052_modulemd_digest.py @@ -0,0 +1,51 @@ +# Generated by Django 4.2.4 on 2023-09-04 14:06 + +from django.db import migrations, models +import hashlib + + +def add_snippet_hash(apps, schema_editor): + """Calculate and add digest hash of the snippet.""" + + Modulemd = apps.get_model("rpm", "Modulemd") + modules_to_update = [] + + for mmd in Modulemd.objects.all().only("snippet").iterator(): + digest = hashlib.sha256(mmd.snippet.encode()).hexdigest() + modules_to_update.append(mmd) + Modulemd.objects.bulk_update(modules_to_update, fields=["digest"]) + + +class Migration(migrations.Migration): + + dependencies = [ + ("rpm", "0051_alter_distributiontree_unique_together_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="modulemd", + name="digest", + field=models.TextField(default=""), + ), + migrations.RunPython( + code=add_snippet_hash, + reverse_code=migrations.RunPython.noop, + elidable=True, + ), + migrations.AlterUniqueTogether( + name="modulemd", + unique_together=set(), + ), + migrations.AlterField( + model_name="modulemd", + name="digest", + field=models.TextField(), + ), + migrations.AlterUniqueTogether( + name="modulemd", + unique_together={ + ("_pulp_domain", "name", "stream", "version", "context", "arch", "digest") + }, + ), + ] diff --git a/pulp_rpm/app/models/modulemd.py b/pulp_rpm/app/models/modulemd.py index 7eae9c9556..abca648f61 100644 --- a/pulp_rpm/app/models/modulemd.py +++ b/pulp_rpm/app/models/modulemd.py @@ -45,7 +45,10 @@ class Modulemd(Content): packages (Text): List of Packages connected to this modulemd. snippet (Text): - A string to hold modulemd-obsolete snippet + A string to hold modulemd snippet + digest (Text): + Modulemd snippet digest + """ TYPE = "modulemd" @@ -63,14 +66,16 @@ class Modulemd(Content): packages = models.ManyToManyField(Package) profiles = models.JSONField(default=dict) description = models.TextField() + digest = models.TextField() snippet = models.TextField() + repo_key_fields = ("name", "stream", "version", "context", "arch") _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("_pulp_domain", "name", "stream", "version", "context", "arch") + unique_together = ("_pulp_domain", "name", "stream", "version", "context", "arch", "digest") class ModulemdDefaults(Content): @@ -85,9 +90,9 @@ class ModulemdDefaults(Content): profiles (Json): Default profiles for modulemd streams. digest (Text): - Modulemd digest + Modulemd defaults snippet digest snippet (Text): - A string to hold modulemd-obsolete snippet + A string to hold modulemd-defaults snippet """ TYPE = "modulemd_defaults" diff --git a/pulp_rpm/app/modulemd.py b/pulp_rpm/app/modulemd.py index 201cf58128..999b772a55 100644 --- a/pulp_rpm/app/modulemd.py +++ b/pulp_rpm/app/modulemd.py @@ -129,6 +129,7 @@ def create_modulemd(modulemd, snippet): new_module[PULP_MODULE_ATTR.PROFILES] = profiles new_module["snippet"] = snippet + new_module["digest"] = hashlib.sha256(snippet.encode()).hexdigest() return new_module