diff --git a/services/director/src/simcore_service_director/registry_proxy.py b/services/director/src/simcore_service_director/registry_proxy.py index bd80228d2fc7..9e4c95e864e1 100644 --- a/services/director/src/simcore_service_director/registry_proxy.py +++ b/services/director/src/simcore_service_director/registry_proxy.py @@ -94,7 +94,9 @@ async def _basic_auth_registry_request( raise ServiceNotAvailableError(service_name=path) elif response.status_code >= status.HTTP_400_BAD_REQUEST: - raise RegistryConnectionError(msg=str(response)) + raise RegistryConnectionError( + msg=f"{response}: {response.text} for {request_url}" + ) else: # registry that does not need an auth @@ -165,7 +167,9 @@ async def _auth_registry_request( # noqa: C901 if resp_wbasic.status_code == status.HTTP_404_NOT_FOUND: raise ServiceNotAvailableError(service_name=f"{url}") if resp_wbasic.status_code >= status.HTTP_400_BAD_REQUEST: - raise RegistryConnectionError(msg=f"{resp_wbasic}") + raise RegistryConnectionError( + msg=f"{resp_wbasic}: {resp_wbasic.text} for {url}" + ) resp_data = await resp_wbasic.json(content_type=None) resp_headers = resp_wbasic.headers return (resp_data, resp_headers) @@ -199,7 +203,22 @@ async def registry_request( if use_cache and (cached_response := await cache.get(cache_key)): assert isinstance(cached_response, tuple) # nosec return cast(tuple[dict, Mapping], cached_response) - + # Add proper Accept headers for manifest requests for accepting both v1 and v2 + if "manifests/" in path and method.upper() == "GET": + headers = session_kwargs.get("headers", {}) + headers.update( + { + "Accept": ", ".join( + [ + "application/vnd.docker.distribution.manifest.v2+json", + "application/vnd.docker.distribution.manifest.list.v2+json", + "application/vnd.docker.distribution.manifest.v1+prettyjws", + "application/json", + ] + ) + } + ) + session_kwargs["headers"] = headers app_settings = get_application_settings(app) try: response, response_headers = await _retried_request( @@ -394,12 +413,29 @@ async def get_image_labels( media_type == "application/vnd.docker.distribution.manifest.list.v2+json" ): - raise DockerRegistryUnsupportedManifestSchemaVersionError( - version=schema_version, - service_name=image, - service_tag=tag, - reason="Multiple architectures images are currently not supported and need to be implemented", + # default to x86_64 architecture + _logger.info( + "Image %s:%s is a docker image with multiple architectures. " + "Currently defaulting to x86_64 architecture", + image, + tag, ) + manifests = request_result.get("manifests", []) + if not manifests: + raise DockerRegistryUnsupportedManifestSchemaVersionError( + version=schema_version, + service_name=image, + service_tag=tag, + reason="Manifest list is empty", + ) + first_manifest_digest = manifests[0]["digest"] + request_result, _ = await registry_request( + app, + path=f"{image}/manifests/{first_manifest_digest}", + method="GET", + use_cache=not update_cache, + ) + config_digest = request_result["config"]["digest"] # Fetch the config blob config_result, _ = await registry_request(