Skip to content

Commit 32a3070

Browse files
committed
Store resolve registry when probing descriptor and use it for copy operator
Signed-off-by: Valentin Delaye <jonesbusy@users.noreply.github.com>
1 parent 15d2874 commit 32a3070

11 files changed

Lines changed: 118 additions & 23 deletions

File tree

src/main/java/land/oras/Config.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ private Config(
6666
mediaType,
6767
annotations != null && !annotations.isEmpty() ? Map.copyOf(annotations) : null,
6868
null,
69+
null,
6970
null);
7071
this.data = data;
7172
}
@@ -77,6 +78,7 @@ private Config(String mediaType, String digest, long size, @Nullable String data
7778
mediaType,
7879
!annotations.configAnnotations().isEmpty() ? Map.copyOf(annotations.configAnnotations()) : null,
7980
null,
81+
null,
8082
null);
8183
this.data = data;
8284
}

src/main/java/land/oras/ContainerRef.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,16 @@ ContainerRef checkBlocked(Registry registry) throws OrasException {
472472
return this;
473473
}
474474

475+
@Override
476+
public ContainerRef forTarget(String target) {
477+
return forRegistry(target);
478+
}
479+
480+
@Override
481+
public String getTarget(OCI<ContainerRef> target) {
482+
return getEffectiveRegistry((Registry) target);
483+
}
484+
475485
/**
476486
* Return a copy of reference for a registry other registry
477487
* @param registry The registry

src/main/java/land/oras/CopyUtils.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ void copy(
6767

6868
Descriptor descriptor = source.probeDescriptor(sourceRef);
6969

70+
// Get the resolved source registry
71+
String resolveSourceRegistry = descriptor.getRegistry();
72+
Objects.requireNonNull(resolveSourceRegistry, "Registry is required for streaming copy");
73+
74+
// Get the resolve target registry
75+
String effectiveTargetRegistry = targetRef.getTarget(target);
76+
Objects.requireNonNull(effectiveTargetRegistry, "Target registry is required for streaming copy");
77+
7078
String contentType = descriptor.getMediaType();
7179
String manifestDigest = descriptor.getDigest();
7280
LOG.debug("Content type: {}", contentType);
@@ -78,9 +86,10 @@ void copy(
7886
Objects.requireNonNull(layer.getSize(), "Layer size is required for streaming copy");
7987
LOG.debug("Copying layer {}", layer.getDigest());
8088
target.pushBlob(
81-
targetRef.withDigest(layer.getDigest()),
89+
targetRef.forTarget(effectiveTargetRegistry).withDigest(layer.getDigest()),
8290
layer.getSize(),
83-
() -> source.fetchBlob(sourceRef.withDigest(layer.getDigest())),
91+
() -> source.fetchBlob(
92+
sourceRef.forTarget(resolveSourceRegistry).withDigest(layer.getDigest())),
8493
layer.getAnnotations());
8594
LOG.debug("Copied layer {}", layer.getDigest());
8695
}

src/main/java/land/oras/Descriptor.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public sealed class Descriptor permits Config, Manifest, Layer, Index {
6767
*/
6868
protected String json;
6969

70+
/**
71+
* The registry
72+
*/
73+
protected @Nullable String registry;
74+
7075
/**
7176
* Constructor
7277
* @param digest The digest
@@ -82,12 +87,14 @@ protected Descriptor(
8287
String mediaType,
8388
Map<String, String> annotations,
8489
String artifactType,
90+
String registry,
8591
String json) {
8692
this.digest = digest;
8793
this.size = size;
8894
this.mediaType = mediaType;
8995
this.annotations = annotations;
9096
this.artifactType = artifactType;
97+
this.registry = registry;
9198
this.json = json;
9299
}
93100

@@ -100,6 +107,15 @@ public String getJson() {
100107
return json;
101108
}
102109

110+
/**
111+
* Return the resolved registry. Useful to avoid querying registry blobs when the registry is already resolved in the descriptor.
112+
* @return The resolved registry or null if not resolved
113+
*/
114+
@JsonIgnore
115+
public @Nullable String getRegistry() {
116+
return registry;
117+
}
118+
103119
/**
104120
* Get the annotations
105121
* @return The annotations
@@ -178,6 +194,16 @@ protected Descriptor withJson(String json) {
178194
return this;
179195
}
180196

197+
/**
198+
* Return same instance but with resolved registry
199+
* @param registry The resolved registry
200+
* @return The descriptor with resolved registry
201+
*/
202+
protected Descriptor withRegistry(String registry) {
203+
this.registry = registry;
204+
return this;
205+
}
206+
181207
/**
182208
* Return this manifest descriptor as a subject
183209
* @return The subject
@@ -199,7 +225,7 @@ public Subject toSubject() {
199225
*/
200226
public static Descriptor of(
201227
String digest, Long size, String mediaType, Map<String, String> annotations, String artifactType) {
202-
return new Descriptor(digest, size, mediaType, annotations, artifactType, null);
228+
return new Descriptor(digest, size, mediaType, annotations, artifactType, null, null);
203229
}
204230

