Skip to content

Commit 25cccf5

Browse files
authored
Do not rely on Docker-Content-Digest when getting manifests (#526)
2 parents f571253 + e7c6b92 commit 25cccf5

4 files changed

Lines changed: 52 additions & 12 deletions

File tree

src/main/java/land/oras/Registry.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,19 @@ public Manifest getManifest(ContainerRef containerRef) {
553553
throw new OrasException(
554554
"Expected manifest but got index. Probably a multi-platform image instead of artifact");
555555
}
556-
ManifestDescriptor manifestDescriptor = ManifestDescriptor.of(descriptor);
557-
return Manifest.fromJson(descriptor.getJson()).withDescriptor(manifestDescriptor);
556+
String json = descriptor.getJson();
557+
String digest = descriptor.getDigest();
558+
if (digest == null) {
559+
LOG.debug("Digest missing from header, using from reference");
560+
digest = containerRef.getDigest();
561+
if (digest == null) {
562+
LOG.debug("Digest missing from reference, computing from content");
563+
digest = containerRef.getAlgorithm().digest(json.getBytes(StandardCharsets.UTF_8));
564+
LOG.debug("Computed index digest: {}", digest);
565+
}
566+
}
567+
ManifestDescriptor manifestDescriptor = ManifestDescriptor.of(descriptor, digest);
568+
return Manifest.fromJson(json).withDescriptor(manifestDescriptor);
558569
}
559570

560571
@Override
@@ -649,7 +660,7 @@ private void validateDockerContentDigest(HttpClient.ResponseWrapper<String> resp
649660
// We need a way to propagate the headers like scoped.
650661
// For now just skip validation
651662
if (digest == null) {
652-
LOG.warn("Docker-Content-Digest header not found in response. Skipping validation.");
663+
LOG.debug("Docker-Content-Digest header not found in response. Skipping validation.");
653664
return;
654665
}
655666
String computedDigest = SupportedAlgorithm.fromDigest(digest).digest(data);
@@ -662,7 +673,7 @@ private void validateDockerContentDigest(HttpClient.ResponseWrapper<Path> respon
662673
// We need a way to propagate the headers like scoped.
663674
// For now just skip validation
664675
if (digest == null) {
665-
LOG.warn("Docker-Content-Digest header not found in response. Skipping validation.");
676+
LOG.debug("Docker-Content-Digest header not found in response. Skipping validation.");
666677
return;
667678
}
668679
String computedDigest = SupportedAlgorithm.fromDigest(digest).digest(path);
@@ -679,7 +690,7 @@ private void validateDockerContentDigest(HttpClient.ResponseWrapper<Path> respon
679690
// We need a way to propagate the headers like scoped.
680691
// For now just skip validation
681692
if (digest == null) {
682-
LOG.warn("Docker-Content-Digest header not found in response. Skipping validation.");
693+
LOG.debug("Docker-Content-Digest header not found in response. Skipping validation.");
683694
return null;
684695
}
685696
SupportedAlgorithm.fromDigest(digest);

src/test/java/land/oras/GitHubContainerRegistryITCase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ void shouldPullIndex() {
4343
assertNotNull(index);
4444
}
4545

46+
@Test
47+
void shouldPUllManifest() {
48+
Registry registry = Registry.builder().build();
49+
ContainerRef containerRef1 = ContainerRef.parse(
50+
"ghcr.io/oras-project/oras@sha256:fd4c818e80ea594cbd39ca47dc05067c8c5690c4eee6c8aee48c508290a5a0c0");
51+
Manifest manifest = registry.getManifest(containerRef1);
52+
assertNotNull(manifest);
53+
}
54+
4655
@Test
4756
void shouldPullOneBlob() throws IOException {
4857
Registry registry = Registry.builder().build();

src/test/java/land/oras/HarborS3ITCase.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,28 @@
2929
import org.junit.jupiter.api.parallel.Execution;
3030
import org.junit.jupiter.api.parallel.ExecutionMode;
3131

32+
/**
33+
* Test disabled due to authentication
34+
* mkdir lib && touch lib/a
35+
* oras push demo.goharbor.io/oras/lib:foo lib
36+
*/
3237
@Execution(ExecutionMode.CONCURRENT)
3338
class HarborS3ITCase {
3439

3540
@TempDir
3641
Path tempDir;
3742

3843
@Test
39-
@Disabled("Only to test with demo Harbor S3 instance")
44+
@Disabled("Only to test with demo Harbor demo instance")
45+
void shouldGetManifest() {
46+
Registry registry = Registry.builder().defaults().build();
47+
ContainerRef containerRef1 = ContainerRef.parse("demo.goharbor.io/oras/lib:foo");
48+
Manifest manifest = registry.getManifest(containerRef1);
49+
assertNotNull(manifest);
50+
}
51+
52+
@Test
53+
@Disabled("Only to test with demo Harbor demo instance")
4054
void shouldPullOneBlob() {
4155
Registry registry = Registry.builder().defaults().build();
4256
ContainerRef containerRef1 = ContainerRef.parse("demo.goharbor.io/oras/lib:foo");

src/test/java/land/oras/PublicECRITCase.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import static org.junit.jupiter.api.Assertions.assertNotNull;
2424

25-
import org.junit.jupiter.api.Disabled;
2625
import org.junit.jupiter.api.Test;
2726
import org.junit.jupiter.api.parallel.Execution;
2827
import org.junit.jupiter.api.parallel.ExecutionMode;
@@ -47,13 +46,20 @@ void shouldPullAnonymousIndex() {
4746
}
4847

4948
@Test
50-
@Disabled("https://github.com/oras-project/oras-java/issues/522")
5149
void shouldPullManifest() {
52-
Registry registry = Registry.builder().build();
53-
ContainerRef containerRef = ContainerRef.parse(
50+
51+
// Via tag
52+
Registry registry1 = Registry.builder().build();
53+
ContainerRef containerRef1 = ContainerRef.parse("public.ecr.aws/bitnami/contour-operator:latest");
54+
Manifest manifest1 = registry1.getManifest(containerRef1);
55+
assertNotNull(manifest1);
56+
57+
// Via digest
58+
Registry registry2 = Registry.builder().build();
59+
ContainerRef containerRef2 = ContainerRef.parse(
5460
"public.ecr.aws/docker/library/alpine@sha256:59855d3dceb3ae53991193bd03301e082b2a7faa56a514b03527ae0ec2ce3a95");
55-
Manifest manifest = registry.getManifest(containerRef);
56-
assertNotNull(manifest);
61+
Manifest manifest2 = registry2.getManifest(containerRef2);
62+
assertNotNull(manifest2);
5763
}
5864

5965
@Test

0 commit comments

Comments
 (0)