diff --git a/CHANGES/1175.feature b/CHANGES/1175.feature new file mode 100644 index 000000000..c567abf70 --- /dev/null +++ b/CHANGES/1175.feature @@ -0,0 +1 @@ +Support per-component/architecture Release files for cross-validation by related installers (i.e. ubiquity and debian-installer). \ No newline at end of file diff --git a/pulp_deb/app/serializers/publication_serializers.py b/pulp_deb/app/serializers/publication_serializers.py index a7d8c2cf5..3da7c68fb 100644 --- a/pulp_deb/app/serializers/publication_serializers.py +++ b/pulp_deb/app/serializers/publication_serializers.py @@ -45,6 +45,10 @@ class AptPublicationSerializer(PublicationSerializer): view_name="signing-services-detail", required=False, ) + publish_legacy_release_files = BooleanField( + help_text="Whether or not to publish Legacy per-component-and-architecture Release files.", + default=False, + ) def validate(self, data): """ @@ -62,6 +66,7 @@ class Meta: "checkpoint", "signing_service", "publish_upstream_release_fields", + "publish_legacy_release_files", ) model = AptPublication diff --git a/pulp_deb/app/tasks/publishing.py b/pulp_deb/app/tasks/publishing.py index 222765e02..11e587433 100644 --- a/pulp_deb/app/tasks/publishing.py +++ b/pulp_deb/app/tasks/publishing.py @@ -83,6 +83,7 @@ def publish( repository_version_pk, simple, structured, + publish_legacy_release_files, checkpoint=False, signing_service_pk=None, publish_upstream_release_fields=None, @@ -109,12 +110,19 @@ def publish( log.info( _( - "Publishing: repository={repo}, version={ver}, simple={simple}, structured={structured}" + ( + "Publishing: repository={repo}, " + "version={ver}, " + "simple={simple}, " + "structured={structured}, " + "publish_legacy_release_files={publish_legacy_release_files}" + ) ).format( # noqa repo=repo_version.repository.name, ver=repo_version.number, simple=simple, structured=structured, + publish_legacy_release_files=publish_legacy_release_files, ) ) with tempfile.TemporaryDirectory(".") as temp_dir: @@ -124,6 +132,7 @@ def publish( publication.simple = simple publication.structured = structured publication.signing_service = signing_service + publication.publish_legacy_release_files = publish_legacy_release_files repository = AptRepository.objects.get(pk=repo_version.repository.pk) if simple: @@ -306,6 +315,7 @@ def __init__(self, parent, component): self.plain_component = os.path.basename(component) self.package_index_files = {} self.source_index_file_info = None + self.release_file_paths = {} for architecture in self.parent.architectures: package_index_path = os.path.join( @@ -320,6 +330,12 @@ def __init__(self, parent, component): open(package_index_path, "wb"), package_index_path, ) + + if self.parent.publication.publish_legacy_release_files: + self.release_file_paths[architecture] = _write_legacy_release_file( + self, architecture + ) + # Source indicies file source_index_path = os.path.join( "dists", @@ -451,6 +467,13 @@ def finish(self): self.parent.add_metadata(source_index) self.parent.add_metadata(gz_source_index) + # Publish per-component/architecture Release files + for release_path in self.release_file_paths.values(): + release = PublishedMetadata.create_from_file( + publication=self.parent.publication, file=File(open(release_path, "rb")) + ) + self.parent.add_metadata(release) + def generate_by_hash(self, index_path, index, gz_index_path, gz_index): for path, index in ( (index_path, index), @@ -477,6 +500,7 @@ def __init__( temp_dir, signing_service=None, ): + self._release = release self.publication = publication self.temp_env = {"PULP_TEMP_WORKING_DIR": _create_random_directory(temp_dir)} self.distribution = distribution = release.distribution @@ -608,3 +632,36 @@ def _create_random_directory(path): dir_path = path + "/" + dir_name os.makedirs(dir_path, exist_ok=True) return dir_path + + +def _write_legacy_release_file(component, arch): + """ + Add legacy per-architecture release files + https://wiki.debian.org/DebianRepository/Format#Legacy_per-component-and-architecture_Release_files + :param component: ComponentHelper instance this belongs to. + :param arch: target architecture + :return: relative path of the release file + """ + + rel = deb822.Release() + + parent_release = component.parent.release + rel["Archive"] = parent_release.get("Suite", parent_release["Codename"]) + rel["Origin"] = parent_release.get("Origin", "Pulp 3") + rel["Label"] = parent_release.get("Label", "Pulp 3") + if settings.APT_BY_HASH: + rel["Acquire-By-Hash"] = settings.APT_BY_HASH + rel["Component"] = component.plain_component + rel["Architecture"] = arch + + rel_path = os.path.join( + "dists", + component.parent.dists_subfolder, + component.plain_component, + f"binary-{arch}", + "Release", + ) + os.makedirs(os.path.dirname(rel_path), exist_ok=True) + with open(rel_path, "wb") as fh: + rel.dump(fh) + return rel_path diff --git a/pulp_deb/app/viewsets/publication.py b/pulp_deb/app/viewsets/publication.py index 3c0624132..82ab27619 100644 --- a/pulp_deb/app/viewsets/publication.py +++ b/pulp_deb/app/viewsets/publication.py @@ -216,6 +216,7 @@ def create(self, request): publish_upstream_release_fields = serializer.validated_data.get( "publish_upstream_release_fields" ) + publish_legacy_release_files = serializer.validated_data.get("publish_legacy_release_files") kwargs = { "repository_version_pk": repository_version.pk, @@ -223,6 +224,7 @@ def create(self, request): "structured": structured, "signing_service_pk": getattr(signing_service, "pk", None), "publish_upstream_release_fields": publish_upstream_release_fields, + "publish_legacy_release_files": publish_legacy_release_files, } if checkpoint: kwargs["checkpoint"] = True