205231
/**
@@ -210,7 +236,7 @@ public static Descriptor of(
210236
* @return The descriptor
211237
*/
212238
public static Descriptor of(String digest, Long size, String mediaType) {
213-
return new Descriptor(digest, size, mediaType, null, null, null);
239+
return new Descriptor(digest, size, mediaType, null, null, null, null);
214240
}
215241

216242
/**
@@ -220,7 +246,7 @@ public static Descriptor of(String digest, Long size, String mediaType) {
220246
* @return The descriptor
221247
*/
222248
public static Descriptor of(String digest, Long size) {
223-
return new Descriptor(digest, size, Const.DEFAULT_DESCRIPTOR_MEDIA_TYPE, null, null, null);
249+
return new Descriptor(digest, size, Const.DEFAULT_DESCRIPTOR_MEDIA_TYPE, null, null, null, null);
224250
}
225251

226252
@Override

src/main/java/land/oras/Index.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private Index(
7070
@JsonProperty(Const.JSON_PROPERTY_MANIFESTS) List<ManifestDescriptor> manifests,
7171
@JsonProperty(Const.JSON_PROPERTY_ANNOTATIONS) Map<String, String> annotations,
7272
@JsonProperty(Const.JSON_PROPERTY_SUBJECT) Subject subject) {
73-
this(schemaVersion, mediaType, artifactType, manifests, annotations, subject, null, null);
73+
this(schemaVersion, mediaType, artifactType, manifests, annotations, subject, null, null, null);
7474
}
7575

