Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added repo_config json file #3298

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):
ipanova marked this conversation as resolved.
Show resolved Hide resolved

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 @@ -423,14 +417,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 @@ -474,16 +465,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."
),
)
ipanova marked this conversation as resolved.
Show resolved Hide resolved
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
Loading