From dd614c24dd35d3e7ae929cf4c89fe92f481450f5 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: May 31 2024 19:07:16 +0000 Subject: [PATCH 1/2] Consistently use the azure_fm_conf fixture There's still a couple of tests duplicating this, make them use the fixture instead. Interestingly this exposes a bug where `test_azure_filters` was changing the config in a way that affected later tests; fix that too, and some similar cases. Signed-off-by: Adam Williamson --- diff --git a/tests/test_handler.py b/tests/test_handler.py index fcf087d..0e0e61c 100644 --- a/tests/test_handler.py +++ b/tests/test_handler.py @@ -53,22 +53,12 @@ def _mock_download_image(self, image: dict, dest_dir: str, decompress=False) -> ("messages/rc_compose.json", "Fedora-Cloud-40"), ], ) -def test_gallery_name(mock_runner, fixtures_dir, compose): +def test_gallery_name(mock_runner, fixtures_dir, azure_fm_conf, compose): mock_runner.interface.run.return_value.rc = 0 message_file, expected_gallery_name = compose with open(os.path.join(fixtures_dir, message_file)) as fd: msg = message.load_message(json.load(fd)) - config.conf["consumer_config"]["azure"] = { - "location": "eastus", - "resource_group_name": "fedora-test", - "gallery_name": "Fedora", - "gallery_description": "The Fedora compute gallery.", - "storage_account_name": "fedoraimageuploads", - "storage_container_name": "vhds", - "target_regions": {}, - } - consumer = Uploader() # disable handlers we don't want to hit in this test consumer.handlers = [consumer.handle_azure] @@ -83,6 +73,10 @@ def test_gallery_name(mock_runner, fixtures_dir, compose): @pytest.mark.vcr +@mock.patch.dict( + config.conf["consumer_config"], + {"container": {"registries": ["registry.fedoraproject.org", "quay.io/fedora"]}}, +) @mock.patch( "fedora_cloud_image_uploader.handler.Uploader.download_image", lambda a, b, c, decompress: f"/test/{os.path.basename(b['path'].removesuffix('.xz'))}", @@ -122,7 +116,6 @@ def test_gallery_name(mock_runner, fixtures_dir, compose): def test_containers(mock_subrun, fixtures_dir, compose): mock_subrun.return_value.returncode = 0 message_file, cidorlabel, relnum, alias, expected_images = compose - registries = ["registry.fedoraproject.org", "quay.io/fedora"] # mapping of reponames to expected image filename base strings repotoid = { "fedora": "Fedora-Container-Base-Generic", @@ -136,7 +129,6 @@ def test_containers(mock_subrun, fixtures_dir, compose): with open(os.path.join(fixtures_dir, message_file)) as fd: msg = message.load_message(json.load(fd)) - config.conf["consumer_config"]["container"] = {"registries": registries} consumer = Uploader() # disable handlers we don't want to hit in this test @@ -149,7 +141,7 @@ def test_containers(mock_subrun, fixtures_dir, compose): # them all, and assert it's empty at the end calls = [" ".join(call.args[0]) for call in mock_subrun.call_args_list] - for registry in registries: + for registry in ["registry.fedoraproject.org", "quay.io/fedora"]: for exprepo, arches in expected_images.items(): # find the expected calls to skopeo copy for arch in arches: @@ -185,6 +177,7 @@ def test_containers(mock_subrun, fixtures_dir, compose): @pytest.mark.vcr +@mock.patch.dict(config.conf["consumer_config"], {"container": {}}) @mock.patch("subprocess.run") @mock.patch("fedora_cloud_image_uploader.handler.Uploader.download_image") def test_containers_registries_not_configured(mock_dl, mock_run, fixtures_dir): @@ -194,7 +187,6 @@ def test_containers_registries_not_configured(mock_dl, mock_run, fixtures_dir): """ with open(os.path.join(fixtures_dir, "messages/rawhide_compose.json")) as fd: msg = message.load_message(json.load(fd)) - config.conf["consumer_config"]["container"] = {} consumer = Uploader() # disable handlers we don't want to hit in this test @@ -206,29 +198,20 @@ def test_containers_registries_not_configured(mock_dl, mock_run, fixtures_dir): @pytest.mark.vcr +@mock.patch.dict( + config.conf["consumer_config"], + {"container": {"registries": ["registry.fedoraproject.org", "quay.io/fedora"]}}, +) @mock.patch( "fedora_cloud_image_uploader.handler.Uploader.download_image", lambda a, b, c, decompress: f"/test/{os.path.basename(b['path'].removesuffix('.xz'))}", ) @mock.patch("fedora_cloud_image_uploader.handler.ansible_runner") -def test_old_unsupported_azure_compose(mock_runner, fixtures_dir): +def test_old_unsupported_azure_compose(mock_runner, azure_fm_conf, fixtures_dir): mock_runner.interface.run.return_value.rc = 0 with open(os.path.join(fixtures_dir, "messages/unsupported_for_azure.json")) as fd: msg = message.load_message(json.load(fd)) - config.conf["consumer_config"]["azure"] = { - "location": "eastus", - "resource_group_name": "fedora-test", - "gallery_name": "Fedora", - "gallery_description": "The Fedora compute gallery.", - "storage_account_name": "fedoraimageuploads", - "storage_container_name": "vhds", - "target_regions": {}, - } - config.conf["consumer_config"]["container"] = { - "registries": ["registry.fedoraproject.org", "quay.io/fedora"] - } - consumer = Uploader() consumer(msg) assert mock_runner.interface.run.call_count == 0 @@ -277,10 +260,10 @@ def test_ansible_fail(mock_run, caplog): assert caplog.records[-1].msg == "Playbook failed with return code 1" +@mock.patch.dict(config.conf["consumer_config"], {"azure": {}}) @mock.patch("fedora_cloud_image_uploader.handler.ansible_runner") def test_azure_filters(mock_runner): """Test the cases where AzureHandler should decide not to handle.""" - config.conf["consumer_config"]["azure"] = {} relinfo = mock.MagicMock() relinfo.relnum = 40 image = {"type": "notonewelike", "arch": "x86_64", "subvariant": "Cloud_Base"} From d0f6558e8542bd95b9d3df619c9f8b40a8d788e4 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Jun 03 2024 17:57:22 +0000 Subject: [PATCH 2/2] Drop ReleaseInfo class now fedfind provides what we need fedfind 5.2.0 provides the relnum and eol properties which we were previously using this to contain. So, let's just use them from there, and simplify the code here. This obviously means we require fedfind 5.2.0, but none of the other requirements are versioned so I didn't version this one. Signed-off-by: Adam Williamson --- diff --git a/fedora_cloud_image_uploader/handler.py b/fedora_cloud_image_uploader/handler.py index 282fdcf..425e82f 100644 --- a/fedora_cloud_image_uploader/handler.py +++ b/fedora_cloud_image_uploader/handler.py @@ -7,7 +7,6 @@ import subprocess import tempfile import time from collections.abc import Iterable -from typing import NamedTuple import ansible_runner from azure import identity as az_identity @@ -45,17 +44,6 @@ def _run(args: Iterable[str]): raise fm_exceptions.Nack() -class ReleaseInfo(NamedTuple): - """ - Container for additional release info that fedfind does not - provide (until fedfind 5.2.0). - """ - - ffrel: ff_release.Release - relnum: int - eol: str - - class Uploader: def __init__(self): @@ -84,17 +72,16 @@ class Uploader: return try: - compose = ff_release.get_release(cid=compose_id) + ffrel = ff_release.get_release(cid=compose_id) except ff_exceptions.UnsupportedComposeError: _log.info("Skipping compose %s as it contains no images", compose_id) return # reset for each message self.container_repos = dict() - relinfo = self.get_relinfo(compose) try: - for image in compose.all_images: + for image in ffrel.all_images: for handler in self.handlers: - handler(image, relinfo) + handler(image, ffrel) except fm_exceptions.Nack: # If we failed to process an image, it's not likely the failure will resolve # itself in the time it takes to re-queue the message and then consume it again. @@ -107,13 +94,13 @@ class Uploader: for repo in self.container_repos: for registry in self.conf["container"]["registries"]: # something like "registry.fedoraproject.org/fedora:40" - regname = f"{registry}/{repo}:{str(relinfo.relnum)}" + regname = f"{registry}/{repo}:{str(ffrel.relnum)}" targets = [regname] # we also create aliased manifests for rawhide and # latest stable - if compose.release.lower() == "rawhide": + if ffrel.release.lower() == "rawhide": targets.append(f"{registry}/{repo}:rawhide") - elif relinfo.relnum == ff_helpers.get_current_release(branched=False): + elif ffrel.relnum == ff_helpers.get_current_release(branched=False): targets.append(f"{registry}/{repo}:latest") for target in targets: # wipe the manifest if it exists already @@ -137,35 +124,6 @@ class Uploader: ) _run(pushargs) - def get_relinfo(self, ffrel: ff_release.Release): - """ - Return a namedtuple that acts as a container for some useful - information about the release that multiple methods and - handlers share. - """ - if ffrel.release.lower() == "rawhide": - relnum = ff_helpers.get_current_release(branched=True) + 1 - else: - relnum = int(ffrel.release) - # get EOL data from Bodhi - try: - req = self.requests.get( - f"https://bodhi.fedoraproject.org/releases/F{relnum}", - timeout=30, - ) - req.raise_for_status() - bodhirel = req.json() - except RequestException as e: - _log.error("Failed to download release data from Bodhi: %s", e) - raise fm_exceptions.Nack() - eol = bodhirel["eol"] - if not eol and ffrel.release.lower() != "rawhide": - # It's probably a pre-release or GA image. We can reasonably guess - # EOL will be at _least_ a year. Better to under-promise and over-deliver. - eol = datetime.datetime.today() + datetime.timedelta(days=365) - eol = eol.strftime("%Y-%m-%d") - return ReleaseInfo(ffrel, relnum, eol) - def download_image(self, image: dict, dest_dir: str, decompress=False) -> str: """ Download, verify, and optionally decompress the image. @@ -246,7 +204,7 @@ class Uploader: _log.error(f"Playbook failed with return code {result.rc}") raise fm_exceptions.Nack() - def handle_azure(self, image: dict, relinfo: ReleaseInfo): + def handle_azure(self, image: dict, ffrel: ff_release.Release): """ Handle Azure images. """ @@ -255,31 +213,37 @@ class Uploader: if image["arch"] not in ("x86_64", "aarch64"): # unsupported arch return - if relinfo.relnum < 40: + if ffrel.relnum < 40: # images prior to F40 aren't supported return with tempfile.TemporaryDirectory() as workdir: image_path = self.download_image(image, workdir, decompress=True) # Generate variables - if hasattr(relinfo.ffrel, "label") and relinfo.ffrel.label: + if hasattr(ffrel, "label") and ffrel.label: # These are in the format {milestone}-X.Z - (y_release, z_release) = relinfo.ffrel.label.split("-")[1].split(".") + (y_release, z_release) = ffrel.label.split("-")[1].split(".") image_suffix = ( - relinfo.ffrel.release - if relinfo.ffrel.label.lower().startswith("rc") - else f"{relinfo.ffrel.release}-Prerelease" + ffrel.release + if ffrel.label.lower().startswith("rc") + else f"{ffrel.release}-Prerelease" ) else: - y_release = relinfo.ffrel.metadata["composeinfo"]["payload"]["compose"]["date"] - z_release = relinfo.ffrel.metadata["composeinfo"]["payload"]["compose"]["respin"] + y_release = ffrel.metadata["composeinfo"]["payload"]["compose"]["date"] + z_release = ffrel.metadata["composeinfo"]["payload"]["compose"]["respin"] image_suffix = ( - relinfo.ffrel.release - if relinfo.ffrel.release.lower() == "rawhide" - else f"{relinfo.ffrel.release}-Prerelease" + ffrel.release + if ffrel.release.lower() == "rawhide" + else f"{ffrel.release}-Prerelease" ) gallery_image_name = f"Fedora-Cloud-{image_suffix}" - image_version = f"{relinfo.relnum}.{y_release}.{z_release}" + image_version = f"{ffrel.relnum}.{y_release}.{z_release}" + eol = ffrel.eol + if not eol and ffrel.release.lower() != "rawhide": + # It's probably a pre-release or GA image. We can reasonably guess + # EOL will be at _least_ a year. Better to under-promise and over-deliver. + eol = datetime.datetime.today() + datetime.timedelta(days=365) + eol = eol.strftime("%Y-%m-%d") variables = { "location": self.conf["azure"]["location"], @@ -293,7 +257,7 @@ class Uploader: "image_source": image_path, "gallery_image_name": gallery_image_name, "gallery_image_version": image_version, - "end_of_life_date": relinfo.eol, + "end_of_life_date": eol, "exclude_from_latest": True, "ansible_remote_tmp": workdir, } @@ -384,7 +348,7 @@ class Uploader: f"Deleted image definition {image_definition.name} since it has no versions" ) - def handle_container(self, image: dict, relinfo: ReleaseInfo): + def handle_container(self, image: dict, ffrel: ff_release.Release): """Handle container images.""" registries = self.conf.get("container", {}).get("registries") if not registries: @@ -406,7 +370,7 @@ class Uploader: if not repo: _log.debug("Unknown subvariant %s", image["subvariant"]) return - if image["type"] == "docker" and relinfo.relnum < 40: + if image["type"] == "docker" and ffrel.relnum < 40: # these are actual docker archive images imgformat = "docker-archive" else: @@ -423,7 +387,7 @@ class Uploader: "skopeo", "copy", f"{imgformat}:{image_path}", - f"docker://{registry}/{repo}:{str(relinfo.relnum)}-{arch}", + f"docker://{registry}/{repo}:{str(ffrel.relnum)}-{arch}", ] _run(args) if repo in self.container_repos: diff --git a/tests/fixtures/cassettes/test_eol_synthesis.yaml b/tests/fixtures/cassettes/test_eol_synthesis.yaml new file mode 100644 index 0000000..5a761fd --- /dev/null +++ b/tests/fixtures/cassettes/test_eol_synthesis.yaml @@ -0,0 +1,1417 @@ +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/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=2343 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:05 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: + - Zl4D8dtTUPqi7MOERgbi4wAAB1g + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=2375 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:06 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: + - Zl4D8rz4XRHQn1YrXlVU1wAABwk + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=3447 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:06 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: + - Zl4D8uM-B-FNDJuGPnL-VQAAAoM + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=2401 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:06 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: + - Zl4D8ohu9NZMplB64Au_FgAAA8Y + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1992 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:06 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: + - Zl4D8txhKd5P8QL-8PAFVAAABYE + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=2011 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:07 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: + - Zl4D88CF6WWR5NXLEuTNPQAAAwQ + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1747 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:07 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: + - Zl4D89A2kX6Qh0wCUMTLcwAABgM + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1790 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:07 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: + - Zl4D89xhKd5P8QL-8PAFYAAABZg + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1787 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:07 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: + - Zl4D88CF6WWR5NXLEuTNSwAAAwc + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Content-Type: + - application/json + Host: + - pdc.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://pdc.fedoraproject.org/rest_api/v1/compose-images/Fedora-Cloud-40-20240503.0/?page=1 + response: + body: + string: '{"header":{"version":"1.2","type":"productmd.images"},"payload":{"images":{"Cloud":{"aarch64":[{"subvariant":"Cloud_Base","format":"raw.xz","volume_id":null,"mtime":1714713849,"checksums":{"sha256":"75925b86a52383e833f8bf07a1136accabcfaab1a1c9b72dc8736c86ddafdba7"},"arch":"aarch64","size":370981752,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-AmazonEC2.aarch64-40-20240503.0.raw.xz","type":"raw-xz"},{"subvariant":"Cloud_Base","format":"vhd.xz","volume_id":null,"mtime":1714714205,"checksums":{"sha256":"ca0814cb1abdb3794dddcd6e698512fcb90dc6c90d76c1664f99e96dff3f6d68"},"arch":"aarch64","size":434709264,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Azure.aarch64-40-20240503.0.vhdfixed.xz","type":"vhd-compressed"},{"subvariant":"Cloud_Base","format":"tar.gz","volume_id":null,"mtime":1714713884,"checksums":{"sha256":"309f10921a11ce619cea4d4dccd2dae01aca8bb940825bffd939b2a89a4a4b13"},"arch":"aarch64","size":413718664,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-GCE.aarch64-40-20240503.0.tar.gz","type":"docker"},{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713846,"checksums":{"sha256":"32d4485b7c4a6444aaaf85decd094c8f15609cd2d5fd51b66fd0d60e52d02eca"},"arch":"aarch64","size":413401088,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Generic.aarch64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base_UKI","format":"qcow2","volume_id":null,"mtime":1714714222,"checksums":{"sha256":"e52df12d824933cd3105b98c2537766e73f73c5bd4f7ba2335181a89f6bbc178"},"arch":"aarch64","size":414777344,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-UEFI-UKI.aarch64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base","format":"vagrant-libvirt.box","volume_id":null,"mtime":1714713927,"checksums":{"sha256":"b82c8cd80a6efa844166c1656f0b606976fbe868cf5e4c775b756ccc00d7416a"},"arch":"aarch64","size":566412569,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Vagrant-libvirt.aarch64-40-20240503.0.vagrant.libvirt.box","type":"vagrant-libvirt"}],"x86_64":[{"subvariant":"Cloud_Base","format":"raw.xz","volume_id":null,"mtime":1714713738,"checksums":{"sha256":"6eb1b8f55570b681ff5af3a21cb4b637755f7c0f8dbc47cfa6853f307f111589"},"arch":"x86_64","size":373315444,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-AmazonEC2.x86_64-40-20240503.0.raw.xz","type":"raw-xz"},{"subvariant":"Cloud_Base","format":"vhd.xz","volume_id":null,"mtime":1714713801,"checksums":{"sha256":"11076f84f8c74e4633f9195eac830a66dffd1032e077a863cf5a7f832daea837"},"arch":"x86_64","size":449121996,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Azure.x86_64-40-20240503.0.vhdfixed.xz","type":"vhd-compressed"},{"subvariant":"Cloud_Base","format":"tar.gz","volume_id":null,"mtime":1714713720,"checksums":{"sha256":"1c128860fe9fd77468bda748fd5edb4daf5c0dfe8b40750b2c44b9f583724539"},"arch":"x86_64","size":408094994,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-GCE.x86_64-40-20240503.0.tar.gz","type":"docker"},{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713683,"checksums":{"sha256":"0f5981337b758640bc0933d2b18df98011143910eca8134008aca2d2465dc248"},"arch":"x86_64","size":404946944,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base_UKI","format":"qcow2","volume_id":null,"mtime":1714713674,"checksums":{"sha256":"78276ae1879e98bcfcd419aaf3d1f37fdd2047149df65bc3b3b61b7e99d8cd63"},"arch":"x86_64","size":421527552,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-UEFI-UKI.x86_64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base","format":"vagrant-virtualbox.box","volume_id":null,"mtime":1714713755,"checksums":{"sha256":"102d8cfeee5b6900d0883f05ca1f2fbe8c1e286a34bfed3a3f486e1f8705afd9"},"arch":"x86_64","size":565651528,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-VirtualBox.x86_64-40-20240503.0.vagrant.virtualbox.box","type":"vagrant-virtualbox"},{"subvariant":"Cloud_Base","format":"vagrant-libvirt.box","volume_id":null,"mtime":1714713755,"checksums":{"sha256":"803d74c4df7cccfa4331d9d70225385aea54e9e15ee6e562f63600d147511251"},"arch":"x86_64","size":574878333,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-libvirt.x86_64-40-20240503.0.vagrant.libvirt.box","type":"vagrant-libvirt"}],"s390x":[{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713603,"checksums":{"sha256":"4b1802c43c0ee83b6976525e47818c134868903b442e362591772e4b76a46e67"},"arch":"s390x","size":372986368,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/s390x/images/Fedora-Cloud-Base-Generic.s390x-40-20240503.0.qcow2","type":"qcow2"}],"ppc64le":[{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713967,"checksums":{"sha256":"d19342d980a3da2f00dc2cf5c6dc338ffa60922c84e0eec566e1bc33a77904b5"},"arch":"ppc64le","size":402784256,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/ppc64le/images/Fedora-Cloud-Base-Generic.ppc64le-40-20240503.0.qcow2","type":"qcow2"}]}},"compose":{"date":"20240503","respin":0,"type":"production","id":"Fedora-Cloud-40-20240503.0"}}}' + headers: + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:08 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy11.fedoraproject.org + X-Fedora-RequestID: + - Zl4D9DieZgbc23mV7rBoQQAAAYM + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + allow: + - GET, HEAD, OPTIONS + apptime: + - D=271691 + cache-control: + - private, max-age=0, must-revalidate + content-type: + - application/json + set-cookie: + - SERVERID=pdc-web02; path=/ + vary: + - Accept,Cookie,Accept-Encoding + x-fedora-appserver: + - pdc-web02.iad2.fedoraproject.org + x-frame-options: + - SAMEORIGIN + - SAMEORIGIN + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Content-Type: + - application/json + Host: + - pdc.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://pdc.fedoraproject.org/rest_api/v1/composes/?compose_id=Fedora-Cloud-40-20240503.0&page=1 + response: + body: + string: '{"count":1,"next":null,"previous":null,"results":[{"compose_id":"Fedora-Cloud-40-20240503.0","compose_date":"2024-05-03","compose_type":"production","compose_respin":0,"release":"fedora-cloud-40","compose_label":"RC-20240503.0","deleted":false,"rpm_mapping_template":"https://pdc.fedoraproject.org/rest_api/v1/composes/Fedora-Cloud-40-20240503.0/rpm-mapping/{{package}}/","sigkeys":[],"acceptance_testing":"untested","linked_releases":[],"rtt_tested_architectures":{"Cloud":{"aarch64":"untested","x86_64":"untested","s390x":"untested","ppc64le":"untested"}}}]}' + headers: + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:08 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy11.fedoraproject.org + X-Fedora-RequestID: + - Zl4D9NqRfZ4n54fRwuQUdQAAAok + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + allow: + - GET, PUT, PATCH, DELETE, HEAD, OPTIONS + apptime: + - D=183470 + cache-control: + - private, max-age=0, must-revalidate + content-type: + - application/json + set-cookie: + - SERVERID=pdc-web01; path=/ + vary: + - Accept,Cookie,Accept-Encoding + x-fedora-appserver: + - pdc-web01.iad2.fedoraproject.org + x-frame-options: + - SAMEORIGIN + - SAMEORIGIN + 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=41457 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:09 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: + - Zl4D9ZvPRasb-g3BJnu2CwAAAdE + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '661' + content-type: + - application/json + set-cookie: + - 1caa5c4232b1a1f24f8c4f6e0f496284=cbca343a697424f4648bad1112e1f4a5; path=/; + HttpOnly; Secure; SameSite=None + x-content-type-options: + - nosniff + - nosniff + 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/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1832 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:09 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: + - Zl4D9dtTUPqi7MOERgbjHQAAB0Y + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1838 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:09 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: + - Zl4D9SVYRS0dbqajd0TCQQAAAZc + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1789 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:10 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: + - Zl4D9vRaprdPrkIxJpVa3QAABow + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1969 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:10 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: + - Zl4D9gFNGcyaq8Nels50UgAABQs + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1472 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:10 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: + - Zl4D9iQaUHfQ4zyABHYnAgAABcg + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1947 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:10 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: + - Zl4D9iVYRS0dbqajd0TCWAAAAYA + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/COMPOSE_ID + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1926 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:11 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: + - Zl4D9wy2bk9VDyIdlb6tTgAABlc + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=1846 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:11 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: + - Zl4D99A2kX6Qh0wCUMTLvQAABgg + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Host: + - kojipkgs.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://kojipkgs.fedoraproject.org/compose/cloud/Fedora-Cloud-40-20240503.0/compose + response: + body: + string: ' + + + + 404 Not Found + + + +

Not Found

+ +

The requested URL was not found on this server.

+ + + + ' + headers: + AppTime: + - D=2066 + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:11 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: + - Zl4D97z4XRHQn1YrXlVVOgAABwo + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + content-length: + - '196' + content-type: + - text/html; charset=iso-8859-1 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + - max-age=31536000; includeSubDomains; preload + status: + code: 404 + message: Not Found +- request: + body: null + headers: + Connection: + - close + Content-Type: + - application/json + Host: + - pdc.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://pdc.fedoraproject.org/rest_api/v1/compose-images/Fedora-Cloud-40-20240503.0/?page=1 + response: + body: + string: '{"header":{"version":"1.2","type":"productmd.images"},"payload":{"images":{"Cloud":{"aarch64":[{"subvariant":"Cloud_Base","format":"raw.xz","volume_id":null,"mtime":1714713849,"checksums":{"sha256":"75925b86a52383e833f8bf07a1136accabcfaab1a1c9b72dc8736c86ddafdba7"},"arch":"aarch64","size":370981752,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-AmazonEC2.aarch64-40-20240503.0.raw.xz","type":"raw-xz"},{"subvariant":"Cloud_Base","format":"vhd.xz","volume_id":null,"mtime":1714714205,"checksums":{"sha256":"ca0814cb1abdb3794dddcd6e698512fcb90dc6c90d76c1664f99e96dff3f6d68"},"arch":"aarch64","size":434709264,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Azure.aarch64-40-20240503.0.vhdfixed.xz","type":"vhd-compressed"},{"subvariant":"Cloud_Base","format":"tar.gz","volume_id":null,"mtime":1714713884,"checksums":{"sha256":"309f10921a11ce619cea4d4dccd2dae01aca8bb940825bffd939b2a89a4a4b13"},"arch":"aarch64","size":413718664,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-GCE.aarch64-40-20240503.0.tar.gz","type":"docker"},{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713846,"checksums":{"sha256":"32d4485b7c4a6444aaaf85decd094c8f15609cd2d5fd51b66fd0d60e52d02eca"},"arch":"aarch64","size":413401088,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Generic.aarch64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base_UKI","format":"qcow2","volume_id":null,"mtime":1714714222,"checksums":{"sha256":"e52df12d824933cd3105b98c2537766e73f73c5bd4f7ba2335181a89f6bbc178"},"arch":"aarch64","size":414777344,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-UEFI-UKI.aarch64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base","format":"vagrant-libvirt.box","volume_id":null,"mtime":1714713927,"checksums":{"sha256":"b82c8cd80a6efa844166c1656f0b606976fbe868cf5e4c775b756ccc00d7416a"},"arch":"aarch64","size":566412569,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/aarch64/images/Fedora-Cloud-Base-Vagrant-libvirt.aarch64-40-20240503.0.vagrant.libvirt.box","type":"vagrant-libvirt"}],"x86_64":[{"subvariant":"Cloud_Base","format":"raw.xz","volume_id":null,"mtime":1714713738,"checksums":{"sha256":"6eb1b8f55570b681ff5af3a21cb4b637755f7c0f8dbc47cfa6853f307f111589"},"arch":"x86_64","size":373315444,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-AmazonEC2.x86_64-40-20240503.0.raw.xz","type":"raw-xz"},{"subvariant":"Cloud_Base","format":"vhd.xz","volume_id":null,"mtime":1714713801,"checksums":{"sha256":"11076f84f8c74e4633f9195eac830a66dffd1032e077a863cf5a7f832daea837"},"arch":"x86_64","size":449121996,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Azure.x86_64-40-20240503.0.vhdfixed.xz","type":"vhd-compressed"},{"subvariant":"Cloud_Base","format":"tar.gz","volume_id":null,"mtime":1714713720,"checksums":{"sha256":"1c128860fe9fd77468bda748fd5edb4daf5c0dfe8b40750b2c44b9f583724539"},"arch":"x86_64","size":408094994,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-GCE.x86_64-40-20240503.0.tar.gz","type":"docker"},{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713683,"checksums":{"sha256":"0f5981337b758640bc0933d2b18df98011143910eca8134008aca2d2465dc248"},"arch":"x86_64","size":404946944,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base_UKI","format":"qcow2","volume_id":null,"mtime":1714713674,"checksums":{"sha256":"78276ae1879e98bcfcd419aaf3d1f37fdd2047149df65bc3b3b61b7e99d8cd63"},"arch":"x86_64","size":421527552,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-UEFI-UKI.x86_64-40-20240503.0.qcow2","type":"qcow2"},{"subvariant":"Cloud_Base","format":"vagrant-virtualbox.box","volume_id":null,"mtime":1714713755,"checksums":{"sha256":"102d8cfeee5b6900d0883f05ca1f2fbe8c1e286a34bfed3a3f486e1f8705afd9"},"arch":"x86_64","size":565651528,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-VirtualBox.x86_64-40-20240503.0.vagrant.virtualbox.box","type":"vagrant-virtualbox"},{"subvariant":"Cloud_Base","format":"vagrant-libvirt.box","volume_id":null,"mtime":1714713755,"checksums":{"sha256":"803d74c4df7cccfa4331d9d70225385aea54e9e15ee6e562f63600d147511251"},"arch":"x86_64","size":574878333,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-libvirt.x86_64-40-20240503.0.vagrant.libvirt.box","type":"vagrant-libvirt"}],"s390x":[{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713603,"checksums":{"sha256":"4b1802c43c0ee83b6976525e47818c134868903b442e362591772e4b76a46e67"},"arch":"s390x","size":372986368,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/s390x/images/Fedora-Cloud-Base-Generic.s390x-40-20240503.0.qcow2","type":"qcow2"}],"ppc64le":[{"subvariant":"Cloud_Base","format":"qcow2","volume_id":null,"mtime":1714713967,"checksums":{"sha256":"d19342d980a3da2f00dc2cf5c6dc338ffa60922c84e0eec566e1bc33a77904b5"},"arch":"ppc64le","size":402784256,"disc_count":1,"bootable":false,"implant_md5":null,"disc_number":1,"path":"Cloud/ppc64le/images/Fedora-Cloud-Base-Generic.ppc64le-40-20240503.0.qcow2","type":"qcow2"}]}},"compose":{"date":"20240503","respin":0,"type":"production","id":"Fedora-Cloud-40-20240503.0"}}}' + headers: + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:11 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy06.fedoraproject.org + X-Fedora-RequestID: + - Zl4D96pShBiDf8YhozuzogAAABg + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + allow: + - GET, HEAD, OPTIONS + apptime: + - D=236738 + cache-control: + - private, max-age=0, must-revalidate + content-type: + - application/json + set-cookie: + - SERVERID=pdc-web01; path=/ + vary: + - Accept,Cookie,Accept-Encoding + x-fedora-appserver: + - pdc-web01.iad2.fedoraproject.org + x-frame-options: + - SAMEORIGIN + - SAMEORIGIN + status: + code: 200 + message: OK +- request: + body: null + headers: + Connection: + - close + Content-Type: + - application/json + Host: + - pdc.fedoraproject.org + User-Agent: + - Python-urllib/3.12 + method: GET + uri: https://pdc.fedoraproject.org/rest_api/v1/composes/?compose_id=Fedora-Cloud-40-20240503.0&page=1 + response: + body: + string: '{"count":1,"next":null,"previous":null,"results":[{"compose_id":"Fedora-Cloud-40-20240503.0","compose_date":"2024-05-03","compose_type":"production","compose_respin":0,"release":"fedora-cloud-40","compose_label":"RC-20240503.0","deleted":false,"rpm_mapping_template":"https://pdc.fedoraproject.org/rest_api/v1/composes/Fedora-Cloud-40-20240503.0/rpm-mapping/{{package}}/","sigkeys":[],"acceptance_testing":"untested","linked_releases":[],"rtt_tested_architectures":{"Cloud":{"aarch64":"untested","x86_64":"untested","s390x":"untested","ppc64le":"untested"}}}]}' + headers: + Connection: + - close + Date: + - Mon, 03 Jun 2024 17:57:12 GMT + Referrer-Policy: + - same-origin + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Fedora-ProxyServer: + - proxy03.fedoraproject.org + X-Fedora-RequestID: + - Zl4D-JQGCAJ0Ghdsyo_cIwAAAlY + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + allow: + - GET, PUT, PATCH, DELETE, HEAD, OPTIONS + apptime: + - D=89253 + cache-control: + - private, max-age=0, must-revalidate + content-type: + - application/json + set-cookie: + - SERVERID=pdc-web01; path=/ + vary: + - Accept,Cookie,Accept-Encoding + x-fedora-appserver: + - pdc-web01.iad2.fedoraproject.org + x-frame-options: + - SAMEORIGIN + - SAMEORIGIN + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_handler.py b/tests/test_handler.py index 0e0e61c..7cefed2 100644 --- a/tests/test_handler.py +++ b/tests/test_handler.py @@ -7,7 +7,6 @@ import tempfile from datetime import timedelta from unittest import mock -import fedfind.release import pytest from azure.mgmt.compute.v2023_07_03.models import ( GalleryImage, @@ -16,7 +15,6 @@ from azure.mgmt.compute.v2023_07_03.models import ( ) from fedora_messaging import config, exceptions, message from freezegun import freeze_time -from requests.exceptions import RequestException from fedora_cloud_image_uploader import PLAYBOOKS, Uploader from fedora_cloud_image_uploader.handler import _run @@ -217,40 +215,29 @@ def test_old_unsupported_azure_compose(mock_runner, azure_fm_conf, fixtures_dir) assert mock_runner.interface.run.call_count == 0 +@mock.patch("fedora_cloud_image_uploader.handler.ansible_runner") @pytest.mark.vcr -@mock.patch("time.sleep") -@mock.patch("fedora_cloud_image_uploader.handler.Session.get", side_effect=RequestException) -def test_bodhi_fail(mock_get, mock_sleep, fixtures_dir, caplog): - """Test we error correctly on failure to reach Bodhi.""" - with open(os.path.join(fixtures_dir, "messages/rawhide_compose.json")) as fd: +def test_eol_synthesis(mock_runner, fixtures_dir, azure_fm_conf): + mock_runner.interface.run.return_value.rc = 0 + with open(os.path.join(fixtures_dir, "messages/stable_nightly_compose.json")) as fd: msg = message.load_message(json.load(fd)) consumer = Uploader() - with pytest.raises(exceptions.Nack): - consumer(msg) - assert caplog.records[-1].msg == "Failed to download release data from Bodhi: %s" - - -@pytest.mark.vcr -@mock.patch("fedora_cloud_image_uploader.handler.Session.get") -def test_release_info(mock_get): - """Test get_relinfo, including EOL synthesis.""" - mock_response = mock_get.return_value - mock_response.json.return_value = {"eol": None} - ffrel = fedfind.release.get_release(release=40) - consumer = Uploader() - with freeze_time("2024-05-08"): - relinfo = consumer.get_relinfo(ffrel) - assert relinfo.eol == "2025-05-08" - assert relinfo.relnum == 40 - assert relinfo.ffrel == ffrel + consumer.download_image = mock.Mock() + # first, check we get the real EOL + consumer(msg) + assert mock_runner.interface.run.call_args[1]["extravars"]["end_of_life_date"] == "2025-05-13" + # now, mock out the eol from fedfind, freeze time, and check the + # synthesis + with mock.patch("fedfind.release.Release.eol", None): + with freeze_time("2024-05-27"): + consumer(msg) + assert mock_runner.interface.run.call_args[1]["extravars"]["end_of_life_date"] == "2025-05-27" @mock.patch("ansible_runner.interface.run", autospec=True) def test_ansible_fail(mock_run, caplog): """Test we error correctly on ansible playbook failure.""" - relinfo = mock.MagicMock() - relinfo.relnum = 40 playbook = os.path.join(PLAYBOOKS, "azure.yml") consumer = Uploader() mock_run.return_value.rc = 1 @@ -264,21 +251,21 @@ def test_ansible_fail(mock_run, caplog): @mock.patch("fedora_cloud_image_uploader.handler.ansible_runner") def test_azure_filters(mock_runner): """Test the cases where AzureHandler should decide not to handle.""" - relinfo = mock.MagicMock() - relinfo.relnum = 40 + ffrel = mock.MagicMock() + ffrel.relnum = 40 image = {"type": "notonewelike", "arch": "x86_64", "subvariant": "Cloud_Base"} consumer = Uploader() - consumer.handle_azure(image, relinfo) + consumer.handle_azure(image, ffrel) assert mock_runner.call_count == 0 image["type"] = "vhd-compressed" image["arch"] = "ppc64le" - consumer.handle_azure(image, relinfo) + consumer.handle_azure(image, ffrel) assert mock_runner.call_count == 0 image["arch"] = "x86_64" - relinfo.relnum = 39 - consumer.handle_azure(image, relinfo) + ffrel.relnum = 39 + consumer.handle_azure(image, ffrel) assert mock_runner.call_count == 0 @@ -313,9 +300,8 @@ def test_non_handled_messages(mock_runner, fixtures_dir, caplog): @mock.patch("time.sleep") -@mock.patch("fedora_cloud_image_uploader.handler.Uploader.get_relinfo") @mock.patch("fedfind.release.get_release") -def test_consumer_handle_exceptions(mock_getrel, mock_relinfo, mock_sleep, fixtures_dir): +def test_consumer_handle_exceptions(mock_getrel, mock_sleep, fixtures_dir): """Test Uploader's handling of exceptions from Handlers.""" with open(os.path.join(fixtures_dir, "messages/rawhide_compose.json")) as fd: msg = message.load_message(json.load(fd))