7676
private Index(
@@ -81,8 +81,9 @@ private Index(
8181
Map<String, String> annotations,
8282
Subject subject,
8383
ManifestDescriptor descriptor,
84+
String registry,
8485
String json) {
85-
super(null, null, mediaType, annotations, artifactType, json);
86+
super(null, null, mediaType, annotations, artifactType, registry, json);
8687
this.schemaVersion = schemaVersion;
8788
this.descriptor = descriptor;
8889
this.subject = subject;
@@ -183,7 +184,8 @@ public Index withNewManifests(ManifestDescriptor manifest) {
183184
newManifests.add(ManifestDescriptor.fromJson(descriptor.toJson()));
184185
}
185186
newManifests.add(manifest);
186-
return new Index(schemaVersion, mediaType, artifactType, newManifests, annotations, subject, descriptor, json);
187+
return new Index(
188+
schemaVersion, mediaType, artifactType, newManifests, annotations, subject, descriptor, registry, json);
187189
}
188190

189191
@Override
@@ -209,7 +211,8 @@ public ManifestDescriptor getDescriptor() {
209211
* @return The manifest
210212
*/
211213
public Index withDescriptor(ManifestDescriptor descriptor) {
212-
return new Index(schemaVersion, mediaType, artifactType, manifests, annotations, subject, descriptor, json);
214+
return new Index(
215+
schemaVersion, mediaType, artifactType, manifests, annotations, subject, descriptor, registry, json);
213216
}
214217

215218
/**
@@ -233,7 +236,8 @@ public Subject getSubject() {
233236
* @return The index
234237
*/
235238
public Index withSubject(Subject subject) {
236-
return new Index(schemaVersion, mediaType, artifactType, manifests, annotations, subject, descriptor, json);
239+
return new Index(
240+
schemaVersion, mediaType, artifactType, manifests, annotations, subject, descriptor, registry, json);
237241
}
238242

239243
/**
@@ -260,7 +264,7 @@ public static Index fromPath(Path path) {
260264
* @return The index
261265
*/
262266
public static Index fromManifests(List<ManifestDescriptor> descriptors) {
263-
return new Index(2, Const.DEFAULT_INDEX_MEDIA_TYPE, null, descriptors, null, null, null, null);
267+
return new Index(2, Const.DEFAULT_INDEX_MEDIA_TYPE, null, descriptors, null, null, null, null, null);
264268
}
265269

266270
@Override

src/main/java/land/oras/Layer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private Layer(
6868
@JsonProperty(Const.JSON_PROPERTY_SIZE) @Nullable Long size,
6969
@JsonProperty(Const.JSON_PROPERTY_DATA) @Nullable String data,
7070
@JsonProperty(Const.JSON_PROPERTY_ANNOTATIONS) @Nullable Map<String, String> annotations) {
71-
super(digest, size, mediaType, annotations, null, null);
71+
super(digest, size, mediaType, annotations, null, null, null);
7272
this.data = data;
7373
this.blobPath = null;
7474
}
@@ -81,7 +81,7 @@ private Layer(
8181
* @param blobPath The path to the blob
8282
*/
8383
private Layer(String mediaType, String digest, long size, Path blobPath, Map<String, String> annotations) {
84-
super(digest, size, mediaType, annotations, null, null);
84+
super(digest, size, mediaType, annotations, null, null, null);
8585
this.data = null;
8686
this.blobPath = blobPath;
8787
}

src/main/java/land/oras/LayoutRef.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ public String getRepository() {
154154
return getFolder().toString();
155155
}
156156

157+
@Override
158+
public LayoutRef forTarget(String target) {
159+
return new LayoutRef(Path.of(target), tag);
160+
}
161+
162+
@Override
163+
public String getTarget(OCI<LayoutRef> target) {
164+
return folder.toString();
165+
}
166+
157167
@Override
158168
public boolean equals(Object o) {
159169
if (o == null || getClass() != o.getClass()) return false;

src/main/java/land/oras/Manifest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ private Manifest(
8484
mediaType,
8585
annotations != null && !annotations.isEmpty() ? Map.copyOf(annotations) : null,
8686
artifactType,
87+
null,
8788
null);
8889
this.schemaVersion = schemaVersion;
8990
this.descriptor = null;
@@ -101,13 +102,15 @@ private Manifest(
101102
Subject subject,
102103
List<Layer> layers,
103104
Annotations annotations,
105+
String registry,
104106
String json) {
105107
super(
106108
null,
107109
null,
108110
mediaType,
109111
Map.copyOf(annotations.manifestAnnotations()),
110112
artifactType != null ? artifactType.getMediaType() : null,
113+
registry,
111114
json);
112115
this.schemaVersion = schemaVersion;
113116
this.descriptor = descriptor;
@@ -208,6 +211,7 @@ public Manifest withArtifactType(ArtifactType artifactType) {
208211
subject,
209212
layers,
210213
Annotations.ofManifest(annotations),
214+
registry,
211215
json);
212216
}
213217

@@ -226,6 +230,7 @@ public Manifest withLayers(List<Layer> layers) {
226230
subject,
227231
layers,
228232
Annotations.ofManifest(annotations),
233+
registry,
229234
json);
230235
}
231236

@@ -244,6 +249,7 @@ public Manifest withConfig(Config config) {
244249
subject,
245250
layers,
246251
Annotations.ofManifest(annotations),
252+
registry,
247253
json);
248254
}
249255

@@ -262,6 +268,7 @@ public Manifest withSubject(Subject subject) {
262268
subject,
263269
layers,
264270
Annotations.ofManifest(annotations),
271+
registry,
265272
json);
266273
}
267274

@@ -280,6 +287,7 @@ public Manifest withAnnotations(Map<String, String> annotations) {
280287
subject,
281288
layers,
282289
Annotations.ofManifest(annotations),
290+
registry,
283291
json);
284292
}
285293

@@ -298,6 +306,7 @@ public Manifest withDescriptor(ManifestDescriptor descriptor) {
298306
subject,
299307
layers,
300308
Annotations.ofManifest(annotations),
309+
registry,
301310
json);
302311
}
303312

@@ -354,6 +363,7 @@ public static Manifest empty() {
354363
null,
355364
List.of(),
356365
Annotations.empty(),
366+
null,
357367
null);
358368
}
359369

src/main/java/land/oras/OCILayout.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ public Descriptor getDescriptor(LayoutRef ref) {
430430
@Override
431431
public Descriptor probeDescriptor(LayoutRef ref) {
432432
// We should probably optimize to avoid reading the descriptor and only get its attributes (JSON path?)
433-
return getDescriptor(ref).withJson(null);
433+
return getDescriptor(ref).withRegistry(ref.getFolder().toString()).withJson(null);
434434
}
435435

436436
private byte[] getDescriptorData(Descriptor descriptor) {

src/main/java/land/oras/Ref.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,18 @@ protected Ref(@Nullable String tag) {
7070
* @return The repository
7171
*/
7272
public abstract String getRepository();
73+
74+
/**
75+
* Return a container ref for the target repository
76+
* @param target The target repository
77+
* @return The container ref
78+
*/
79+
public abstract T forTarget(String target);
80+
81+
/**
82+
* Get the target repository for the ref
83+
* @param target The target repository
84+
* @return The target repository
85+
*/
86+
public abstract String getTarget(OCI<T> target);
7387
}

0 commit comments

Comments
 (0)