From e5c110760133160dd7849848100dd69391444e53 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Nov 04 2024 15:26:07 +0000 Subject: Add support for Google Cloud Platform Introduce a handler to upload the images we're building for Google's cloud. --- diff --git a/fedora-image-uploader-messages/fedora_image_uploader_messages/__init__.py b/fedora-image-uploader-messages/fedora_image_uploader_messages/__init__.py index c09856a..344d713 100644 --- a/fedora-image-uploader-messages/fedora_image_uploader_messages/__init__.py +++ b/fedora-image-uploader-messages/fedora_image_uploader_messages/__init__.py @@ -1,7 +1,8 @@ -__version__ = "1.1.1" +__version__ = "1.2.0" from .publish import ( # noqa: F401 AwsPublishedV1, AzurePublishedV1, ContainerPublishedV1, + GcpPublishedV1, ) diff --git a/fedora-image-uploader-messages/fedora_image_uploader_messages/publish.py b/fedora-image-uploader-messages/fedora_image_uploader_messages/publish.py index 2427158..f72a7a4 100644 --- a/fedora-image-uploader-messages/fedora_image_uploader_messages/publish.py +++ b/fedora-image-uploader-messages/fedora_image_uploader_messages/publish.py @@ -250,3 +250,79 @@ class ContainerPublishedV1(_PublishedV1): f"\tTags: {', '.join(self.body['tags'])}\n" f"\tArchitectures: {', '.join(self.body['architectures'])}\n" ) + + +class GcpPublishedV1(_PublishedV1): + topic = ".".join([_PublishedV1.topic, "gcp"]) + body_schema = { + "id": f"{SCHEMA_URL}/v1/{'.'.join([_PublishedV1.topic, 'gcp'])}", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "description": ( + "Schema for messages sent by fedora-image-uploader when a " + "new Google Cloud Platform image is published." + ), + "type": "object", + "properties": { + "architecture": { + "type": "string", + "description": "The machine architecture of the image (x86_64, aarch64, etc).", + }, + "compose_id": { + "type": "string", + "description": "The compose ID this image was created from.", + }, + "release": { + "type": "integer", + "description": "The release number associated with the image.", + }, + "subvariant": { + "type": "string", + "description": "The subvariant of the image (e.g. Cloud_Base).", + }, + "family": { + "type": "string", + "description": "The Google Compute Engine OS family for the image.", + }, + "image_name": { + "type": "string", + "description": "The name of the image.", + }, + "image_url": { + "type": "string", + "description": "The URL of the image in Google Cloud Engine.", + }, + "storage_locations": { + "type": "array", + "items": {"type": "string"}, + "description": "The geographic location codes where the image is available.", + }, + }, + "required": [ + "architecture", + "compose_id", + "release", + "subvariant", + "family", + "image_name", + "image_url", + "storage_locations", + ], + } + + @property + def summary(self): + return ( + f"{self.app_name} published the {self.body['architecture']} image from compose" + f" {self.body['compose_id']} to the {self.body['family']} family in Google" + " Cloud Platform" + ) + + def __str__(self): + return ( + "A new image has been published to Google Cloud Platform:\n\n" + f"\tArchitecture: {self.body['architecture']}\n" + f"\tCompose ID: {self.body['compose_id']}\n" + f"\tFamily: {self.body['family']}\n" + f"\tImage Name: {self.body['image_name']}\n" + f"\tImage URL: {self.body['image_url']}\n" + ) diff --git a/fedora-image-uploader-messages/pyproject.toml b/fedora-image-uploader-messages/pyproject.toml index 7488fb7..d4c5c36 100644 --- a/fedora-image-uploader-messages/pyproject.toml +++ b/fedora-image-uploader-messages/pyproject.toml @@ -45,6 +45,7 @@ test = [ "fedora_image_uploader.published.v1.aws" = "fedora_image_uploader_messages.publish:AwsPublishedV1" "fedora_image_uploader.published.v1.azure" = "fedora_image_uploader_messages.publish:AzurePublishedV1" "fedora_image_uploader.published.v1.container" = "fedora_image_uploader_messages.publish:ContainerPublishedV1" +"fedora_image_uploader.published.v1.gcp" = "fedora_image_uploader_messages.publish:GcpPublishedV1" [tool.hatch.version] path = "fedora_image_uploader_messages/__init__.py" diff --git a/fedora-image-uploader-messages/tests/test_publish.py b/fedora-image-uploader-messages/tests/test_publish.py index 6052452..b71e81c 100644 --- a/fedora-image-uploader-messages/tests/test_publish.py +++ b/fedora-image-uploader-messages/tests/test_publish.py @@ -11,6 +11,7 @@ from fedora_image_uploader_messages import ( AwsPublishedV1, AzurePublishedV1, ContainerPublishedV1, + GcpPublishedV1, ) @@ -192,3 +193,34 @@ def test_container_str(): message = ContainerPublishedV1(body=body) assert expected_summary == message.summary assert expected_str == str(message) + + +def test_gcp_str(): + message = GcpPublishedV1( + topic="fedora_image_uploader.published.v1.gcp.rc.Cloud_Base.aarch64", + body={ + "architecture": "x86_64", + "compose_id": "Fedora-40-20240414.0", + "release": 40, + "subvariant": "Cloud_Base", + "family": "fedora-cloud-40", + "image_name": "fedora-cloud-40-1-14-x86-64", + "image_url": "https://example.com/link", + "storage_locations": ["us"], + }, + ) + expected_summary = ( + "fedora-image-uploader published the x86_64 image from compose Fedora-40-20240414.0 to " + "the fedora-cloud-40 family in Google Cloud Platform" + ) + expected_str = ( + "A new image has been published to Google Cloud Platform:\n\n" + "\tArchitecture: x86_64\n" + "\tCompose ID: Fedora-40-20240414.0\n" + "\tFamily: fedora-cloud-40\n" + "\tImage Name: fedora-cloud-40-1-14-x86-64\n" + "\tImage URL: https://example.com/link\n" + ) + + assert message.summary == expected_summary + assert str(message) == expected_str diff --git a/fedora-image-uploader/fedora_image_uploader/gcp.py b/fedora-image-uploader/fedora_image_uploader/gcp.py new file mode 100644 index 0000000..23650e7 --- /dev/null +++ b/fedora-image-uploader/fedora_image_uploader/gcp.py @@ -0,0 +1,435 @@ +import datetime +import hashlib +import logging +import tempfile +import uuid + +from fedfind import release as ff_release +from fedora_image_uploader_messages import GcpPublishedV1 +from fedora_messaging import config +from fedora_messaging import exceptions as fm_exceptions +from google.api_core import exceptions as google_exceptions +from google.cloud import compute_v1, storage + +from .utils import ( + download_image, + fallible_publish, + get_eol, + get_milestone, + parse_release, +) + +_log = logging.getLogger(__name__) + + +class Gcp: + """ + Uploader for Google Cloud Platform. + + This handler uses the following configuration keys under the "gcp" section of "consumer_config": + - project: The GCP project to upload images to. + - bucket_name: The name of the GCP storage bucket to upload images to. + - storage_locations: A list of GCP storage locations to store the image in. Currently this + list should contain only one location since GCP rejects it otherwise. + - publish_amqp_messages: Whether to publish messages to the AMQP broker. + """ + + SUPPORTED_ARCHES = { + "x86_64": compute_v1.Image.Architecture.X86_64, + "aarch64": compute_v1.Image.Architecture.ARM64, + } + + def __init__(self): + self.conf = config.conf["consumer_config"]["gcp"] + self.storage_client = storage.Client(project=self.conf["project"]) + self.images_client = compute_v1.ImagesClient() + + def __call__(self, image: dict, ffrel: ff_release.Release): + if image.get("arch") not in self.SUPPORTED_ARCHES.keys(): + _log.debug(f"Skipping unsupported arch '{image['arch']}' for GCP") + return + if image.get("format") != "tar.gz": + _log.debug(f"Skipping unsupported format '{image['format']}' (need tar.gz) for GCP") + return + if image.get("subvariant") not in ("Cloud_Base", "BaseOS"): + _log.debug( + "Skipping %s for GCP: subvariant is %s", image.get("path"), image.get("arch") + ) + return + if ffrel.relnum < 40 and ffrel.release.lower() != "eln": + # The format changed with F40 and I can't be bothered to support the old format for + # a month + _log.debug("Skipping %s for GCP: F{ffrel.relnum} not supported", image.get("path")) + return + + blob = self.upload_disk_image(image) + try: + uploaded_image = self.import_image(image, ffrel, blob) + except google_exceptions.Conflict as e: + # The name conflicts; requests are idempotent if and only if the image sha256 is the + # same. Something's gone quite wrong here so log at error level, but don't nack the + # message since there's not much we can programmatically do to fix this. + _log.error( + "Unable to import image from %s as it conflicts with an existing image (%s)", + blob.self_link, + str(e), + ) + return + + message = GcpPublishedV1( + topic=".".join( + [GcpPublishedV1.topic, get_milestone(ffrel), image["subvariant"], image["arch"]] + ), + body={ + "architecture": image["arch"], + "compose_id": ffrel.cid, + "release": ffrel.relnum, + "subvariant": image["subvariant"], + "family": uploaded_image.family, + "image_name": uploaded_image.name, + "image_url": uploaded_image.self_link, + "storage_locations": uploaded_image.storage_locations, + }, + ) + + if self.conf.get("publish_amqp_messages", False): + fallible_publish(message) + + try: + self.promote_image(uploaded_image) + except google_exceptions.GoogleAPICallError as e: + # We'll try again next time + _log.error("Failed to promote images: %s", str(e)) + + try: + self.cleanup_old_images() + except google_exceptions.GoogleAPICallError as e: + # We'll try again next time + _log.error("Failed to clean up images: %s", str(e)) + + def import_image( + self, image: dict, ffrel: ff_release.Release, blob: storage.Blob + ) -> compute_v1.Image: + image_suffix, y_release, z_release = parse_release(ffrel) + image_version = f"{ffrel.relnum}.{y_release}.{z_release}" + image_name = ( + f"fedora-cloud-{ffrel.relnum}-{y_release}-{z_release}-{image['arch']}".lower().replace( + "_", "-" + ) + ) + family = f"fedora-cloud-{image_suffix.lower()}" + architecture = self.SUPPORTED_ARCHES[image["arch"]] + eol = get_eol(ffrel) + if eol: + eol = eol.strftime("%Y-%m-%d") + else: + eol = "none" + + # This list may not be complete... + features = [ + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.UEFI_COMPATIBLE.name), + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.VIRTIO_SCSI_MULTIQUEUE.name + ), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.IDPF.name), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.GVNIC.name), + ] + # Once aarch64 is signed for Secure Boot, we can include this unconditionally + if architecture == compute_v1.Image.Architecture.X86_64: + features.append( + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.SECURE_BOOT.name), + ) + + # With the exception of Rawhide and ELN, we initially upload the image as deprecated so + # thatit doesn't became the default for the image family. Images can then be selectively + # promoted to be "ACTIVE". + # + # https://cloud.google.com/compute/docs/images/deprecate-custom#deprecation-states + deprecated = compute_v1.DeprecationStatus.State.DEPRECATED.name + if ffrel.release.lower() in ("rawhide", "eln"): + deprecated = compute_v1.DeprecationStatus.State.ACTIVE.name + # Also, if this is the first image of a family, make it active + request = compute_v1.ListImagesRequest( + project=self.conf["project"], + filter=f"(family = {family}) AND (architecture = {architecture.name})", + max_results=1, + ) + if len(list(self.images_client.list(request=request, timeout=60))) == 0: + deprecated = compute_v1.DeprecationStatus.State.ACTIVE.name + + disk = compute_v1.RawDisk(source=blob.self_link) + image_resource = compute_v1.Image( + architecture=architecture.name, + family=family, + description=f"Fedora Cloud base image version {image_version}", + # Despite being able to set this, it seems to be ignored when adding the image, + # so there's a call below to set it again. + deprecated=compute_v1.DeprecationStatus(state=deprecated), + guest_os_features=features, + labels={ + # Sadly only ASCII lowercase, numeric, underscore and dash are allowed + "fedora-compose-id": ffrel.cid.lower().replace(".", "-"), + "fedora-subvariant": image["subvariant"].lower(), + "fedora-release": ffrel.release.lower(), + "fedora-version": str(ffrel.relnum), + "end-of-life": eol, + "fedora-image-uploader-managed": "true", + }, + # The API rejects this as an "invalid URL". + # licenses=["https://docs.fedoraproject.org/en-US/legal/fedora-linux-license/"], + name=image_name, + raw_disk=disk, + # Despite the name, it seems to only accept a list of length 1. + storage_locations=self.conf["storage_locations"], + ) + image_request = compute_v1.InsertImageRequest( + project=self.conf["project"], + image_resource=image_resource, + request_id=str(uuid.UUID(hex=image["checksums"]["sha256"][:32])), + ) + _log.info( + "Requesting import of image %s to the %s family in GCP as %s", + blob.self_link, + family, + image_name, + ) + try: + response = self.images_client.insert(image_request, timeout=60) + response.result(timeout=60 * 30) + response.exception(timeout=5) + if response.warnings: + for warning in response.warnings: + _log.warning("Warning during image import: %s", warning.message) + except google_exceptions.Conflict: + # This specific error needs to be handled by this function's caller since retrying is + # not going to fix it. + raise + except google_exceptions.GoogleAPICallError as e: + _log.error("Failed to import image %s: %s", image_name, str(e)) + raise fm_exceptions.Nack() + + # GCE doesn't actually mark the image deprecated despite our request (maybe they'll + # fix that some day?), so do it a second time. This obviously introduces a race where + # booting from the family during this time gets the new image, but there's not much we + # can do about that. + if deprecated == compute_v1.DeprecationStatus.State.DEPRECATED.name: + try: + _log.info( + "Requesting new image %s in the %s family be marked DEPRECATED", + image_name, + family, + ) + request = compute_v1.DeprecateImageRequest( + project=self.conf["project"], + image=image_name, + deprecation_status_resource=compute_v1.DeprecationStatus( + state=compute_v1.DeprecationStatus.State.DEPRECATED.name, + ), + request_id=str(uuid.UUID(hex=image["checksums"]["sha256"][:32])), + ) + response = self.images_client.deprecate(request=request, timeout=60) + response.result(timeout=60 * 10) + response.exception(timeout=5) + except google_exceptions.GoogleAPICallError as e: + _log.error("Failed to deprecate image %s: %s", image_name, str(e)) + raise fm_exceptions.Nack() + + try: + image_request = compute_v1.GetImageRequest( + project=self.conf["project"], image=image_name + ) + image_resource = self.images_client.get(image_request, timeout=30) + except google_exceptions.GoogleAPICallError as e: + _log.error("Failed to read image details for %s: %s", image_name, str(e)) + raise fm_exceptions.Nack() + + _log.info( + "Successfully uploaded image %s to GCP under the %s family", + image_resource.name, + image_resource.family, + ) + return image_resource + + def upload_disk_image(self, image: dict) -> storage.Blob: + """ + Upload the disk image to a GCP storage bucket. + + This is a pre-requisite for importing the image as a machine image. + """ + bucket = self.storage_client.bucket(self.conf["bucket_name"]) + blob_name = f"{image['checksums']['sha256']}.tar.gz" + blob = bucket.blob(blob_name) + + if blob.exists(): + blob.reload() + _log.info("Skipping upload of GCP image to %s as it already exists", blob.self_link) + else: + with tempfile.TemporaryDirectory() as workdir: + image_path = download_image(image, workdir, decompress=False) + _log.info("Starting upload of GCP image to %s", bucket.name) + try: + blob.upload_from_filename(image_path, if_generation_match=0, timeout=60 * 30) + _log.info("Finished upload of GCP image as %s", blob.self_link) + except google_exceptions.GoogleAPICallError as e: + _log.error("Failed to upload image to bucket: %s", str(e)) + raise fm_exceptions.Nack() + + return blob + + def promote_image(self, new_image: compute_v1.Image): + """ + Promote an image from deprecated to active state if it's been 2 weeks since the last + promotion. + """ + # These are always active + if new_image.labels["fedora-release"] in ("rawhide", "eln"): + return + + # We can't filter on deprecated.state = ACTIVE since that's not set initially and no value + # is the same thing as ACTIVE, apparently. + request = compute_v1.ListImagesRequest( + project=self.conf["project"], + filter=( + f"(family = {new_image.family}) AND " f"(architecture = {new_image.architecture})" + ), + ) + response = self.images_client.list(request=request, timeout=60) + + today = datetime.datetime.now(tz=datetime.UTC) + two_weeks_ago = today - datetime.timedelta(days=14) + active_images = [ + image + for image in response + if image.deprecated != compute_v1.DeprecationStatus.State.DEPRECATED.name + ] + active_images.sort( + key=lambda image: datetime.datetime.fromisoformat(image.creation_timestamp), + reverse=True, + ) + + try: + latest_active = active_images[0] + if two_weeks_ago > datetime.datetime.fromisoformat(latest_active.creation_timestamp): + _log.info( + "The latest active image in the %s family, %s, is more than two weeks old", + latest_active.family, + latest_active.name, + ) + else: + _log.info( + "The latest active image in the %s family, %s, is less than two weeks old (%s)", + latest_active.family, + latest_active.name, + str(latest_active.creation_timestamp), + ) + return + except IndexError: + _log.error( + "No active images found in the %s family, but the first image should have been" + " active!", + new_image.family, + ) + return + + request = compute_v1.DeprecateImageRequest( + project=self.conf["project"], + image=new_image.name, + deprecation_status_resource=compute_v1.DeprecationStatus( + state=compute_v1.DeprecationStatus.State.ACTIVE.name, + ), + ) + response = self.images_client.deprecate(request=request, timeout=60) + _log.info("Requested image %s in the %s be marked ACTIVE", new_image.name) + response.result(timeout=60 * 10) + response.exception(timeout=5) + if response.warnings: + for warning in response.warnings: + _log.warning("Warning while marking image active: %s", warning.message) + + def cleanup_old_images(self): + """ + Remove old images from GCP. + + The retention policy implemented here is as follows: + - Images for stable releases marked as active are retained until their EOL date. + - Images for stable releases marked as deprecated are deleted after 14 days. + - Rawhide and ELN images are retained for 14 days. + """ + # Start by cleaning up deprecated and Rawhide/ELN images + request = compute_v1.ListImagesRequest( + project=self.conf["project"], + filter=( + "(deprecated.state = DEPRECATED) OR " + "(labels.fedora-release = rawhide) OR " + "(labels.fedora-release = eln)" + ), + ) + today = datetime.datetime.today().replace(tzinfo=datetime.UTC) + two_weeks_ago = today - datetime.timedelta(days=14) + delete_responses = [] + response = self.images_client.list(request=request, timeout=60) + for image in response: + if image.labels.get("fedora-image-uploader-managed") != "true": + # We didn't upload this image, so we shouldn't delete it + continue + image_creation = datetime.datetime.fromisoformat(image.creation_timestamp) + if two_weeks_ago > image_creation: + _log.info( + "Requesting delete for image %s since it's older than %s", + image.name, + str(two_weeks_ago), + ) + request = compute_v1.DeleteImageRequest( + project=self.conf["project"], + image=image.name, + request_id=str( + uuid.UUID( + hex=hashlib.sha256(image.name.encode(errors="ignore")).hexdigest()[:32] + ) + ), + ) + delete_responses.append(self.images_client.delete(request, timeout=60 * 10)) + + # Next, remove any images with an EOL date that has passed. There's probably a fancy filter + # to do this, but I don't know the right syntax and we're going to be dealing with no more + # than a couple hundred images at a time. + request = compute_v1.ListImagesRequest(project=self.conf["project"]) + response = self.images_client.list(request=request, timeout=60) + for image in response: + if image.labels.get("fedora-image-uploader-managed") != "true": + # We didn't upload this image, so we shouldn't delete it + continue + + try: + eol = datetime.datetime.fromisoformat(image.labels["end-of-life"]).replace( + tzinfo=datetime.UTC + ) + except ValueError: + # Pre-release, Rawhide, and ELN have an EOL of "none" + _log.debug( + "Skipping image %s with EOL of %s", image.name, image.labels["end-of-life"] + ) + continue + except KeyError: + _log.error("Image %s is missing an EOL label", image.name) + continue + + if today > eol: + _log.info("Requesting delete for image %s since it's past EOL", image.name) + request = compute_v1.DeleteImageRequest( + project=self.conf["project"], + image=image.name, + request_id=str( + uuid.UUID( + hex=hashlib.sha256(image.name.encode(errors="ignore")).hexdigest()[:32] + ) + ), + ) + delete_responses.append(self.images_client.delete(request, timeout=60 * 10)) + + for response in delete_responses: + response.result(timeout=60 * 30) + response.exception(timeout=5) + if response.warnings: + for warning in response.warnings: + _log.warning("Warning during image import: %s", warning.message) diff --git a/fedora-image-uploader/fedora_image_uploader/handler.py b/fedora-image-uploader/fedora_image_uploader/handler.py index 5f6953a..3e0c968 100644 --- a/fedora-image-uploader/fedora_image_uploader/handler.py +++ b/fedora-image-uploader/fedora_image_uploader/handler.py @@ -30,6 +30,11 @@ try: except ImportError: _log.info("Install the 'azure' extra for Azure support") +try: + from . import gcp +except ImportError: + _log.info("Install the 'gcp' extra for Google Cloud Platform support") + DOCKER_ARCHES = {"amd64": "x86_64", "arm64": "aarch64", "ppc64le": "ppc64le", "s390x": "s390x"} @@ -76,6 +81,8 @@ class Uploader: self.handlers["azure"] = azure.Azure() if "aws" in self.conf.keys(): self.handlers["aws"] = aws.Aws() + if "gcp" in self.conf.keys(): + self.handlers["gcp"] = gcp.Gcp() # tracks the container repos we got images for, for manifest # creation purposes diff --git a/fedora-image-uploader/pyproject.toml b/fedora-image-uploader/pyproject.toml index c88c770..182d4b5 100644 --- a/fedora-image-uploader/pyproject.toml +++ b/fedora-image-uploader/pyproject.toml @@ -30,8 +30,12 @@ azure = [ "azure-mgmt-compute", "azure-storage-blob", ] +gcp = [ + "google-cloud-compute", + "google-cloud-storage", +] dev = [ - "fedora-image-uploader[aws,azure]", + "fedora-image-uploader[aws,azure,gcp]", "black", "isort", "flake8", diff --git a/fedora-image-uploader/tests/fixtures/cassettes/test_import_image.yaml b/fedora-image-uploader/tests/fixtures/cassettes/test_import_image.yaml new file mode 100644 index 0000000..5c8eba6 --- /dev/null +++ b/fedora-image-uploader/tests/fixtures/cassettes/test_import_image.yaml @@ -0,0 +1,1446 @@ +interactions: +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose + response: + body: + string: ' + + + + 301 Moved Permanently + + + +

Moved Permanently

+ +

The document has moved here.

+ + + + ' + headers: + AppTime: + - D=2819 + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:01 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-QcawcAsBr8BXU1EekQAAAwI + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '283' + content-type: + - text/html; charset=iso-8859-1 + location: + - https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/ + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 301 + message: Moved Permanently +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/ + response: + body: + string: "\n\n + \n Index of /compose/40/Fedora-40-20240414.0/compose\n + \n \n

Index of /compose/40/Fedora-40-20240414.0/compose

\n
\"Icon Name                              Last modified      Size  Description
\"[PARENTDIR]\" + Parent Directory - + \ \n\"[DIR]\" Cloud/ + \ 2024-04-14 23:08 - \n\"[DIR]\" Container/ 2024-04-14 + 22:55 - \n\"[DIR]\" Everything/ + \ 2024-04-14 18:34 - \n\"[DIR]\" Kinoite/ 2024-04-14 + 17:59 - \n\"[DIR]\" Labs/ + \ 2024-04-14 23:57 - \n\"[DIR]\" Onyx/ 2024-04-14 + 17:59 - \n\"[DIR]\" Sericea/ + \ 2024-04-14 17:59 - \n\"[DIR]\" Server/ 2024-04-14 + 18:44 - \n\"[DIR]\" Silverblue/ + \ 2024-04-14 17:59 - \n\"[DIR]\" Spins/ 2024-04-14 + 23:07 - \n\"[DIR]\" Workstation/ + \ 2024-04-14 23:51 - \n\"[DIR]\" metadata/ 2024-04-15 + 01:25 - \n
\n\n" + headers: + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:01 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-QVweItWA-4QCrCd7KQAAA9Q + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + apptime: + - D=133042 + content-length: + - '2096' + content-type: + - text/html;charset=ISO-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/STATUS + response: + body: + string: 'FINISHED_INCOMPLETE + + ' + headers: + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:01 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy10.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-QfjPII4CGq__A-urjgAABoQ + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=2626 + content-length: + - '20' + last-modified: + - Mon, 15 Apr 2024 01:25:57 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs01.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/metadata/composeinfo.json + response: + body: + string: "{\n \"header\": {\n \"type\": \"productmd.composeinfo\",\n + \ \"version\": \"1.2\"\n },\n \"payload\": {\n \"compose\": + {\n \"date\": \"20240414\",\n \"final\": true,\n \"id\": + \"Fedora-40-20240414.0\",\n \"label\": \"RC-1.14\",\n \"respin\": + 0,\n \"type\": \"production\"\n },\n \"release\": + {\n \"internal\": false,\n \"name\": \"Fedora\",\n \"short\": + \"Fedora\",\n \"type\": \"ga\",\n \"version\": \"40\"\n + \ },\n \"variants\": {\n \"Cloud\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"s390x\",\n + \ \"x86_64\"\n ],\n \"id\": + \"Cloud\",\n \"name\": \"Cloud\",\n \"paths\": + {\n \"images\": {\n \"aarch64\": + \"Cloud/aarch64/images\",\n \"ppc64le\": \"Cloud/ppc64le/images\",\n + \ \"s390x\": \"Cloud/s390x/images\",\n \"x86_64\": + \"Cloud/x86_64/images\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Cloud\"\n },\n \"Container\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Container\",\n \"name\": \"Container\",\n + \ \"paths\": {\n \"images\": {\n \"aarch64\": + \"Container/aarch64/images\",\n \"ppc64le\": \"Container/ppc64le/images\",\n + \ \"s390x\": \"Container/s390x/images\",\n \"x86_64\": + \"Container/x86_64/images\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Container\"\n },\n \"Everything\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Everything\",\n \"name\": \"Everything\",\n + \ \"paths\": {\n \"debug_packages\": {\n + \ \"aarch64\": \"Everything/aarch64/debug/tree/Packages\",\n + \ \"ppc64le\": \"Everything/ppc64le/debug/tree/Packages\",\n + \ \"s390x\": \"Everything/s390x/debug/tree/Packages\",\n + \ \"x86_64\": \"Everything/x86_64/debug/tree/Packages\"\n + \ },\n \"debug_repository\": {\n \"aarch64\": + \"Everything/aarch64/debug/tree\",\n \"ppc64le\": \"Everything/ppc64le/debug/tree\",\n + \ \"s390x\": \"Everything/s390x/debug/tree\",\n \"x86_64\": + \"Everything/x86_64/debug/tree\"\n },\n \"debug_tree\": + {\n \"aarch64\": \"Everything/aarch64/debug/tree\",\n + \ \"ppc64le\": \"Everything/ppc64le/debug/tree\",\n + \ \"s390x\": \"Everything/s390x/debug/tree\",\n \"x86_64\": + \"Everything/x86_64/debug/tree\"\n },\n \"isos\": + {\n \"aarch64\": \"Everything/aarch64/iso\",\n \"ppc64le\": + \"Everything/ppc64le/iso\",\n \"s390x\": \"Everything/s390x/iso\",\n + \ \"x86_64\": \"Everything/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"aarch64\": \"Everything/aarch64/os\",\n + \ \"ppc64le\": \"Everything/ppc64le/os\",\n \"s390x\": + \"Everything/s390x/os\",\n \"x86_64\": \"Everything/x86_64/os\"\n + \ },\n \"packages\": {\n \"aarch64\": + \"Everything/aarch64/os/Packages\",\n \"ppc64le\": + \"Everything/ppc64le/os/Packages\",\n \"s390x\": \"Everything/s390x/os/Packages\",\n + \ \"x86_64\": \"Everything/x86_64/os/Packages\"\n },\n + \ \"repository\": {\n \"aarch64\": + \"Everything/aarch64/os\",\n \"ppc64le\": \"Everything/ppc64le/os\",\n + \ \"s390x\": \"Everything/s390x/os\",\n \"x86_64\": + \"Everything/x86_64/os\"\n },\n \"source_packages\": + {\n \"aarch64\": \"Everything/source/tree/Packages\",\n + \ \"ppc64le\": \"Everything/source/tree/Packages\",\n + \ \"s390x\": \"Everything/source/tree/Packages\",\n + \ \"x86_64\": \"Everything/source/tree/Packages\"\n + \ },\n \"source_repository\": {\n \"aarch64\": + \"Everything/source/tree\",\n \"ppc64le\": \"Everything/source/tree\",\n + \ \"s390x\": \"Everything/source/tree\",\n \"x86_64\": + \"Everything/source/tree\"\n },\n \"source_tree\": + {\n \"aarch64\": \"Everything/source/tree\",\n \"ppc64le\": + \"Everything/source/tree\",\n \"s390x\": \"Everything/source/tree\",\n + \ \"x86_64\": \"Everything/source/tree\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Everything\"\n },\n \"Kinoite\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"x86_64\"\n + \ ],\n \"id\": \"Kinoite\",\n \"name\": + \"Kinoite\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Kinoite/aarch64/images\",\n \"ppc64le\": + \"Kinoite/ppc64le/images\",\n \"x86_64\": \"Kinoite/x86_64/images\"\n + \ },\n \"isos\": {\n \"aarch64\": + \"Kinoite/aarch64/iso\",\n \"x86_64\": \"Kinoite/x86_64/iso\"\n + \ },\n \"os_tree\": {\n \"aarch64\": + \"Kinoite/aarch64/os\",\n \"x86_64\": \"Kinoite/x86_64/os\"\n + \ },\n \"repository\": {\n \"aarch64\": + \"Kinoite/aarch64/os\",\n \"x86_64\": \"Kinoite/x86_64/os\"\n + \ }\n },\n \"type\": \"variant\",\n + \ \"uid\": \"Kinoite\"\n },\n \"Labs\": + {\n \"arches\": [\n \"aarch64\",\n \"x86_64\"\n + \ ],\n \"id\": \"Labs\",\n \"name\": + \"Labs\",\n \"paths\": {\n \"images\": {\n + \ \"aarch64\": \"Labs/aarch64/images\",\n \"x86_64\": + \"Labs/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Labs/x86_64/iso\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Labs\"\n },\n \"Onyx\": {\n \"arches\": + [\n \"x86_64\"\n ],\n \"id\": + \"Onyx\",\n \"name\": \"Onyx\",\n \"paths\": + {\n \"images\": {\n \"x86_64\": + \"Onyx/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Onyx/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"x86_64\": \"Onyx/x86_64/os\"\n + \ },\n \"repository\": {\n \"x86_64\": + \"Onyx/x86_64/os\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Onyx\"\n },\n \"Sericea\": + {\n \"arches\": [\n \"aarch64\",\n \"x86_64\"\n + \ ],\n \"id\": \"Sericea\",\n \"name\": + \"Sericea\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Sericea/aarch64/images\",\n \"x86_64\": + \"Sericea/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Sericea/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"x86_64\": \"Sericea/x86_64/os\"\n + \ },\n \"repository\": {\n \"x86_64\": + \"Sericea/x86_64/os\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Sericea\"\n },\n \"Server\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Server\",\n \"name\": \"Server\",\n + \ \"paths\": {\n \"debug_packages\": {\n + \ \"aarch64\": \"Server/aarch64/debug/tree/Packages\",\n + \ \"ppc64le\": \"Server/ppc64le/debug/tree/Packages\",\n + \ \"s390x\": \"Server/s390x/debug/tree/Packages\",\n + \ \"x86_64\": \"Server/x86_64/debug/tree/Packages\"\n + \ },\n \"debug_repository\": {\n \"aarch64\": + \"Server/aarch64/debug/tree\",\n \"ppc64le\": \"Server/ppc64le/debug/tree\",\n + \ \"s390x\": \"Server/s390x/debug/tree\",\n \"x86_64\": + \"Server/x86_64/debug/tree\"\n },\n \"debug_tree\": + {\n \"aarch64\": \"Server/aarch64/debug/tree\",\n \"ppc64le\": + \"Server/ppc64le/debug/tree\",\n \"s390x\": \"Server/s390x/debug/tree\",\n + \ \"x86_64\": \"Server/x86_64/debug/tree\"\n },\n + \ \"images\": {\n \"aarch64\": \"Server/aarch64/images\",\n + \ \"ppc64le\": \"Server/ppc64le/images\",\n \"s390x\": + \"Server/s390x/images\",\n \"x86_64\": \"Server/x86_64/images\"\n + \ },\n \"isos\": {\n \"aarch64\": + \"Server/aarch64/iso\",\n \"ppc64le\": \"Server/ppc64le/iso\",\n + \ \"s390x\": \"Server/s390x/iso\",\n \"x86_64\": + \"Server/x86_64/iso\"\n },\n \"os_tree\": + {\n \"aarch64\": \"Server/aarch64/os\",\n \"ppc64le\": + \"Server/ppc64le/os\",\n \"s390x\": \"Server/s390x/os\",\n + \ \"x86_64\": \"Server/x86_64/os\"\n },\n + \ \"packages\": {\n \"aarch64\": + \"Server/aarch64/os/Packages\",\n \"ppc64le\": \"Server/ppc64le/os/Packages\",\n + \ \"s390x\": \"Server/s390x/os/Packages\",\n \"x86_64\": + \"Server/x86_64/os/Packages\"\n },\n \"repository\": + {\n \"aarch64\": \"Server/aarch64/os\",\n \"ppc64le\": + \"Server/ppc64le/os\",\n \"s390x\": \"Server/s390x/os\",\n + \ \"x86_64\": \"Server/x86_64/os\"\n },\n + \ \"source_packages\": {\n \"aarch64\": + \"Server/source/tree/Packages\",\n \"ppc64le\": \"Server/source/tree/Packages\",\n + \ \"s390x\": \"Server/source/tree/Packages\",\n \"x86_64\": + \"Server/source/tree/Packages\"\n },\n \"source_repository\": + {\n \"aarch64\": \"Server/source/tree\",\n \"ppc64le\": + \"Server/source/tree\",\n \"s390x\": \"Server/source/tree\",\n + \ \"x86_64\": \"Server/source/tree\"\n },\n + \ \"source_tree\": {\n \"aarch64\": + \"Server/source/tree\",\n \"ppc64le\": \"Server/source/tree\",\n + \ \"s390x\": \"Server/source/tree\",\n \"x86_64\": + \"Server/source/tree\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Server\"\n },\n \"Silverblue\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"x86_64\"\n ],\n \"id\": + \"Silverblue\",\n \"name\": \"Silverblue\",\n \"paths\": + {\n \"images\": {\n \"aarch64\": + \"Silverblue/aarch64/images\",\n \"ppc64le\": \"Silverblue/ppc64le/images\",\n + \ \"x86_64\": \"Silverblue/x86_64/images\"\n },\n + \ \"isos\": {\n \"aarch64\": \"Silverblue/aarch64/iso\",\n + \ \"ppc64le\": \"Silverblue/ppc64le/iso\",\n \"x86_64\": + \"Silverblue/x86_64/iso\"\n },\n \"os_tree\": + {\n \"aarch64\": \"Silverblue/aarch64/os\",\n \"ppc64le\": + \"Silverblue/ppc64le/os\",\n \"x86_64\": \"Silverblue/x86_64/os\"\n + \ },\n \"repository\": {\n \"aarch64\": + \"Silverblue/aarch64/os\",\n \"ppc64le\": \"Silverblue/ppc64le/os\",\n + \ \"x86_64\": \"Silverblue/x86_64/os\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Silverblue\"\n },\n \"Spins\": {\n \"arches\": + [\n \"aarch64\",\n \"x86_64\"\n ],\n + \ \"id\": \"Spins\",\n \"name\": \"Spins\",\n + \ \"paths\": {\n \"images\": {\n \"aarch64\": + \"Spins/aarch64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Spins/x86_64/iso\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Spins\"\n },\n \"Workstation\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"x86_64\"\n + \ ],\n \"id\": \"Workstation\",\n \"name\": + \"Workstation\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Workstation/aarch64/images\"\n },\n + \ \"isos\": {\n \"aarch64\": \"Workstation/aarch64/iso\",\n + \ \"ppc64le\": \"Workstation/ppc64le/iso\",\n \"x86_64\": + \"Workstation/x86_64/iso\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Workstation\"\n }\n }\n + \ }\n}" + headers: + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:01 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-QWJhy7kUT8g7VI47qAAAAUM + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=2404 + content-length: + - '14963' + content-type: + - application/json + last-modified: + - Mon, 15 Apr 2024 01:25:53 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/metadata/images.json + response: + body: + string: "{\n \"header\": {\n \"type\": \"productmd.images\",\n \"version\": + \"1.2\"\n },\n \"payload\": {\n \"compose\": {\n \"date\": + \"20240414\",\n \"id\": \"Fedora-40-20240414.0\",\n \"respin\": + 0,\n \"type\": \"production\"\n },\n \"images\": + {\n \"Cloud\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ab0fcaf5b5bbb4362d3757ff5e3fcea04fb4a4d6c501c19c1a55064194290230\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135599,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-AmazonEC2.aarch64-40-1.14.raw.xz\",\n + \ \"size\": 365970064,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"d53dbc3f75e527f12bad03c0b00f6b3ebbc45be3098c37cf932cdb3b2889c0ab\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vhd.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135978,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Azure.aarch64-40-1.14.vhdfixed.xz\",\n + \ \"size\": 426868528,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vhd-compressed\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"7153713f2a44607376b45786f609026cd64b2c3e276ee421c70a6f4fea74b501\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.gz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135981,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-GCE.aarch64-40-1.14.tar.gz\",\n \"size\": + 407577788,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"docker\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ebdce26d861a9d15072affe1919ed753ec7015bd97b3a7d0d0df6a10834f7459\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135596,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Generic.aarch64-40-1.14.qcow2\",\n + \ \"size\": 408289280,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"95224953d04b8af9447c5422e6af819e8e47a961476528b9b814dc52d48f424e\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135984,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-UEFI-UKI.aarch64-40-1.14.qcow2\",\n + \ \"size\": 400883712,\n \"subvariant\": + \"Cloud_Base_UKI\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"02aca73fe591bcc8e7d02b69d15d58a40110e73c7dd33de819aae3c602e9e1ed\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135601,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Vagrant-libvirt.aarch64-40-1.14.vagrant.libvirt.box\",\n + \ \"size\": 384506222,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"ede915e0461c112b444519559fbed5f9c9f69a72db215a2c2989b99f03f0b08a\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713136020,\n \"path\": + \"Cloud/ppc64le/images/Fedora-Cloud-Base-Generic.ppc64le-40-1.14.qcow2\",\n + \ \"size\": 398589952,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"808226b31c6c61e08cde77fe7ba61d766f7528c857e7ae8553040c177cbda9a7\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135364,\n \"path\": + \"Cloud/s390x/images/Fedora-Cloud-Base-Generic.s390x-40-1.14.qcow2\",\n \"size\": + 367915520,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"42c682c2c77ead24ea6af989d1fed28d93e2134c85b016674e109ee6f6699446\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135441,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-AmazonEC2.x86_64-40-1.14.raw.xz\",\n + \ \"size\": 366518332,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"9630c21d15990a08a793c35d4ef70dbef4bf98d8865dda6081aa14c1a90200e3\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vhd.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135500,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Azure.x86_64-40-1.14.vhdfixed.xz\",\n + \ \"size\": 437304100,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vhd-compressed\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"dcc05425e07b87f6f53f142c693bff3d47942fa4b05e1e08ab122db57ba478b5\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.gz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135465,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-GCE.x86_64-40-1.14.tar.gz\",\n \"size\": + 400065273,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"docker\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ac58f3c35b73272d5986fa6d3bc44fd246b45df4c334e99a07b3bbd00684adee\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135440,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2\",\n + \ \"size\": 397475840,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"e58fbd6c147c0eda6eca72491ddc74871c3c3db9b808dc4fcf0d313510c43d81\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135438,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-UEFI-UKI.x86_64-40-1.14.qcow2\",\n + \ \"size\": 403767296,\n \"subvariant\": + \"Cloud_Base_UKI\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"35f734b81396b3da3bc75c201cb71458745f7539f22ac1dd11b8268a81fa2915\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135451,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-VirtualBox.x86_64-40-1.14.vagrant.virtualbox.box\",\n + \ \"size\": 375556047,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"359c93a006c378210ae8f3a26eb7333693152ed2a6960904a9113742850ad12b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135456,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-libvirt.x86_64-40-1.14.vagrant.libvirt.box\",\n + \ \"size\": 379222737,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n }\n ]\n + \ },\n \"Container\": {\n \"aarch64\": + [\n {\n \"arch\": \"aarch64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"e374388c2a158729dcc7e9b4d61507ee0146103119eb711e9b91745e559ee94b\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135329,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Base-Generic-Minimal.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 44594488,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"8f7262dfaf502787581c49669d73b3bd0210b5d916f1d669b9a5737ad1a84830\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135489,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Base-Generic.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 80074648,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"247ec625257f0da9f5ce637e65900e61a127e60f508c8f489c13a14521a6f8a4\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135395,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Toolbox.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 302343672,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"c8fd5cfab4d0a960a28df32d187c9b83133953aebc8096bd9c1bc37a71b592dd\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135311,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Base-Generic-Minimal.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 51102672,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"ppc64le\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"75d9864be59de913596240bca2779697d3a5f18e1a4fc0c8a05aafcb13a0034b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136025,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Base-Generic.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 87901272,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"0bbf987a98ebf61b24e89f4a1b6e348edc690e87ee7eb3a410c9bef56f75eece\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136473,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Toolbox.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 307939276,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"90704b4ce8156cb26e4e92c3eafb69e823c8c837d7567b5287dca7c9e7e4d631\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135252,\n \"path\": + \"Container/s390x/images/Fedora-Container-Base-Generic-Minimal.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 46196064,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"3930880dc22d405611f4aaae3526d45024ecf71f5ae0825fd397c176fd61aaa1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135272,\n \"path\": + \"Container/s390x/images/Fedora-Container-Base-Generic.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 81930940,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"s390x\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"49bc41d3180300abaced1c49be91f2c4050551c4c81652e672c197649519b050\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135340,\n \"path\": + \"Container/s390x/images/Fedora-Container-Toolbox.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 285858376,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"78434b6f41b209a2ed882b0c0f4f9f78a20aa965899c7860da24d02ab11235e3\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135278,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Base-Generic-Minimal.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 45908620,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"c5c9dc3320ca474ff40b5a378b443a2b290f258a08e909a43fe81ca7a9bbe966\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135297,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Base-Generic.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 81711536,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"335900c5185c273e68da30c461ba4739f0a9692a8013014032c9929396840bf8\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135361,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Toolbox.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 323370324,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ]\n },\n \"Everything\": + {\n \"aarch64\": [\n {\n \"arch\": + \"aarch64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"512d1da43a71cde6fd20a4c2f5cae39fab2966fe6d3ad491964dd0be9b0772fc\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"7bf3fd693814339bad5d61b4c2fe368b\",\n \"mtime\": + 1713118156,\n \"path\": \"Everything/aarch64/iso/Fedora-Everything-netinst-aarch64-40-1.14.iso\",\n + \ \"size\": 837763072,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-aarch64-40\"\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"8dc915fabe631cf235820a0e41a8bc6ca30664f5fa5aa3e17bb7b9c064e31afe\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"7d35e0a335a3efe6d8f15e7d8cfb9d16\",\n \"mtime\": + 1713119671,\n \"path\": \"Everything/ppc64le/iso/Fedora-Everything-netinst-ppc64le-40-1.14.iso\",\n + \ \"size\": 802918400,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-ppc64le-40\"\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"a9cf7091294710615c10fba7a3ce25da6de516cccf77c6956e8ce5e883704307\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"24a9ee5e8abda63188ee8c7bedc2cec5\",\n \"mtime\": + 1713118230,\n \"path\": \"Everything/s390x/iso/Fedora-Everything-netinst-s390x-40-1.14.iso\",\n + \ \"size\": 500766720,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-s390x-40\"\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"4d1c0a7dda6c1d21a1483acb6c7914193158921113f947c5a0519d26bcc548b2\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"76fd4488e0831e52f521992d29dcc53d\",\n \"mtime\": + 1713118558,\n \"path\": \"Everything/x86_64/iso/Fedora-Everything-netinst-x86_64-40-1.14.iso\",\n + \ \"size\": 812255232,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-x86_64-40\"\n }\n ]\n },\n + \ \"Kinoite\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"d3f5cea671ea0fed7f036091be0514bf290340e09cea6232a907b747c6a24217\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713120245,\n \"path\": + \"Kinoite/aarch64/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2644884992,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6fb0687148f494ba273eb9e278bcf269f88be7d1783c6e380067d540a995fbda\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"e5bf9a93a95b4d4660cdcbc8af891ec7\",\n \"mtime\": + 1713133789,\n \"path\": \"Kinoite/aarch64/iso/Fedora-Kinoite-ostree-aarch64-40-1.14.iso\",\n + \ \"size\": 4161081344,\n \"subvariant\": + \"Kinoite\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Knt-ostree-aarch64-40\"\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"7ee09b442e2bc77cf9516315724c37e33c7ca729080db56db14e71c2a7e16be8\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713127760,\n \"path\": + \"Kinoite/ppc64le/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2489408000,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"0afed26d6101f52f2481230978f1491401a332f6d427bdefe657248e09d4981d\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713120471,\n \"path\": + \"Kinoite/x86_64/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2659151872,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"c6abc4d88de97fd62f42b299cd2879a0e68d9552c9cfd3cc98753a1ff27be16c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"f66598e2003985c75bd9f6e30680fddd\",\n \"mtime\": + 1713134646,\n \"path\": \"Kinoite/x86_64/iso/Fedora-Kinoite-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 4181080064,\n \"subvariant\": + \"Kinoite\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Knt-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Labs\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"9c3f177cf24a802eaf8ce616b3b8e349b2850f7ea9692c05e9bf068255de1a7a\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713138953,\n \"path\": + \"Labs/aarch64/images/Fedora-Python-Classroom-40-1.14.aarch64.raw.xz\",\n + \ \"size\": 2709743384,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"163ed90b1c47d8428959c825ea92974fe153714b6c3ca438c91c0b316645baef\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713136066,\n \"path\": + \"Labs/x86_64/images/Fedora-Python-Classroom-Vagrant-40-1.14.x86_64.vagrant-libvirt.box\",\n + \ \"size\": 1547788429,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"aa4da25b27e82add30e5eb0c8526af28963eafcde6f3c7c6a6a96122819e1389\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713136106,\n \"path\": + \"Labs/x86_64/images/Fedora-Python-Classroom-Vagrant-40-1.14.x86_64.vagrant-virtualbox.box\",\n + \ \"size\": 1569054720,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"78c2cfe481c9ef549eca5808ffc9f0a21a85ad2bb4c444369740fd8d9dd32b6f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713137373,\n \"path\": + \"Labs/x86_64/images/Fedora-Scientific-Vagrant-40-1.14.x86_64.vagrant-libvirt.box\",\n + \ \"size\": 4930855083,\n \"subvariant\": + \"Scientific\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ab61c41a4199165ee85b00b1bb3b1f5c27f7d10603ab13e4116e6d27951406bf\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713137485,\n \"path\": + \"Labs/x86_64/images/Fedora-Scientific-Vagrant-40-1.14.x86_64.vagrant-virtualbox.box\",\n + \ \"size\": 4987146240,\n \"subvariant\": + \"Scientific\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"af586cefa44b7f9c8b755c121e7d5c99f3d88beb39721daec7f3a626622b64fb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136830,\n \"path\": + \"Labs/x86_64/iso/Fedora-Astronomy_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 4634284032,\n \"subvariant\": \"Astronomy_KDE\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"3e17b61870224ca92f85cb031070c4a969a07ad7dacfaacbfd5b70ecb32331c1\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136579,\n \"path\": + \"Labs/x86_64/iso/Fedora-Comp_Neuro-Live-x86_64-40-1.14.iso\",\n \"size\": + 3074414592,\n \"subvariant\": \"Comp_Neuro\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"d99ad7ec55a27393dcb846a333b0e74d5d8b0c70a335b4a0a98ff6e850c852aa\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136822,\n \"path\": + \"Labs/x86_64/iso/Fedora-Games-Live-x86_64-40-1.14.iso\",\n \"size\": + 6890553344,\n \"subvariant\": \"Games\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"816a7d24aa1afc5e875a33e319204a7cd12a7780ae33ab019ee1c5141941611f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136478,\n \"path\": + \"Labs/x86_64/iso/Fedora-Jam_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 3520172032,\n \"subvariant\": \"Jam_KDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"5893394eccd8228f9e4f708e76f6cdb77f61ba79c6d19a1dd4a11776e824afe6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136343,\n \"path\": + \"Labs/x86_64/iso/Fedora-Python-Classroom-Live-x86_64-40-1.14.iso\",\n \"size\": + 2346051584,\n \"subvariant\": \"Python_Classroom\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"c8de28ddb4667d57dc9527d2a7b445ec77861e129b3354251068a0ca9a2e640d\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136335,\n \"path\": + \"Labs/x86_64/iso/Fedora-Robotics-Live-x86_64-40-1.14.iso\",\n \"size\": + 3168759808,\n \"subvariant\": \"Robotics\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4cfb06b40a5b7fbbc46794a8a1fa89f819712681fc2b8d23d3beb4b394cea0db\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713137226,\n \"path\": + \"Labs/x86_64/iso/Fedora-Scientific_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 5545820160,\n \"subvariant\": \"Scientific_KDE\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"2a2e55d2fb08c905e945e259d8b5cab55701c3dbdec717d178d7fb4a5da45608\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136333,\n \"path\": + \"Labs/x86_64/iso/Fedora-Security-Live-x86_64-40-1.14.iso\",\n \"size\": + 2463766528,\n \"subvariant\": \"Security\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n },\n \"Onyx\": {\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"511c2f46c298d1cff1df08b770d23f6fcd25d252d19ca837732e349f12086bb1\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713134693,\n \"path\": + \"Onyx/x86_64/images/Fedora-Onyx-40.1.14.ociarchive\",\n \"size\": + 2201719808,\n \"subvariant\": \"Onyx\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"b196159ab8bf2ced06204a13925f330546f9b0f3db253f6b399a3a5dac517acb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"6d1aaecf42d3d0cc855324173ccf6859\",\n \"mtime\": + 1713133807,\n \"path\": \"Onyx/x86_64/iso/Fedora-Onyx-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 2701541376,\n \"subvariant\": + \"Onyx\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Onyx-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Sericea\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"216c52c960f4a7da1a5fc0056ee138e25cef3f41d2131501089cb3486aaff35e\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713118667,\n \"path\": + \"Sericea/aarch64/images/Fedora-Sericea-40.1.14.ociarchive\",\n \"size\": + 1987797504,\n \"subvariant\": \"Sericea\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"f5d797d8ff27771b95aedd418eebc0d271904505e9156444c8a0c7c5dca0a08a\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119001,\n \"path\": + \"Sericea/x86_64/images/Fedora-Sericea-40.1.14.ociarchive\",\n \"size\": + 2001887744,\n \"subvariant\": \"Sericea\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"9b8cce1ecbaba24a7e8db1b401b240382954acee5fb9993ad4b536f42f9186a6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"030db49ce5182ba4e71c717b950598fb\",\n \"mtime\": + 1713133600,\n \"path\": \"Sericea/x86_64/iso/Fedora-Sericea-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 2536486912,\n \"subvariant\": + \"Sericea\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Src-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Server\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"a624d7275bf8538ee875a5f69b60b04d9114ad6ea918ecad160dde24b4b75b35\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713137407,\n \"path\": + \"Server/aarch64/images/Fedora-Server-40-1.14.aarch64.raw.xz\",\n \"size\": + 1108904380,\n \"subvariant\": \"Server\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"2fed4e38a927824704d6bd88466b3b938543b335669e470981fa123f965f1c68\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713136435,\n \"path\": + \"Server/aarch64/images/Fedora-Server-KVM-40-1.14.aarch64.qcow2\",\n \"size\": + 672661504,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"9146b9563d68c9c9cc53fac75f5e9caefaff8d0e350cd6c4312553deb99b5430\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"1ec36133552bcf746633b30e19b7b0eb\",\n \"mtime\": + 1713135235,\n \"path\": \"Server/aarch64/iso/Fedora-Server-dvd-aarch64-40-1.14.iso\",\n + \ \"size\": 2535260160,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-aarch64-40\"\n },\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"690731ac6abba81413d97517baa80841cb122d07b296ec3f2935848be45be8fe\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"5a1006b4b30a1ad1b21d4d756c9495cd\",\n \"mtime\": + 1713118154,\n \"path\": \"Server/aarch64/iso/Fedora-Server-netinst-aarch64-40-1.14.iso\",\n + \ \"size\": 837820416,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-aarch64-40\"\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"b5817bcabd28f336f457cc7cafedeef963dc6e1b3227786b92446a8f9bade549\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713143951,\n \"path\": + \"Server/ppc64le/images/Fedora-Server-KVM-40-1.14.ppc64le.qcow2\",\n \"size\": + 675479552,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4fa5eafedf7668093f5b10dbbefa8f3d49269036af09dd35f17247d1aed8c0a6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"dfe900eaeea376d841d11cecdfa6d01e\",\n \"mtime\": + 1713135288,\n \"path\": \"Server/ppc64le/iso/Fedora-Server-dvd-ppc64le-40-1.14.iso\",\n + \ \"size\": 2357985280,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-ppc64le-40\"\n },\n {\n + \ \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"e24354b40722b7a1964e50abae0efc1030faa5605503fcc371bece1897b289eb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"178c3a1225edc5110692bb32ebae55db\",\n \"mtime\": + 1713118384,\n \"path\": \"Server/ppc64le/iso/Fedora-Server-netinst-ppc64le-40-1.14.iso\",\n + \ \"size\": 802988032,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-ppc64le-40\"\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"091c232a7301be14e19c76ce9a0c1cbd2be2c4157884a731e1fc4f89e7455a5f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135580,\n \"path\": + \"Server/s390x/images/Fedora-Server-KVM-40-1.14.s390x.qcow2\",\n \"size\": + 646119424,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"5e1844fa681ddedcd69ef10a54b4c7bf0dadcb335027b9982c26d53acc9c0f61\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"a32cc4d8ca8f0e1074a6231d5a77a678\",\n \"mtime\": + 1713135471,\n \"path\": \"Server/s390x/iso/Fedora-Server-dvd-s390x-40-1.14.iso\",\n + \ \"size\": 1990197248,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-s390x-40\"\n },\n {\n + \ \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6daee5daf5367802633ca8262e122df74ce0cbdab0e39a6ecb6ad4c18bd9afda\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"a25987f92bde5966a9decffdb1681cd1\",\n \"mtime\": + 1713118230,\n \"path\": \"Server/s390x/iso/Fedora-Server-netinst-s390x-40-1.14.iso\",\n + \ \"size\": 500807680,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-s390x-40\"\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"a16ba1f26aaf010f62bd94e9f772079353e4bbcffe2c8078f1dfab8aeb848851\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135735,\n \"path\": + \"Server/x86_64/images/Fedora-Server-KVM-40-1.14.x86_64.qcow2\",\n \"size\": + 658702336,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"32d9ab1798fc8106a0b06e873bdcd83a3efea8412c9401dfe4097347ed0cfc65\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"cff4f63cc29f4c5a34b3187e643646d4\",\n \"mtime\": + 1713135246,\n \"path\": \"Server/x86_64/iso/Fedora-Server-dvd-x86_64-40-1.14.iso\",\n + \ \"size\": 2612854784,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-x86_64-40\"\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"1b4f163c55aa9b35bb08f3d465534aa68899a4984b8ba8976b1e7b28297b61fe\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"da6ff3e6d0ffe4bae7cea6062f6fe307\",\n \"mtime\": + 1713119419,\n \"path\": \"Server/x86_64/iso/Fedora-Server-netinst-x86_64-40-1.14.iso\",\n + \ \"size\": 812312576,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-x86_64-40\"\n }\n ]\n },\n + \ \"Silverblue\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"7f7c6839aa83c03c388b37f6b90c57c799a56a1eab45443a57400b410ac591d1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119502,\n \"path\": + \"Silverblue/aarch64/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2108361216,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"c482885894c0ff722c305ca36259dc59d94a36582053b64d6042287c103c9c1c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"0f104e39971464627679ed12a1fb8d9b\",\n \"mtime\": + 1713133688,\n \"path\": \"Silverblue/aarch64/iso/Fedora-Silverblue-ostree-aarch64-40-1.14.iso\",\n + \ \"size\": 3573305344,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-aarch64-40\"\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"32107335909c0bb98c195c1bcd1b3c7b515409ac3cd9460c020a5dd8d8ca9a1d\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713127903,\n \"path\": + \"Silverblue/ppc64le/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2049432576,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"cbadcf23a74783bb61f0907329310ad4ac07e7b06659f33afa9106f896fafb25\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"3f83f88976c5551c67b6e9ac831f7faf\",\n \"mtime\": + 1713134909,\n \"path\": \"Silverblue/ppc64le/iso/Fedora-Silverblue-ostree-ppc64le-40-1.14.iso\",\n + \ \"size\": 3499855872,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-ppc64le-40\"\n }\n ],\n + \ \"x86_64\": [\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"706ddc97e9cc8a35d3ce457370aecae032f382bffd0de404aeba062f74940d4c\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119572,\n \"path\": + \"Silverblue/x86_64/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2124795904,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"8f49c9880cf0eb24e0461498d27d3d5134f056975c478f7d0febb1b9e5d1edbb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"4cc0e9c55bdaad116a611d41223e5d54\",\n \"mtime\": + 1713134394,\n \"path\": \"Silverblue/x86_64/iso/Fedora-Silverblue-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 3582482432,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Spins\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"3840ebba322b9a24867a777c472f510a47193db90cf96a51da074758cc5299e1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713140460,\n \"path\": + \"Spins/aarch64/images/Fedora-KDE-40-1.14.aarch64.raw.xz\",\n \"size\": + 3297951536,\n \"subvariant\": \"KDE\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"9a0aa0a82a10edc184f67c1c2609f11f06a2ea43dd6801863df4189dd647e62b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136738,\n \"path\": + \"Spins/aarch64/images/Fedora-LXQt-40-1.14.aarch64.raw.xz\",\n \"size\": + 1995815572,\n \"subvariant\": \"LXQt\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"36920c0f7a0ae00c2542579f9b600108f77de228a892417ebf8cb651123ad1e8\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135848,\n \"path\": + \"Spins/aarch64/images/Fedora-Minimal-40-1.14.aarch64.raw.xz\",\n \"size\": + 912716876,\n \"subvariant\": \"Minimal\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"27a015a74dd7cdfd8a2a13cf0fec521e04f04249e5430e26bc698719f6df60b1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136685,\n \"path\": + \"Spins/aarch64/images/Fedora-Phosh-40-1.14.aarch64.raw.xz\",\n \"size\": + 2086621740,\n \"subvariant\": \"Phosh\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"a4cdd47d37438bbd90ddf1f9ecde7ed94765788381afa4a93412a22301014c87\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136186,\n \"path\": + \"Spins/aarch64/images/Fedora-SoaS-40-1.14.aarch64.raw.xz\",\n \"size\": + 1720404580,\n \"subvariant\": \"SoaS\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"8622a0f05cc09ec22bd63bc3712b552cee3512f2b135fa51d08a745e4b0169ce\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136735,\n \"path\": + \"Spins/aarch64/images/Fedora-Xfce-40-1.14.aarch64.raw.xz\",\n \"size\": + 2282925736,\n \"subvariant\": \"Xfce\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"18a2876d031fd58d00d9a37d3a823caa03cf7059309bed1de79eb3a46dc4bc21\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136139,\n \"path\": + \"Spins/x86_64/iso/Fedora-Budgie-Live-x86_64-40-1.14.iso\",\n \"size\": + 2146633728,\n \"subvariant\": \"Budgie\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"081ac2402d3e2e704d36ee6aacd67ba631d1939e0c35cf517e996dbb70117735\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136218,\n \"path\": + \"Spins/x86_64/iso/Fedora-Cinnamon-Live-x86_64-40-1.14.iso\",\n \"size\": + 2558238720,\n \"subvariant\": \"Cinnamon\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"8b9da20cfa947b16c8f0c5187e9b4389e13821e31b062688a48cf1b3028c335c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136407,\n \"path\": + \"Spins/x86_64/iso/Fedora-KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 2645645312,\n \"subvariant\": \"KDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"3be326068be6bd7e98d7e7e89f4427648fe83484ecd36e1e77304af1369d1920\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713135996,\n \"path\": + \"Spins/x86_64/iso/Fedora-LXDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 1741191168,\n \"subvariant\": \"LXDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"ef0fbed423acc7484b6fea14a062c41a3026ca93d71edf28debe2d883f9ce61c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136088,\n \"path\": + \"Spins/x86_64/iso/Fedora-LXQt-Live-x86_64-40-1.14.iso\",\n \"size\": + 1845794816,\n \"subvariant\": \"LXQt\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"3242eb53dd2d0bad66dff04f7e54848aa750910171a110e2f8677aa23b8e84e0\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136230,\n \"path\": + \"Spins/x86_64/iso/Fedora-MATE_Compiz-Live-x86_64-40-1.14.iso\",\n \"size\": + 2454198272,\n \"subvariant\": \"Mate\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4287b380b4be2f2c421178b9dfdcaf8c64ed58e343baa7d1d482c4f3481975fb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136027,\n \"path\": + \"Spins/x86_64/iso/Fedora-SoaS-Live-x86_64-40-1.14.iso\",\n \"size\": + 1440874496,\n \"subvariant\": \"SoaS\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6974428b65153156e133fe0165cdf5cb4420b987fe27c53218480414b685e602\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713135976,\n \"path\": + \"Spins/x86_64/iso/Fedora-Sway-Live-x86_64-40-1.14.iso\",\n \"size\": + 1637679104,\n \"subvariant\": \"Sway\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"519db49a21587c007b8135cfc8fba470951937d2f7edc01a8f4b96abc772370c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136105,\n \"path\": + \"Spins/x86_64/iso/Fedora-Xfce-Live-x86_64-40-1.14.iso\",\n \"size\": + 1889988608,\n \"subvariant\": \"Xfce\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"1f55028b79c6633178a0106fdb3d34ccb489f1dc039c5e96a829cea28624d7a8\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136412,\n \"path\": + \"Spins/x86_64/iso/Fedora-i3-Live-x86_64-40-1.14.iso\",\n \"size\": + 1617053696,\n \"subvariant\": \"i3\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n },\n \"Workstation\": {\n \"aarch64\": + [\n {\n \"arch\": \"aarch64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"edaaf8e78db25c81c5600ef65b1ed2c85417ba7b51c3a5785d5acff6e8c90721\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713137105,\n \"path\": + \"Workstation/aarch64/images/Fedora-Workstation-40-1.14.aarch64.raw.xz\",\n + \ \"size\": 2622667416,\n \"subvariant\": + \"Workstation\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"ebb1edbf16da88ed3fb804eca01625fb4341f59ce747c6b89ec00af58a9a6158\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138011,\n \"path\": + \"Workstation/aarch64/iso/Fedora-Workstation-Live-osb-40-1.14.aarch64.iso\",\n + \ \"size\": 2582759424,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live-osbuild\",\n \"volume_id\": + null\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"d015fe246beac888433a1e5b3bc314d29946e91a4df90bb24d1c7b1903e8edf4\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138621,\n \"path\": + \"Workstation/ppc64le/iso/Fedora-Workstation-Live-ppc64le-40-1.14.iso\",\n + \ \"size\": 2228242432,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"8d3cb4d99f27eb932064915bc9ad34a7529d5d073a390896152a8a899518573f\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138847,\n \"path\": + \"Workstation/x86_64/iso/Fedora-Workstation-Live-osb-40-1.14.x86_64.iso\",\n + \ \"size\": 2623733760,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live-osbuild\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"dd1faca950d1a8c3d169adf2df4c3644ebb62f8aac04c401f2393e521395d613\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136256,\n \"path\": + \"Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-40-1.14.iso\",\n \"size\": + 2295853056,\n \"subvariant\": \"Workstation\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n }\n }\n }\n}" + headers: + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:02 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy10.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-Qh4SM9Fi5Np6-B3EIQAAB9I + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=3045 + content-length: + - '78266' + content-type: + - application/json + last-modified: + - Mon, 15 Apr 2024 01:25:53 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - bodhi.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://bodhi.fedoraproject.org/releases/F40 + response: + body: + string: '{"name": "F40", "long_name": "Fedora 40", "version": "40", "id_prefix": + "FEDORA", "branch": "f40", "dist_tag": "f40", "stable_tag": "f40-updates", + "testing_tag": "f40-updates-testing", "candidate_tag": "f40-updates-candidate", + "pending_signing_tag": "f40-signing-pending", "pending_testing_tag": "f40-updates-testing-pending", + "pending_stable_tag": "f40-updates-pending", "override_tag": "f40-override", + "mail_template": "fedora_errata_template", "state": "current", "composed_by_bodhi": + true, "create_automatic_updates": false, "package_manager": "dnf", "testing_repository": + "updates-testing", "released_on": null, "eol": "2025-05-13", "setting_status": + null}' + headers: + AppTime: + - D=14813 + Connection: + - close + Date: + - Mon, 21 Oct 2024 16:16:02 GMT + Referrer-Policy: + - same-origin + Server: + - gunicorn + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + - nosniff + X-Fedora-ProxyServer: + - proxy04.fedoraproject.org + X-Fedora-RequestID: + - ZxZ-QnHXC7AYihZIumSU8AAAAU0 + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '661' + content-type: + - application/json + set-cookie: + - 1caa5c4232b1a1f24f8c4f6e0f496284=40bbcfa70685d8ee10668236fc386817; path=/; + HttpOnly; Secure; SameSite=None + x-content-type-options: + - nosniff + - nosniff + status: + code: 200 + message: OK +version: 1 diff --git a/fedora-image-uploader/tests/fixtures/cassettes/test_messages.yaml b/fedora-image-uploader/tests/fixtures/cassettes/test_messages.yaml new file mode 100644 index 0000000..28ffe62 --- /dev/null +++ b/fedora-image-uploader/tests/fixtures/cassettes/test_messages.yaml @@ -0,0 +1,1387 @@ +interactions: +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose + response: + body: + string: ' + + + + 301 Moved Permanently + + + +

