Skip to content

Commit

Permalink
Added new json field repo_config that can be used to configure .repo …
Browse files Browse the repository at this point in the history
…file

closes #2902
closes #2903
closes #2295
  • Loading branch information
ipanova authored and ggainey committed Nov 3, 2023
1 parent b012db7 commit 8fda3c8
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGES/2295.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added ability to customize config .repo file.
1 change: 1 addition & 0 deletions CHANGES/2902.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added new json field repo_config that can be used to configure .repo file
1 change: 1 addition & 0 deletions CHANGES/2903.deprecation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecated ``gpgcheck`` and ``repo_gpgcheck`` options in favour of ``repo_config``.
1 change: 1 addition & 0 deletions CHANGES/2903.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added new json field ``repo_config`` that can be used to configure .repo file.
10 changes: 3 additions & 7 deletions docs/workflows/create_sync_publish.rst
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,10 @@ Publication GET response (when task complete):
"repository_version": "/pulp/api/v3/repositories/rpm/rpm/a02ace53-d490-458d-8b93-604fbcd23a9c/versions/1/"
}
The GPG signature check options are configurable from this REST API endpoint as well. This can be
done via the following options:
The GPG signature check options, like ``gpgcheck`` and ``repo_gpgcheck`` are configurable via the ``repo_config`` option.
This option has a json format and can contain any of the configuration for the ``.repo`` file.

- gpgcheck: perform a GPG signature check on the packages retrieved from this repository.

- repo_gpgcheck: perform a GPG signature check on the repodata.

Additionally, an option is provided to let the user decide whether or not to generate sqlite metadata
A separate option is provided to let the user decide whether or not to generate sqlite metadata
(defaults to 'false'). Sqlite metadata not commonly used.

- sqlite_metadata: generate sqlite metadata in addition to standard XML metadata
Expand Down
29 changes: 29 additions & 0 deletions pulp_rpm/app/migrations/0054_remove_gpg_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.4 on 2023-09-08 14:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("rpm", "0053_rpmdistribution_generate_repo_config"),
]

operations = [
migrations.RemoveField(
model_name="rpmpublication",
name="gpgcheck",
),
migrations.RemoveField(
model_name="rpmpublication",
name="repo_gpgcheck",
),
migrations.RemoveField(
model_name="rpmrepository",
name="gpgcheck",
),
migrations.RemoveField(
model_name="rpmrepository",
name="repo_gpgcheck",
),
]
23 changes: 23 additions & 0 deletions pulp_rpm/app/migrations/0055_add_repo_config_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.4 on 2023-09-08 14:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("rpm", "0054_remove_gpg_fields"),
]

operations = [
migrations.AddField(
model_name="rpmpublication",
name="repo_config",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="rpmrepository",
name="repo_config",
field=models.JSONField(default=dict),
),
]
34 changes: 18 additions & 16 deletions pulp_rpm/app/models/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,8 @@ class RpmRepository(Repository, AutoAddObjPermsMixin):
The name of a checksum type to use for metadata when generating metadata.
package_checksum_type (String):
The name of a default checksum type to use for packages when generating metadata.
gpgcheck (Integer):
1 or 0 corresponding to whether gpgcheck should be enabled in the generated .repo file.
repo_gpgcheck (Integer):
1 or 0 corresponding to whether repo_gpgcheck should be enabled in the generated
.repo file.
sqlite_metadata (Boolean): Whether to generate sqlite metadata files on publish.
repo_config (JSON): repo configuration that will be served by distribution
"""

TYPE = "rpm"
Expand All @@ -221,7 +217,6 @@ class RpmRepository(Repository, AutoAddObjPermsMixin):
ModulemdObsolete,
]
REMOTE_TYPES = [RpmRemote, UlnRemote]
GPGCHECK_CHOICES = [(0, 0), (1, 1)]

metadata_signing_service = models.ForeignKey(
AsciiArmoredDetachedSigningService, on_delete=models.SET_NULL, null=True
Expand All @@ -233,9 +228,8 @@ class RpmRepository(Repository, AutoAddObjPermsMixin):
autopublish = models.BooleanField(default=False)
metadata_checksum_type = models.TextField(null=True, choices=CHECKSUM_CHOICES)
package_checksum_type = models.TextField(null=True, choices=CHECKSUM_CHOICES)
gpgcheck = models.IntegerField(default=0, choices=GPGCHECK_CHOICES)
repo_gpgcheck = models.IntegerField(default=0, choices=GPGCHECK_CHOICES)
sqlite_metadata = models.BooleanField(default=False)
repo_config = models.JSONField(default=dict)

def on_new_version(self, version):
"""
Expand All @@ -258,13 +252,13 @@ def on_new_version(self, version):
if self.autopublish:
tasks.publish(
repository_version_pk=version.pk,
gpgcheck_options={"gpgcheck": self.gpgcheck, "repo_gpgcheck": self.repo_gpgcheck},
metadata_signing_service=self.metadata_signing_service,
checksum_types={
"metadata": self.metadata_checksum_type,
"package": self.package_checksum_type,
},
sqlite_metadata=self.sqlite_metadata,
repo_config=self.repo_config,
)

