Skip to content

Commit fe0f07b

Browse files
author
Yalin Li
authored
[ACR] Update manifest digest check (Azure#29207)
1 parent 5bd6b6f commit fe0f07b

File tree

3 files changed

+19
-30
lines changed

3 files changed

+19
-30
lines changed

sdk/containerregistry/azure-containerregistry/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/containerregistry/azure-containerregistry",
5-
"Tag": "python/containerregistry/azure-containerregistry_a2d3792ebb"
5+
"Tag": "python/containerregistry/azure-containerregistry_448865ae2e"
66
}

sdk/containerregistry/azure-containerregistry/azure/containerregistry/_container_registry_client.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@
4242
def _return_response_and_deserialized(pipeline_response, deserialized, _):
4343
return pipeline_response, deserialized
4444

45-
def _return_deserialized(_, deserialized, __):
46-
return deserialized
47-
4845
def _return_response_headers(_, __, response_headers):
4946
return response_headers
5047

@@ -799,15 +796,13 @@ def upload_manifest(
799796
cls=_return_response_headers,
800797
**kwargs
801798
)
802-
803799
digest = response_headers['Docker-Content-Digest']
800+
if not _validate_digest(data, digest):
801+
raise ValueError("The digest in the response does not match the digest of the uploaded manifest.")
804802
except ValueError:
805803
if repository is None or manifest is None:
806804
raise ValueError("The parameter repository and manifest cannot be None.")
807-
if not _validate_digest(data, digest):
808-
raise ValueError("The digest in the response does not match the digest of the uploaded manifest.")
809805
raise
810-
811806
return digest
812807

813808
@distributed_trace
@@ -855,6 +850,8 @@ def download_manifest(self, repository, tag_or_digest, **kwargs):
855850
856851
:param str repository: Name of the repository
857852
:param str tag_or_digest: The tag or digest of the manifest to download.
853+
When digest is provided, will use this digest to compare with the one calculated by the response payload.
854+
When tag is provided, will use the digest in response headers to compare.
858855
:returns: DownloadManifestResult
859856
:rtype: ~azure.containerregistry.models.DownloadManifestResult
860857
:raises ValueError: If the parameter repository or tag_or_digest is None.
@@ -872,16 +869,18 @@ def download_manifest(self, repository, tag_or_digest, **kwargs):
872869
**kwargs
873870
)
874871
)
875-
digest = response.http_response.headers['Docker-Content-Digest']
876872
manifest = OCIManifest.deserialize(cast(ManifestWrapper, manifest_wrapper).serialize())
877873
manifest_stream = _serialize_manifest(manifest)
874+
if tag_or_digest.startswith("sha256:"):
875+
digest = tag_or_digest
876+
else:
877+
digest = response.http_response.headers['Docker-Content-Digest']
878+
if not _validate_digest(manifest_stream, digest):
879+
raise ValueError("The requested digest does not match the digest of the received manifest.")
878880
except ValueError:
879881
if repository is None or tag_or_digest is None:
880882
raise ValueError("The parameter repository and tag_or_digest cannot be None.")
881-
if not _validate_digest(manifest_stream, digest):
882-
raise ValueError("The requested digest does not match the digest of the received manifest.")
883883
raise
884-
885884
return DownloadManifestResult(digest=digest, data=manifest_stream, manifest=manifest)
886885