Moved Permanently

+ +

The document has moved here.

+ + + + ' + headers: + AppTime: + - D=3754 + Connection: + - close + Date: + - Thu, 17 Oct 2024 19:08:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxFgnMJEd0U1Dq2BrRY7UwAABVA + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '283' + content-type: + - text/html; charset=iso-8859-1 + location: + - https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/ + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 301 + message: Moved Permanently +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/ + response: + body: + string: "\n\n + \n Index of /compose/40/Fedora-40-20240414.0/compose\n + \n \n

Index of /compose/40/Fedora-40-20240414.0/compose

\n
\"Icon Name                              Last modified      Size  Description
\"[PARENTDIR]\" + Parent Directory - + \ \n\"[DIR]\" Cloud/ + \ 2024-04-14 23:08 - \n\"[DIR]\" Container/ 2024-04-14 + 22:55 - \n\"[DIR]\" Everything/ + \ 2024-04-14 18:34 - \n\"[DIR]\" Kinoite/ 2024-04-14 + 17:59 - \n\"[DIR]\" Labs/ + \ 2024-04-14 23:57 - \n\"[DIR]\" Onyx/ 2024-04-14 + 17:59 - \n\"[DIR]\" Sericea/ + \ 2024-04-14 17:59 - \n\"[DIR]\" Server/ 2024-04-14 + 18:44 - \n\"[DIR]\" Silverblue/ + \ 2024-04-14 17:59 - \n\"[DIR]\" Spins/ 2024-04-14 + 23:07 - \n\"[DIR]\" Workstation/ + \ 2024-04-14 23:51 - \n\"[DIR]\" metadata/ 2024-04-15 + 01:25 - \n
\n\n" + headers: + Connection: + - close + Date: + - Thu, 17 Oct 2024 19:08:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy10.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxFgnIpKjNDNGWNXWSdRUQAAApY + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + apptime: + - D=189830 + content-length: + - '2096' + content-type: + - text/html;charset=ISO-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/STATUS + response: + body: + string: 'FINISHED_INCOMPLETE + + ' + headers: + Connection: + - close + Date: + - Thu, 17 Oct 2024 19:08:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxFgnA69PzHvKsTgQS-JrgAAJkI + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=17737 + content-length: + - '20' + last-modified: + - Mon, 15 Apr 2024 01:25:57 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs01.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/metadata/composeinfo.json + response: + body: + string: "{\n \"header\": {\n \"type\": \"productmd.composeinfo\",\n + \ \"version\": \"1.2\"\n },\n \"payload\": {\n \"compose\": + {\n \"date\": \"20240414\",\n \"final\": true,\n \"id\": + \"Fedora-40-20240414.0\",\n \"label\": \"RC-1.14\",\n \"respin\": + 0,\n \"type\": \"production\"\n },\n \"release\": + {\n \"internal\": false,\n \"name\": \"Fedora\",\n \"short\": + \"Fedora\",\n \"type\": \"ga\",\n \"version\": \"40\"\n + \ },\n \"variants\": {\n \"Cloud\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"s390x\",\n + \ \"x86_64\"\n ],\n \"id\": + \"Cloud\",\n \"name\": \"Cloud\",\n \"paths\": + {\n \"images\": {\n \"aarch64\": + \"Cloud/aarch64/images\",\n \"ppc64le\": \"Cloud/ppc64le/images\",\n + \ \"s390x\": \"Cloud/s390x/images\",\n \"x86_64\": + \"Cloud/x86_64/images\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Cloud\"\n },\n \"Container\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Container\",\n \"name\": \"Container\",\n + \ \"paths\": {\n \"images\": {\n \"aarch64\": + \"Container/aarch64/images\",\n \"ppc64le\": \"Container/ppc64le/images\",\n + \ \"s390x\": \"Container/s390x/images\",\n \"x86_64\": + \"Container/x86_64/images\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Container\"\n },\n \"Everything\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Everything\",\n \"name\": \"Everything\",\n + \ \"paths\": {\n \"debug_packages\": {\n + \ \"aarch64\": \"Everything/aarch64/debug/tree/Packages\",\n + \ \"ppc64le\": \"Everything/ppc64le/debug/tree/Packages\",\n + \ \"s390x\": \"Everything/s390x/debug/tree/Packages\",\n + \ \"x86_64\": \"Everything/x86_64/debug/tree/Packages\"\n + \ },\n \"debug_repository\": {\n \"aarch64\": + \"Everything/aarch64/debug/tree\",\n \"ppc64le\": \"Everything/ppc64le/debug/tree\",\n + \ \"s390x\": \"Everything/s390x/debug/tree\",\n \"x86_64\": + \"Everything/x86_64/debug/tree\"\n },\n \"debug_tree\": + {\n \"aarch64\": \"Everything/aarch64/debug/tree\",\n + \ \"ppc64le\": \"Everything/ppc64le/debug/tree\",\n + \ \"s390x\": \"Everything/s390x/debug/tree\",\n \"x86_64\": + \"Everything/x86_64/debug/tree\"\n },\n \"isos\": + {\n \"aarch64\": \"Everything/aarch64/iso\",\n \"ppc64le\": + \"Everything/ppc64le/iso\",\n \"s390x\": \"Everything/s390x/iso\",\n + \ \"x86_64\": \"Everything/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"aarch64\": \"Everything/aarch64/os\",\n + \ \"ppc64le\": \"Everything/ppc64le/os\",\n \"s390x\": + \"Everything/s390x/os\",\n \"x86_64\": \"Everything/x86_64/os\"\n + \ },\n \"packages\": {\n \"aarch64\": + \"Everything/aarch64/os/Packages\",\n \"ppc64le\": + \"Everything/ppc64le/os/Packages\",\n \"s390x\": \"Everything/s390x/os/Packages\",\n + \ \"x86_64\": \"Everything/x86_64/os/Packages\"\n },\n + \ \"repository\": {\n \"aarch64\": + \"Everything/aarch64/os\",\n \"ppc64le\": \"Everything/ppc64le/os\",\n + \ \"s390x\": \"Everything/s390x/os\",\n \"x86_64\": + \"Everything/x86_64/os\"\n },\n \"source_packages\": + {\n \"aarch64\": \"Everything/source/tree/Packages\",\n + \ \"ppc64le\": \"Everything/source/tree/Packages\",\n + \ \"s390x\": \"Everything/source/tree/Packages\",\n + \ \"x86_64\": \"Everything/source/tree/Packages\"\n + \ },\n \"source_repository\": {\n \"aarch64\": + \"Everything/source/tree\",\n \"ppc64le\": \"Everything/source/tree\",\n + \ \"s390x\": \"Everything/source/tree\",\n \"x86_64\": + \"Everything/source/tree\"\n },\n \"source_tree\": + {\n \"aarch64\": \"Everything/source/tree\",\n \"ppc64le\": + \"Everything/source/tree\",\n \"s390x\": \"Everything/source/tree\",\n + \ \"x86_64\": \"Everything/source/tree\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Everything\"\n },\n \"Kinoite\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"x86_64\"\n + \ ],\n \"id\": \"Kinoite\",\n \"name\": + \"Kinoite\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Kinoite/aarch64/images\",\n \"ppc64le\": + \"Kinoite/ppc64le/images\",\n \"x86_64\": \"Kinoite/x86_64/images\"\n + \ },\n \"isos\": {\n \"aarch64\": + \"Kinoite/aarch64/iso\",\n \"x86_64\": \"Kinoite/x86_64/iso\"\n + \ },\n \"os_tree\": {\n \"aarch64\": + \"Kinoite/aarch64/os\",\n \"x86_64\": \"Kinoite/x86_64/os\"\n + \ },\n \"repository\": {\n \"aarch64\": + \"Kinoite/aarch64/os\",\n \"x86_64\": \"Kinoite/x86_64/os\"\n + \ }\n },\n \"type\": \"variant\",\n + \ \"uid\": \"Kinoite\"\n },\n \"Labs\": + {\n \"arches\": [\n \"aarch64\",\n \"x86_64\"\n + \ ],\n \"id\": \"Labs\",\n \"name\": + \"Labs\",\n \"paths\": {\n \"images\": {\n + \ \"aarch64\": \"Labs/aarch64/images\",\n \"x86_64\": + \"Labs/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Labs/x86_64/iso\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Labs\"\n },\n \"Onyx\": {\n \"arches\": + [\n \"x86_64\"\n ],\n \"id\": + \"Onyx\",\n \"name\": \"Onyx\",\n \"paths\": + {\n \"images\": {\n \"x86_64\": + \"Onyx/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Onyx/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"x86_64\": \"Onyx/x86_64/os\"\n + \ },\n \"repository\": {\n \"x86_64\": + \"Onyx/x86_64/os\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Onyx\"\n },\n \"Sericea\": + {\n \"arches\": [\n \"aarch64\",\n \"x86_64\"\n + \ ],\n \"id\": \"Sericea\",\n \"name\": + \"Sericea\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Sericea/aarch64/images\",\n \"x86_64\": + \"Sericea/x86_64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Sericea/x86_64/iso\"\n },\n + \ \"os_tree\": {\n \"x86_64\": \"Sericea/x86_64/os\"\n + \ },\n \"repository\": {\n \"x86_64\": + \"Sericea/x86_64/os\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Sericea\"\n },\n \"Server\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"s390x\",\n \"x86_64\"\n ],\n + \ \"id\": \"Server\",\n \"name\": \"Server\",\n + \ \"paths\": {\n \"debug_packages\": {\n + \ \"aarch64\": \"Server/aarch64/debug/tree/Packages\",\n + \ \"ppc64le\": \"Server/ppc64le/debug/tree/Packages\",\n + \ \"s390x\": \"Server/s390x/debug/tree/Packages\",\n + \ \"x86_64\": \"Server/x86_64/debug/tree/Packages\"\n + \ },\n \"debug_repository\": {\n \"aarch64\": + \"Server/aarch64/debug/tree\",\n \"ppc64le\": \"Server/ppc64le/debug/tree\",\n + \ \"s390x\": \"Server/s390x/debug/tree\",\n \"x86_64\": + \"Server/x86_64/debug/tree\"\n },\n \"debug_tree\": + {\n \"aarch64\": \"Server/aarch64/debug/tree\",\n \"ppc64le\": + \"Server/ppc64le/debug/tree\",\n \"s390x\": \"Server/s390x/debug/tree\",\n + \ \"x86_64\": \"Server/x86_64/debug/tree\"\n },\n + \ \"images\": {\n \"aarch64\": \"Server/aarch64/images\",\n + \ \"ppc64le\": \"Server/ppc64le/images\",\n \"s390x\": + \"Server/s390x/images\",\n \"x86_64\": \"Server/x86_64/images\"\n + \ },\n \"isos\": {\n \"aarch64\": + \"Server/aarch64/iso\",\n \"ppc64le\": \"Server/ppc64le/iso\",\n + \ \"s390x\": \"Server/s390x/iso\",\n \"x86_64\": + \"Server/x86_64/iso\"\n },\n \"os_tree\": + {\n \"aarch64\": \"Server/aarch64/os\",\n \"ppc64le\": + \"Server/ppc64le/os\",\n \"s390x\": \"Server/s390x/os\",\n + \ \"x86_64\": \"Server/x86_64/os\"\n },\n + \ \"packages\": {\n \"aarch64\": + \"Server/aarch64/os/Packages\",\n \"ppc64le\": \"Server/ppc64le/os/Packages\",\n + \ \"s390x\": \"Server/s390x/os/Packages\",\n \"x86_64\": + \"Server/x86_64/os/Packages\"\n },\n \"repository\": + {\n \"aarch64\": \"Server/aarch64/os\",\n \"ppc64le\": + \"Server/ppc64le/os\",\n \"s390x\": \"Server/s390x/os\",\n + \ \"x86_64\": \"Server/x86_64/os\"\n },\n + \ \"source_packages\": {\n \"aarch64\": + \"Server/source/tree/Packages\",\n \"ppc64le\": \"Server/source/tree/Packages\",\n + \ \"s390x\": \"Server/source/tree/Packages\",\n \"x86_64\": + \"Server/source/tree/Packages\"\n },\n \"source_repository\": + {\n \"aarch64\": \"Server/source/tree\",\n \"ppc64le\": + \"Server/source/tree\",\n \"s390x\": \"Server/source/tree\",\n + \ \"x86_64\": \"Server/source/tree\"\n },\n + \ \"source_tree\": {\n \"aarch64\": + \"Server/source/tree\",\n \"ppc64le\": \"Server/source/tree\",\n + \ \"s390x\": \"Server/source/tree\",\n \"x86_64\": + \"Server/source/tree\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Server\"\n },\n \"Silverblue\": + {\n \"arches\": [\n \"aarch64\",\n \"ppc64le\",\n + \ \"x86_64\"\n ],\n \"id\": + \"Silverblue\",\n \"name\": \"Silverblue\",\n \"paths\": + {\n \"images\": {\n \"aarch64\": + \"Silverblue/aarch64/images\",\n \"ppc64le\": \"Silverblue/ppc64le/images\",\n + \ \"x86_64\": \"Silverblue/x86_64/images\"\n },\n + \ \"isos\": {\n \"aarch64\": \"Silverblue/aarch64/iso\",\n + \ \"ppc64le\": \"Silverblue/ppc64le/iso\",\n \"x86_64\": + \"Silverblue/x86_64/iso\"\n },\n \"os_tree\": + {\n \"aarch64\": \"Silverblue/aarch64/os\",\n \"ppc64le\": + \"Silverblue/ppc64le/os\",\n \"x86_64\": \"Silverblue/x86_64/os\"\n + \ },\n \"repository\": {\n \"aarch64\": + \"Silverblue/aarch64/os\",\n \"ppc64le\": \"Silverblue/ppc64le/os\",\n + \ \"x86_64\": \"Silverblue/x86_64/os\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Silverblue\"\n },\n \"Spins\": {\n \"arches\": + [\n \"aarch64\",\n \"x86_64\"\n ],\n + \ \"id\": \"Spins\",\n \"name\": \"Spins\",\n + \ \"paths\": {\n \"images\": {\n \"aarch64\": + \"Spins/aarch64/images\"\n },\n \"isos\": + {\n \"x86_64\": \"Spins/x86_64/iso\"\n }\n + \ },\n \"type\": \"variant\",\n \"uid\": + \"Spins\"\n },\n \"Workstation\": {\n \"arches\": + [\n \"aarch64\",\n \"ppc64le\",\n \"x86_64\"\n + \ ],\n \"id\": \"Workstation\",\n \"name\": + \"Workstation\",\n \"paths\": {\n \"images\": + {\n \"aarch64\": \"Workstation/aarch64/images\"\n },\n + \ \"isos\": {\n \"aarch64\": \"Workstation/aarch64/iso\",\n + \ \"ppc64le\": \"Workstation/ppc64le/iso\",\n \"x86_64\": + \"Workstation/x86_64/iso\"\n }\n },\n \"type\": + \"variant\",\n \"uid\": \"Workstation\"\n }\n }\n + \ }\n}" + headers: + Connection: + - close + Date: + - Thu, 17 Oct 2024 19:08:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy10.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxFgnNMXuuQcf7bFEAeN9gAACoE + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=2863 + content-length: + - '14963' + content-type: + - application/json + last-modified: + - Mon, 15 Apr 2024 01:25:53 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/40/Fedora-40-20240414.0/compose/metadata/images.json + response: + body: + string: "{\n \"header\": {\n \"type\": \"productmd.images\",\n \"version\": + \"1.2\"\n },\n \"payload\": {\n \"compose\": {\n \"date\": + \"20240414\",\n \"id\": \"Fedora-40-20240414.0\",\n \"respin\": + 0,\n \"type\": \"production\"\n },\n \"images\": + {\n \"Cloud\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ab0fcaf5b5bbb4362d3757ff5e3fcea04fb4a4d6c501c19c1a55064194290230\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135599,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-AmazonEC2.aarch64-40-1.14.raw.xz\",\n + \ \"size\": 365970064,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"d53dbc3f75e527f12bad03c0b00f6b3ebbc45be3098c37cf932cdb3b2889c0ab\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vhd.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135978,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Azure.aarch64-40-1.14.vhdfixed.xz\",\n + \ \"size\": 426868528,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vhd-compressed\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"7153713f2a44607376b45786f609026cd64b2c3e276ee421c70a6f4fea74b501\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.gz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135981,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-GCE.aarch64-40-1.14.tar.gz\",\n \"size\": + 407577788,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"docker\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ebdce26d861a9d15072affe1919ed753ec7015bd97b3a7d0d0df6a10834f7459\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135596,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Generic.aarch64-40-1.14.qcow2\",\n + \ \"size\": 408289280,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"95224953d04b8af9447c5422e6af819e8e47a961476528b9b814dc52d48f424e\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135984,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-UEFI-UKI.aarch64-40-1.14.qcow2\",\n + \ \"size\": 400883712,\n \"subvariant\": + \"Cloud_Base_UKI\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"02aca73fe591bcc8e7d02b69d15d58a40110e73c7dd33de819aae3c602e9e1ed\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135601,\n \"path\": + \"Cloud/aarch64/images/Fedora-Cloud-Base-Vagrant-libvirt.aarch64-40-1.14.vagrant.libvirt.box\",\n + \ \"size\": 384506222,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"ede915e0461c112b444519559fbed5f9c9f69a72db215a2c2989b99f03f0b08a\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713136020,\n \"path\": + \"Cloud/ppc64le/images/Fedora-Cloud-Base-Generic.ppc64le-40-1.14.qcow2\",\n + \ \"size\": 398589952,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"808226b31c6c61e08cde77fe7ba61d766f7528c857e7ae8553040c177cbda9a7\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135364,\n \"path\": + \"Cloud/s390x/images/Fedora-Cloud-Base-Generic.s390x-40-1.14.qcow2\",\n \"size\": + 367915520,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"42c682c2c77ead24ea6af989d1fed28d93e2134c85b016674e109ee6f6699446\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135441,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-AmazonEC2.x86_64-40-1.14.raw.xz\",\n + \ \"size\": 366518332,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"9630c21d15990a08a793c35d4ef70dbef4bf98d8865dda6081aa14c1a90200e3\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vhd.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135500,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Azure.x86_64-40-1.14.vhdfixed.xz\",\n + \ \"size\": 437304100,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vhd-compressed\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"dcc05425e07b87f6f53f142c693bff3d47942fa4b05e1e08ab122db57ba478b5\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.gz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135465,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-GCE.x86_64-40-1.14.tar.gz\",\n \"size\": + 400065273,\n \"subvariant\": \"Cloud_Base\",\n \"type\": + \"docker\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ac58f3c35b73272d5986fa6d3bc44fd246b45df4c334e99a07b3bbd00684adee\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135440,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2\",\n + \ \"size\": 397475840,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"e58fbd6c147c0eda6eca72491ddc74871c3c3db9b808dc4fcf0d313510c43d81\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135438,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-UEFI-UKI.x86_64-40-1.14.qcow2\",\n + \ \"size\": 403767296,\n \"subvariant\": + \"Cloud_Base_UKI\",\n \"type\": \"qcow2\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"35f734b81396b3da3bc75c201cb71458745f7539f22ac1dd11b8268a81fa2915\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135451,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-VirtualBox.x86_64-40-1.14.vagrant.virtualbox.box\",\n + \ \"size\": 375556047,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"359c93a006c378210ae8f3a26eb7333693152ed2a6960904a9113742850ad12b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713135456,\n \"path\": + \"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-libvirt.x86_64-40-1.14.vagrant.libvirt.box\",\n + \ \"size\": 379222737,\n \"subvariant\": + \"Cloud_Base\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n }\n ]\n + \ },\n \"Container\": {\n \"aarch64\": + [\n {\n \"arch\": \"aarch64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"e374388c2a158729dcc7e9b4d61507ee0146103119eb711e9b91745e559ee94b\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135329,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Base-Generic-Minimal.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 44594488,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"8f7262dfaf502787581c49669d73b3bd0210b5d916f1d669b9a5737ad1a84830\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135489,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Base-Generic.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 80074648,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"247ec625257f0da9f5ce637e65900e61a127e60f508c8f489c13a14521a6f8a4\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135395,\n \"path\": + \"Container/aarch64/images/Fedora-Container-Toolbox.aarch64-40-1.14.oci.tar.xz\",\n + \ \"size\": 302343672,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"c8fd5cfab4d0a960a28df32d187c9b83133953aebc8096bd9c1bc37a71b592dd\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135311,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Base-Generic-Minimal.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 51102672,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"ppc64le\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"75d9864be59de913596240bca2779697d3a5f18e1a4fc0c8a05aafcb13a0034b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136025,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Base-Generic.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 87901272,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"0bbf987a98ebf61b24e89f4a1b6e348edc690e87ee7eb3a410c9bef56f75eece\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136473,\n \"path\": + \"Container/ppc64le/images/Fedora-Container-Toolbox.ppc64le-40-1.14.oci.tar.xz\",\n + \ \"size\": 307939276,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"90704b4ce8156cb26e4e92c3eafb69e823c8c837d7567b5287dca7c9e7e4d631\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135252,\n \"path\": + \"Container/s390x/images/Fedora-Container-Base-Generic-Minimal.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 46196064,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"3930880dc22d405611f4aaae3526d45024ecf71f5ae0825fd397c176fd61aaa1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135272,\n \"path\": + \"Container/s390x/images/Fedora-Container-Base-Generic.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 81930940,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"s390x\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"49bc41d3180300abaced1c49be91f2c4050551c4c81652e672c197649519b050\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135340,\n \"path\": + \"Container/s390x/images/Fedora-Container-Toolbox.s390x-40-1.14.oci.tar.xz\",\n + \ \"size\": 285858376,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"78434b6f41b209a2ed882b0c0f4f9f78a20aa965899c7860da24d02ab11235e3\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135278,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Base-Generic-Minimal.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 45908620,\n \"subvariant\": + \"Container_Minimal_Base\",\n \"type\": \"docker\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"c5c9dc3320ca474ff40b5a378b443a2b290f258a08e909a43fe81ca7a9bbe966\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135297,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Base-Generic.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 81711536,\n \"subvariant\": + \"Container_Base\",\n \"type\": \"docker\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"335900c5185c273e68da30c461ba4739f0a9692a8013014032c9929396840bf8\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"tar.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135361,\n \"path\": + \"Container/x86_64/images/Fedora-Container-Toolbox.x86_64-40-1.14.oci.tar.xz\",\n + \ \"size\": 323370324,\n \"subvariant\": + \"Container_Toolbox\",\n \"type\": \"docker\",\n \"volume_id\": + null\n }\n ]\n },\n \"Everything\": + {\n \"aarch64\": [\n {\n \"arch\": + \"aarch64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"512d1da43a71cde6fd20a4c2f5cae39fab2966fe6d3ad491964dd0be9b0772fc\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"7bf3fd693814339bad5d61b4c2fe368b\",\n \"mtime\": + 1713118156,\n \"path\": \"Everything/aarch64/iso/Fedora-Everything-netinst-aarch64-40-1.14.iso\",\n + \ \"size\": 837763072,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-aarch64-40\"\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"8dc915fabe631cf235820a0e41a8bc6ca30664f5fa5aa3e17bb7b9c064e31afe\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"7d35e0a335a3efe6d8f15e7d8cfb9d16\",\n \"mtime\": + 1713119671,\n \"path\": \"Everything/ppc64le/iso/Fedora-Everything-netinst-ppc64le-40-1.14.iso\",\n + \ \"size\": 802918400,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-ppc64le-40\"\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"a9cf7091294710615c10fba7a3ce25da6de516cccf77c6956e8ce5e883704307\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"24a9ee5e8abda63188ee8c7bedc2cec5\",\n \"mtime\": + 1713118230,\n \"path\": \"Everything/s390x/iso/Fedora-Everything-netinst-s390x-40-1.14.iso\",\n + \ \"size\": 500766720,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-s390x-40\"\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"4d1c0a7dda6c1d21a1483acb6c7914193158921113f947c5a0519d26bcc548b2\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"76fd4488e0831e52f521992d29dcc53d\",\n \"mtime\": + 1713118558,\n \"path\": \"Everything/x86_64/iso/Fedora-Everything-netinst-x86_64-40-1.14.iso\",\n + \ \"size\": 812255232,\n \"subvariant\": + \"Everything\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-E-dvd-x86_64-40\"\n }\n ]\n },\n + \ \"Kinoite\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"d3f5cea671ea0fed7f036091be0514bf290340e09cea6232a907b747c6a24217\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713120245,\n \"path\": + \"Kinoite/aarch64/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2644884992,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6fb0687148f494ba273eb9e278bcf269f88be7d1783c6e380067d540a995fbda\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"e5bf9a93a95b4d4660cdcbc8af891ec7\",\n \"mtime\": + 1713133789,\n \"path\": \"Kinoite/aarch64/iso/Fedora-Kinoite-ostree-aarch64-40-1.14.iso\",\n + \ \"size\": 4161081344,\n \"subvariant\": + \"Kinoite\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Knt-ostree-aarch64-40\"\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"7ee09b442e2bc77cf9516315724c37e33c7ca729080db56db14e71c2a7e16be8\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713127760,\n \"path\": + \"Kinoite/ppc64le/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2489408000,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"0afed26d6101f52f2481230978f1491401a332f6d427bdefe657248e09d4981d\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713120471,\n \"path\": + \"Kinoite/x86_64/images/Fedora-Kinoite-40.1.14.ociarchive\",\n \"size\": + 2659151872,\n \"subvariant\": \"Kinoite\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"c6abc4d88de97fd62f42b299cd2879a0e68d9552c9cfd3cc98753a1ff27be16c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"f66598e2003985c75bd9f6e30680fddd\",\n \"mtime\": + 1713134646,\n \"path\": \"Kinoite/x86_64/iso/Fedora-Kinoite-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 4181080064,\n \"subvariant\": + \"Kinoite\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Knt-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Labs\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"9c3f177cf24a802eaf8ce616b3b8e349b2850f7ea9692c05e9bf068255de1a7a\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713138953,\n \"path\": + \"Labs/aarch64/images/Fedora-Python-Classroom-40-1.14.aarch64.raw.xz\",\n + \ \"size\": 2709743384,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"163ed90b1c47d8428959c825ea92974fe153714b6c3ca438c91c0b316645baef\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713136066,\n \"path\": + \"Labs/x86_64/images/Fedora-Python-Classroom-Vagrant-40-1.14.x86_64.vagrant-libvirt.box\",\n + \ \"size\": 1547788429,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"aa4da25b27e82add30e5eb0c8526af28963eafcde6f3c7c6a6a96122819e1389\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713136106,\n \"path\": + \"Labs/x86_64/images/Fedora-Python-Classroom-Vagrant-40-1.14.x86_64.vagrant-virtualbox.box\",\n + \ \"size\": 1569054720,\n \"subvariant\": + \"Python_Classroom\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"78c2cfe481c9ef549eca5808ffc9f0a21a85ad2bb4c444369740fd8d9dd32b6f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-libvirt.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713137373,\n \"path\": + \"Labs/x86_64/images/Fedora-Scientific-Vagrant-40-1.14.x86_64.vagrant-libvirt.box\",\n + \ \"size\": 4930855083,\n \"subvariant\": + \"Scientific\",\n \"type\": \"vagrant-libvirt\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"ab61c41a4199165ee85b00b1bb3b1f5c27f7d10603ab13e4116e6d27951406bf\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"vagrant-virtualbox.box\",\n \"implant_md5\": + null,\n \"mtime\": 1713137485,\n \"path\": + \"Labs/x86_64/images/Fedora-Scientific-Vagrant-40-1.14.x86_64.vagrant-virtualbox.box\",\n + \ \"size\": 4987146240,\n \"subvariant\": + \"Scientific\",\n \"type\": \"vagrant-virtualbox\",\n + \ \"volume_id\": null\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"af586cefa44b7f9c8b755c121e7d5c99f3d88beb39721daec7f3a626622b64fb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136830,\n \"path\": + \"Labs/x86_64/iso/Fedora-Astronomy_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 4634284032,\n \"subvariant\": \"Astronomy_KDE\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"3e17b61870224ca92f85cb031070c4a969a07ad7dacfaacbfd5b70ecb32331c1\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136579,\n \"path\": + \"Labs/x86_64/iso/Fedora-Comp_Neuro-Live-x86_64-40-1.14.iso\",\n \"size\": + 3074414592,\n \"subvariant\": \"Comp_Neuro\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"d99ad7ec55a27393dcb846a333b0e74d5d8b0c70a335b4a0a98ff6e850c852aa\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136822,\n \"path\": + \"Labs/x86_64/iso/Fedora-Games-Live-x86_64-40-1.14.iso\",\n \"size\": + 6890553344,\n \"subvariant\": \"Games\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"816a7d24aa1afc5e875a33e319204a7cd12a7780ae33ab019ee1c5141941611f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136478,\n \"path\": + \"Labs/x86_64/iso/Fedora-Jam_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 3520172032,\n \"subvariant\": \"Jam_KDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"5893394eccd8228f9e4f708e76f6cdb77f61ba79c6d19a1dd4a11776e824afe6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136343,\n \"path\": + \"Labs/x86_64/iso/Fedora-Python-Classroom-Live-x86_64-40-1.14.iso\",\n \"size\": + 2346051584,\n \"subvariant\": \"Python_Classroom\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"c8de28ddb4667d57dc9527d2a7b445ec77861e129b3354251068a0ca9a2e640d\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136335,\n \"path\": + \"Labs/x86_64/iso/Fedora-Robotics-Live-x86_64-40-1.14.iso\",\n \"size\": + 3168759808,\n \"subvariant\": \"Robotics\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4cfb06b40a5b7fbbc46794a8a1fa89f819712681fc2b8d23d3beb4b394cea0db\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713137226,\n \"path\": + \"Labs/x86_64/iso/Fedora-Scientific_KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 5545820160,\n \"subvariant\": \"Scientific_KDE\",\n + \ \"type\": \"live\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"2a2e55d2fb08c905e945e259d8b5cab55701c3dbdec717d178d7fb4a5da45608\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136333,\n \"path\": + \"Labs/x86_64/iso/Fedora-Security-Live-x86_64-40-1.14.iso\",\n \"size\": + 2463766528,\n \"subvariant\": \"Security\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n },\n \"Onyx\": {\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"511c2f46c298d1cff1df08b770d23f6fcd25d252d19ca837732e349f12086bb1\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713134693,\n \"path\": + \"Onyx/x86_64/images/Fedora-Onyx-40.1.14.ociarchive\",\n \"size\": + 2201719808,\n \"subvariant\": \"Onyx\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"b196159ab8bf2ced06204a13925f330546f9b0f3db253f6b399a3a5dac517acb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"6d1aaecf42d3d0cc855324173ccf6859\",\n \"mtime\": + 1713133807,\n \"path\": \"Onyx/x86_64/iso/Fedora-Onyx-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 2701541376,\n \"subvariant\": + \"Onyx\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Onyx-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Sericea\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"216c52c960f4a7da1a5fc0056ee138e25cef3f41d2131501089cb3486aaff35e\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713118667,\n \"path\": + \"Sericea/aarch64/images/Fedora-Sericea-40.1.14.ociarchive\",\n \"size\": + 1987797504,\n \"subvariant\": \"Sericea\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"f5d797d8ff27771b95aedd418eebc0d271904505e9156444c8a0c7c5dca0a08a\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119001,\n \"path\": + \"Sericea/x86_64/images/Fedora-Sericea-40.1.14.ociarchive\",\n \"size\": + 2001887744,\n \"subvariant\": \"Sericea\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"9b8cce1ecbaba24a7e8db1b401b240382954acee5fb9993ad4b536f42f9186a6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"030db49ce5182ba4e71c717b950598fb\",\n \"mtime\": + 1713133600,\n \"path\": \"Sericea/x86_64/iso/Fedora-Sericea-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 2536486912,\n \"subvariant\": + \"Sericea\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-Src-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Server\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"a624d7275bf8538ee875a5f69b60b04d9114ad6ea918ecad160dde24b4b75b35\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713137407,\n \"path\": + \"Server/aarch64/images/Fedora-Server-40-1.14.aarch64.raw.xz\",\n \"size\": + 1108904380,\n \"subvariant\": \"Server\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"2fed4e38a927824704d6bd88466b3b938543b335669e470981fa123f965f1c68\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713136435,\n \"path\": + \"Server/aarch64/images/Fedora-Server-KVM-40-1.14.aarch64.qcow2\",\n \"size\": + 672661504,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"9146b9563d68c9c9cc53fac75f5e9caefaff8d0e350cd6c4312553deb99b5430\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"1ec36133552bcf746633b30e19b7b0eb\",\n \"mtime\": + 1713135235,\n \"path\": \"Server/aarch64/iso/Fedora-Server-dvd-aarch64-40-1.14.iso\",\n + \ \"size\": 2535260160,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-aarch64-40\"\n },\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"690731ac6abba81413d97517baa80841cb122d07b296ec3f2935848be45be8fe\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"5a1006b4b30a1ad1b21d4d756c9495cd\",\n \"mtime\": + 1713118154,\n \"path\": \"Server/aarch64/iso/Fedora-Server-netinst-aarch64-40-1.14.iso\",\n + \ \"size\": 837820416,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-aarch64-40\"\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"b5817bcabd28f336f457cc7cafedeef963dc6e1b3227786b92446a8f9bade549\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713143951,\n \"path\": + \"Server/ppc64le/images/Fedora-Server-KVM-40-1.14.ppc64le.qcow2\",\n \"size\": + 675479552,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4fa5eafedf7668093f5b10dbbefa8f3d49269036af09dd35f17247d1aed8c0a6\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"dfe900eaeea376d841d11cecdfa6d01e\",\n \"mtime\": + 1713135288,\n \"path\": \"Server/ppc64le/iso/Fedora-Server-dvd-ppc64le-40-1.14.iso\",\n + \ \"size\": 2357985280,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-ppc64le-40\"\n },\n {\n + \ \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"e24354b40722b7a1964e50abae0efc1030faa5605503fcc371bece1897b289eb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"178c3a1225edc5110692bb32ebae55db\",\n \"mtime\": + 1713118384,\n \"path\": \"Server/ppc64le/iso/Fedora-Server-netinst-ppc64le-40-1.14.iso\",\n + \ \"size\": 802988032,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-ppc64le-40\"\n }\n ],\n \"s390x\": + [\n {\n \"arch\": \"s390x\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"091c232a7301be14e19c76ce9a0c1cbd2be2c4157884a731e1fc4f89e7455a5f\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135580,\n \"path\": + \"Server/s390x/images/Fedora-Server-KVM-40-1.14.s390x.qcow2\",\n \"size\": + 646119424,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"5e1844fa681ddedcd69ef10a54b4c7bf0dadcb335027b9982c26d53acc9c0f61\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"a32cc4d8ca8f0e1074a6231d5a77a678\",\n \"mtime\": + 1713135471,\n \"path\": \"Server/s390x/iso/Fedora-Server-dvd-s390x-40-1.14.iso\",\n + \ \"size\": 1990197248,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-s390x-40\"\n },\n {\n + \ \"arch\": \"s390x\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6daee5daf5367802633ca8262e122df74ce0cbdab0e39a6ecb6ad4c18bd9afda\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"a25987f92bde5966a9decffdb1681cd1\",\n \"mtime\": + 1713118230,\n \"path\": \"Server/s390x/iso/Fedora-Server-netinst-s390x-40-1.14.iso\",\n + \ \"size\": 500807680,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-s390x-40\"\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"a16ba1f26aaf010f62bd94e9f772079353e4bbcffe2c8078f1dfab8aeb848851\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"qcow2\",\n \"implant_md5\": + null,\n \"mtime\": 1713135735,\n \"path\": + \"Server/x86_64/images/Fedora-Server-KVM-40-1.14.x86_64.qcow2\",\n \"size\": + 658702336,\n \"subvariant\": \"Server_KVM\",\n \"type\": + \"qcow2\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"32d9ab1798fc8106a0b06e873bdcd83a3efea8412c9401dfe4097347ed0cfc65\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"cff4f63cc29f4c5a34b3187e643646d4\",\n \"mtime\": + 1713135246,\n \"path\": \"Server/x86_64/iso/Fedora-Server-dvd-x86_64-40-1.14.iso\",\n + \ \"size\": 2612854784,\n \"subvariant\": + \"Server\",\n \"type\": \"dvd\",\n \"volume_id\": + \"Fedora-S-dvd-x86_64-40\"\n },\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"1b4f163c55aa9b35bb08f3d465534aa68899a4984b8ba8976b1e7b28297b61fe\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"da6ff3e6d0ffe4bae7cea6062f6fe307\",\n \"mtime\": + 1713119419,\n \"path\": \"Server/x86_64/iso/Fedora-Server-netinst-x86_64-40-1.14.iso\",\n + \ \"size\": 812312576,\n \"subvariant\": + \"Server\",\n \"type\": \"boot\",\n \"volume_id\": + \"Fedora-S-dvd-x86_64-40\"\n }\n ]\n },\n + \ \"Silverblue\": {\n \"aarch64\": [\n {\n + \ \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"7f7c6839aa83c03c388b37f6b90c57c799a56a1eab45443a57400b410ac591d1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119502,\n \"path\": + \"Silverblue/aarch64/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2108361216,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"c482885894c0ff722c305ca36259dc59d94a36582053b64d6042287c103c9c1c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"0f104e39971464627679ed12a1fb8d9b\",\n \"mtime\": + 1713133688,\n \"path\": \"Silverblue/aarch64/iso/Fedora-Silverblue-ostree-aarch64-40-1.14.iso\",\n + \ \"size\": 3573305344,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-aarch64-40\"\n }\n ],\n + \ \"ppc64le\": [\n {\n \"arch\": + \"ppc64le\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"32107335909c0bb98c195c1bcd1b3c7b515409ac3cd9460c020a5dd8d8ca9a1d\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713127903,\n \"path\": + \"Silverblue/ppc64le/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2049432576,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"ppc64le\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"cbadcf23a74783bb61f0907329310ad4ac07e7b06659f33afa9106f896fafb25\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"3f83f88976c5551c67b6e9ac831f7faf\",\n \"mtime\": + 1713134909,\n \"path\": \"Silverblue/ppc64le/iso/Fedora-Silverblue-ostree-ppc64le-40-1.14.iso\",\n + \ \"size\": 3499855872,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-ppc64le-40\"\n }\n ],\n + \ \"x86_64\": [\n {\n \"arch\": + \"x86_64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"706ddc97e9cc8a35d3ce457370aecae032f382bffd0de404aeba062f74940d4c\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"ociarchive\",\n \"implant_md5\": + null,\n \"mtime\": 1713119572,\n \"path\": + \"Silverblue/x86_64/images/Fedora-Silverblue-40.1.14.ociarchive\",\n \"size\": + 2124795904,\n \"subvariant\": \"Silverblue\",\n \"type\": + \"ociarchive\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"8f49c9880cf0eb24e0461498d27d3d5134f056975c478f7d0febb1b9e5d1edbb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + \"4cc0e9c55bdaad116a611d41223e5d54\",\n \"mtime\": + 1713134394,\n \"path\": \"Silverblue/x86_64/iso/Fedora-Silverblue-ostree-x86_64-40-1.14.iso\",\n + \ \"size\": 3582482432,\n \"subvariant\": + \"Silverblue\",\n \"type\": \"dvd-ostree\",\n \"volume_id\": + \"Fedora-SB-ostree-x86_64-40\"\n }\n ]\n + \ },\n \"Spins\": {\n \"aarch64\": [\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"3840ebba322b9a24867a777c472f510a47193db90cf96a51da074758cc5299e1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713140460,\n \"path\": + \"Spins/aarch64/images/Fedora-KDE-40-1.14.aarch64.raw.xz\",\n \"size\": + 3297951536,\n \"subvariant\": \"KDE\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"9a0aa0a82a10edc184f67c1c2609f11f06a2ea43dd6801863df4189dd647e62b\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136738,\n \"path\": + \"Spins/aarch64/images/Fedora-LXQt-40-1.14.aarch64.raw.xz\",\n \"size\": + 1995815572,\n \"subvariant\": \"LXQt\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"36920c0f7a0ae00c2542579f9b600108f77de228a892417ebf8cb651123ad1e8\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713135848,\n \"path\": + \"Spins/aarch64/images/Fedora-Minimal-40-1.14.aarch64.raw.xz\",\n \"size\": + 912716876,\n \"subvariant\": \"Minimal\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"27a015a74dd7cdfd8a2a13cf0fec521e04f04249e5430e26bc698719f6df60b1\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136685,\n \"path\": + \"Spins/aarch64/images/Fedora-Phosh-40-1.14.aarch64.raw.xz\",\n \"size\": + 2086621740,\n \"subvariant\": \"Phosh\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"a4cdd47d37438bbd90ddf1f9ecde7ed94765788381afa4a93412a22301014c87\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136186,\n \"path\": + \"Spins/aarch64/images/Fedora-SoaS-40-1.14.aarch64.raw.xz\",\n \"size\": + 1720404580,\n \"subvariant\": \"SoaS\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"aarch64\",\n \"bootable\": + false,\n \"checksums\": {\n \"sha256\": + \"8622a0f05cc09ec22bd63bc3712b552cee3512f2b135fa51d08a745e4b0169ce\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713136735,\n \"path\": + \"Spins/aarch64/images/Fedora-Xfce-40-1.14.aarch64.raw.xz\",\n \"size\": + 2282925736,\n \"subvariant\": \"Xfce\",\n \"type\": + \"raw-xz\",\n \"volume_id\": null\n }\n + \ ],\n \"x86_64\": [\n {\n + \ \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"18a2876d031fd58d00d9a37d3a823caa03cf7059309bed1de79eb3a46dc4bc21\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136139,\n \"path\": + \"Spins/x86_64/iso/Fedora-Budgie-Live-x86_64-40-1.14.iso\",\n \"size\": + 2146633728,\n \"subvariant\": \"Budgie\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"081ac2402d3e2e704d36ee6aacd67ba631d1939e0c35cf517e996dbb70117735\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136218,\n \"path\": + \"Spins/x86_64/iso/Fedora-Cinnamon-Live-x86_64-40-1.14.iso\",\n \"size\": + 2558238720,\n \"subvariant\": \"Cinnamon\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"8b9da20cfa947b16c8f0c5187e9b4389e13821e31b062688a48cf1b3028c335c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136407,\n \"path\": + \"Spins/x86_64/iso/Fedora-KDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 2645645312,\n \"subvariant\": \"KDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"3be326068be6bd7e98d7e7e89f4427648fe83484ecd36e1e77304af1369d1920\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713135996,\n \"path\": + \"Spins/x86_64/iso/Fedora-LXDE-Live-x86_64-40-1.14.iso\",\n \"size\": + 1741191168,\n \"subvariant\": \"LXDE\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"ef0fbed423acc7484b6fea14a062c41a3026ca93d71edf28debe2d883f9ce61c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136088,\n \"path\": + \"Spins/x86_64/iso/Fedora-LXQt-Live-x86_64-40-1.14.iso\",\n \"size\": + 1845794816,\n \"subvariant\": \"LXQt\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"3242eb53dd2d0bad66dff04f7e54848aa750910171a110e2f8677aa23b8e84e0\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136230,\n \"path\": + \"Spins/x86_64/iso/Fedora-MATE_Compiz-Live-x86_64-40-1.14.iso\",\n \"size\": + 2454198272,\n \"subvariant\": \"Mate\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"4287b380b4be2f2c421178b9dfdcaf8c64ed58e343baa7d1d482c4f3481975fb\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136027,\n \"path\": + \"Spins/x86_64/iso/Fedora-SoaS-Live-x86_64-40-1.14.iso\",\n \"size\": + 1440874496,\n \"subvariant\": \"SoaS\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"6974428b65153156e133fe0165cdf5cb4420b987fe27c53218480414b685e602\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713135976,\n \"path\": + \"Spins/x86_64/iso/Fedora-Sway-Live-x86_64-40-1.14.iso\",\n \"size\": + 1637679104,\n \"subvariant\": \"Sway\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"519db49a21587c007b8135cfc8fba470951937d2f7edc01a8f4b96abc772370c\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136105,\n \"path\": + \"Spins/x86_64/iso/Fedora-Xfce-Live-x86_64-40-1.14.iso\",\n \"size\": + 1889988608,\n \"subvariant\": \"Xfce\",\n \"type\": + \"live\",\n \"volume_id\": null\n },\n + \ {\n \"arch\": \"x86_64\",\n \"bootable\": + true,\n \"checksums\": {\n \"sha256\": + \"1f55028b79c6633178a0106fdb3d34ccb489f1dc039c5e96a829cea28624d7a8\"\n },\n + \ \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136412,\n \"path\": + \"Spins/x86_64/iso/Fedora-i3-Live-x86_64-40-1.14.iso\",\n \"size\": + 1617053696,\n \"subvariant\": \"i3\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n },\n \"Workstation\": {\n \"aarch64\": + [\n {\n \"arch\": \"aarch64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"edaaf8e78db25c81c5600ef65b1ed2c85417ba7b51c3a5785d5acff6e8c90721\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"raw.xz\",\n \"implant_md5\": + null,\n \"mtime\": 1713137105,\n \"path\": + \"Workstation/aarch64/images/Fedora-Workstation-40-1.14.aarch64.raw.xz\",\n + \ \"size\": 2622667416,\n \"subvariant\": + \"Workstation\",\n \"type\": \"raw-xz\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"aarch64\",\n \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"ebb1edbf16da88ed3fb804eca01625fb4341f59ce747c6b89ec00af58a9a6158\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138011,\n \"path\": + \"Workstation/aarch64/iso/Fedora-Workstation-Live-osb-40-1.14.aarch64.iso\",\n + \ \"size\": 2582759424,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live-osbuild\",\n \"volume_id\": + null\n }\n ],\n \"ppc64le\": + [\n {\n \"arch\": \"ppc64le\",\n + \ \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"d015fe246beac888433a1e5b3bc314d29946e91a4df90bb24d1c7b1903e8edf4\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138621,\n \"path\": + \"Workstation/ppc64le/iso/Fedora-Workstation-Live-ppc64le-40-1.14.iso\",\n + \ \"size\": 2228242432,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live\",\n \"volume_id\": + null\n }\n ],\n \"x86_64\": + [\n {\n \"arch\": \"x86_64\",\n + \ \"bootable\": false,\n \"checksums\": + {\n \"sha256\": \"8d3cb4d99f27eb932064915bc9ad34a7529d5d073a390896152a8a899518573f\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713138847,\n \"path\": + \"Workstation/x86_64/iso/Fedora-Workstation-Live-osb-40-1.14.x86_64.iso\",\n + \ \"size\": 2623733760,\n \"subvariant\": + \"Workstation\",\n \"type\": \"live-osbuild\",\n \"volume_id\": + null\n },\n {\n \"arch\": + \"x86_64\",\n \"bootable\": true,\n \"checksums\": + {\n \"sha256\": \"dd1faca950d1a8c3d169adf2df4c3644ebb62f8aac04c401f2393e521395d613\"\n + \ },\n \"disc_count\": 1,\n \"disc_number\": + 1,\n \"format\": \"iso\",\n \"implant_md5\": + null,\n \"mtime\": 1713136256,\n \"path\": + \"Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-40-1.14.iso\",\n \"size\": + 2295853056,\n \"subvariant\": \"Workstation\",\n \"type\": + \"live\",\n \"volume_id\": null\n }\n + \ ]\n }\n }\n }\n}" + headers: + Connection: + - close + Date: + - Thu, 17 Oct 2024 19:08:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy01.iad2.fedoraproject.org + X-Fedora-RequestID: + - ZxFgnMJEd0U1Dq2BrRY7XQAABUk + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + accept-ranges: + - bytes + apptime: + - D=2482 + content-length: + - '78266' + content-type: + - application/json + last-modified: + - Mon, 15 Apr 2024 01:25:53 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + x-fedora-appserver: + - kojipkgs02.iad2.fedoraproject.org + status: + code: 200 + message: OK +version: 1 diff --git a/fedora-image-uploader/tests/test_gcp.py b/fedora-image-uploader/tests/test_gcp.py new file mode 100644 index 0000000..f01b298 --- /dev/null +++ b/fedora-image-uploader/tests/test_gcp.py @@ -0,0 +1,574 @@ +import json +import os +from unittest import mock + +import freezegun +import pytest +from fedora_image_uploader_messages import GcpPublishedV1 +from fedora_messaging import config, message +from fedora_messaging import testing as fm_testing +from google.cloud import compute_v1, storage + +from fedora_image_uploader import Uploader + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + "publish_amqp_messages": True, + } + }, + }, +) +def test_image_filter(fixtures_dir): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.upload_disk_image = mock.Mock() + image = { + "arch": "aarch64", + "format": "tar.gz", + "subvariant": "Cloud_Base", + } + ffrel = mock.Mock(relnum=42, release="Rawhide") + + # Arch isn't supported + image["arch"] = "ppc64le" + handler(image, ffrel) + handler.upload_disk_image.call_count == 0 + image["arch"] = "aarch64" + + # Format isn't tar.gz + image["format"] = "qcow2" + handler(image, ffrel) + handler.upload_disk_image.call_count == 0 + image["format"] = "tar.gz" + + # Subvariant isn't supported + image["subvariant"] = "CoreOS" + handler(image, ffrel) + handler.upload_disk_image.call_count == 0 + + # Don't bother with 39 + handler(image, mock.Mock(relnum=39, release="39")) + handler.upload_disk_image.call_count == 0 + + +@pytest.mark.vcr +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + "publish_amqp_messages": True, + } + }, + }, +) +def test_messages(fixtures_dir): + with open(os.path.join(fixtures_dir, "messages/rc_compose.json")) as fd: + msg = message.load_message(json.load(fd)) + fake_images = [ + mock.Mock( + family="fedora-cloud-40", + name="fedora-cloud-40-1-14-aarch64", + self_link="http://example.com/link", + storage_locations=["us"], + ), + mock.Mock( + family="fedora-cloud-40", + name="fedora-cloud-40-1-14-x86-64", + self_link="http://example.com/link", + storage_locations=["us"], + ), + ] + fake_images[0].name = "fedora-cloud-40-1-14-aarch64" + fake_images[1].name = "fedora-cloud-40-1-14-x86-64" + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.upload_disk_image = mock.Mock() + handler.import_image = mock.Mock(side_effect=fake_images) + handler.promote_image = mock.Mock() + handler.cleanup_old_images = mock.Mock() + + expected_messages = [ + GcpPublishedV1( + topic="fedora_image_uploader.published.v1.gcp.rc.Cloud_Base.aarch64", + body={ + "architecture": "aarch64", + "compose_id": "Fedora-40-20240414.0", + "release": 40, + "subvariant": "Cloud_Base", + "family": "fedora-cloud-40", + "image_name": "fedora-cloud-40-1-14-aarch64", + "image_url": "http://example.com/link", + "storage_locations": ["us"], + }, + ), + GcpPublishedV1( + topic="fedora_image_uploader.published.v1.gcp.rc.Cloud_Base.x86_64", + body={ + "architecture": "x86_64", + "compose_id": "Fedora-40-20240414.0", + "release": 40, + "subvariant": "Cloud_Base", + "family": "fedora-cloud-40", + "image_name": "fedora-cloud-40-1-14-x86-64", + "image_url": "http://example.com/link", + "storage_locations": ["us"], + }, + ), + ] + with fm_testing.mock_sends(*expected_messages): + consumer(msg) + + +@pytest.mark.vcr +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_import_image(fixtures_dir): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.upload_disk_image = mock.Mock() + handler.promote_image = mock.Mock() + handler.cleanup_old_image = mock.Mock() + handler.images_client.list.return_value = [] + handler.images_client.insert.return_value.warnings = [] + handler.upload_disk_image.return_value = mock.Mock( + spec=storage.Blob, self_link="http://example.com/link" + ) + expected_calls = [ + mock.call( + compute_v1.InsertImageRequest( + request_id="7153713f-2a44-6073-76b4-5786f609026c", + project="fedora-cloud-devel", + image_resource=compute_v1.Image( + architecture="ARM64", + family="fedora-cloud-40", + description="Fedora Cloud base image version 40.1.14", + deprecated=compute_v1.DeprecationStatus(state="ACTIVE"), + guest_os_features=[ + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.UEFI_COMPATIBLE.name + ), + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.VIRTIO_SCSI_MULTIQUEUE.name + ), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.IDPF.name), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.GVNIC.name), + ], + labels={ + "fedora-compose-id": "fedora-40-20240414-0", + "fedora-subvariant": "cloud_base", + "fedora-release": "40", + "fedora-version": "40", + "end-of-life": "2025-05-13", + "fedora-image-uploader-managed": "true", + }, + name="fedora-cloud-40-1-14-aarch64", + raw_disk=compute_v1.RawDisk( + source=handler.upload_disk_image.return_value.self_link + ), + storage_locations=["us"], + ), + ), + timeout=60, + ), + mock.call( + compute_v1.InsertImageRequest( + request_id="dcc05425-e07b-87f6-f53f-142c693bff3d", + project="fedora-cloud-devel", + image_resource=compute_v1.Image( + architecture="X86_64", + family="fedora-cloud-40", + description="Fedora Cloud base image version 40.1.14", + deprecated=compute_v1.DeprecationStatus(state="ACTIVE"), + guest_os_features=[ + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.UEFI_COMPATIBLE.name + ), + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.VIRTIO_SCSI_MULTIQUEUE.name + ), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.IDPF.name), + compute_v1.GuestOsFeature(type_=compute_v1.GuestOsFeature.Type.GVNIC.name), + compute_v1.GuestOsFeature( + type_=compute_v1.GuestOsFeature.Type.SECURE_BOOT.name + ), + ], + labels={ + "fedora-compose-id": "fedora-40-20240414-0", + "fedora-subvariant": "cloud_base", + "fedora-release": "40", + "fedora-version": "40", + "end-of-life": "2025-05-13", + "fedora-image-uploader-managed": "true", + }, + name="fedora-cloud-40-1-14-x86-64", + raw_disk=compute_v1.RawDisk( + source=handler.upload_disk_image.return_value.self_link + ), + storage_locations=["us"], + ), + ), + timeout=60, + ), + ] + + with open(os.path.join(fixtures_dir, "messages/rc_compose.json")) as fd: + consumer(message.load_message(json.load(fd))) + + for call in handler.images_client.insert.call_args_list: + assert call in expected_calls + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_promote_image_eln_rawhide(): + """Assert this is a no-op for eln and rawhide""" + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + + # rawhide + handler.promote_image( + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "rawhide", + "fedora-image-uploader-managed": "true", + }, + name="fedora-40-1-14-x86-64", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ) + ) + handler.images_client.list.call_count = 0 + + # eln + handler.promote_image( + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "eln", + "fedora-image-uploader-managed": "true", + }, + name="fedora-40-1-14-x86-64", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ) + ) + handler.images_client.list.call_count = 0 + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_needs_promotion(): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.images_client.list.side_effect = ( + [ + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + }, + name="olde", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ) + ], + ) + handler.images_client.deprecate.return_value.warnings = [] + + with freezegun.freeze_time("2024-10-16"): + handler.promote_image( + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + }, + name="promoted", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-15T00:00:00Z", + ) + ) + + handler.images_client.deprecate.assert_called_once_with( + request=compute_v1.DeprecateImageRequest( + project="fedora-cloud-devel", + image="promoted", + deprecation_status_resource=compute_v1.DeprecationStatus( + state=compute_v1.DeprecationStatus.State.ACTIVE.name, + ), + ), + timeout=60, + ) + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_no_promotion(): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.images_client.list.side_effect = ( + [ + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + }, + name="olde", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-05T00:00:00Z", + ) + ], + ) + handler.images_client.deprecate.return_value.warnings = [] + + with freezegun.freeze_time("2024-10-16"): + handler.promote_image( + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + }, + name="promoted", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-15T00:00:00Z", + ) + ) + + assert handler.images_client.deprecate.call_count == 0 + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_cleanup_skips_unmanaged_images(): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.images_client.list.return_value = [ + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + name="fedora-40-1-14-aarch64", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + ) + ] + + # Test that cleanup_old_images is not called when the image is not managed + handler.cleanup_old_images() + assert handler.images_client.delete.call_count == 0 + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_cleanup_rawhide(): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.images_client.list.side_effect = ( + [ + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "rawhide", + "fedora-image-uploader-managed": "true", + }, + name="gone-but-not-forgotten", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ), + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "rawhide", + "fedora-image-uploader-managed": "true", + }, + name="soon-to-go-but-not-yet", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-02T00:00:00Z", + ), + ], + [], + ) + handler.images_client.delete.return_value.warnings = [] + + # Test that cleanup_old_images is not called when the image is not managed + with freezegun.freeze_time("2024-10-16"): + handler.cleanup_old_images() + assert handler.images_client.delete.call_count == 1 + handler.images_client.delete.assert_called_once_with( + compute_v1.DeleteImageRequest( + project="fedora-cloud-devel", + image="gone-but-not-forgotten", + request_id="347bf095-cee1-dc0f-8b0b-287da4300d98", + ), + timeout=600, + ) + + +@mock.patch.dict( + config.conf, + { + "consumer_config": { + "gcp": { + "project": "fedora-cloud-devel", + "bucket_name": "some-unique-bucket-name", + "storage_locations": ["us"], + } + }, + }, +) +def test_cleanup_eol(): + consumer = Uploader() + handler = consumer.handlers["gcp"] + handler.images_client = mock.Mock() + handler.images_client.list.side_effect = ( + [], + [ + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + "end-of-life": "2024-10-01", + }, + name="gone-but-not-forgotten", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ), + compute_v1.Image( + architecture="X86_64", + family="fedora-40", + description="Fedora Cloud base image version", + labels={ + "fedora-release": "40", + "fedora-image-uploader-managed": "true", + "end-of-life": "2024-10-17", + }, + name="still-alive", + raw_disk=compute_v1.RawDisk(source="http://example.com/link"), + storage_locations=["us"], + creation_timestamp="2024-10-01T00:00:00Z", + ), + ], + ) + handler.images_client.delete.return_value.warnings = [] + + # Test that cleanup_old_images is not called when the image is not managed + with freezegun.freeze_time("2024-10-16"): + handler.cleanup_old_images() + + handler.images_client.delete.assert_called_once_with( + compute_v1.DeleteImageRequest( + project="fedora-cloud-devel", + image="gone-but-not-forgotten", + request_id="347bf095-cee1-dc0f-8b0b-287da4300d98", + ), + timeout=600, + ) diff --git a/fedora-image-uploader/tox.ini b/fedora-image-uploader/tox.ini index 6af5f8c..e08c13b 100644 --- a/fedora-image-uploader/tox.ini +++ b/fedora-image-uploader/tox.ini @@ -5,7 +5,7 @@ isolated_build = True [testenv] deps = ../fedora-image-uploader-messages/ - .[test,azure,aws] + .[test,azure,aws,gcp] sitepackages = False skip_install = True commands_pre = diff --git a/fedora-messaging.toml.example b/fedora-messaging.toml.example index 5b23849..3958c01 100644 --- a/fedora-messaging.toml.example +++ b/fedora-messaging.toml.example @@ -35,6 +35,7 @@ queue = "my_queue" exchange = "amq.topic" routing_keys = ["org.fedoraproject.*.pungi.compose.status.change"] + [consumer_config.azure] location = "eastus" resource_group_name = "fedora-test" @@ -108,6 +109,11 @@ ami_regions = [ ] +[consumer_config.gcp] +project = "fedora-cloud-devel" +bucket_name = "fedora-cloud-image-upload-devel" +storage_locations = ["us"] + [qos] prefetch_size = 0 prefetch_count = 25