@staticmethod
Expand Down Expand Up @@ -427,14 +421,11 @@ class RpmPublication(Publication, AutoAddObjPermsMixin):
Publication for "rpm" content.
"""

GPGCHECK_CHOICES = [(0, 0), (1, 1)]

TYPE = "rpm"
metadata_checksum_type = models.TextField(choices=CHECKSUM_CHOICES)
package_checksum_type = models.TextField(choices=CHECKSUM_CHOICES)
gpgcheck = models.IntegerField(default=0, choices=GPGCHECK_CHOICES)
repo_gpgcheck = models.IntegerField(default=0, choices=GPGCHECK_CHOICES)
sqlite_metadata = models.BooleanField(default=False)
repo_config = models.JSONField(default=dict)

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"
Expand Down Expand Up @@ -478,16 +469,27 @@ def content_handler(self, path):
self.base_path,
)
)
repo_config = publication.repo_config
repo_config.pop("name", None)
repo_config.pop("baseurl", None)
val = textwrap.dedent(
f"""\
[{re.sub(self.INVALID_REPO_ID_CHARS, "", self.name)}]
name={self.name}
enabled=1
baseurl={base_url}
gpgcheck={publication.gpgcheck}
repo_gpgcheck={publication.repo_gpgcheck}
"""
)
for k, v in repo_config.items():
val += f"{k}={v}\n"

if "repo_gpgcheck" not in repo_config:
val += "repo_gpgcheck=0\n"

if "gpgcheck" not in repo_config:
val += "gpgcheck=0\n"

if "enabled" not in repo_config:
val += "enabled=1\n"

signing_service = repository.metadata_signing_service
if signing_service:
Expand Down
73 changes: 67 additions & 6 deletions pulp_rpm/app/serializers/repository.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from gettext import gettext as _

import logging

from django.conf import settings
from jsonschema import Draft7Validator
from rest_framework import serializers
Expand Down Expand Up @@ -82,20 +84,20 @@ class RpmRepositorySerializer(RepositorySerializer):
gpgcheck = serializers.IntegerField(
max_value=1,
min_value=0,
default=0,
required=False,
allow_null=True,
help_text=_(
"An option specifying whether a client should perform "
"DEPRECATED: An option specifying whether a client should perform "
"a GPG signature check on packages."
),
)
repo_gpgcheck = serializers.IntegerField(
max_value=1,
min_value=0,
default=0,
required=False,
allow_null=True,
help_text=_(
"An option specifying whether a client should perform "
"DEPRECATED: An option specifying whether a client should perform "
"a GPG signature check on the repodata."
),
)
Expand All @@ -106,6 +108,10 @@ class RpmRepositorySerializer(RepositorySerializer):
"DEPRECATED: An option specifying whether Pulp should generate SQLite metadata."
),
)
repo_config = serializers.JSONField(
required=False,
help_text=_("A JSON document describing config.repo file"),
)

def validate(self, data):
"""Validate data."""
Expand All @@ -118,8 +124,47 @@ def validate(self, data):
raise serializers.ValidationError({field: _(ALLOWED_CHECKSUM_ERROR_MSG)})

validated_data = super().validate(data)
if (data.get("gpgcheck") or data.get("repo_gpgcheck")) and data.get("repo_config"):
raise serializers.ValidationError(
_(
"Cannot use gpg options and 'repo_config' options simultaneously. "
"The 'gpgcheck' and 'repo_gpgcheck' options are deprecated, please use "
"'repo_config' only."
)
)
return validated_data

def create(self, validated_data):
"""
Save the repo and handle gpg options
Args:
validated_data (dict): A dict of validated data to create the repo
Returns:
repo: the created repo
"""
# gpg options are deprecated in favour of repo_config
# acting as shim layer between old and new api
gpgcheck = validated_data.get("gpgcheck")
repo_gpgcheck = validated_data.get("repo_gpgcheck")

gpgcheck_options = {}
if gpgcheck is not None:
gpgcheck_options["gpgcheck"] = gpgcheck
if repo_gpgcheck is not None:
gpgcheck_options["repo_gpgcheck"] = repo_gpgcheck
if gpgcheck_options.keys():
logging.getLogger("pulp_rpm.deprecation").info(
"Support for gpg options will be removed from a future release of pulp_rpm."
)
repo_config = (
gpgcheck_options if gpgcheck_options else validated_data.get("repo_config", {})
)
repo = super().create(validated_data)
repo.repo_config = repo_config
return repo

class Meta:
fields = RepositorySerializer.Meta.fields + (
"autopublish",
Expand All @@ -130,6 +175,7 @@ class Meta:
"gpgcheck",
"repo_gpgcheck",
"sqlite_metadata",
"repo_config",
)
model = RpmRepository

Expand Down Expand Up @@ -223,17 +269,19 @@ class RpmPublicationSerializer(PublicationSerializer):
max_value=1,
min_value=0,
required=False,
allow_null=True,
help_text=_(
"An option specifying whether a client should perform "
"DEPRECATED: An option specifying whether a client should perform "
"a GPG signature check on packages."
),
)
repo_gpgcheck = serializers.IntegerField(
max_value=1,
min_value=0,
required=False,
allow_null=True,
help_text=_(
"An option specifying whether a client should perform "
"DEPRECATED: An option specifying whether a client should perform "
"a GPG signature check on the repodata."
),
)
Expand All @@ -244,6 +292,10 @@ class RpmPublicationSerializer(PublicationSerializer):
"DEPRECATED: An option specifying whether Pulp should generate SQLite metadata."
),
)
repo_config = serializers.JSONField(
required=False,
help_text=_("A JSON document describing config.repo file"),
)

def validate(self, data):
"""Validate data."""
Expand All @@ -256,6 +308,14 @@ def validate(self, data):
):
raise serializers.ValidationError(_(ALLOWED_CHECKSUM_ERROR_MSG))
validated_data = super().validate(data)
if (data.get("gpgcheck") or data.get("repo_gpgcheck")) and data.get("repo_config"):
raise serializers.ValidationError(
_(
"Cannot use gpg options and 'repo_config' options simultaneously. "
"The 'gpgcheck' and 'repo_gpgcheck' options are deprecated, please use "
"'repo_config' only."
)
)
return validated_data

class Meta:
Expand All @@ -265,6 +325,7 @@ class Meta:
"gpgcheck",
"repo_gpgcheck",
"sqlite_metadata",
"repo_config",
)
model = RpmPublication

Expand Down
10 changes: 4 additions & 6 deletions pulp_rpm/app/tasks/publishing.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,21 +320,21 @@ def cr_checksum_type_from_string(checksum_type):

def publish(
repository_version_pk,
gpgcheck_options=None,
metadata_signing_service=None,
checksum_types=None,
sqlite_metadata=False,
repo_config=None,
):
"""
Create a Publication based on a RepositoryVersion.
Args:
repository_version_pk (str): Create a publication from this repository version.
gpgcheck_options (dict): GPG signature check options.
metadata_signing_service (pulpcore.app.models.AsciiArmoredDetachedSigningService):
A reference to an associated signing service.
checksum_types (dict): Checksum types for metadata and packages.
sqlite_metadata (bool): Whether to generate metadata files in sqlite format.
repo_config (JSON): repo config that will be served by distribution
"""
repository_version = RepositoryVersion.objects.get(pk=repository_version_pk)
Expand All @@ -361,13 +361,11 @@ def publish(
checksum_types.get("package") or publication.metadata_checksum_type
)

if gpgcheck_options is not None:
publication.gpgcheck = gpgcheck_options.get("gpgcheck")
publication.repo_gpgcheck = gpgcheck_options.get("repo_gpgcheck")

if sqlite_metadata:
publication.sqlite_metadata = True

publication.repo_config = repo_config

publication_data = PublicationData(publication)
publication_data.populate()

Expand Down
3 changes: 1 addition & 2 deletions pulp_rpm/app/tasks/synchronizing.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ def add_metadata_to_publication(publication, version, prefix=""):

publication.package_checksum_type = CHECKSUM_TYPES.UNKNOWN
publication.metadata_checksum_type = CHECKSUM_TYPES.UNKNOWN
publication.gpgcheck = 0
publication.repo_gpgcheck = has_repomd_signature
publication.repo_config = {"repo_gpgcheck": has_repomd_signature, "gpgcheck": 0}
publication.sqlite_metadata = has_sqlite

for relative_path, metadata_file_path in repo_metadata_files.items():
Expand Down
Loading

0 comments on commit 8fda3c8

Please sign in to comment.