887886
@distributed_trace
@@ -896,9 +895,7 @@ def download_blob(self, repository, digest, **kwargs):
896895
:raises ValueError: If the parameter repository or digest is None.
897896
"""
898897
try:
899-
deserialized = self._client.container_registry_blob.get_blob( # type: ignore
900-
repository, digest, cls=_return_deserialized, **kwargs
901-
)
898+
deserialized = self._client.container_registry_blob.get_blob(repository, digest, **kwargs)
902899
except ValueError:
903900
if repository is None or digest is None:
904901
raise ValueError("The parameter repository and digest cannot be None.")

sdk/containerregistry/azure-containerregistry/tests/test_container_registry_client.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
ArtifactTagOrder,
1717
ContainerRegistryClient,
1818
)
19-
from azure.containerregistry._helpers import _deserialize_manifest
19+
from azure.containerregistry._helpers import _deserialize_manifest, _serialize_manifest
2020
from azure.core.exceptions import ResourceNotFoundError, ClientAuthenticationError
2121
from azure.core.paging import ItemPaged
2222
from azure.identity import AzureAuthorityHosts
@@ -461,7 +461,6 @@ def test_upload_oci_manifest(self, containerregistry_endpoint):
461461

462462
# Assert
463463
response = client.download_manifest(repo, digest)
464-
assert response.digest == digest
465464
assert response.data.tell() == 0
466465
self.assert_manifest(response.manifest, manifest)
467466

@@ -472,9 +471,8 @@ def test_upload_oci_manifest(self, containerregistry_endpoint):
472471
@recorded_by_proxy
473472
def test_upload_oci_manifest_stream(self, containerregistry_endpoint):
474473
repo = self.get_resource_name("repo")
475-
base_path = os.path.join(self.get_test_directory(), "data", "oci_artifact")
476-
manifest_stream = open(os.path.join(base_path, "manifest.json"), "rb")
477-
manifest = _deserialize_manifest(manifest_stream)
474+
manifest = self.create_oci_manifest()
475+
manifest_stream = _serialize_manifest(manifest)
478476
with self.create_registry_client(containerregistry_endpoint) as client:
479477
self.upload_manifest_prerequisites(repo, client)
480478

@@ -483,7 +481,6 @@ def test_upload_oci_manifest_stream(self, containerregistry_endpoint):
483481

484482
# Assert
485483
response = client.download_manifest(repo, digest)
486-
assert response.digest == digest
487484
assert response.data.tell() == 0
488485
self.assert_manifest(response.manifest, manifest)
489486

@@ -494,18 +491,16 @@ def test_upload_oci_manifest_stream(self, containerregistry_endpoint):
494491
@recorded_by_proxy
495492
def test_upload_oci_manifest_with_tag(self, containerregistry_endpoint):
496493
repo = self.get_resource_name("repo")
494+
tag = "v1"
497495
manifest = self.create_oci_manifest()
498496
with self.create_registry_client(containerregistry_endpoint) as client:
499-
tag = "v1"
500-
501497
self.upload_manifest_prerequisites(repo, client)
502498

503499
# Act
504500
digest = client.upload_manifest(repo, manifest, tag=tag)
505501

506502
# Assert
507503
response = client.download_manifest(repo, digest)
508-
assert response.digest == digest
509504
assert response.data.tell() == 0
510505
self.assert_manifest(response.manifest, manifest)
511506

@@ -525,20 +520,17 @@ def test_upload_oci_manifest_with_tag(self, containerregistry_endpoint):
525520
@recorded_by_proxy
526521
def test_upload_oci_manifest_stream_with_tag(self, containerregistry_endpoint):
527522
repo = self.get_resource_name("repo")
528-
base_path = os.path.join(self.get_test_directory(), "data", "oci_artifact")
529-
manifest_stream = open(os.path.join(base_path, "manifest.json"), "rb")
530-
manifest = _deserialize_manifest(manifest_stream)
523+
tag = "v1"
524+
manifest = self.create_oci_manifest()
525+
manifest_stream = _serialize_manifest(manifest)
531526
with self.create_registry_client(containerregistry_endpoint) as client:
532-
tag = "v1"
533-
534527
self.upload_manifest_prerequisites(repo, client)
535528

536529
# Act
537530
digest = client.upload_manifest(repo, manifest_stream, tag=tag)
538531

539532
# Assert
540533
response = client.download_manifest(repo, digest)
541-
assert response.digest == digest
542534
assert response.data.tell() == 0
543535
self.assert_manifest(response.manifest, manifest)
544536

0 commit comments

Comments
 (0)